Skip to content

Fix flaky UI test - Firefox star_labs/applab/shared_apps - #51266

Merged
fisher-alice merged 19 commits into
stagingfrom
alice/fix-firefox-starlabs-applab-test
Apr 19, 2023
Merged

Fix flaky UI test - Firefox star_labs/applab/shared_apps#51266
fisher-alice merged 19 commits into
stagingfrom
alice/fix-firefox-starlabs-applab-test

Conversation

@fisher-alice

@fisher-alice fisher-alice commented Apr 11, 2023

Copy link
Copy Markdown
Contributor

This PR:

  • updates the UI tests shared_apps.featureand person_project_gallery.feature,
  • adds a And I wait until element...has the value... command in steps.rb

My original task was to fix the flaky Firefox star_labs/applab/shared_apps UI test. I examined this consistently flaky UI test's history over the week of April 4-11 in SauceLabs Insights. Out of 70 test runs, there were 11 failures. There were an additional 6 test errors due to a SauceLabs outage on April 6. Discounting these errors, the failure rate of this UI test is ~17%.
Interestingly, the failures occurred at 2 different places in the UI test. 4/11 failures occurred after line 34 and 7 occurred after line 87.

Taking a look at several of the videos of the failed runs in Sauce Labs, I didn't notice anything unusual about the UI at the 2 failure points.

At line 35, we test that after the 'testButton1' is clicked, the text the button contains changes from 'Click Me' to 'Clicked'. It seems like when the test is checking the contained text after the click, there isn't enough time allowed for the text to change. Thus, I modify the statement on line 35 to And I wait until element "#testButton1" contains text "Clicked".

At line 88, we test that after the keys 'GLULX' are pressed in the input box, the input box text has the value of 'GLULX'. Similar to the situation above, it seems like when the test is checking the value of the input box, there isn't enough time for the value to change. Initially, I added And I wait for 3 seconds before checking the value of the input box because because I saw examples of this command in several other UI test files.

However, I discussed with @breville this approach, and he suggested instead to use a command that waited for something specific to have changed (visibility or content). When Sauce Labs is particularly slow, 3 seconds may not be sufficient, but normally, it may be longer than needed.

Although there is a command that waits for an element's contained text to change, there isn't a command that waits until an element's value has changed.

At first, I modified the And I press keys...for element... command and added a wait_short_until that waits up to 30 seconds until the element's value string matched the string composed of the keys that were pressed. It evolved quite a bit because there were many different cases to consider - these cases are described more in detail below. Eventually, I added a new command And I wait until element...has the value.... This new command can be called in flaky tests for which the subsequent command is checking the value but the value hasn't had time to change yet.

Special cases that were considered:

  1. As I mentioned above, the condition I set for the wait_short_until was initially the element's value string matching the key string. However, there are cases when the user presses keys for an input box that already contains text.

This occurs in the personal_projects_gallery.feature test. When I watched the Sauce Labs video of a failed test run after my update, I saw that the project title 'Old Name' was in the input box and 'New Name' was appended to the existing title.
Go to 1:21.

video.mp4

Thus, I added the line And I clear the text from element ".ui-project-rename-input" before pressing the keys for 'New Name' in personal_projects_gallery.feature.

An example of a UI test for which the text in an input box is intentionally not cleared is in scenarios.feature. In the 'Scenario: Change event works in text input and text area', the user enters the keys '123' into the input box, and then '456' without clearing the previous input. Thus, the debug console prints all 6 digits.

  1. When press keys "456\n" is executed, the newline character is not included in the value of the element.

  2. Special keys are used such as ":enter" and ":down" in droplet.feature when the keys pressed are for element ".ace_text-input".

  3. There are instances when we refer to user-entered data using syntax such as'#{@temp_user_data}'.

Thanks to @breville for pairing with me on this task. It was a really valuable introduction to UI tests and the Ruby language.

Links

jira ticket

Testing story

I set up locally to run tests remotely on Sauce Labs.

Deployment strategy

Follow-up work

While updating this UI test, noticed @no_ie tags still existing in test files even though we no longer run tests on IE. Remove references to tags '@eyes_ie' and '@no_ie'.
jira ticket

Privacy

Security

Caching

PR Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@fisher-alice fisher-alice changed the title Closed Fix flaky UI test - Firefox star_labs/applab/shared_apps Fix flaky UI test - Firefox star_labs/applab/shared_apps Apr 11, 2023
@fisher-alice
fisher-alice marked this pull request as ready for review April 11, 2023 15:15
@fisher-alice
fisher-alice requested review from a team and breville April 11, 2023 15:15
@fisher-alice
fisher-alice marked this pull request as draft April 11, 2023 15:27
@fisher-alice
fisher-alice marked this pull request as ready for review April 12, 2023 18:00
Then element "#checkbox1" is checked
And element "#checkbox2" is checked

@no_ie

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this still needed with the below fix that adds a wait?

@fisher-alice fisher-alice Apr 12, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The comment above the step definition is that 'IE does not register the key presses in this step`. So does adding a wait resolve this issue? Seems like if we're on IE, we would just wait 30 sec and then proceed to next step.

Also, I'm new to UI tests, but do we check on IE still? I don't see IE listed at https://test-studio.code.org/ui_test/test_status_UI.html.

I see you added mentioned @no_ie tags in this past PR.

Either way, I'm happy to remove tag!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, I'm new to UI tests, but do we check on IE still?

Hah, I don't think I do, otherwise it would be listed in browsers.json. Looks like we removed it here.

@fisher-alice fisher-alice Apr 12, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cool! I see Darin wrote in the PR that removed IE:

Not removing IE references from
- test cases with @eyes_ie or @no_ie annotations
- assertions of IE compatability in "activity-guidelines" or other documents
We recommend that teams spend some time searching for any cleanup opportunities.

I'll go ahead and remove this tag - should I go ahead and remove this tag and comments/references to it in other files in this PR or in a separate PR?
I'll also create a ticket to remove the other @no_ie and @eyes_ie tags and comments/references to them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@fisher-alice
fisher-alice requested a review from breville April 12, 2023 22:46
press_keys(element, key)
wait_short_until do
element_text = element.attribute("value")
element_text.include? key

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are there remaining known cases in which this text might not match exactly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There were other tests that failed on the Drone build so I surmise that there are. I can follow up with an investigation to see if other tests can be updated similar to personal_projects_gallery.feature.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Seems reasonable. It might be worth adding a brief comment to explain this deliberate behaviour.

@breville breville left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Curious about more recent changes.

@fisher-alice

Copy link
Copy Markdown
Contributor Author

Curious about more recent changes.

Yes - I've been following up on other UI tests and pushed another change based on findings. Happy to discuss!

@fisher-alice
fisher-alice requested a review from breville April 13, 2023 15:16
Comment on lines +1151 to +1159
only_alphanumeric_backslash = key.gsub(/[^0-9a-z \\]/i, '') == key
check_key_values = only_alphanumeric_backslash && selector != ".ace_text-input"
if check_key_values
wait_short_until do
element_text = element.attribute("value")
input_key = key.delete "\n"
element_text.include? input_key
end
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just to capture our discussion:

For a newcomer arriving at this code, even if a lot of comments are added, it feels like there is a lot of special-casing here, mostly related to Droplet, that will be hard to figure out. I think it would probably be better to keep "I press keys X for element Y" really simple, where it just does what it says, which is press some specific keys. That means going back to how it was before.

This would mean that if we want to wait until we know the text has been entered, we would add another step that does that, and modify the tests to call that additional step. The downside is that we don't get the wait everywhere "for free" without changing the tests, but the upside is that we can customise what we look for to handle specific situations, such as in Droplet.

One other possibility would be to have two different steps here: one which is the regular "I press keys X for element Y" and does wait for the result in a typical input, and another which is a "I press keys X for element Y in Droplet" and which does the special-casing unique to Droplet.

@fisher-alice fisher-alice Apr 13, 2023

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks Brendan! I opted for adding a command that presses keys and then waits for the value to change appropriately. But this new command will strip out the "\n" from the input string. Lmk what you think.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

After discussion online, I updated the step to wait until element's value changes to expected value.

@fisher-alice
fisher-alice requested review from a team and breville April 13, 2023 18:36
And I wait until element "#divApplab > .screen > div#text_area1" is visible
Then element "div#text_area1" has html "Line 1<div>Line 2</div><div><br></div><div>Line3</div>"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

super nit: remove unnecessary whitespace.

Then element "#testButton1" contains text "Click me"
When I press "testButton1"
Then element "#testButton1" contains text "Clicked"
And I wait until element "#testButton1" contains text "Clicked"

@breville breville Apr 14, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Out of curiosity would step element X eventually contains text Y also have worked?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I tried this command and it works as well.

Is there a reason to use one command vs the other?

Also, there are different versions:

  • When I press "testButton1" Then element "#testButton1" eventually contains text "Clicked"
  • And I press "testButton1" And element "#testButton1" eventually contains text "Clicked"

It doesn't seem to make a difference to use when/then vs and/and. Is there a convention? Thanks!

@breville breville Apr 14, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like "wait until element X contains text Y" uses jQuery, here, injected into the browser, while "element X eventually contains text Y" uses Selenium functionality and also ensures that the element includes Y but isn't an necessarily an exact match, here and here. So I guess you can pick the best one for the job, though it's probably just a quirk of history that we have two similar but different steps. Whenever we add new steps, we should take to keep things well-factored and avoid duplicate functionality.

I believe those keywords are interchangeable. Details here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thank you for the refs and the resource link! Definitely will take another look to make sure that the new step I'm adding is not duplicating an existing step.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I will go ahead and use "wait until element X contains text Y" because it is used four other times in this file.

Also, I looked for an existing step command which waited a given amount of time before checking the value of an element, but I did not find it. I did see 'Then I wait up to X seconds for element Y to have css property Z equal to W". But not a step that checked the value of an element within a certain time interval.

@fisher-alice
fisher-alice merged commit a3b4578 into staging Apr 19, 2023
@fisher-alice
fisher-alice deleted the alice/fix-firefox-starlabs-applab-test branch April 19, 2023 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants