You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.1 KiB
JavaScript
120 lines
3.1 KiB
JavaScript
/*
|
|
* Copyright (c) Jupyter Development Team.
|
|
* Distributed under the terms of the Modified BSD License.
|
|
*/
|
|
|
|
const playwright = require('playwright');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
// eslint-disable-next-line no-redeclare
|
|
const URL = process.argv[2];
|
|
const BROWSER_VAR = 'JLAB_BROWSER_TYPE';
|
|
const BROWSER = process.env[BROWSER_VAR] || 'chromium';
|
|
const HEADLESS_VAR = 'JLAB_BROWSER_HEADLESS';
|
|
const HEADLESS = process.env[HEADLESS_VAR] === 'false' ? false : true;
|
|
const OUTPUT_VAR = 'JLAB_BROWSER_CHECK_OUTPUT';
|
|
const OUTPUT = process.env[OUTPUT_VAR];
|
|
|
|
let nextScreenshot = 0;
|
|
const screenshotStem = `screenshot-${+new Date()}`;
|
|
|
|
if (OUTPUT) {
|
|
console.log(`Screenshots will be saved in ${OUTPUT}...`);
|
|
if (!fs.existsSync(OUTPUT)) {
|
|
console.log(`Creating ${OUTPUT}...`);
|
|
fs.mkdirSync(OUTPUT, { recursive: true });
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
/* eslint-disable no-console */
|
|
console.info(`Starting headless ${BROWSER}...`);
|
|
let testError = null;
|
|
|
|
const pwBrowser = playwright[BROWSER];
|
|
const browser = await pwBrowser.launch({
|
|
headless: HEADLESS,
|
|
logger: {
|
|
isEnabled: () => !!OUTPUT,
|
|
log: (name, severity, message, args) => console.log(name, message)
|
|
}
|
|
});
|
|
|
|
const context = await browser.newContext();
|
|
const page = await context.newPage();
|
|
|
|
async function screenshot() {
|
|
if (!OUTPUT) {
|
|
return;
|
|
}
|
|
const screenshotPath = path.join(
|
|
OUTPUT,
|
|
`${screenshotStem}-${++nextScreenshot}.png`
|
|
);
|
|
console.log(`Capturing screenshot ${screenshotPath}...`);
|
|
await page.screenshot({
|
|
type: 'png',
|
|
path: screenshotPath
|
|
});
|
|
}
|
|
|
|
console.info('Navigating to page:', URL);
|
|
await page.goto(URL);
|
|
console.info('Waiting for page to load...');
|
|
|
|
// Wait for the local file to redirect on notebook >= 6.0
|
|
await page.waitForNavigation();
|
|
|
|
console.log('Waiting for page content..');
|
|
|
|
try {
|
|
await page.locator('#jupyter-config-data').waitFor({ state: 'attached' });
|
|
} catch (reason) {
|
|
console.error('Error loading JupyterLab page:', reason);
|
|
// Limit to 1000 characters
|
|
console.error((await page.content()).substring(0, 1000));
|
|
testError = reason;
|
|
}
|
|
|
|
console.log('Waiting for #main selector...');
|
|
await page.waitForSelector('#main', { timeout: 100000 });
|
|
|
|
console.log('Waiting for #browserTest selector...');
|
|
const el = await page.waitForSelector('#browserTest', {
|
|
timeout: 100000,
|
|
state: 'attached'
|
|
});
|
|
console.log('Waiting for application to start...');
|
|
|
|
try {
|
|
await page.waitForSelector('.completed', { state: 'attached' });
|
|
} catch (e) {
|
|
testError = e;
|
|
}
|
|
|
|
await screenshot();
|
|
|
|
const textContent = await el.getProperty('textContent');
|
|
const errors = JSON.parse(await textContent.jsonValue());
|
|
|
|
for (let error of errors) {
|
|
console.error(`Parsed an error from text content: ${error.message}`, error);
|
|
testError = true;
|
|
}
|
|
|
|
await browser.close();
|
|
|
|
if (testError) {
|
|
throw testError;
|
|
}
|
|
console.info('Browser test complete');
|
|
}
|
|
|
|
// Stop the process if an error is raised in the async function.
|
|
process.on('unhandledRejection', up => {
|
|
throw up;
|
|
});
|
|
|
|
void main();
|