Add automatted tests for Nav block editable list view#49433
Conversation
|
Size Change: +476 B (0%) Total Size: 1.34 MB
ℹ️ View Unchanged
|
|
Flaky tests detected in d94e5c1. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/4563456799
|
|
|
||
| // The options menu button is a sibling of the menu item gridcell. | ||
| const firstItemOptions = firstMenuItem | ||
| .locator( '..' ) // parent selector. |
There was a problem hiding this comment.
Same. Turns out reading the docs is useful 😆
There was a problem hiding this comment.
Nit: This technique assumes the structure of the button to be a direct child of the row, which might change as an implementation detail? I would probably refactor this to select the row instead in the first place:
const firstMenuRow = page.getByRole( 'row' )
.filter({ has: firstMenuItem });
const firstItemOptions = firstMenuRow
.getByRole( 'button', {
name: 'Options for Page Link block',
} );Isn't critical though!
There was a problem hiding this comment.
For whatever reason that didn't work. It ended up producing
getByRole( 'treegrid', { name: 'Block navigation structure' } )
.getByRole( 'row' )
.filter( {
has: getByRole( 'treegrid', { name: 'Block navigation structure' } )
.getByRole( 'gridcell', { name: 'Page Link link' } )
.filter( { hasText: 'Block 1 of 2, Level 1' } ),
} )
.getByRole( 'button', { name: 'Options for Page Link block' } );
|
|
||
| // Grab the text from the first result so we can check it was inserted. | ||
| const firstResultText = await firstResult | ||
| .locator( '.block-editor-link-control__search-item-title' ) // this is the only way to get the label text without the URL. |
There was a problem hiding this comment.
I tried to find a different way to target this to avoid the CSS selector but I couldn't :S
There was a problem hiding this comment.
Nope. There isn't a way which probably points to a flaw in the markup of the component. It's due an a11y review as part of #49091
There was a problem hiding this comment.
maybe add a comment referring that PR so we can update the test once that gets merged?
There was a problem hiding this comment.
I'm not sure there's an issue with the markup. It's a tricky one to solve.
You could possibly do something like this pseudocode:
const expectedPageTitle = 'My sample page';
await linkControl.search( expectedPageTitle );
await linkControl.selectOption( expectedPageTitle );
await expect( listView ).toHaveBlock( expectedPageTitle );Have the test select a known page title, rather than trying to read the text from the option.
It might also be good to assert that the URL added is correct.
There was a problem hiding this comment.
I would agree with @MaggieCabrera to add a comment referencing that PR, but it's non-blocking 👍 .
There was a problem hiding this comment.
Have the test select a known page title, rather than trying to read the text from the option.
That might be better.
There was a problem hiding this comment.
Only thing is if we ever change the implementation of "Recently Added" results in Link UI the test would start failing.
That's why I wanted to get the first result's text. I can extract to a helper on the utility class if that helps.
There was a problem hiding this comment.
I added a getSearchResultText method to the LinkControl test util class.
talldan
left a comment
There was a problem hiding this comment.
Looks good. Nice work on making them so comprehensive.
I think it would be good to add a ListView utils class, as some of the locators for gridcells span multiple lines and are repeated a lot. Test readability is one of the main things that keeps them maintainable, IMO.
It could be done after the initial merge though, as it would be good to get this in before #49417 (as was mentioned on that PR).
| } ); | ||
|
|
||
| test.describe( 'List view editing', () => { | ||
| test( 'it should show a list view in the inspector controls', async ( { |
There was a problem hiding this comment.
| test( 'it should show a list view in the inspector controls', async ( { | |
| test( 'shows list view in the inspector controls', async ( { |
In most frameworks test is just an alias for it, so the word it doesn't need to be in the description itself. I always think removing the word 'should' makes the description shorter and easier to read, so also suggesting that.
Maybe I should add some of this to the docs.
| await expect( | ||
| listView | ||
| .getByRole( 'gridcell', { | ||
| name: 'Page Link link', | ||
| } ) | ||
| .filter( { | ||
| hasText: 'Block 1 of 2, Level 1', // proxy for filtering by description. | ||
| } ) | ||
| .getByText( 'Top Level Item 1' ) | ||
| ).toBeVisible(); | ||
|
|
||
| await expect( | ||
| listView | ||
| .getByRole( 'gridcell', { | ||
| name: 'Submenu link', | ||
| } ) | ||
| .filter( { | ||
| hasText: 'Block 2 of 2, Level 1', // proxy for filtering by description. | ||
| } ) | ||
| .getByText( 'Top Level Item 2' ) | ||
| ).toBeVisible(); | ||
|
|
||
| await expect( | ||
| listView | ||
| .getByRole( 'gridcell', { | ||
| name: 'Page Link link', | ||
| } ) | ||
| .filter( { | ||
| hasText: 'Block 1 of 1, Level 2', // proxy for filtering by description. | ||
| } ) | ||
| .getByText( 'Test Submenu Item' ) | ||
| ).toBeVisible(); |
There was a problem hiding this comment.
This is really nice. I wonder if there's a way to ensure that the blocks are in the right order, maybe by selecting an nth row in the table as part of the selector.
It might also be good to port some of these tests over to the main List View once this PR is in, perhaps with groups and other blocks.
There was a problem hiding this comment.
I wonder if there's a way to ensure that the blocks are in the right order, maybe by selecting an nth row in the table as part of the selector.
The tricky part is getting a list of gridcells for the blocks but not including other gridcells. If you have that then you can do nth() and assert on that.
I spent far too long trying to do that with @kevin940726 yesterday so ended up settling on this route.
| const blockResults = page.getByRole( 'listbox', { | ||
| name: 'Blocks', | ||
| } ); | ||
|
|
||
| await expect( blockResults ).toBeVisible(); | ||
|
|
||
| const blockResultOptions = blockResults.getByRole( 'option' ); | ||
|
|
||
| // Expect to see the Page Link and Custom Link blocks as the nth(0) and nth(1) results. | ||
| // This is important for usability as the Page Link block is the most likely to be used. | ||
| await expect( blockResultOptions.nth( 0 ) ).toHaveText( 'Page Link' ); | ||
| await expect( blockResultOptions.nth( 1 ) ).toHaveText( 'Custom Link' ); | ||
|
|
||
| // Select the Page Link option. | ||
| const pageLinkResult = blockResultOptions.nth( 0 ); | ||
| await pageLinkResult.click(); |
There was a problem hiding this comment.
For some of these operations that are a bit more complex, it might help to include a utility class in the test file. Possibly one for LinkControl and one for ListView itself.
There's an example here:
gutenberg/test/e2e/specs/site-editor/style-variations.spec.js
Lines 215 to 234 in 9ee0f4b
And here's where it gets configured:
gutenberg/test/e2e/specs/site-editor/style-variations.spec.js
Lines 6 to 10 in 9ee0f4b
I think it could also be worth considering moving the block's List View tests into a separate file to keep things tidy.
There was a problem hiding this comment.
I haven't made any utilities yet. Curious to try that.
There was a problem hiding this comment.
I made one for Link Control.
and one for ListView itself.
I decided this was too much for this PR. Going to do a follow up.
|
|
||
| // Grab the text from the first result so we can check it was inserted. | ||
| const firstResultText = await firstResult | ||
| .locator( '.block-editor-link-control__search-item-title' ) // this is the only way to get the label text without the URL. |
There was a problem hiding this comment.
I'm not sure there's an issue with the markup. It's a tricky one to solve.
You could possibly do something like this pseudocode:
const expectedPageTitle = 'My sample page';
await linkControl.search( expectedPageTitle );
await linkControl.selectOption( expectedPageTitle );
await expect( listView ).toHaveBlock( expectedPageTitle );Have the test select a known page title, rather than trying to read the text from the option.
It might also be good to assert that the URL added is correct.
Should be visible by default. Left one test which will fail if the tab isn’t automatically pre-selected.
What?
Adds a series of tests to provide high level coverage for the editable list view in the Navigation block.
Why?
Currently this feature has no test coverage. These tests provide that.
Moreover, the
<OffcanvasEditor>which currently powers the editable list view in the Nav block is due to be refactor to use the standard<ListView>component. This refactoring would be a lot easier if the current functionality of the editable list view were covered by tests.How?
Adds Playwright e2e tests to cover the top level scenarios:
Testing Instructions
Run
Testing Instructions for Keyboard
Screenshots or screencast