mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 21:53:35 +03:00
040c6a6a41
Experimentally run `npx jest` to run our tests with jest.
187 lines
6.9 KiB
JavaScript
187 lines
6.9 KiB
JavaScript
/**
|
|
* Copyright (c) Microsoft Corporation.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
const path = require('path');
|
|
const wrapper = require('@playwright/jest-wrapper');
|
|
const DefaultTestRunner = require('../utils/testrunner');
|
|
const {TestRunner, TestRun} = require('../utils/testrunner/TestRunner');
|
|
const { PlaywrightEnvironment, BrowserTypeEnvironment, BrowserEnvironment, PageEnvironment} = require('./environments.js');
|
|
const fs = require('fs');
|
|
const pirates = require('pirates');
|
|
const babel = require('@babel/core');
|
|
const testRunnerInfo = makeTestRunnerInfo();
|
|
|
|
|
|
module.exports = wrapper.createJestRunner(async ({path: filePath}) => {
|
|
const config = require('./test.config');
|
|
const spec = config.specs.find(spec => {
|
|
return spec.files.some(f => path.join(__dirname, f) === filePath);
|
|
});
|
|
if (!spec) {
|
|
console.error('cannot find spec for', filePath);
|
|
return [];
|
|
}
|
|
const {testRunner, browserInfo} = testRunnerInfo;
|
|
testRunner.collector()._tests = [];
|
|
for (const [key, value] of Object.entries(testRunner.api()))
|
|
global[key] = value;
|
|
for (const {browserEnvironment, browserTypeEnvironment, browserName, browserType, pageEnvironment, launchOptions} of browserInfo) {
|
|
const suiteName = { 'chromium': 'Chromium', 'firefox': 'Firefox', 'webkit': 'WebKit' }[browserName];
|
|
describe(suiteName, () => {
|
|
// In addition to state, expose these two on global so that describes can access them.
|
|
global.browserType = browserType;
|
|
global.HEADLESS = !!launchOptions.headless;
|
|
|
|
testRunner.collector().useEnvironment(browserTypeEnvironment);
|
|
const skip = spec.browsers && !spec.browsers.includes(browserName);
|
|
(skip ? xdescribe : describe)(spec.title || '', () => {
|
|
for (const e of spec.environments || ['page']) {
|
|
if (e === 'browser') {
|
|
testRunner.collector().useEnvironment(browserEnvironment);
|
|
} else if (e === 'page') {
|
|
testRunner.collector().useEnvironment(browserEnvironment);
|
|
testRunner.collector().useEnvironment(pageEnvironment);
|
|
} else {
|
|
testRunner.collector().useEnvironment(e);
|
|
}
|
|
}
|
|
const revert = pirates.addHook((code, filename) => {
|
|
const result = babel.transformFileSync(filename, {
|
|
presets: [
|
|
['@babel/preset-env', {targets: {node: 'current'}}],
|
|
'@babel/preset-typescript']
|
|
});
|
|
return result.code;
|
|
}, {
|
|
exts: ['.ts']
|
|
});
|
|
require(filePath);
|
|
revert();
|
|
delete require.cache[require.resolve(filePath)];
|
|
});
|
|
|
|
delete global.HEADLESS;
|
|
delete global.browserType;
|
|
});
|
|
}
|
|
for (const key of Object.keys(testRunner.api())) {
|
|
// expect is used when running tests, while the rest of api is not.
|
|
if (key !== 'expect')
|
|
delete global[key];
|
|
}
|
|
|
|
return testRunner._filter.filter(testRunner.collector().tests()).map(test => {
|
|
return {
|
|
titles: test.titles(),
|
|
test
|
|
};
|
|
});
|
|
}, async (tests, options, onStart, onResult) => {
|
|
const parallel = Math.min(options.workers, 30);
|
|
require('events').defaultMaxListeners *= parallel;
|
|
const runner = new TestRunner();
|
|
const runs = tests.map(test => {
|
|
const run = new TestRun(test.test);
|
|
run.__test__ = test;
|
|
return run;
|
|
});
|
|
await runner.run(runs, {
|
|
parallel,
|
|
breakOnFailure: false,
|
|
hookTimeout: options.timeout,
|
|
totalTimeout: options.timeout,
|
|
// onStarted = async (testRuns) => {},
|
|
// onFinished = async (result) => {},
|
|
onTestRunStarted: async testRun => {
|
|
onStart(testRun.__test__);
|
|
},
|
|
onTestRunFinished: async testRun => {
|
|
let status = 'skip';
|
|
if (testRun.isFailure())
|
|
status = 'fail';
|
|
else if (testRun.result() === 'ok')
|
|
status = 'pass';
|
|
else if (testRun.test().expectation() === 'fail')
|
|
status = 'todo';
|
|
onResult(testRun.__test__, {
|
|
status,
|
|
error: testRun.error(),
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
function makeTestRunnerInfo() {
|
|
const parallel = 1;
|
|
const timeout = process.env.CI ? 30 * 1000 : 10 * 1000;
|
|
const config = require('./test.config');
|
|
const testRunner = new DefaultTestRunner({
|
|
timeout,
|
|
totalTimeout: process.env.CI ? 30 * 60 * 1000 * browserNames.length : 0, // 30 minutes per browser on CI
|
|
parallel,
|
|
breakOnFailure: process.argv.indexOf('--break-on-failure') !== -1,
|
|
verbose: process.argv.includes('--verbose'),
|
|
summary: !process.argv.includes('--verbose'),
|
|
showSlowTests: process.env.CI ? 5 : 0,
|
|
showMarkedAsFailingTests: 10,
|
|
});
|
|
if (config.setupTestRunner)
|
|
config.setupTestRunner(testRunner);
|
|
|
|
// TODO: this should be a preinstalled playwright by default.
|
|
const playwrightPath = config.playwrightPath;
|
|
const playwright = require('..');
|
|
const { setUnderTest } = require(require('path').join(playwrightPath, 'lib/helper.js'));
|
|
setUnderTest();
|
|
|
|
const playwrightEnvironment = new PlaywrightEnvironment(playwright);
|
|
|
|
testRunner.collector().useEnvironment(playwrightEnvironment);
|
|
for (const e of config.globalEnvironments || [])
|
|
testRunner.collector().useEnvironment(e);
|
|
|
|
global.playwright = playwright;
|
|
const browserNames = ['chromium'];
|
|
const browserInfo = browserNames.map(browserName => {
|
|
const browserType = playwright[browserName];
|
|
|
|
const browserTypeEnvironment = new BrowserTypeEnvironment(browserType);
|
|
|
|
// TODO: maybe launch options per browser?
|
|
const launchOptions = {
|
|
...(config.launchOptions || {}),
|
|
handleSIGINT: false,
|
|
};
|
|
if (launchOptions.executablePath)
|
|
launchOptions.executablePath = launchOptions.executablePath[browserName];
|
|
if (launchOptions.executablePath) {
|
|
const YELLOW_COLOR = '\x1b[33m';
|
|
const RESET_COLOR = '\x1b[0m';
|
|
console.warn(`${YELLOW_COLOR}WARN: running ${browserName} tests with ${launchOptions.executablePath}${RESET_COLOR}`);
|
|
browserType._executablePath = launchOptions.executablePath;
|
|
delete launchOptions.executablePath;
|
|
} else {
|
|
if (!fs.existsSync(browserType.executablePath()))
|
|
throw new Error(`Browser is not downloaded. Run 'npm install' and try to re-run tests`);
|
|
}
|
|
|
|
const browserEnvironment = new BrowserEnvironment(launchOptions, config.dumpLogOnFailure);
|
|
|
|
const pageEnvironment = new PageEnvironment();
|
|
return {browserName, browserType, browserEnvironment, browserTypeEnvironment, pageEnvironment, launchOptions};
|
|
});
|
|
return {testRunner, browserInfo};
|
|
} |