Skip to content

Commit fb72b3f

Browse files
Osong-Michaelmleray
authored andcommitted
Fix flakiness for webkit
- Added code to ensure DOM is ready in webkit - Ensure page is not closed before interacting with elements
1 parent 1d70f87 commit fb72b3f

File tree

3 files changed

+71
-21
lines changed

3 files changed

+71
-21
lines changed

tests/e2e/blocks/secondary-navigation.spec.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ const HEADINGS = [
2424
'Donec tristique',
2525
];
2626

27+
async function waitForBlock({page, blockType}) {
28+
await page.waitForFunction(
29+
type => {
30+
return !!document.querySelector(`[data-type="${type}"]`);
31+
},
32+
blockType,
33+
{timeout: 40000}
34+
);
35+
}
36+
2737
test.useAdminLoggedIn();
2838

2939
test('Test Secondary Navigation block', async ({page, admin, editor}) => {
@@ -37,15 +47,23 @@ test('Test Secondary Navigation block', async ({page, admin, editor}) => {
3747
await searchAndInsertBlock({page}, 'Secondary Navigation Menu');
3848
await closeBlockInserter({page});
3949

50+
await waitForBlock({
51+
page,
52+
blockType: 'planet4-blocks/secondary-navigation',
53+
});
54+
55+
const blockRoot = page.locator('[data-type="planet4-blocks/secondary-navigation"]');
56+
4057
// Make sure it displays the empty message at first.
41-
await expect(page.locator('.EmptyMessage')).toBeVisible();
58+
const emptyMessage = blockRoot.locator('.EmptyMessage');
59+
await expect(emptyMessage).toBeVisible();
4260

4361
// Add content (headings and paragraphs).
44-
for (let index = 0; index < HEADINGS.length; index++) {
45-
await addHeadingOrParagraph({page}, 'Heading', 'h2', index, HEADINGS[index]);
46-
// For the paragraphs, we need to use index + 1 because there is a paragraph in the Page Header.
47-
await addHeadingOrParagraph({page}, 'Paragraph', 'p', index + 1, PARAGRAPH_CONTENT);
48-
};
62+
for (const heading of HEADINGS) {
63+
await addHeadingOrParagraph({page}, 'Heading', 'h2', heading);
64+
await page.waitForTimeout(20);
65+
await addHeadingOrParagraph({page}, 'Paragraph', 'p', PARAGRAPH_CONTENT);
66+
}
4967

5068
// Publish page.
5169
await publishPostAndVisit({page, editor});

tests/e2e/tools/lib/editor.js

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,19 @@ async function openComponentPanel({page, editor}, panelTitle) {
2727
* @param {{Page}} page
2828
*/
2929
const closeBlockInserter = async ({page}) => {
30-
const inserter = page.locator('.editor-inserter-sidebar');
30+
const getCloseButton = () => page.getByRole('button', {name: 'Close Block Inserter'});
3131

32-
if (await inserter.isVisible()) {
33-
await page.keyboard.press('Escape');
32+
try {
33+
await expect(getCloseButton()).toBeVisible({timeout: 1000});
34+
await getCloseButton().click();
35+
} catch (error) {
36+
if (process.env.CI) {
37+
// eslint-disable-next-line no-console
38+
console.warn(
39+
'[closeBlockInserter] skipped:',
40+
error?.message?.split('\n')[0]
41+
);
42+
}
3443
}
3544
};
3645

@@ -55,19 +64,17 @@ const searchAndInsertBlock = async ({page}, blockName, namespace = '') => {
5564
await searchInput.fill('');
5665
await searchInput.fill(blockName);
5766

58-
const blocksList = page.getByRole('listbox', {name: 'Blocks'});
59-
await expect(blocksList).toBeVisible();
60-
61-
let blockOption = blocksList.getByRole('option', {name: blockName});
67+
let blockOption = page.getByRole('option', {name: blockName});
6268

6369
if (namespace) {
64-
blockOption = blocksList.locator(
70+
blockOption = page.locator(
6571
`button.editor-block-list-item-${namespace.toLowerCase()}[role="option"]`
6672
);
6773
}
6874

69-
await expect(blockOption).toBeVisible();
70-
await blockOption.click();
75+
if (!page.isClosed()) {
76+
await page.evaluate(el => el.click(), await blockOption.elementHandle());
77+
}
7178
};
7279

7380
/**
@@ -86,14 +93,35 @@ const searchAndInsertPattern = async ({page}, id) => {
8693
* @param {{Page}} page
8794
* @param {string} blockName
8895
* @param {string} blockTag
89-
* @param {number} number
9096
* @param {string} text
9197
*/
92-
const addHeadingOrParagraph = async ({page}, blockName, blockTag, number, text) => {
98+
const addHeadingOrParagraph = async ({page}, blockName, blockTag, text) => {
9399
await searchAndInsertBlock({page}, blockName, blockName.toLowerCase());
94-
const newBlock = page.getByRole('region', {name: 'Editor content'}).locator(blockTag).nth(number);
95-
await expect(newBlock).toBeVisible();
100+
101+
const getNewBlock = () => page.getByRole('region', {name: 'Editor content'}).locator(`${blockTag}[contenteditable="true"]`).last();
102+
103+
// Wait for Gutenberg to finish inserting and the block to become editable
104+
await page.waitForFunction(
105+
newBlockTag => {
106+
const region = document.querySelector('[role="region"][aria-label="Editor content"]');
107+
if (!region) {return false;}
108+
const blocks = Array.from(region.querySelectorAll(newBlockTag));
109+
return blocks.some(b => b.isContentEditable && b.offsetParent !== null);
110+
},
111+
blockTag,
112+
{timeout: 5000}
113+
);
114+
96115
await closeBlockInserter({page});
116+
117+
// Webkit hack to allow re-render
118+
if (page.context().browser()?.browserType().name() === 'webkit') {
119+
if (!page.isClosed()) {
120+
await page.evaluate(() => new Promise(requestAnimationFrame));
121+
}
122+
}
123+
124+
const newBlock = getNewBlock();
97125
await newBlock.fill(text);
98126
};
99127

tests/e2e/tools/lib/post.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ async function updatePost({page}) {
5151
async function publishPostAndVisit({page, editor}) {
5252
const urlString = await publishPost({page, editor});
5353

54-
await page.goto(urlString);
54+
if (page.isClosed()) {
55+
page = await page.context().newPage();
56+
}
57+
58+
await page.goto(urlString, {waitUntil: 'load'});
5559
}
5660

5761
/**

0 commit comments

Comments
 (0)