Skip to content

Commit

Permalink
[code-infra] Tentative fix for Argos flaky screenshot tests (@JCQuintas
Browse files Browse the repository at this point in the history
…) (#15399)

Co-authored-by: Jose C Quintas Jr <[email protected]>
  • Loading branch information
github-actions[bot] and JCQuintas authored Nov 13, 2024
1 parent 5ab3eec commit 044cd21
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"test:regressions": "cross-env NODE_ENV=production pnpm test:regressions:build && concurrently --success first --kill-others \"pnpm test:regressions:run\" \"pnpm test:regressions:server\"",
"test:regressions:build": "cross-env E2E_BUILD=true webpack --config test/regressions/webpack.config.js",
"test:regressions:dev": "concurrently \"pnpm test:regressions:build --watch\" \"pnpm test:regressions:server\"",
"test:regressions:run": "mocha --config test/regressions/.mocharc.js --delay 'test/regressions/**/*.test.js'",
"test:regressions:run": "mocha --config test/regressions/.mocharc.js --delay 'test/regressions/**/*.test.ts'",
"test:regressions:server": "serve test/regressions -p 5001",
"test:argos": "node ./scripts/pushArgos.mjs",
"typescript": "lerna run --no-bail --parallel typescript",
Expand Down
3 changes: 2 additions & 1 deletion test/regressions/.mocharc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
extension: ['js', 'ts', 'tsx'],
recursive: true,
slow: 500,
timeout: (process.env.CIRCLECI === 'true' ? 5 : 2) * 1000, // Circle CI has low-performance CPUs.
require: [require.resolve('@babel/register')],
require: [require.resolve('../utils/setupBabel')],
};
51 changes: 33 additions & 18 deletions test/regressions/index.test.js → test/regressions/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import * as childProcess from 'child_process';
import { chromium } from '@playwright/test';
import materialPackageJson from '@mui/material/package.json';

function sleep(timeoutMS) {
function sleep(timeoutMS: number | undefined) {
return new Promise((resolve) => {
setTimeout(() => resolve(), timeoutMS);
setTimeout(resolve, timeoutMS);
});
}

const isMaterialUIv6 = materialPackageJson.version.startsWith('6.');

const isConsoleWarningIgnored = (msg) => {
// Tests that need a longer timeout.
const timeSensitiveSuites = ['ColumnAutosizingAsync'];

const isConsoleWarningIgnored = (msg?: string) => {
if (
msg &&
isMaterialUIv6 &&
Expand Down Expand Up @@ -51,7 +54,7 @@ async function main() {
}
});

let errorConsole;
let errorConsole: string | undefined;

page.on('console', (msg) => {
// Filter out native user-agent errors e.g. "Failed to load resource: net::ERR_FAILED"
Expand All @@ -62,7 +65,7 @@ async function main() {

// Wait for all requests to finish.
// This should load shared resources such as fonts.
await page.goto(`${baseUrl}#no-dev`, { waitUntil: 'networkidle0' });
await page.goto(`${baseUrl}#no-dev`, { waitUntil: 'networkidle' });

// Simulate portrait mode for date pickers.
// See `useIsLandscape`.
Expand All @@ -76,20 +79,20 @@ async function main() {

const routes = await page.$$eval('#tests a', (links) => {
return links.map((link) => {
return link.href;
return (link as HTMLAnchorElement).href;
});
});

// prepare screenshots
await fse.emptyDir(screenshotDir);

function navigateToTest(testIndex) {
function navigateToTest(testIndex: number) {
// Use client-side routing which is much faster than full page navigation via page.goto().
// Could become an issue with test isolation.
// If tests are flaky due to global pollution switch to page.goto(route);
// puppeteers built-in click() times out
return page.$eval(`#tests li:nth-of-type(${testIndex}) a`, (link) => {
link.click();
(link as HTMLAnchorElement).click();
});
}

Expand Down Expand Up @@ -130,12 +133,7 @@ async function main() {
await navigateToTest(index + 1);
}
// Move cursor offscreen to not trigger unwanted hover effects.
page.mouse.move(0, 0);

if (/^\docs-charts-.*/.test(pathURL)) {
// Run one tick of the clock to get the final animation state
await sleep(10);
}
await page.mouse.move(0, 0);

const screenshotPath = path.resolve(screenshotDir, `${route.replace(baseUrl, '.')}.png`);
await fse.ensureDir(path.dirname(screenshotPath));
Expand All @@ -160,6 +158,18 @@ async function main() {
{ timeout: 1000 },
);

if (/^\docs-charts-.*/.test(pathURL)) {
// Run one tick of the clock to get the final animation state
await sleep(10);
}

if (timeSensitiveSuites.some((suite) => pathURL.includes(suite))) {
await sleep(100);
}

// Wait for the page to settle after taking the screenshot.
await page.waitForLoadState();

await testcase.screenshot({ path: screenshotPath, type: 'png' });
});

Expand All @@ -183,7 +193,7 @@ async function main() {

const testcaseIndex = routes.indexOf(route);
await page.$eval(`#tests li:nth-of-type(${testcaseIndex + 1}) a`, (link) => {
link.click();
(link as HTMLAnchorElement).click();
});

const testcase = await page.waitForSelector(
Expand All @@ -192,6 +202,11 @@ async function main() {

await page.evaluate(() => {
const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller');

if (!virtualScroller) {
throw new Error('missing virtualScroller');
}

virtualScroller.scrollLeft = 400;
virtualScroller.dispatchEvent(new Event('scroll'));
});
Expand All @@ -208,20 +223,20 @@ async function main() {

const testcaseIndex = routes.indexOf(route);
await page.$eval(`#tests li:nth-of-type(${testcaseIndex + 1}) a`, (link) => {
link.click();
(link as HTMLAnchorElement).click();
});

// Click the export button in the toolbar.
await page.$eval(`button[aria-label="Export"]`, (exportButton) => {
exportButton.click();
(exportButton as HTMLAnchorElement).click();
});

// Click the print export option from the export menu in the toolbar.
await page.$eval(`li[role="menuitem"]:last-child`, (printButton) => {
// Trigger the action async because window.print() is blocking the main thread
// like window.alert() is.
setTimeout(() => {
printButton.click();
(printButton as HTMLAnchorElement).click();
});
});

Expand Down

0 comments on commit 044cd21

Please sign in to comment.