-
Notifications
You must be signed in to change notification settings - Fork 2k
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
E2E: refactor Support specs into one flow. #76960
Conversation
This PR does not affect the size of JS and CSS bundles shipped to the user's browser. Generated by performance advisor bot at iscalypsofastyet.com. |
this.page.waitForSelector( selectors.resultsPlaceholderHelpCenter, { state: 'hidden' } ), | ||
this.page.waitForSelector( selectors.resultsPlaceholder, { state: 'hidden' } ), | ||
] ); | ||
this.root = this.page.getByLabel( 'Help Center' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a technique/style I learned from working on the Gutenberg Playwright migration, specifically this comment.
The idea is that, when using role-based selectors (as recommended by Playwright now), we trade legibility for some ambiguity in the locator structure. For instance, the following locator is easy to read and understand, but there is potential to match on multiple elements on a page.
page.getByRole('button', { name: 'home' });
By always selecting from a parent/root locator it is possible to understand the overall structure hierarchy.
Note: if I was following the Gutenberg code style, this would probably be named something like this.helpCenter
instead of this.root
.
expect( articles ).toBeTruthy(); | ||
expect( links ).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change in assertion is also from my experience with Gutenberg Playwright migration. In working on the PR, one thing that was repeated over the course of the PR is to not structure tests around implementation details.
In the case of Support testing, my thoughts are that the following constitute implementation detail:
- how the results are presented;
- the order in which the results are presented.
Additionally, we cannot control:
- names of the returned resources;
- how many results are returned.
Throw on top of this the fact that the reworked Support popover does not have a true "empty results" state anymore and it becomes apparent the existing component is no longer fit for purpose.
By removing the assertion for default state is shown
or empty results are shown
and instead testing that the query returned some sort of results for the expected categories, implementation detail testing is removed as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I'd go for the isGreaterThan( 0 )
matcher instead of toBeTruthy()
. The reason for that is that articles
or links
could be an array as well, and expect( [] ).toBeTruthy()
would return true. Being a little bit more explicit here could potentially guard us against some false negatives in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for that is that articles or links could be an array as well, and expect( [] ).toBeTruthy() would return true.
Great point and something I have yet to come to grips with despite a couple of years of working in JS/TS ecosystem.
Assertions changed in 23ed24e76e93e4ec1b0598cbedc0e6ad2f89f4dd, but may change again if the loop stress test fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This spec has been removed because of a couple of reasons:
- the support card present in
/home
serves up an older version of the inline help. - usage for the support card in
/home
is lower than the popover help.
For the second point, I compared the Tracks events for the two different Supports that are in production.
calypso_inlinehelp_show
(new Support)calypso_inlinehelp_article_open
(legacy Support)
For the legacy Support, the calypso_inlinehelp_article_open
stands in for the number of times a user interacts with the card and opens a link. It is not the perfect approximation, but there is no Tracks event exclusively for the user interacting with the card.
For a 7-day trailing period as of today, the popover has ~66k interactions while the card has just under half at ~31k interactions. So while not trivial, the card variant sees significantly fewer interactions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few non-blocking comments. Thanks! 🚀
await Promise.all( [ | ||
// Waits for all placeholder CSS elements to be removed from the DOM. | ||
this.waitForQueryComplete(), | ||
this.page.waitForSelector( selectors.supportPopoverButton() ), | ||
this.page.click( selectors.supportPopoverButton() ), | ||
] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand this chain - why do we need to wait for the same selector we're about to click here? I think it's what internally happens with click()
- before it clicks, it waits for the given selector to be clickable, so the click
itself should be sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was a mistake on my part. Can't think of reasons to explain this, all I can maybe come up with is that I mistyped a selector and forgot about it.
Edit: it looks like this was in place in the original file. Even more of a head scratcher.
expect( articles ).toBeTruthy(); | ||
expect( links ).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I'd go for the isGreaterThan( 0 )
matcher instead of toBeTruthy()
. The reason for that is that articles
or links
could be an array as well, and expect( [] ).toBeTruthy()
would return true. Being a little bit more explicit here could potentially guard us against some false negatives in the future.
major refactor - use locators and role-based locators where possible - replace single-purpose methods with multi-purpose methods
test/e2e/specs/support/support__home.ts - discontinue. test/e2e/specs/support/support__showme-where.ts - refactor to use the popover. test/e2e/specs/support/support__popover-invalid.ts - merge into one. test/e2e/specs/support/support__popover-valid.ts - merge into one. test/e2e/specs/support/support__popover.ts - merged spec that runs the "invalid" and "valid" choices. - discontinue parametrization.
- rename step packages/calypso-e2e/src/lib/components/support-component.ts - add wait for the placeholder to disappear
- replace the placeholder CSS
- replace `this.root` with `this.helpCenter`.
- return named values instead of array of values - add comment for the URL being matched. test/e2e/specs/support/support__popover.ts - change how the values being returned are referenced. - change the assertions to check `greaterthan` and `tobe`. test/e2e/specs/support/support__showme-where.ts - add URL example
- refactor the popover methods
- wait for the results to populate first
f53cfb7
to
3c656b6
Compare
- remove debug message
- remove commented out code - update comment
this.page.waitForSelector( selectors.resultsPlaceholderHelpCenter, { state: 'hidden' } ), | ||
this.page.waitForSelector( selectors.resultsPlaceholder, { state: 'hidden' } ), | ||
] ); | ||
this.helpCenter = this.page.locator( '.components-card__body > .inline-help__search' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new solution wasn't perfect (failed at 94 iterations) but it was much better than the previous ones I had come up with, plus I didn't want to block #76734. |
Fixes #76916.
Proposed Changes
This PR is a semi-major refactor of how we think about Support related E2E specs. These specs were a near carbon copy of the ones that existed back in the Selenium framework days (prior to 2021).
Now that we have the ability to execute component testing with `react-testing-library, most of what's covered in the specs (even in revised form) should be tested at the component level.
However, to address the issue of permanent failure in #76916, I've decided to restructure the specs as a temporary bridge until they are moved into the component testing level.
Key changes:
/home
.Testing Instructions
Ensure the following build configurations are passing:
Pre-merge Checklist