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

tests(devtools): ensure Lighthouse starts in smoke tests #15459

Merged
merged 11 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/devtools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ jobs:
- run: mkdir latest-run
working-directory: ${{ github.workspace }}/lighthouse
- name: yarn smoke --runner devtools
run: xvfb-run --auto-servernum yarn smoke --runner devtools --shard=${{ matrix.smoke-test-shard }}/${{ strategy.job-total }} --jobs=3 --retries=2
run: xvfb-run --auto-servernum yarn smoke --runner devtools --shard=${{ matrix.smoke-test-shard }}/${{ strategy.job-total }} --jobs=3 --retries=2 --debug
working-directory: ${{ github.workspace }}/lighthouse

- name: Upload failures
Expand Down
4 changes: 3 additions & 1 deletion cli/test/smokehouse/lighthouse-runners/devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,17 @@ async function setup() {
* CHROME_PATH determines which Chrome is used–otherwise the default is puppeteer's chrome binary.
* @param {string} url
* @param {LH.Config=} config
* @param {{isDebug?: boolean}=} options
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, log: string}>}
*/
async function runLighthouse(url, config) {
async function runLighthouse(url, config, options) {
const chromeFlags = [
`--custom-devtools-frontend=file://${devtoolsDir}/out/LighthouseIntegration/gen/front_end`,
];
const {lhr, artifacts, logs} = await testUrlFromDevtools(url, {
config,
chromeFlags,
includedScreenshotInError: options?.isDebug,
adamraine marked this conversation as resolved.
Show resolved Hide resolved
});

const log = logs.join('') + '\n';
Expand Down
12 changes: 9 additions & 3 deletions cli/test/smokehouse/smokehouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

/* eslint-disable no-console */

/** @typedef {import('./lib/child-process-error.js').ChildProcessError} ChildProcessError */

/**
* @typedef Run
* @property {string[] | undefined} networkRequests
Expand All @@ -39,6 +37,7 @@ import {runLighthouse as cliLighthouseRunner} from './lighthouse-runners/cli.js'
import {getAssertionReport} from './report-assert.js';
import {LocalConsole} from './lib/local-console.js';
import {ConcurrentMapper} from './lib/concurrent-mapper.js';
import {ChildProcessError} from './lib/child-process-error.js';

// The number of concurrent (`!runSerially`) tests to run if `jobs` isn't set.
const DEFAULT_CONCURRENT_RUNS = 5;
Expand Down Expand Up @@ -239,11 +238,18 @@ async function runSmokeTest(smokeTestDefn, testOptions) {
* @param {ChildProcessError|Error} err
*/
function logChildProcessError(localConsole, err) {
if ('stdout' in err && 'stderr' in err) {
if (err instanceof ChildProcessError) {
localConsole.adoptStdStrings(err);
}

localConsole.log(log.redify(err.stack || err.message));
if (err.cause) {
if (err.cause instanceof Error) {
localConsole.log(log.redify(`[cause] ${err.cause.stack || err.cause.message}`));
} else {
localConsole.log(log.redify(`[cause] ${err.cause}`));
}
}
}

/**
Expand Down
32 changes: 28 additions & 4 deletions core/scripts/pptr-run-devtools.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,19 @@ async function runLighthouse() {
);
});

const button = panel.contentElement.querySelector('button');
button.click();
// In CI there ins't a 100% guarantee that clicking the start button once
// will start the run.
// Therefore, keep clicking the button until we detect that the run started.
const intervalHandle = setInterval(() => {
const button = panel.contentElement.querySelector('button');
button.click();
}, 100);

addSniffer(
panel.__proto__,
'handleCompleteRun',
() => clearInterval(intervalHandle),
);

return resultPromise;
}
Expand Down Expand Up @@ -286,7 +297,7 @@ function dismissDialog(dialog) {

/**
* @param {string} url
* @param {{config?: LH.Config, chromeFlags?: string[]}} [options]
* @param {{config?: LH.Config, chromeFlags?: string[], includedScreenshotInError?: boolean}} [options]
* @return {Promise<{lhr: LH.Result, artifacts: LH.Artifacts, logs: string[]}>}
*/
async function testUrlFromDevtools(url, options = {}) {
Expand All @@ -299,6 +310,9 @@ async function testUrlFromDevtools(url, options = {}) {
defaultViewport: null,
});

/** @type {puppeteer.CDPSession|undefined} */
let inspectorSession;

try {
if ((await browser.version()).startsWith('Headless')) {
throw new Error('You cannot use headless');
Expand All @@ -307,7 +321,7 @@ async function testUrlFromDevtools(url, options = {}) {
const page = (await browser.pages())[0];

const inspectorTarget = await browser.waitForTarget(t => t.url().includes('devtools'));
const inspectorSession = await inspectorTarget.createCDPSession();
inspectorSession = await inspectorTarget.createCDPSession();

/** @type {string[]} */
const logs = [];
Expand All @@ -328,6 +342,16 @@ async function testUrlFromDevtools(url, options = {}) {
const result = await evaluateInSession(inspectorSession, runLighthouse, [addSniffer]);

return {...result, logs};
} catch (err) {
if (options.includedScreenshotInError && inspectorSession) {
const {data} = await inspectorSession.send('Page.captureScreenshot', {format: 'webp'});
const image = `data:image/webp;base64,${data}`;
throw new Error(
`Lighthouse in DevTool failed. DevTools screenshot:\n${image}`,
{cause: err}
);
}
throw err;
} finally {
await browser.close();
}
Expand Down
Loading