Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Bug on URLInput & Intermitent end to end test on the buttons block #19490

Conversation

jorgefilipecosta
Copy link
Member

Description

Buttons had an end to end test that fails from time to time.
This PR adds a waitForSelector call to avoid this failure.

How has this been tested?

I executed the end to end tests for the buttons block multiple times and verified they consistently pass.

@jorgefilipecosta jorgefilipecosta added [Type] Bug An existing feature does not function as intended [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. labels Jan 7, 2020
@aduth
Copy link
Member

aduth commented Jan 7, 2020

Can you explain why it should have to wait? If we're using a plain URL, it shouldn't need to care that any search results exist for the entered input? (Just want to make sure we're not covering up a legitimate bug where a user might not be able to insert a link for a plain URL if search results haven't yet populated)

@jorgefilipecosta
Copy link
Member Author

jorgefilipecosta commented Jan 7, 2020

Hi @aduth thank you for sharing your thoughts 👍

We were pressing enter and right after we were checking the markup from the store:

		await page.keyboard.press( 'Enter' );
		expect( await getEditedPostContent() ).toMatchSnapshot();

I think the bug happened because after enter is pressed things need to be processed and it may take some time until getEditedPostContent() returns the markup with the link. That said I will need to restart the tests a few times to confirm this PR fixes the issue.

Just want to make sure we're not covering up a legitimate bug where a user might not be able to insert a link for a plain URL if search results haven't yet populated

If that's the case, I think this fix should not hide that issue because we are waiting after enter is pressed and not before while search results are being populated

@aduth
Copy link
Member

aduth commented Jan 8, 2020

According to the build failure, the test which was meant to be corrected is still failing, now with:

TimeoutError: waiting for selector "a.block-editor-link-control__search-item-title[href="https://www.wordpress.org/"]" failed: timeout 30000ms exceeded


I think the bug happened because after enter is pressed things need to be processed and it may take some time until getEditedPostContent() returns the markup with the link.

From the waitForSelector selector, I was expecting the revision to be in some way related to the search results. But based on what you're saying here, it's more to do with how the link is applied? I'd asked at some point in the past about what this sort of processing might be, because we've seen other similar issues, because it doesn't seem like there should be anything asynchronous happening here which would cause race conditions in the end-to-end test (cc @ellatrix). I don't consider it blocking, but the fact that we don't have a good understanding of what's happening here will probably make us prone to dealing with similar issues again in the future.

@jorgefilipecosta jorgefilipecosta force-pushed the fix/intermitent-end-2-end-test-on-the-buttons-block branch from 162b52c to 35cbc6e Compare January 8, 2020 18:58
@jorgefilipecosta jorgefilipecosta changed the title Fix: Intermitent end to end test on the buttons block Fix: Bug on URLInput & Intermitent end to end test on the buttons block Jan 9, 2020
@jorgefilipecosta
Copy link
Member Author

Hi @aduth,
I think you were right and we had a bug on the URLInput. I updated this PR to fix that bug.

Steps to reproduce:
I simulated a network with 5 seconds latency using the debugging tools.
I added a buttons block I inserted a link on the block.
I typed "someprotocol:ok" I verified pressing ok does nothing until the 5 seconds the request takes are passed. I typed enter after five seconds are passed and verified a link to "someprotocol:ok" was inserted.

In this PR pressing enter inserts the link right away even if the request was not finished.

@aduth
Copy link
Member

aduth commented Jan 9, 2020

I haven't looked in too much detail yet, but I wonder if the recent change might have some impact (improvement or conflict) on issues described at #19056 / #18933 (comment) . I know some of these link components use a form element and expect to be handling an Enter press as a form submission, so curious if explicitly handling the key press could help or hurt.

(I notice we're not event.preventDefault(), so if there was a form wrapper, it would still run its onSubmit handling, which could hypothetically be an issue if it would then proceed to try to duplicate the logic of selecting the link)

@jorgefilipecosta jorgefilipecosta force-pushed the fix/intermitent-end-2-end-test-on-the-buttons-block branch from 35cbc6e to 35e3da5 Compare January 13, 2020 16:02
@@ -179,6 +183,11 @@ class URLInput extends Component {
}
break;
}
case ENTER: {
event.preventDefault();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this preventing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, for the current enter keypress code we were calling "event.preventDefault();" so I followed similar logic. But, it seems the calls to event.preventDefault(); are not needed so I removed them.

@@ -214,9 +223,12 @@ class URLInput extends Component {
break;
}
case ENTER: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the above case for TAB ? It seems like it has an identical expected behavior, where it's selecting a link (but also with an explicit speak announcement?)

I wonder if we should just remove the condition on selectedSuggestion in both places, then handle a null/empty/undefined suggestion from selectLink as the current input value.

@jorgefilipecosta jorgefilipecosta force-pushed the fix/intermitent-end-2-end-test-on-the-buttons-block branch from 35e3da5 to 55ed619 Compare January 13, 2020 17:39
@jorgefilipecosta
Copy link
Member Author

I applied some changes to this PR:
Right now, when we press enter we always submit the link with what the user typed.
Previously if there was only one suggestion the link submitted would not be what the user typed but the first suggestion. That happened because the enter key was not handled, a form submission was triggered and given that the suggestions are buttons inside the form the onClick function of the only suggestion rendered was called this also triggered a warning #19056, #19462 (comment).
Of course, this change makes the user need to use the arrow key to select the suggestion if the user wants to use it, but this behavior is what normally happens on other autocompletes.

@aduth
Copy link
Member

aduth commented Jan 13, 2020

I don't know that we can force the current value to be passed up as the suggestion option, at least not based on how the component is currently documented:

https://github.com/WordPress/gutenberg/tree/master/packages/block-editor/src/components/url-input#onchange-url-string-post-object--function-1

This object is supposed to represent a post object. We can imitate some of these properties using the input value as a raw URL, but it seems prone to issues if we're communicating it as if it were a post, when it's not necessarily a post.

Based on some of my observations in #19462 (especially #19462 (comment)), I think we have some misunderstanding in what it's supposed to mean to "select" a link. If I understand correctly, URLInput isn't supposed to have any opinions about link submission, it purely holds a value. It depends on some ancestor component to manage how that value is applied, usually via a form's onSubmit, or some other button to commit the value.

With that in mind: I don't think we want to try to force the value to be treated as a selected suggestion, because that only perpetuates this idea that URLInput "submits" a value.

I think the true issue is a combination of:

<div class=\\"wp-block-button\\"><a class=\\"wp-block-button__link\\">WordPress</a></div>
<div class=\\"wp-block-button\\"><a class=\\"wp-block-button__link\\" href=\\"https://www.wordpress.org/\\" title=\\"https://www.wordpress.org/\\">WordPress</a></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change highlights another issue: I think we shouldn't want to assign a title attribute here? Based on what a title would be used for (advisory information), I would think it less meaningful than the text it's supposedly meant to advise.

It also seems like it could be an accessibility concern, to the extent that I might question whether we want to be surfacing title at all from LinkControl.

References:

Relying on the title attribute is currently discouraged as many user agents do not expose the attribute in an accessible manner as required by this specification (e.g., requiring a pointing device such as a mouse to cause a tooltip to appear, which excludes keyboard-only users and touch-only users, such as anyone with a modern phone or tablet).

https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute

Or: https://silktide.com/blog/2013/i-thought-title-text-improved-accessibility-i-was-wrong

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title should only be used to provide legitimate context to the link. It shouldn't repeat the link text. Therefore if the title isn't handcrafted by the user then it should be omitted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

title should only be used to provide legitimate context to the link. It shouldn't repeat the link text. Therefore if the title isn't handcrafted by the user then it should be omitted.

@getdave You might also be interested in my comment at #19462 (comment) , where I share a few more resources which would seem to support the claim that the title attribute should never be used for links.

[1] [2] [3] [4] [5]

https://core.trac.wordpress.org/ticket/24766

Do you have any more context for the value we were hoping to get out of it?

Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • We probably want to remove this onSelect handling, and only track the changes. The Enter behavior to select a link should take effect by the form's onSubmit.

I've been tracking this bug over at #19458.

I didn't fix it but came to the same conclusions as you. I believe we should approve this from the perspective of how we would craft this form if React were not a thing (ie: in plain old semantic HTML).

In this scenario we'd have a form with a submit handler that manages the value. For some reason we're not doing that and it's necessitating all kinds of bespoke keyboard handlers and also causing console warnings.

I agree that a rewrite of this logic is required.

@@ -179,6 +183,10 @@ class URLInput extends Component {
}
break;
}
case ENTER: {
// If pressing enter before suggestions are loaded use the current input as the link.
setCurrentInputAsLink();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly what I was thinking of doing in my PR. However, I decided it was probably papering over the cracks and we should rewrite the form submit handler logic instead.

@@ -52,6 +52,7 @@ async function updateActiveNavigationLink( { url, label } ) {
await page.type( 'input[placeholder="Search or type url"]', url );
// Wait for the autocomplete suggestion item to appear.
await page.waitForXPath( `//span[@class="block-editor-link-control__search-item-title"]/mark[text()="${ url }"]` );
await page.keyboard.press( 'ArrowDown' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: if we're entering a direct URL then should we have to use arrow to select an option before submitting the link back to the consuming component?

I'd say that you should be able to add whatever you type into the box using the ENTER key without first having to select the URL search suggestion.

In the future this PR will mean that URL search results actually mean something (ie: display data from the remote URL) but at the moment they are really only visual and serve no purpose.

@aduth
Copy link
Member

aduth commented Jan 20, 2020

Superseded by #19490

@aduth aduth closed this Jan 20, 2020
@aduth aduth deleted the fix/intermitent-end-2-end-test-on-the-buttons-block branch January 20, 2020 21:21
@jorgefilipecosta
Copy link
Member Author

Thank you for fixing this issue 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants