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 flaky widgets-related E2E tests #33066

Merged
merged 14 commits into from
Jun 30, 2021
Merged
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