Skip to content

Commit

Permalink
Fix flaky widgets-related E2E tests (#33066)
Browse files Browse the repository at this point in the history
* Remove empty keys from the compared object

* Revert dev artifacts

* Disable the gutenberg-test-marquee-widget plugin

* Wrap marquee tests in their own describe statement

* Lint

* Update snapshots

* Replace hello with howdy

* Move plugin activation to beforeEach

* Move deleteAllWidgets to beforeEach

* Update tests

* use data-testid rather than name attribute selectors

* Remove any existing marquees before running the tests, use the "save" form button

* Remove dev artifact

Co-authored-by: Kai Hao <[email protected]>
(cherry picked from commit 5cafe02)
  • Loading branch information
adamziel authored and desrosj committed Jul 2, 2021
1 parent 95b2117 commit 178ba0b
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 95 deletions.
20 changes: 11 additions & 9 deletions packages/e2e-tests/plugins/marquee-function-widget.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ function() {
$greeting = get_option( 'marquee_greeting' );
?>
<p>
<label for="marquee-greeting">Greeting:</label>
<input
id="marquee-greeting"
class="widefat"
name="marquee-greeting"
type="text"
value="<?php echo esc_attr( $greeting ); ?>"
placeholder="Hello!"
/>
<label>
Greeting:
<input
class="widefat"
data-testid="marquee-greeting"
name="marquee-greeting"
type="text"
value="<?php echo esc_attr( $greeting ); ?>"
placeholder="Hello!"
/>
</label>
</p>
<?php
}
Expand Down
190 changes: 104 additions & 86 deletions packages/e2e-tests/specs/widgets/editing-widgets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
* External dependencies
*/
// eslint-disable-next-line no-restricted-imports
import { find, findAll, waitFor } from 'puppeteer-testing-library';
import { find, findAll } from 'puppeteer-testing-library';
import { groupBy, mapValues } from 'lodash';

describe( 'Widgets screen', () => {
Expand Down Expand Up @@ -89,6 +89,12 @@ describe( 'Widgets screen', () => {
);
expect( categoryHeaders.length > 0 ).toBe( true );

const searchBox = await find( {
role: 'searchbox',
name: 'Search for blocks and patterns',
} );
await searchBox.type( blockName );

const addBlock = await find(
{
role: 'option',
Expand Down Expand Up @@ -394,109 +400,123 @@ describe( 'Widgets screen', () => {
` );
} );

async function addMarquee() {
// There will be 2 matches here.
// One is the in-between inserter,
// and the other one is the button block appender.
const [ inlineInserterButton ] = await findAll( {
role: 'combobox',
name: 'Add block',
} );
await inlineInserterButton.click();

// TODO: Convert to find() API from puppeteer-testing-library.
const inserterSearchBox = await page.waitForSelector(
'aria/Search for blocks and patterns[role="searchbox"]'
);
await expect( inserterSearchBox ).toHaveFocus();
describe( 'Function widgets', () => {
async function addMarquee( nbExpectedMarquees ) {
const marqueeBlock = await getBlockInGlobalInserter(
'Marquee Greeting'
);
await marqueeBlock.click();
await page.waitForFunction(
( expectedMarquees ) => {
return (
document.querySelectorAll(
'[data-testid="marquee-greeting"]'
).length === expectedMarquees
);
},
{},
nbExpectedMarquees
);
}

await page.keyboard.type( 'Marquee' );
async function deleteExistingMarquees() {
const widgetAreasHoldingMarqueeWidgets = await page.$x(
'//input[@data-testid="marquee-greeting"]/ancestor::div[@aria-label="Block: Widget Area"]'
);
for ( const widgetArea of widgetAreasHoldingMarqueeWidgets ) {
const closedPanelBody = await widgetArea.$(
'.components-panel__body:not(.is-opened)'
);
if ( closedPanelBody ) {
await closedPanelBody.focus();
await closedPanelBody.click();
}

const inlineQuickInserter = await find( {
role: 'listbox',
name: 'Blocks',
} );
const marqueeBlockOption = await find(
{
role: 'option',
},
{
root: inlineQuickInserter,
const [ existingMarqueeWidgets ] = await widgetArea.$x(
'//input[@data-testid="marquee-greeting"]/ancestor::div[@data-block][contains(@class, "wp-block-legacy-widget")]'
);
if ( existingMarqueeWidgets ) {
await existingMarqueeWidgets.focus();
await pressKeyWithModifier( 'access', 'z' );
}
}
);
await marqueeBlockOption.click();
}

it( 'Should add and save the marquee widget', async () => {
await activatePlugin( 'gutenberg-test-marquee-widget' );
await visitAdminPage( 'widgets.php' );
}

await addMarquee();
beforeAll( async () => {
await activatePlugin( 'gutenberg-test-marquee-widget' );
} );

await find( {
selector: '[data-block][data-type="core/legacy-widget"]',
beforeEach( async () => {
await deleteExistingMarquees();
} );

const greetingsInput = await find( {
selector: '#marquee-greeting',
afterAll( async () => {
await deactivatePlugin( 'gutenberg-test-marquee-widget' );
} );
await greetingsInput.click();
await page.keyboard.type( 'Howdy' );

await saveWidgets();
it( 'Should add and save the marquee widget', async () => {
await addMarquee( 1 );

let editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Hello!</marquee>",
}
` );
const [ marqueeInput ] = await page.$x(
'//input[@data-testid="marquee-greeting"]'
);
await marqueeInput.focus();
await marqueeInput.type( 'Howdy' );

await page.reload();
// The first marquee is saved after clicking the form save button.
const [ marqueeSaveButton ] = await marqueeInput.$x(
'//input/ancestor::div[@data-block][contains(@class, "wp-block-legacy-widget")]//button[@type="submit"]'
);
await marqueeSaveButton.click();

editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Hello!</marquee>",
}
` );
await saveWidgets();

// Add another marquee, it shouldn't be saved
await addMarquee();
let editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Howdy</marquee>",
}
` );

// It takes a moment to load the form, let's wait for it.
await waitFor( async () => {
const marquees = await findAll( {
selector: '[id=marquee-greeting]',
} );
if ( marquees.length === 1 ) {
throw new Error();
await page.reload();

editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Howdy</marquee>",
}
} );
` );

const marquees = await findAll( {
selector: '[id=marquee-greeting]',
} );
await addMarquee( 2 );

expect( marquees ).toHaveLength( 2 );
await marquees[ 1 ].click();
await page.keyboard.type( 'Second howdy' );
const marqueeInputs = await page.$$(
'[data-testid="marquee-greeting"]'
);

await saveWidgets();
editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Hello!</marquee>",
}
` );
expect( marqueeInputs ).toHaveLength( 2 );
await marqueeInputs[ 0 ].focus();
await marqueeInputs[ 0 ].type( 'first howdy' );

await marqueeInputs[ 1 ].focus();
await marqueeInputs[ 1 ].type( 'Second howdy' );

// No marquee should be changed without clicking on their "save" button.
// The second marquee shouldn't be stored as a widget.
// See #32978 for more info.
await saveWidgets();
editedSerializedWidgetAreas = await getSerializedWidgetAreas();
await expect( editedSerializedWidgetAreas ).toMatchInlineSnapshot( `
Object {
"sidebar-1": "<marquee>Howdy</marquee>",
}
` );

await page.reload();
const marqueesAfter = await findAll( {
selector: '[id=marquee-greeting]',
await page.reload();
const marqueesAfter = await findAll( {
selector: '[data-testid="marquee-greeting"]',
} );
expect( marqueesAfter ).toHaveLength( 1 );
} );
expect( marqueesAfter ).toHaveLength( 1 );

await deactivatePlugin( 'gutenberg-test-marquee-widget' );
} );

// Disable reason: We temporary skip this test until we can figure out why it fails sometimes.
Expand Down Expand Up @@ -528,7 +548,6 @@ describe( 'Widgets screen', () => {
"sidebar-1": "<div class=\\"widget widget_block widget_text\\"><div class=\\"widget-content\\">
<p>First Paragraph</p>
</div></div>",
"wp_inactive_widgets": "",
}
` );
const initialWidgets = await getWidgetAreaWidgets();
Expand Down Expand Up @@ -599,7 +618,6 @@ describe( 'Widgets screen', () => {
<div class=\\"widget widget_block widget_text\\"><div class=\\"widget-content\\">
<p>First Paragraph</p>
</div></div>",
"wp_inactive_widgets": "",
}
` );
const editedWidgets = await getWidgetAreaWidgets();
Expand Down

0 comments on commit 178ba0b

Please sign in to comment.