screenshot/test_1

This commit is contained in:
ramkumarp
2025-03-27 11:21:02 +00:00
commit 616d466383
470 changed files with 144705 additions and 0 deletions

271
node_modules/playwright/lib/common/config.js generated vendored Normal file
View File

@@ -0,0 +1,271 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.defaultTimeout = exports.defaultReporter = exports.defaultGrep = exports.builtInReporters = exports.FullProjectInternal = exports.FullConfigInternal = void 0;
exports.getProjectId = getProjectId;
exports.takeFirst = takeFirst;
exports.toReporters = toReporters;
var _fs = _interopRequireDefault(require("fs"));
var _os = _interopRequireDefault(require("os"));
var _path = _interopRequireDefault(require("path"));
var _util = require("../util");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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 defaultTimeout = exports.defaultTimeout = 30000;
class FullConfigInternal {
constructor(location, userConfig, configCLIOverrides, metadata) {
var _this$globalSetups$, _this$globalTeardowns;
this.config = void 0;
this.configDir = void 0;
this.configCLIOverrides = void 0;
this.webServers = void 0;
this.plugins = void 0;
this.projects = [];
this.singleTSConfigPath = void 0;
this.captureGitInfo = void 0;
this.cliArgs = [];
this.cliGrep = void 0;
this.cliGrepInvert = void 0;
this.cliOnlyChanged = void 0;
this.cliProjectFilter = void 0;
this.cliListOnly = false;
this.cliPassWithNoTests = void 0;
this.cliFailOnFlakyTests = void 0;
this.cliLastFailed = void 0;
this.testIdMatcher = void 0;
this.lastFailedTestIdMatcher = void 0;
this.defineConfigWasUsed = false;
this.globalSetups = [];
this.globalTeardowns = [];
if (configCLIOverrides.projects && userConfig.projects) throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);
const {
resolvedConfigFile,
configDir
} = location;
const packageJsonPath = (0, _util.getPackageJsonPath)(configDir);
const packageJsonDir = packageJsonPath ? _path.default.dirname(packageJsonPath) : process.cwd();
this.configDir = configDir;
this.configCLIOverrides = configCLIOverrides;
const privateConfiguration = userConfig['@playwright/test'];
this.plugins = ((privateConfiguration === null || privateConfiguration === void 0 ? void 0 : privateConfiguration.plugins) || []).map(p => ({
factory: p
}));
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
this.captureGitInfo = userConfig.captureGitInfo;
this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);
// Make sure we reuse same metadata instance between FullConfigInternal instances,
// so that plugins such as gitCommitInfoPlugin can populate metadata once.
userConfig.metadata = userConfig.metadata || {};
this.config = {
configFile: resolvedConfigFile,
rootDir: pathResolve(configDir, userConfig.testDir) || configDir,
forbidOnly: takeFirst(configCLIOverrides.forbidOnly, userConfig.forbidOnly, false),
fullyParallel: takeFirst(configCLIOverrides.fullyParallel, userConfig.fullyParallel, false),
globalSetup: (_this$globalSetups$ = this.globalSetups[0]) !== null && _this$globalSetups$ !== void 0 ? _this$globalSetups$ : null,
globalTeardown: (_this$globalTeardowns = this.globalTeardowns[0]) !== null && _this$globalTeardowns !== void 0 ? _this$globalTeardowns : null,
globalTimeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.globalTimeout, userConfig.globalTimeout, 0),
grep: takeFirst(userConfig.grep, defaultGrep),
grepInvert: takeFirst(userConfig.grepInvert, null),
maxFailures: takeFirst(configCLIOverrides.debug ? 1 : undefined, configCLIOverrides.maxFailures, userConfig.maxFailures, 0),
metadata: metadata !== null && metadata !== void 0 ? metadata : userConfig.metadata,
preserveOutput: takeFirst(userConfig.preserveOutput, 'always'),
reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]),
reportSlowTests: takeFirst(userConfig.reportSlowTests, {
max: 5,
threshold: 300_000 /* 5 minutes */
}),
quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false),
projects: [],
shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null),
updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'),
updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, 'patch'),
version: require('../../package.json').version,
workers: 0,
webServer: null
};
for (const key in userConfig) {
if (key.startsWith('@')) this.config[key] = userConfig[key];
}
this.config[configInternalSymbol] = this;
const workers = takeFirst(configCLIOverrides.debug ? 1 : undefined, configCLIOverrides.workers, userConfig.workers, '50%');
if (typeof workers === 'string') {
if (workers.endsWith('%')) {
const cpus = _os.default.cpus().length;
this.config.workers = Math.max(1, Math.floor(cpus * (parseInt(workers, 10) / 100)));
} else {
this.config.workers = parseWorkers(workers);
}
} else {
this.config.workers = workers;
}
const webServers = takeFirst(userConfig.webServer, null);
if (Array.isArray(webServers)) {
// multiple web server mode
// Due to previous choices, this value shows up to the user in globalSetup as part of FullConfig. Arrays are not supported by the old type.
this.config.webServer = null;
this.webServers = webServers;
} else if (webServers) {
// legacy singleton mode
this.config.webServer = webServers;
this.webServers = [webServers];
} else {
this.webServers = [];
}
const projectConfigs = configCLIOverrides.projects || userConfig.projects || [userConfig];
this.projects = projectConfigs.map(p => new FullProjectInternal(configDir, userConfig, this, p, this.configCLIOverrides, packageJsonDir));
resolveProjectDependencies(this.projects);
this._assignUniqueProjectIds(this.projects);
this.config.projects = this.projects.map(p => p.project);
}
_assignUniqueProjectIds(projects) {
const usedNames = new Set();
for (const p of projects) {
const name = p.project.name || '';
for (let i = 0; i < projects.length; ++i) {
const candidate = name + (i ? i : '');
if (usedNames.has(candidate)) continue;
p.id = candidate;
p.project.__projectId = p.id;
usedNames.add(candidate);
break;
}
}
}
}
exports.FullConfigInternal = FullConfigInternal;
class FullProjectInternal {
constructor(configDir, config, fullConfig, projectConfig, configCLIOverrides, packageJsonDir) {
var _this$expect$toHaveSc;
this.project = void 0;
this.fullConfig = void 0;
this.fullyParallel = void 0;
this.expect = void 0;
this.respectGitIgnore = void 0;
this.snapshotPathTemplate = void 0;
this.ignoreSnapshots = void 0;
this.id = '';
this.deps = [];
this.teardown = void 0;
this.fullConfig = fullConfig;
const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);
this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate);
this.project = {
grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),
grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),
outputDir: takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, projectConfig.outputDir), pathResolve(configDir, config.outputDir), _path.default.join(packageJsonDir, 'test-results')),
// Note: we either apply the cli override for repeatEach or not, depending on whether the
// project is top-level vs dependency. See collectProjectsAndTestFiles in loadUtils.
repeatEach: takeFirst(projectConfig.repeatEach, config.repeatEach, 1),
retries: takeFirst(configCLIOverrides.retries, projectConfig.retries, config.retries, 0),
metadata: takeFirst(projectConfig.metadata, config.metadata, {}),
name: takeFirst(projectConfig.name, config.name, ''),
testDir,
snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir),
testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []),
testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).?(c|m)[jt]s?(x)'),
timeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout),
use: (0, _util.mergeObjects)(config.use, projectConfig.use, configCLIOverrides.use),
dependencies: projectConfig.dependencies || [],
teardown: projectConfig.teardown
};
this.fullyParallel = takeFirst(configCLIOverrides.fullyParallel, projectConfig.fullyParallel, config.fullyParallel, undefined);
this.expect = takeFirst(projectConfig.expect, config.expect, {});
if ((_this$expect$toHaveSc = this.expect.toHaveScreenshot) !== null && _this$expect$toHaveSc !== void 0 && _this$expect$toHaveSc.stylePath) {
const stylePaths = Array.isArray(this.expect.toHaveScreenshot.stylePath) ? this.expect.toHaveScreenshot.stylePath : [this.expect.toHaveScreenshot.stylePath];
this.expect.toHaveScreenshot.stylePath = stylePaths.map(stylePath => _path.default.resolve(configDir, stylePath));
}
this.respectGitIgnore = takeFirst(projectConfig.respectGitIgnore, config.respectGitIgnore, !projectConfig.testDir && !config.testDir);
this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, projectConfig.ignoreSnapshots, config.ignoreSnapshots, false);
}
}
exports.FullProjectInternal = FullProjectInternal;
function takeFirst(...args) {
for (const arg of args) {
if (arg !== undefined) return arg;
}
return undefined;
}
function pathResolve(baseDir, relative) {
if (!relative) return undefined;
return _path.default.resolve(baseDir, relative);
}
function resolveReporters(reporters, rootDir) {
var _toReporters;
return (_toReporters = toReporters(reporters)) === null || _toReporters === void 0 ? void 0 : _toReporters.map(([id, arg]) => {
if (builtInReporters.includes(id)) return [id, arg];
return [require.resolve(id, {
paths: [rootDir]
}), arg];
});
}
function parseWorkers(workers) {
const parsedWorkers = parseInt(workers, 10);
if (isNaN(parsedWorkers)) throw new Error(`Workers ${workers} must be a number or percentage.`);
return parsedWorkers;
}
function resolveProjectDependencies(projects) {
const teardownSet = new Set();
for (const project of projects) {
for (const dependencyName of project.project.dependencies) {
const dependencies = projects.filter(p => p.project.name === dependencyName);
if (!dependencies.length) throw new Error(`Project '${project.project.name}' depends on unknown project '${dependencyName}'`);
if (dependencies.length > 1) throw new Error(`Project dependencies should have unique names, reading ${dependencyName}`);
project.deps.push(...dependencies);
}
if (project.project.teardown) {
const teardowns = projects.filter(p => p.project.name === project.project.teardown);
if (!teardowns.length) throw new Error(`Project '${project.project.name}' has unknown teardown project '${project.project.teardown}'`);
if (teardowns.length > 1) throw new Error(`Project teardowns should have unique names, reading ${project.project.teardown}`);
const teardown = teardowns[0];
project.teardown = teardown;
teardownSet.add(teardown);
}
}
for (const teardown of teardownSet) {
if (teardown.deps.length) throw new Error(`Teardown project ${teardown.project.name} must not have dependencies`);
}
for (const project of projects) {
for (const dep of project.deps) {
if (teardownSet.has(dep)) throw new Error(`Project ${project.project.name} must not depend on a teardown project ${dep.project.name}`);
}
}
}
function toReporters(reporters) {
if (!reporters) return;
if (typeof reporters === 'string') return [[reporters]];
return reporters;
}
const builtInReporters = exports.builtInReporters = ['list', 'line', 'dot', 'json', 'junit', 'null', 'github', 'html', 'blob'];
function resolveScript(id, rootDir) {
if (!id) return undefined;
const localPath = _path.default.resolve(rootDir, id);
if (_fs.default.existsSync(localPath)) return localPath;
return require.resolve(id, {
paths: [rootDir]
});
}
const defaultGrep = exports.defaultGrep = /.*/;
const defaultReporter = exports.defaultReporter = process.env.CI ? 'dot' : 'list';
const configInternalSymbol = Symbol('configInternalSymbol');
function getProjectId(project) {
return project.__projectId;
}

333
node_modules/playwright/lib/common/configLoader.js generated vendored Normal file
View File

@@ -0,0 +1,333 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.defineConfig = void 0;
exports.deserializeConfig = deserializeConfig;
exports.loadConfig = loadConfig;
exports.loadConfigFromFileRestartIfNeeded = loadConfigFromFileRestartIfNeeded;
exports.loadEmptyConfigForMergeReports = loadEmptyConfigForMergeReports;
exports.resolveConfigLocation = resolveConfigLocation;
exports.restartWithExperimentalTsEsm = restartWithExperimentalTsEsm;
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _utils = require("playwright-core/lib/utils");
var _transform = require("../transform/transform");
var _util = require("../util");
var _config = require("./config");
var _esmLoaderHost = require("./esmLoaderHost");
var _compilationCache = require("../transform/compilationCache");
var _esmUtils = require("../transform/esmUtils");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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 kDefineConfigWasUsed = Symbol('defineConfigWasUsed');
const defineConfig = (...configs) => {
let result = configs[0];
for (let i = 1; i < configs.length; ++i) {
const config = configs[i];
result = {
...result,
...config,
expect: {
...result.expect,
...config.expect
},
use: {
...result.use,
...config.use
},
build: {
...result.build,
...config.build
},
webServer: [...(Array.isArray(result.webServer) ? result.webServer : result.webServer ? [result.webServer] : []), ...(Array.isArray(config.webServer) ? config.webServer : config.webServer ? [config.webServer] : [])]
};
if (!result.projects && !config.projects) continue;
const projectOverrides = new Map();
for (const project of config.projects || []) projectOverrides.set(project.name, project);
const projects = [];
for (const project of result.projects || []) {
const projectOverride = projectOverrides.get(project.name);
if (projectOverride) {
projects.push({
...project,
...projectOverride,
use: {
...project.use,
...projectOverride.use
}
});
projectOverrides.delete(project.name);
} else {
projects.push(project);
}
}
projects.push(...projectOverrides.values());
result.projects = projects;
}
result[kDefineConfigWasUsed] = true;
return result;
};
exports.defineConfig = defineConfig;
async function deserializeConfig(data) {
if (data.compilationCache) (0, _compilationCache.addToCompilationCache)(data.compilationCache);
return await loadConfig(data.location, data.configCLIOverrides, undefined, data.metadata ? JSON.parse(data.metadata) : undefined);
}
async function loadUserConfig(location) {
let object = location.resolvedConfigFile ? await (0, _transform.requireOrImport)(location.resolvedConfigFile) : {};
if (object && typeof object === 'object' && 'default' in object) object = object['default'];
return object;
}
async function loadConfig(location, overrides, ignoreProjectDependencies = false, metadata) {
var _playwrightTest, _userConfig$build;
// 1. Setup tsconfig; configure ESM loader with tsconfig and compilation cache.
(0, _transform.setSingleTSConfig)(overrides === null || overrides === void 0 ? void 0 : overrides.tsconfig);
await (0, _esmLoaderHost.configureESMLoader)();
// 2. Load and validate playwright config.
const userConfig = await loadUserConfig(location);
validateConfig(location.resolvedConfigFile || '<default config>', userConfig);
const fullConfig = new _config.FullConfigInternal(location, userConfig, overrides || {}, metadata);
fullConfig.defineConfigWasUsed = !!userConfig[kDefineConfigWasUsed];
if (ignoreProjectDependencies) {
for (const project of fullConfig.projects) {
project.deps = [];
project.teardown = undefined;
}
}
// 3. Load transform options from the playwright config.
const babelPlugins = ((_playwrightTest = userConfig['@playwright/test']) === null || _playwrightTest === void 0 ? void 0 : _playwrightTest.babelPlugins) || [];
const external = ((_userConfig$build = userConfig.build) === null || _userConfig$build === void 0 ? void 0 : _userConfig$build.external) || [];
(0, _transform.setTransformConfig)({
babelPlugins,
external
});
if (!(overrides !== null && overrides !== void 0 && overrides.tsconfig)) (0, _transform.setSingleTSConfig)(fullConfig === null || fullConfig === void 0 ? void 0 : fullConfig.singleTSConfigPath);
// 4. Send transform options to ESM loader.
await (0, _esmLoaderHost.configureESMLoaderTransformConfig)();
return fullConfig;
}
function validateConfig(file, config) {
if (typeof config !== 'object' || !config) throw (0, _util.errorWithFile)(file, `Configuration file must export a single object`);
validateProject(file, config, 'config');
if ('forbidOnly' in config && config.forbidOnly !== undefined) {
if (typeof config.forbidOnly !== 'boolean') throw (0, _util.errorWithFile)(file, `config.forbidOnly must be a boolean`);
}
if ('globalSetup' in config && config.globalSetup !== undefined) {
if (Array.isArray(config.globalSetup)) {
config.globalSetup.forEach((item, index) => {
if (typeof item !== 'string') throw (0, _util.errorWithFile)(file, `config.globalSetup[${index}] must be a string`);
});
} else if (typeof config.globalSetup !== 'string') {
throw (0, _util.errorWithFile)(file, `config.globalSetup must be a string`);
}
}
if ('globalTeardown' in config && config.globalTeardown !== undefined) {
if (Array.isArray(config.globalTeardown)) {
config.globalTeardown.forEach((item, index) => {
if (typeof item !== 'string') throw (0, _util.errorWithFile)(file, `config.globalTeardown[${index}] must be a string`);
});
} else if (typeof config.globalTeardown !== 'string') {
throw (0, _util.errorWithFile)(file, `config.globalTeardown must be a string`);
}
}
if ('globalTimeout' in config && config.globalTimeout !== undefined) {
if (typeof config.globalTimeout !== 'number' || config.globalTimeout < 0) throw (0, _util.errorWithFile)(file, `config.globalTimeout must be a non-negative number`);
}
if ('grep' in config && config.grep !== undefined) {
if (Array.isArray(config.grep)) {
config.grep.forEach((item, index) => {
if (!(0, _utils.isRegExp)(item)) throw (0, _util.errorWithFile)(file, `config.grep[${index}] must be a RegExp`);
});
} else if (!(0, _utils.isRegExp)(config.grep)) {
throw (0, _util.errorWithFile)(file, `config.grep must be a RegExp`);
}
}
if ('grepInvert' in config && config.grepInvert !== undefined) {
if (Array.isArray(config.grepInvert)) {
config.grepInvert.forEach((item, index) => {
if (!(0, _utils.isRegExp)(item)) throw (0, _util.errorWithFile)(file, `config.grepInvert[${index}] must be a RegExp`);
});
} else if (!(0, _utils.isRegExp)(config.grepInvert)) {
throw (0, _util.errorWithFile)(file, `config.grepInvert must be a RegExp`);
}
}
if ('maxFailures' in config && config.maxFailures !== undefined) {
if (typeof config.maxFailures !== 'number' || config.maxFailures < 0) throw (0, _util.errorWithFile)(file, `config.maxFailures must be a non-negative number`);
}
if ('preserveOutput' in config && config.preserveOutput !== undefined) {
if (typeof config.preserveOutput !== 'string' || !['always', 'never', 'failures-only'].includes(config.preserveOutput)) throw (0, _util.errorWithFile)(file, `config.preserveOutput must be one of "always", "never" or "failures-only"`);
}
if ('projects' in config && config.projects !== undefined) {
if (!Array.isArray(config.projects)) throw (0, _util.errorWithFile)(file, `config.projects must be an array`);
config.projects.forEach((project, index) => {
validateProject(file, project, `config.projects[${index}]`);
});
}
if ('quiet' in config && config.quiet !== undefined) {
if (typeof config.quiet !== 'boolean') throw (0, _util.errorWithFile)(file, `config.quiet must be a boolean`);
}
if ('reporter' in config && config.reporter !== undefined) {
if (Array.isArray(config.reporter)) {
config.reporter.forEach((item, index) => {
if (!Array.isArray(item) || item.length <= 0 || item.length > 2 || typeof item[0] !== 'string') throw (0, _util.errorWithFile)(file, `config.reporter[${index}] must be a tuple [name, optionalArgument]`);
});
} else if (typeof config.reporter !== 'string') {
throw (0, _util.errorWithFile)(file, `config.reporter must be a string`);
}
}
if ('reportSlowTests' in config && config.reportSlowTests !== undefined && config.reportSlowTests !== null) {
if (!config.reportSlowTests || typeof config.reportSlowTests !== 'object') throw (0, _util.errorWithFile)(file, `config.reportSlowTests must be an object`);
if (!('max' in config.reportSlowTests) || typeof config.reportSlowTests.max !== 'number' || config.reportSlowTests.max < 0) throw (0, _util.errorWithFile)(file, `config.reportSlowTests.max must be a non-negative number`);
if (!('threshold' in config.reportSlowTests) || typeof config.reportSlowTests.threshold !== 'number' || config.reportSlowTests.threshold < 0) throw (0, _util.errorWithFile)(file, `config.reportSlowTests.threshold must be a non-negative number`);
}
if ('shard' in config && config.shard !== undefined && config.shard !== null) {
if (!config.shard || typeof config.shard !== 'object') throw (0, _util.errorWithFile)(file, `config.shard must be an object`);
if (!('total' in config.shard) || typeof config.shard.total !== 'number' || config.shard.total < 1) throw (0, _util.errorWithFile)(file, `config.shard.total must be a positive number`);
if (!('current' in config.shard) || typeof config.shard.current !== 'number' || config.shard.current < 1 || config.shard.current > config.shard.total) throw (0, _util.errorWithFile)(file, `config.shard.current must be a positive number, not greater than config.shard.total`);
}
if ('updateSnapshots' in config && config.updateSnapshots !== undefined) {
if (typeof config.updateSnapshots !== 'string' || !['all', 'changed', 'missing', 'none'].includes(config.updateSnapshots)) throw (0, _util.errorWithFile)(file, `config.updateSnapshots must be one of "all", "changed", "missing" or "none"`);
}
if ('workers' in config && config.workers !== undefined) {
if (typeof config.workers === 'number' && config.workers <= 0) throw (0, _util.errorWithFile)(file, `config.workers must be a positive number`);else if (typeof config.workers === 'string' && !config.workers.endsWith('%')) throw (0, _util.errorWithFile)(file, `config.workers must be a number or percentage`);
}
if ('tsconfig' in config && config.tsconfig !== undefined) {
if (typeof config.tsconfig !== 'string') throw (0, _util.errorWithFile)(file, `config.tsconfig must be a string`);
if (!_fs.default.existsSync(_path.default.resolve(file, '..', config.tsconfig))) throw (0, _util.errorWithFile)(file, `config.tsconfig does not exist`);
}
}
function validateProject(file, project, title) {
if (typeof project !== 'object' || !project) throw (0, _util.errorWithFile)(file, `${title} must be an object`);
if ('name' in project && project.name !== undefined) {
if (typeof project.name !== 'string') throw (0, _util.errorWithFile)(file, `${title}.name must be a string`);
}
if ('outputDir' in project && project.outputDir !== undefined) {
if (typeof project.outputDir !== 'string') throw (0, _util.errorWithFile)(file, `${title}.outputDir must be a string`);
}
if ('repeatEach' in project && project.repeatEach !== undefined) {
if (typeof project.repeatEach !== 'number' || project.repeatEach < 0) throw (0, _util.errorWithFile)(file, `${title}.repeatEach must be a non-negative number`);
}
if ('retries' in project && project.retries !== undefined) {
if (typeof project.retries !== 'number' || project.retries < 0) throw (0, _util.errorWithFile)(file, `${title}.retries must be a non-negative number`);
}
if ('testDir' in project && project.testDir !== undefined) {
if (typeof project.testDir !== 'string') throw (0, _util.errorWithFile)(file, `${title}.testDir must be a string`);
}
for (const prop of ['testIgnore', 'testMatch']) {
if (prop in project && project[prop] !== undefined) {
const value = project[prop];
if (Array.isArray(value)) {
value.forEach((item, index) => {
if (typeof item !== 'string' && !(0, _utils.isRegExp)(item)) throw (0, _util.errorWithFile)(file, `${title}.${prop}[${index}] must be a string or a RegExp`);
});
} else if (typeof value !== 'string' && !(0, _utils.isRegExp)(value)) {
throw (0, _util.errorWithFile)(file, `${title}.${prop} must be a string or a RegExp`);
}
}
}
if ('timeout' in project && project.timeout !== undefined) {
if (typeof project.timeout !== 'number' || project.timeout < 0) throw (0, _util.errorWithFile)(file, `${title}.timeout must be a non-negative number`);
}
if ('use' in project && project.use !== undefined) {
if (!project.use || typeof project.use !== 'object') throw (0, _util.errorWithFile)(file, `${title}.use must be an object`);
}
if ('ignoreSnapshots' in project && project.ignoreSnapshots !== undefined) {
if (typeof project.ignoreSnapshots !== 'boolean') throw (0, _util.errorWithFile)(file, `${title}.ignoreSnapshots must be a boolean`);
}
}
function resolveConfigLocation(configFile) {
const configFileOrDirectory = configFile ? _path.default.resolve(process.cwd(), configFile) : process.cwd();
const resolvedConfigFile = resolveConfigFile(configFileOrDirectory);
return {
resolvedConfigFile,
configDir: resolvedConfigFile ? _path.default.dirname(resolvedConfigFile) : configFileOrDirectory
};
}
function resolveConfigFile(configFileOrDirectory) {
const resolveConfig = configFile => {
if (_fs.default.existsSync(configFile)) return configFile;
};
const resolveConfigFileFromDirectory = directory => {
for (const ext of ['.ts', '.js', '.mts', '.mjs', '.cts', '.cjs']) {
const configFile = resolveConfig(_path.default.resolve(directory, 'playwright.config' + ext));
if (configFile) return configFile;
}
};
if (!_fs.default.existsSync(configFileOrDirectory)) throw new Error(`${configFileOrDirectory} does not exist`);
if (_fs.default.statSync(configFileOrDirectory).isDirectory()) {
// When passed a directory, look for a config file inside.
const configFile = resolveConfigFileFromDirectory(configFileOrDirectory);
if (configFile) return configFile;
// If there is no config, assume this as a root testing directory.
return undefined;
}
// When passed a file, it must be a config file.
return configFileOrDirectory;
}
async function loadConfigFromFileRestartIfNeeded(configFile, overrides, ignoreDeps) {
const location = resolveConfigLocation(configFile);
if (restartWithExperimentalTsEsm(location.resolvedConfigFile)) return null;
return await loadConfig(location, overrides, ignoreDeps);
}
async function loadEmptyConfigForMergeReports() {
// Merge reports is "different" for no good reason. It should not pick up local config from the cwd.
return await loadConfig({
configDir: process.cwd()
});
}
function restartWithExperimentalTsEsm(configFile, force = false) {
// Opt-out switch.
if (process.env.PW_DISABLE_TS_ESM) return false;
// There are two esm loader APIs:
// - Older API that needs a process restart. Available in Node 16, 17, and non-latest 18, 19 and 20.
// - Newer API that works in-process. Available in Node 21+ and latest 18, 19 and 20.
// First check whether we have already restarted with the ESM loader from the older API.
if (globalThis.__esmLoaderPortPreV20) {
// clear execArgv after restart, so that childProcess.fork in user code does not inherit our loader.
process.execArgv = (0, _esmUtils.execArgvWithoutExperimentalLoaderOptions)();
return false;
}
// Now check for the newer API presence.
if (!require('node:module').register) {
// With older API requiring a process restart, do so conditionally on the config.
const configIsModule = !!configFile && (0, _util.fileIsModule)(configFile);
if (!force && !configIsModule) return false;
const innerProcess = require('child_process').fork(require.resolve('../../cli'), process.argv.slice(2), {
env: {
...process.env,
PW_TS_ESM_LEGACY_LOADER_ON: '1'
},
execArgv: (0, _esmUtils.execArgvWithExperimentalLoaderOptions)()
});
innerProcess.on('close', code => {
if (code !== 0 && code !== null) (0, _utils.gracefullyProcessExitDoNotHang)(code);
});
return true;
}
// With the newer API, always enable the ESM loader, because it does not need a restart.
(0, _esmLoaderHost.registerESMLoader)();
return false;
}

95
node_modules/playwright/lib/common/esmLoaderHost.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.configureESMLoader = configureESMLoader;
exports.configureESMLoaderTransformConfig = configureESMLoaderTransformConfig;
exports.esmLoaderRegistered = void 0;
exports.incorporateCompilationCache = incorporateCompilationCache;
exports.registerESMLoader = registerESMLoader;
exports.startCollectingFileDeps = startCollectingFileDeps;
exports.stopCollectingFileDeps = stopCollectingFileDeps;
var _url = _interopRequireDefault(require("url"));
var _compilationCache = require("../transform/compilationCache");
var _portTransport = require("../transform/portTransport");
var _transform = require("../transform/transform");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* 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.
*/
let loaderChannel;
// Node.js < 20
if (globalThis.__esmLoaderPortPreV20) loaderChannel = createPortTransport(globalThis.__esmLoaderPortPreV20);
// Node.js >= 20
let esmLoaderRegistered = exports.esmLoaderRegistered = false;
function registerESMLoader() {
const {
port1,
port2
} = new MessageChannel();
// register will wait until the loader is initialized.
require('node:module').register(_url.default.pathToFileURL(require.resolve('../transform/esmLoader')), {
data: {
port: port2
},
transferList: [port2]
});
loaderChannel = createPortTransport(port1);
exports.esmLoaderRegistered = esmLoaderRegistered = true;
}
function createPortTransport(port) {
return new _portTransport.PortTransport(port, async (method, params) => {
if (method === 'pushToCompilationCache') (0, _compilationCache.addToCompilationCache)(params.cache);
});
}
async function startCollectingFileDeps() {
if (!loaderChannel) return;
await loaderChannel.send('startCollectingFileDeps', {});
}
async function stopCollectingFileDeps(file) {
if (!loaderChannel) return;
await loaderChannel.send('stopCollectingFileDeps', {
file
});
}
async function incorporateCompilationCache() {
if (!loaderChannel) return;
// This is needed to gather dependency information from the esm loader
// that is populated from the resolve hook. We do not need to push
// this information proactively during load, but gather it at the end.
const result = await loaderChannel.send('getCompilationCache', {});
(0, _compilationCache.addToCompilationCache)(result.cache);
}
async function configureESMLoader() {
if (!loaderChannel) return;
await loaderChannel.send('setSingleTSConfig', {
tsconfig: (0, _transform.singleTSConfig)()
});
await loaderChannel.send('addToCompilationCache', {
cache: (0, _compilationCache.serializeCompilationCache)()
});
}
async function configureESMLoaderTransformConfig() {
if (!loaderChannel) return;
await loaderChannel.send('setSingleTSConfig', {
tsconfig: (0, _transform.singleTSConfig)()
});
await loaderChannel.send('setTransformConfig', {
config: (0, _transform.transformConfig)()
});
}

30
node_modules/playwright/lib/common/expectBundle.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.printReceived = exports.mock = exports.matcherUtils = exports.expect = exports.asymmetricMatchers = exports.RECEIVED_COLOR = exports.INVERTED_COLOR = exports.EXPECTED_COLOR = void 0;
/**
* 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 expect = exports.expect = require('./expectBundleImpl').expect;
const mock = exports.mock = require('./expectBundleImpl').mock;
const asymmetricMatchers = exports.asymmetricMatchers = require('./expectBundleImpl').asymmetricMatchers;
const matcherUtils = exports.matcherUtils = require('./expectBundleImpl').matcherUtils;
const EXPECTED_COLOR = exports.EXPECTED_COLOR = require('./expectBundleImpl').EXPECTED_COLOR;
const INVERTED_COLOR = exports.INVERTED_COLOR = require('./expectBundleImpl').INVERTED_COLOR;
const RECEIVED_COLOR = exports.RECEIVED_COLOR = require('./expectBundleImpl').RECEIVED_COLOR;
const printReceived = exports.printReceived = require('./expectBundleImpl').printReceived;

389
node_modules/playwright/lib/common/expectBundleImpl.js generated vendored Normal file

File diff suppressed because one or more lines are too long

322
node_modules/playwright/lib/common/fixtures.js generated vendored Normal file
View File

@@ -0,0 +1,322 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.FixturePool = void 0;
exports.fixtureParameterNames = fixtureParameterNames;
exports.formatPotentiallyInternalLocation = formatPotentiallyInternalLocation;
exports.inheritFixtureNames = inheritFixtureNames;
var _crypto = _interopRequireDefault(require("crypto"));
var _util = require("../util");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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 kScopeOrder = ['test', 'worker'];
function isFixtureTuple(value) {
return Array.isArray(value) && typeof value[1] === 'object';
}
function isFixtureOption(value) {
return isFixtureTuple(value) && !!value[1].option;
}
class FixturePool {
constructor(fixturesList, onLoadError, parentPool, disallowWorkerFixtures, optionOverrides) {
var _optionOverrides$over;
this.digest = void 0;
this._registrations = void 0;
this._onLoadError = void 0;
this._registrations = new Map(parentPool ? parentPool._registrations : []);
this._onLoadError = onLoadError;
const allOverrides = (_optionOverrides$over = optionOverrides === null || optionOverrides === void 0 ? void 0 : optionOverrides.overrides) !== null && _optionOverrides$over !== void 0 ? _optionOverrides$over : {};
const overrideKeys = new Set(Object.keys(allOverrides));
for (const list of fixturesList) {
this._appendFixtureList(list, !!disallowWorkerFixtures, false);
// Process option overrides immediately after original option definitions,
// so that any test.use() override it.
const selectedOverrides = {};
for (const [key, value] of Object.entries(list.fixtures)) {
if (isFixtureOption(value) && overrideKeys.has(key)) selectedOverrides[key] = [allOverrides[key], value[1]];
}
if (Object.entries(selectedOverrides).length) this._appendFixtureList({
fixtures: selectedOverrides,
location: optionOverrides.location
}, !!disallowWorkerFixtures, true);
}
this.digest = this.validate();
}
_appendFixtureList(list, disallowWorkerFixtures, isOptionsOverride) {
const {
fixtures,
location
} = list;
for (const entry of Object.entries(fixtures)) {
const name = entry[0];
let value = entry[1];
let options;
if (isFixtureTuple(value)) {
var _value$1$auto;
options = {
auto: (_value$1$auto = value[1].auto) !== null && _value$1$auto !== void 0 ? _value$1$auto : false,
scope: value[1].scope || 'test',
option: !!value[1].option,
timeout: value[1].timeout,
customTitle: value[1].title,
box: value[1].box
};
value = value[0];
}
let fn = value;
const previous = this._registrations.get(name);
if (previous && options) {
if (previous.scope !== options.scope) {
this._addLoadError(`Fixture "${name}" has already been registered as a { scope: '${previous.scope}' } fixture defined in ${(0, _util.formatLocation)(previous.location)}.`, location);
continue;
}
if (previous.auto !== options.auto) {
this._addLoadError(`Fixture "${name}" has already been registered as a { auto: '${previous.scope}' } fixture defined in ${(0, _util.formatLocation)(previous.location)}.`, location);
continue;
}
} else if (previous) {
options = {
auto: previous.auto,
scope: previous.scope,
option: previous.option,
timeout: previous.timeout,
customTitle: previous.customTitle,
box: previous.box
};
} else if (!options) {
options = {
auto: false,
scope: 'test',
option: false,
timeout: undefined
};
}
if (!kScopeOrder.includes(options.scope)) {
this._addLoadError(`Fixture "${name}" has unknown { scope: '${options.scope}' }.`, location);
continue;
}
if (options.scope === 'worker' && disallowWorkerFixtures) {
this._addLoadError(`Cannot use({ ${name} }) in a describe group, because it forces a new worker.\nMake it top-level in the test file or put in the configuration file.`, location);
continue;
}
// Overriding option with "undefined" value means setting it to the default value
// from the config or from the original declaration of the option.
if (fn === undefined && options.option && previous) {
let original = previous;
while (!original.optionOverride && original.super) original = original.super;
fn = original.fn;
}
const deps = fixtureParameterNames(fn, location, e => this._onLoadError(e));
const registration = {
id: '',
name,
location,
scope: options.scope,
fn,
auto: options.auto,
option: options.option,
timeout: options.timeout,
customTitle: options.customTitle,
box: options.box,
deps,
super: previous,
optionOverride: isOptionsOverride
};
registrationId(registration);
this._registrations.set(name, registration);
}
}
validate() {
const markers = new Map();
const stack = [];
let hasDependencyErrors = false;
const addDependencyError = (message, location) => {
hasDependencyErrors = true;
this._addLoadError(message, location);
};
const visit = (registration, boxedOnly) => {
markers.set(registration, 'visiting');
stack.push(registration);
for (const name of registration.deps) {
const dep = this.resolve(name, registration);
if (!dep) {
if (name === registration.name) addDependencyError(`Fixture "${registration.name}" references itself, but does not have a base implementation.`, registration.location);else addDependencyError(`Fixture "${registration.name}" has unknown parameter "${name}".`, registration.location);
continue;
}
if (kScopeOrder.indexOf(registration.scope) > kScopeOrder.indexOf(dep.scope)) {
addDependencyError(`${registration.scope} fixture "${registration.name}" cannot depend on a ${dep.scope} fixture "${name}" defined in ${formatPotentiallyInternalLocation(dep.location)}.`, registration.location);
continue;
}
if (!markers.has(dep)) {
visit(dep, boxedOnly);
} else if (markers.get(dep) === 'visiting') {
const index = stack.indexOf(dep);
const allRegs = stack.slice(index, stack.length);
const filteredRegs = allRegs.filter(r => !r.box);
const regs = boxedOnly ? filteredRegs : allRegs;
const names = regs.map(r => `"${r.name}"`);
addDependencyError(`Fixtures ${names.join(' -> ')} -> "${dep.name}" form a dependency cycle: ${regs.map(r => formatPotentiallyInternalLocation(r.location)).join(' -> ')} -> ${formatPotentiallyInternalLocation(dep.location)}`, dep.location);
continue;
}
}
markers.set(registration, 'visited');
stack.pop();
};
const names = Array.from(this._registrations.keys()).sort();
// First iterate over non-boxed fixtures to provide clear error messages.
for (const name of names) {
const registration = this._registrations.get(name);
if (!registration.box) visit(registration, true);
}
// If no errors found, iterate over boxed fixtures
if (!hasDependencyErrors) {
for (const name of names) {
const registration = this._registrations.get(name);
if (registration.box) visit(registration, false);
}
}
const hash = _crypto.default.createHash('sha1');
for (const name of names) {
const registration = this._registrations.get(name);
if (registration.scope === 'worker') hash.update(registration.id + ';');
}
return hash.digest('hex');
}
validateFunction(fn, prefix, location) {
for (const name of fixtureParameterNames(fn, location, e => this._onLoadError(e))) {
const registration = this._registrations.get(name);
if (!registration) this._addLoadError(`${prefix} has unknown parameter "${name}".`, location);
}
}
resolve(name, forFixture) {
if (name === (forFixture === null || forFixture === void 0 ? void 0 : forFixture.name)) return forFixture.super;
return this._registrations.get(name);
}
autoFixtures() {
return [...this._registrations.values()].filter(r => r.auto !== false);
}
_addLoadError(message, location) {
this._onLoadError({
message,
location
});
}
}
exports.FixturePool = FixturePool;
const signatureSymbol = Symbol('signature');
function formatPotentiallyInternalLocation(location) {
const isUserFixture = location && (0, _util.filterStackFile)(location.file);
return isUserFixture ? (0, _util.formatLocation)(location) : '<builtin>';
}
function fixtureParameterNames(fn, location, onError) {
if (typeof fn !== 'function') return [];
if (!fn[signatureSymbol]) fn[signatureSymbol] = innerFixtureParameterNames(fn, location, onError);
return fn[signatureSymbol];
}
function inheritFixtureNames(from, to) {
to[signatureSymbol] = from[signatureSymbol];
}
function innerFixtureParameterNames(fn, location, onError) {
const text = filterOutComments(fn.toString());
const match = text.match(/(?:async)?(?:\s+function)?[^(]*\(([^)]*)/);
if (!match) return [];
const trimmedParams = match[1].trim();
if (!trimmedParams) return [];
const [firstParam] = splitByComma(trimmedParams);
if (firstParam[0] !== '{' || firstParam[firstParam.length - 1] !== '}') {
onError({
message: 'First argument must use the object destructuring pattern: ' + firstParam,
location
});
return [];
}
const props = splitByComma(firstParam.substring(1, firstParam.length - 1)).map(prop => {
const colon = prop.indexOf(':');
return colon === -1 ? prop.trim() : prop.substring(0, colon).trim();
});
const restProperty = props.find(prop => prop.startsWith('...'));
if (restProperty) {
onError({
message: `Rest property "${restProperty}" is not supported. List all used fixtures explicitly, separated by comma.`,
location
});
return [];
}
return props;
}
function filterOutComments(s) {
const result = [];
let commentState = 'none';
for (let i = 0; i < s.length; ++i) {
if (commentState === 'singleline') {
if (s[i] === '\n') commentState = 'none';
} else if (commentState === 'multiline') {
if (s[i - 1] === '*' && s[i] === '/') commentState = 'none';
} else if (commentState === 'none') {
if (s[i] === '/' && s[i + 1] === '/') {
commentState = 'singleline';
} else if (s[i] === '/' && s[i + 1] === '*') {
commentState = 'multiline';
i += 2;
} else {
result.push(s[i]);
}
}
}
return result.join('');
}
function splitByComma(s) {
const result = [];
const stack = [];
let start = 0;
for (let i = 0; i < s.length; i++) {
if (s[i] === '{' || s[i] === '[') {
stack.push(s[i] === '{' ? '}' : ']');
} else if (s[i] === stack[stack.length - 1]) {
stack.pop();
} else if (!stack.length && s[i] === ',') {
const token = s.substring(start, i).trim();
if (token) result.push(token);
start = i + 1;
}
}
const lastToken = s.substring(start).trim();
if (lastToken) result.push(lastToken);
return result;
}
// name + superId, fn -> id
const registrationIdMap = new Map();
let lastId = 0;
function registrationId(registration) {
if (registration.id) return registration.id;
const key = registration.name + '@@@' + (registration.super ? registrationId(registration.super) : '');
let map = registrationIdMap.get(key);
if (!map) {
map = new Map();
registrationIdMap.set(key, map);
}
if (!map.has(registration.fn)) map.set(registration.fn, String(lastId++));
registration.id = map.get(registration.fn);
return registration.id;
}

48
node_modules/playwright/lib/common/globals.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.currentTestInfo = currentTestInfo;
exports.currentlyLoadingFileSuite = currentlyLoadingFileSuite;
exports.isWorkerProcess = isWorkerProcess;
exports.setCurrentTestInfo = setCurrentTestInfo;
exports.setCurrentlyLoadingFileSuite = setCurrentlyLoadingFileSuite;
exports.setIsWorkerProcess = setIsWorkerProcess;
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
let currentTestInfoValue = null;
function setCurrentTestInfo(testInfo) {
currentTestInfoValue = testInfo;
}
function currentTestInfo() {
return currentTestInfoValue;
}
let currentFileSuite;
function setCurrentlyLoadingFileSuite(suite) {
currentFileSuite = suite;
}
function currentlyLoadingFileSuite() {
return currentFileSuite;
}
let _isWorkerProcess = false;
function setIsWorkerProcess() {
_isWorkerProcess = true;
}
function isWorkerProcess() {
return _isWorkerProcess;
}

51
node_modules/playwright/lib/common/ipc.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.serializeConfig = serializeConfig;
exports.stdioChunkToParams = stdioChunkToParams;
var _util = _interopRequireDefault(require("util"));
var _compilationCache = require("../transform/compilationCache");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
function serializeConfig(config, passCompilationCache) {
const result = {
location: {
configDir: config.configDir,
resolvedConfigFile: config.config.configFile
},
configCLIOverrides: config.configCLIOverrides,
compilationCache: passCompilationCache ? (0, _compilationCache.serializeCompilationCache)() : undefined
};
try {
result.metadata = JSON.stringify(config.config.metadata);
} catch (error) {}
return result;
}
function stdioChunkToParams(chunk) {
if (chunk instanceof Uint8Array) return {
buffer: Buffer.from(chunk).toString('base64')
};
if (typeof chunk !== 'string') return {
text: _util.default.inspect(chunk)
};
return {
text: chunk
};
}

79
node_modules/playwright/lib/common/poolBuilder.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PoolBuilder = void 0;
var _fixtures = require("./fixtures");
var _util = require("../util");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
class PoolBuilder {
static createForLoader() {
return new PoolBuilder('loader');
}
static createForWorker(project) {
return new PoolBuilder('worker', project);
}
constructor(type, project) {
this._project = void 0;
this._testTypePools = new Map();
this._type = void 0;
this._type = type;
this._project = project;
}
buildPools(suite, testErrors) {
suite.forEachTest(test => {
const pool = this._buildPoolForTest(test, testErrors);
if (this._type === 'loader') test._poolDigest = pool.digest;
if (this._type === 'worker') test._pool = pool;
});
}
_buildPoolForTest(test, testErrors) {
let pool = this._buildTestTypePool(test._testType, testErrors);
const parents = [];
for (let parent = test.parent; parent; parent = parent.parent) parents.push(parent);
parents.reverse();
for (const parent of parents) {
if (parent._use.length) pool = new _fixtures.FixturePool(parent._use, e => this._handleLoadError(e, testErrors), pool, parent._type === 'describe');
for (const hook of parent._hooks) pool.validateFunction(hook.fn, hook.type + ' hook', hook.location);
for (const modifier of parent._modifiers) pool.validateFunction(modifier.fn, modifier.type + ' modifier', modifier.location);
}
pool.validateFunction(test.fn, 'Test', test.location);
return pool;
}
_buildTestTypePool(testType, testErrors) {
if (!this._testTypePools.has(testType)) {
var _this$_project$projec, _this$_project, _this$_project2;
const optionOverrides = {
overrides: (_this$_project$projec = (_this$_project = this._project) === null || _this$_project === void 0 || (_this$_project = _this$_project.project) === null || _this$_project === void 0 ? void 0 : _this$_project.use) !== null && _this$_project$projec !== void 0 ? _this$_project$projec : {},
location: {
file: `project#${(_this$_project2 = this._project) === null || _this$_project2 === void 0 ? void 0 : _this$_project2.id}`,
line: 1,
column: 1
}
};
const pool = new _fixtures.FixturePool(testType.fixtures, e => this._handleLoadError(e, testErrors), undefined, undefined, optionOverrides);
this._testTypePools.set(testType, pool);
}
return this._testTypePools.get(testType);
}
_handleLoadError(e, testErrors) {
if (testErrors) testErrors.push(e);else throw new Error(`${(0, _util.formatLocation)(e.location)}: ${e.message}`);
}
}
exports.PoolBuilder = PoolBuilder;

140
node_modules/playwright/lib/common/process.js generated vendored Normal file
View File

@@ -0,0 +1,140 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ProcessRunner = void 0;
var _utils = require("playwright-core/lib/utils");
var _util = require("../util");
var _esmLoaderHost = require("./esmLoaderHost");
var _esmUtils = require("../transform/esmUtils");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
class ProcessRunner {
async gracefullyClose() {}
dispatchEvent(method, params) {
const response = {
method,
params
};
sendMessageToParent({
method: '__dispatch__',
params: response
});
}
}
exports.ProcessRunner = ProcessRunner;
let gracefullyCloseCalled = false;
let forceExitInitiated = false;
sendMessageToParent({
method: 'ready'
});
process.on('disconnect', () => gracefullyCloseAndExit(true));
process.on('SIGINT', () => {});
process.on('SIGTERM', () => {});
// Clear execArgv immediately, so that the user-code does not inherit our loader.
process.execArgv = (0, _esmUtils.execArgvWithoutExperimentalLoaderOptions)();
// Node.js >= 20
if (process.env.PW_TS_ESM_LOADER_ON) (0, _esmLoaderHost.registerESMLoader)();
let processRunner;
let processName;
const startingEnv = {
...process.env
};
process.on('message', async message => {
if (message.method === '__init__') {
const {
processParams,
runnerParams,
runnerScript
} = message.params;
void (0, _utils.startProfiling)();
const {
create
} = require(runnerScript);
processRunner = create(runnerParams);
processName = processParams.processName;
return;
}
if (message.method === '__stop__') {
const keys = new Set([...Object.keys(process.env), ...Object.keys(startingEnv)]);
const producedEnv = [...keys].filter(key => startingEnv[key] !== process.env[key]).map(key => {
var _process$env$key;
return [key, (_process$env$key = process.env[key]) !== null && _process$env$key !== void 0 ? _process$env$key : null];
});
sendMessageToParent({
method: '__env_produced__',
params: producedEnv
});
await gracefullyCloseAndExit(false);
return;
}
if (message.method === '__dispatch__') {
const {
id,
method,
params
} = message.params;
try {
const result = await processRunner[method](params);
const response = {
id,
result
};
sendMessageToParent({
method: '__dispatch__',
params: response
});
} catch (e) {
const response = {
id,
error: (0, _util.serializeError)(e)
};
sendMessageToParent({
method: '__dispatch__',
params: response
});
}
}
});
const kForceExitTimeout = +(process.env.PWTEST_FORCE_EXIT_TIMEOUT || 30000);
async function gracefullyCloseAndExit(forceExit) {
if (forceExit && !forceExitInitiated) {
forceExitInitiated = true;
// Force exit after 30 seconds.
// eslint-disable-next-line no-restricted-properties
setTimeout(() => process.exit(0), kForceExitTimeout);
}
if (!gracefullyCloseCalled) {
var _processRunner;
gracefullyCloseCalled = true;
// Meanwhile, try to gracefully shutdown.
await ((_processRunner = processRunner) === null || _processRunner === void 0 ? void 0 : _processRunner.gracefullyClose().catch(() => {}));
if (processName) await (0, _utils.stopProfiling)(processName).catch(() => {});
// eslint-disable-next-line no-restricted-properties
process.exit(0);
}
}
function sendMessageToParent(message) {
try {
process.send(message);
} catch (e) {
// Can throw when closing.
}
}

132
node_modules/playwright/lib/common/suiteUtils.js generated vendored Normal file
View File

@@ -0,0 +1,132 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyRepeatEachIndex = applyRepeatEachIndex;
exports.bindFileSuiteToProject = bindFileSuiteToProject;
exports.filterByFocusedLine = filterByFocusedLine;
exports.filterByTestIds = filterByTestIds;
exports.filterOnly = filterOnly;
exports.filterSuite = filterSuite;
exports.filterSuiteWithOnlySemantics = filterSuiteWithOnlySemantics;
exports.filterTestsRemoveEmptySuites = filterTestsRemoveEmptySuites;
var _path = _interopRequireDefault(require("path"));
var _utils = require("playwright-core/lib/utils");
var _util = require("../util");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
function filterSuite(suite, suiteFilter, testFilter) {
for (const child of suite.suites) {
if (!suiteFilter(child)) filterSuite(child, suiteFilter, testFilter);
}
const filteredTests = suite.tests.filter(testFilter);
const entries = new Set([...suite.suites, ...filteredTests]);
suite._entries = suite._entries.filter(e => entries.has(e)); // Preserve the order.
}
function filterTestsRemoveEmptySuites(suite, filter) {
const filteredSuites = suite.suites.filter(child => filterTestsRemoveEmptySuites(child, filter));
const filteredTests = suite.tests.filter(filter);
const entries = new Set([...filteredSuites, ...filteredTests]);
suite._entries = suite._entries.filter(e => entries.has(e)); // Preserve the order.
return !!suite._entries.length;
}
function bindFileSuiteToProject(project, suite) {
const relativeFile = _path.default.relative(project.project.testDir, suite.location.file);
const fileId = (0, _utils.calculateSha1)((0, _utils.toPosixPath)(relativeFile)).slice(0, 20);
// Clone suite.
const result = suite._deepClone();
result._fileId = fileId;
// Assign test properties with project-specific values.
result.forEachTest((test, suite) => {
suite._fileId = fileId;
// At the point of the query, suite is not yet attached to the project, so we only get file, describe and test titles.
const [file, ...titles] = test.titlePath();
const testIdExpression = `[project=${project.id}]${(0, _utils.toPosixPath)(file)}\x1e${titles.join('\x1e')}`;
const testId = fileId + '-' + (0, _utils.calculateSha1)(testIdExpression).slice(0, 20);
test.id = testId;
test._projectId = project.id;
// Inherit properties from parent suites.
let inheritedRetries;
let inheritedTimeout;
test.annotations = [];
for (let parentSuite = suite; parentSuite; parentSuite = parentSuite.parent) {
if (parentSuite._staticAnnotations.length) test.annotations = [...parentSuite._staticAnnotations, ...test.annotations];
if (inheritedRetries === undefined && parentSuite._retries !== undefined) inheritedRetries = parentSuite._retries;
if (inheritedTimeout === undefined && parentSuite._timeout !== undefined) inheritedTimeout = parentSuite._timeout;
}
test.retries = inheritedRetries !== null && inheritedRetries !== void 0 ? inheritedRetries : project.project.retries;
test.timeout = inheritedTimeout !== null && inheritedTimeout !== void 0 ? inheritedTimeout : project.project.timeout;
test.annotations.push(...test._staticAnnotations);
// Skip annotations imply skipped expectedStatus.
if (test.annotations.some(a => a.type === 'skip' || a.type === 'fixme')) test.expectedStatus = 'skipped';
// We only compute / set digest in the runner.
if (test._poolDigest) test._workerHash = `${project.id}-${test._poolDigest}-0`;
});
return result;
}
function applyRepeatEachIndex(project, fileSuite, repeatEachIndex) {
// Assign test properties with project-specific values.
fileSuite.forEachTest((test, suite) => {
if (repeatEachIndex) {
const [file, ...titles] = test.titlePath();
const testIdExpression = `[project=${project.id}]${(0, _utils.toPosixPath)(file)}\x1e${titles.join('\x1e')} (repeat:${repeatEachIndex})`;
const testId = suite._fileId + '-' + (0, _utils.calculateSha1)(testIdExpression).slice(0, 20);
test.id = testId;
test.repeatEachIndex = repeatEachIndex;
if (test._poolDigest) test._workerHash = `${project.id}-${test._poolDigest}-${repeatEachIndex}`;
}
});
}
function filterOnly(suite) {
if (!suite._getOnlyItems().length) return;
const suiteFilter = suite => suite._only;
const testFilter = test => test._only;
return filterSuiteWithOnlySemantics(suite, suiteFilter, testFilter);
}
function filterSuiteWithOnlySemantics(suite, suiteFilter, testFilter) {
const onlySuites = suite.suites.filter(child => filterSuiteWithOnlySemantics(child, suiteFilter, testFilter) || suiteFilter(child));
const onlyTests = suite.tests.filter(testFilter);
const onlyEntries = new Set([...onlySuites, ...onlyTests]);
if (onlyEntries.size) {
suite._entries = suite._entries.filter(e => onlyEntries.has(e)); // Preserve the order.
return true;
}
return false;
}
function filterByFocusedLine(suite, focusedTestFileLines) {
if (!focusedTestFileLines.length) return;
const matchers = focusedTestFileLines.map(createFileMatcherFromFilter);
const testFileLineMatches = (testFileName, testLine, testColumn) => matchers.some(m => m(testFileName, testLine, testColumn));
const suiteFilter = suite => !!suite.location && testFileLineMatches(suite.location.file, suite.location.line, suite.location.column);
const testFilter = test => testFileLineMatches(test.location.file, test.location.line, test.location.column);
return filterSuite(suite, suiteFilter, testFilter);
}
function filterByTestIds(suite, testIdMatcher) {
if (!testIdMatcher) return;
filterTestsRemoveEmptySuites(suite, test => testIdMatcher(test.id));
}
function createFileMatcherFromFilter(filter) {
const fileMatcher = (0, _util.createFileMatcher)(filter.re || filter.exact || '');
return (testFileName, testLine, testColumn) => fileMatcher(testFileName) && (filter.line === testLine || filter.line === null) && (filter.column === testColumn || filter.column === null);
}

309
node_modules/playwright/lib/common/test.js generated vendored Normal file
View File

@@ -0,0 +1,309 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TestCase = exports.Suite = void 0;
var _testType = require("./testType");
var _teleReceiver = require("../isomorphic/teleReceiver");
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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.
*/
class Base {
constructor(title) {
this.title = void 0;
this._only = false;
this._requireFile = '';
this.title = title;
}
}
class Suite extends Base {
constructor(title, type) {
super(title);
this.location = void 0;
this.parent = void 0;
this._use = [];
this._entries = [];
this._hooks = [];
this._timeout = void 0;
this._retries = void 0;
// Annotations known statically before running the test, e.g. `test.describe.skip()` or `test.describe({ annotation }, body)`.
this._staticAnnotations = [];
// Explicitly declared tags that are not a part of the title.
this._tags = [];
this._modifiers = [];
this._parallelMode = 'none';
this._fullProject = void 0;
this._fileId = void 0;
this._type = void 0;
this._type = type;
}
get type() {
return this._type;
}
entries() {
return this._entries;
}
get suites() {
return this._entries.filter(entry => entry instanceof Suite);
}
get tests() {
return this._entries.filter(entry => entry instanceof TestCase);
}
_addTest(test) {
test.parent = this;
this._entries.push(test);
}
_addSuite(suite) {
suite.parent = this;
this._entries.push(suite);
}
_prependSuite(suite) {
suite.parent = this;
this._entries.unshift(suite);
}
allTests() {
const result = [];
const visit = suite => {
for (const entry of suite._entries) {
if (entry instanceof Suite) visit(entry);else result.push(entry);
}
};
visit(this);
return result;
}
_hasTests() {
let result = false;
const visit = suite => {
for (const entry of suite._entries) {
if (result) return;
if (entry instanceof Suite) visit(entry);else result = true;
}
};
visit(this);
return result;
}
titlePath() {
const titlePath = this.parent ? this.parent.titlePath() : [];
// Ignore anonymous describe blocks.
if (this.title || this._type !== 'describe') titlePath.push(this.title);
return titlePath;
}
_collectGrepTitlePath(path) {
if (this.parent) this.parent._collectGrepTitlePath(path);
if (this.title || this._type !== 'describe') path.push(this.title);
path.push(...this._tags);
}
_getOnlyItems() {
const items = [];
if (this._only) items.push(this);
for (const suite of this.suites) items.push(...suite._getOnlyItems());
items.push(...this.tests.filter(test => test._only));
return items;
}
_deepClone() {
const suite = this._clone();
for (const entry of this._entries) {
if (entry instanceof Suite) suite._addSuite(entry._deepClone());else suite._addTest(entry._clone());
}
return suite;
}
_deepSerialize() {
const suite = this._serialize();
suite.entries = [];
for (const entry of this._entries) {
if (entry instanceof Suite) suite.entries.push(entry._deepSerialize());else suite.entries.push(entry._serialize());
}
return suite;
}
static _deepParse(data) {
const suite = Suite._parse(data);
for (const entry of data.entries) {
if (entry.kind === 'suite') suite._addSuite(Suite._deepParse(entry));else suite._addTest(TestCase._parse(entry));
}
return suite;
}
forEachTest(visitor) {
for (const entry of this._entries) {
if (entry instanceof Suite) entry.forEachTest(visitor);else visitor(entry, this);
}
}
_serialize() {
return {
kind: 'suite',
title: this.title,
type: this._type,
location: this.location,
only: this._only,
requireFile: this._requireFile,
timeout: this._timeout,
retries: this._retries,
staticAnnotations: this._staticAnnotations.slice(),
tags: this._tags.slice(),
modifiers: this._modifiers.slice(),
parallelMode: this._parallelMode,
hooks: this._hooks.map(h => ({
type: h.type,
location: h.location,
title: h.title
})),
fileId: this._fileId
};
}
static _parse(data) {
const suite = new Suite(data.title, data.type);
suite.location = data.location;
suite._only = data.only;
suite._requireFile = data.requireFile;
suite._timeout = data.timeout;
suite._retries = data.retries;
suite._staticAnnotations = data.staticAnnotations;
suite._tags = data.tags;
suite._modifiers = data.modifiers;
suite._parallelMode = data.parallelMode;
suite._hooks = data.hooks.map(h => ({
type: h.type,
location: h.location,
title: h.title,
fn: () => {}
}));
suite._fileId = data.fileId;
return suite;
}
_clone() {
const data = this._serialize();
const suite = Suite._parse(data);
suite._use = this._use.slice();
suite._hooks = this._hooks.slice();
suite._fullProject = this._fullProject;
return suite;
}
project() {
var _this$_fullProject, _this$parent;
return ((_this$_fullProject = this._fullProject) === null || _this$_fullProject === void 0 ? void 0 : _this$_fullProject.project) || ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.project());
}
}
exports.Suite = Suite;
class TestCase extends Base {
constructor(title, fn, testType, location) {
super(title);
this.fn = void 0;
this.results = [];
this.location = void 0;
this.parent = void 0;
this.type = 'test';
this.expectedStatus = 'passed';
this.timeout = 0;
this.annotations = [];
this.retries = 0;
this.repeatEachIndex = 0;
this._testType = void 0;
this.id = '';
this._pool = void 0;
this._poolDigest = '';
this._workerHash = '';
this._projectId = '';
// Annotations known statically before running the test, e.g. `test.skip()` or `test(title, { annotation }, body)`.
this._staticAnnotations = [];
// Explicitly declared tags that are not a part of the title.
this._tags = [];
this.fn = fn;
this._testType = testType;
this.location = location;
}
titlePath() {
const titlePath = this.parent ? this.parent.titlePath() : [];
titlePath.push(this.title);
return titlePath;
}
outcome() {
return (0, _teleReceiver.computeTestCaseOutcome)(this);
}
ok() {
const status = this.outcome();
return status === 'expected' || status === 'flaky' || status === 'skipped';
}
get tags() {
return this._grepTitle().match(/@[\S]+/g) || [];
}
_serialize() {
return {
kind: 'test',
id: this.id,
title: this.title,
retries: this.retries,
timeout: this.timeout,
expectedStatus: this.expectedStatus,
location: this.location,
only: this._only,
requireFile: this._requireFile,
poolDigest: this._poolDigest,
workerHash: this._workerHash,
staticAnnotations: this._staticAnnotations.slice(),
annotations: this.annotations.slice(),
tags: this._tags.slice(),
projectId: this._projectId
};
}
static _parse(data) {
const test = new TestCase(data.title, () => {}, _testType.rootTestType, data.location);
test.id = data.id;
test.retries = data.retries;
test.timeout = data.timeout;
test.expectedStatus = data.expectedStatus;
test._only = data.only;
test._requireFile = data.requireFile;
test._poolDigest = data.poolDigest;
test._workerHash = data.workerHash;
test._staticAnnotations = data.staticAnnotations;
test.annotations = data.annotations;
test._tags = data.tags;
test._projectId = data.projectId;
return test;
}
_clone() {
const data = this._serialize();
const test = TestCase._parse(data);
test._testType = this._testType;
test.fn = this.fn;
return test;
}
_appendTestResult() {
const result = {
retry: this.results.length,
parallelIndex: -1,
workerIndex: -1,
duration: 0,
startTime: new Date(),
stdout: [],
stderr: [],
attachments: [],
status: 'skipped',
steps: [],
errors: []
};
this.results.push(result);
return result;
}
_grepTitle() {
const path = [];
this.parent._collectGrepTitlePath(path);
path.push(this.title);
path.push(...this._tags);
return path.join(' ');
}
}
exports.TestCase = TestCase;

102
node_modules/playwright/lib/common/testLoader.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.defaultTimeout = void 0;
exports.loadTestFile = loadTestFile;
var _path = _interopRequireDefault(require("path"));
var _util = _interopRequireDefault(require("util"));
var esmLoaderHost = _interopRequireWildcard(require("./esmLoaderHost"));
var _globals = require("./globals");
var _test = require("./test");
var _compilationCache = require("../transform/compilationCache");
var _transform = require("../transform/transform");
var _util2 = require("../util");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
/**
* Copyright Microsoft Corporation. All rights reserved.
*
* 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 defaultTimeout = exports.defaultTimeout = 30000;
// To allow multiple loaders in the same process without clearing require cache,
// we make these maps global.
const cachedFileSuites = new Map();
async function loadTestFile(file, rootDir, testErrors) {
if (cachedFileSuites.has(file)) return cachedFileSuites.get(file);
const suite = new _test.Suite(_path.default.relative(rootDir, file) || _path.default.basename(file), 'file');
suite._requireFile = file;
suite.location = {
file,
line: 0,
column: 0
};
(0, _globals.setCurrentlyLoadingFileSuite)(suite);
if (!(0, _globals.isWorkerProcess)()) {
(0, _compilationCache.startCollectingFileDeps)();
await esmLoaderHost.startCollectingFileDeps();
}
try {
await (0, _transform.requireOrImport)(file);
cachedFileSuites.set(file, suite);
} catch (e) {
if (!testErrors) throw e;
testErrors.push(serializeLoadError(file, e));
} finally {
(0, _globals.setCurrentlyLoadingFileSuite)(undefined);
if (!(0, _globals.isWorkerProcess)()) {
(0, _compilationCache.stopCollectingFileDeps)(file);
await esmLoaderHost.stopCollectingFileDeps(file);
}
}
{
// Test locations that we discover potentially have different file name.
// This could be due to either
// a) use of source maps or due to
// b) require of one file from another.
// Try fixing (a) w/o regressing (b).
const files = new Set();
suite.allTests().map(t => files.add(t.location.file));
if (files.size === 1) {
// All tests point to one file.
const mappedFile = files.values().next().value;
if (suite.location.file !== mappedFile) {
// The file is different, check for a likely source map case.
if (_path.default.extname(mappedFile) !== _path.default.extname(suite.location.file)) suite.location.file = mappedFile;
}
}
}
return suite;
}
function serializeLoadError(file, error) {
if (error instanceof Error) {
const result = (0, _util2.filterStackTrace)(error);
// Babel parse errors have location.
const loc = error.loc;
result.location = loc ? {
file,
line: loc.line || 0,
column: loc.column || 0
} : undefined;
return result;
}
return {
value: _util.default.inspect(error)
};
}

302
node_modules/playwright/lib/common/testType.js generated vendored Normal file
View File

@@ -0,0 +1,302 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TestTypeImpl = void 0;
exports.mergeTests = mergeTests;
exports.rootTestType = void 0;
var _playwrightCore = require("playwright-core");
var _utils = require("playwright-core/lib/utils");
var _globals = require("./globals");
var _test = require("./test");
var _expect = require("../matchers/expect");
var _transform = require("../transform/transform");
/**
* 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 testTypeSymbol = Symbol('testType');
class TestTypeImpl {
constructor(fixtures) {
this.fixtures = void 0;
this.test = void 0;
this.fixtures = fixtures;
const test = (0, _transform.wrapFunctionWithLocation)(this._createTest.bind(this, 'default'));
test[testTypeSymbol] = this;
test.expect = _expect.expect;
test.only = (0, _transform.wrapFunctionWithLocation)(this._createTest.bind(this, 'only'));
test.describe = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'default'));
test.describe.only = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'only'));
test.describe.configure = (0, _transform.wrapFunctionWithLocation)(this._configure.bind(this));
test.describe.fixme = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'fixme'));
test.describe.parallel = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'parallel'));
test.describe.parallel.only = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'parallel.only'));
test.describe.serial = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'serial'));
test.describe.serial.only = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'serial.only'));
test.describe.skip = (0, _transform.wrapFunctionWithLocation)(this._describe.bind(this, 'skip'));
test.beforeEach = (0, _transform.wrapFunctionWithLocation)(this._hook.bind(this, 'beforeEach'));
test.afterEach = (0, _transform.wrapFunctionWithLocation)(this._hook.bind(this, 'afterEach'));
test.beforeAll = (0, _transform.wrapFunctionWithLocation)(this._hook.bind(this, 'beforeAll'));
test.afterAll = (0, _transform.wrapFunctionWithLocation)(this._hook.bind(this, 'afterAll'));
test.skip = (0, _transform.wrapFunctionWithLocation)(this._modifier.bind(this, 'skip'));
test.fixme = (0, _transform.wrapFunctionWithLocation)(this._modifier.bind(this, 'fixme'));
test.fail = (0, _transform.wrapFunctionWithLocation)(this._modifier.bind(this, 'fail'));
test.fail.only = (0, _transform.wrapFunctionWithLocation)(this._createTest.bind(this, 'fail.only'));
test.slow = (0, _transform.wrapFunctionWithLocation)(this._modifier.bind(this, 'slow'));
test.setTimeout = (0, _transform.wrapFunctionWithLocation)(this._setTimeout.bind(this));
test.step = this._step.bind(this, 'pass');
test.step.skip = this._step.bind(this, 'skip');
test.use = (0, _transform.wrapFunctionWithLocation)(this._use.bind(this));
test.extend = (0, _transform.wrapFunctionWithLocation)(this._extend.bind(this));
test.info = () => {
const result = (0, _globals.currentTestInfo)();
if (!result) throw new Error('test.info() can only be called while test is running');
return result;
};
this.test = test;
}
_currentSuite(location, title) {
const suite = (0, _globals.currentlyLoadingFileSuite)();
if (!suite) {
throw new Error([`Playwright Test did not expect ${title} to be called here.`, `Most common reasons include:`, `- You are calling ${title} in a configuration file.`, `- You are calling ${title} in a file that is imported by the configuration file.`, `- You have two different versions of @playwright/test. This usually happens`, ` when one of the dependencies in your package.json depends on @playwright/test.`].join('\n'));
}
return suite;
}
_createTest(type, location, title, fnOrDetails, fn) {
throwIfRunningInsideJest();
const suite = this._currentSuite(location, 'test()');
if (!suite) return;
let details;
let body;
if (typeof fnOrDetails === 'function') {
body = fnOrDetails;
details = {};
} else {
body = fn;
details = fnOrDetails;
}
const validatedDetails = validateTestDetails(details);
const test = new _test.TestCase(title, body, this, location);
test._requireFile = suite._requireFile;
test._staticAnnotations.push(...validatedDetails.annotations);
test._tags.push(...validatedDetails.tags);
suite._addTest(test);
if (type === 'only' || type === 'fail.only') test._only = true;
if (type === 'skip' || type === 'fixme' || type === 'fail') test._staticAnnotations.push({
type
});else if (type === 'fail.only') test._staticAnnotations.push({
type: 'fail'
});
}
_describe(type, location, titleOrFn, fnOrDetails, fn) {
throwIfRunningInsideJest();
const suite = this._currentSuite(location, 'test.describe()');
if (!suite) return;
let title;
let body;
let details;
if (typeof titleOrFn === 'function') {
title = '';
details = {};
body = titleOrFn;
} else if (typeof fnOrDetails === 'function') {
title = titleOrFn;
details = {};
body = fnOrDetails;
} else {
title = titleOrFn;
details = fnOrDetails;
body = fn;
}
const validatedDetails = validateTestDetails(details);
const child = new _test.Suite(title, 'describe');
child._requireFile = suite._requireFile;
child.location = location;
child._staticAnnotations.push(...validatedDetails.annotations);
child._tags.push(...validatedDetails.tags);
suite._addSuite(child);
if (type === 'only' || type === 'serial.only' || type === 'parallel.only') child._only = true;
if (type === 'serial' || type === 'serial.only') child._parallelMode = 'serial';
if (type === 'parallel' || type === 'parallel.only') child._parallelMode = 'parallel';
if (type === 'skip' || type === 'fixme') child._staticAnnotations.push({
type
});
for (let parent = suite; parent; parent = parent.parent) {
if (parent._parallelMode === 'serial' && child._parallelMode === 'parallel') throw new Error('describe.parallel cannot be nested inside describe.serial');
if (parent._parallelMode === 'default' && child._parallelMode === 'parallel') throw new Error('describe.parallel cannot be nested inside describe with default mode');
}
(0, _globals.setCurrentlyLoadingFileSuite)(child);
body();
(0, _globals.setCurrentlyLoadingFileSuite)(suite);
}
_hook(name, location, title, fn) {
const suite = this._currentSuite(location, `test.${name}()`);
if (!suite) return;
if (typeof title === 'function') {
fn = title;
title = `${name} hook`;
}
suite._hooks.push({
type: name,
fn: fn,
title,
location
});
}
_configure(location, options) {
throwIfRunningInsideJest();
const suite = this._currentSuite(location, `test.describe.configure()`);
if (!suite) return;
if (options.timeout !== undefined) suite._timeout = options.timeout;
if (options.retries !== undefined) suite._retries = options.retries;
if (options.mode !== undefined) {
if (suite._parallelMode !== 'none') throw new Error(`"${suite._parallelMode}" mode is already assigned for the enclosing scope.`);
suite._parallelMode = options.mode;
for (let parent = suite.parent; parent; parent = parent.parent) {
if (parent._parallelMode === 'serial' && suite._parallelMode === 'parallel') throw new Error('describe with parallel mode cannot be nested inside describe with serial mode');
if (parent._parallelMode === 'default' && suite._parallelMode === 'parallel') throw new Error('describe with parallel mode cannot be nested inside describe with default mode');
}
}
}
_modifier(type, location, ...modifierArgs) {
const suite = (0, _globals.currentlyLoadingFileSuite)();
if (suite) {
if (typeof modifierArgs[0] === 'string' && typeof modifierArgs[1] === 'function' && (type === 'skip' || type === 'fixme' || type === 'fail')) {
// Support for test.{skip,fixme,fail}(title, body)
this._createTest(type, location, modifierArgs[0], modifierArgs[1]);
return;
}
if (typeof modifierArgs[0] === 'string' && typeof modifierArgs[1] === 'object' && typeof modifierArgs[2] === 'function' && (type === 'skip' || type === 'fixme' || type === 'fail')) {
// Support for test.{skip,fixme,fail}(title, details, body)
this._createTest(type, location, modifierArgs[0], modifierArgs[1], modifierArgs[2]);
return;
}
if (typeof modifierArgs[0] === 'function') {
suite._modifiers.push({
type,
fn: modifierArgs[0],
location,
description: modifierArgs[1]
});
} else {
if (modifierArgs.length >= 1 && !modifierArgs[0]) return;
const description = modifierArgs[1];
suite._staticAnnotations.push({
type,
description
});
}
return;
}
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`test.${type}() can only be called inside test, describe block or fixture`);
if (typeof modifierArgs[0] === 'function') throw new Error(`test.${type}() with a function can only be called inside describe block`);
testInfo[type](...modifierArgs);
}
_setTimeout(location, timeout) {
const suite = (0, _globals.currentlyLoadingFileSuite)();
if (suite) {
suite._timeout = timeout;
return;
}
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`test.setTimeout() can only be called from a test`);
testInfo.setTimeout(timeout);
}
_use(location, fixtures) {
const suite = this._currentSuite(location, `test.use()`);
if (!suite) return;
suite._use.push({
fixtures,
location
});
}
_step(expectation, title, body, options = {}) {
const testInfo = (0, _globals.currentTestInfo)();
if (!testInfo) throw new Error(`test.step() can only be called from a test`);
return testInfo._floatingPromiseScope.wrapPromiseAPIResult(this._stepInternal(expectation, testInfo, title, body, options));
}
async _stepInternal(expectation, testInfo, title, body, options = {}) {
const step = testInfo._addStep({
category: 'test.step',
title,
location: options.location,
box: options.box
});
return await (0, _utils.currentZone)().with('stepZone', step).run(async () => {
try {
let result = undefined;
result = await (0, _utils.raceAgainstDeadline)(async () => {
try {
return await step.info._runStepBody(expectation === 'skip', body);
} catch (e) {
var _result;
// If the step timed out, the test fixtures will tear down, which in turn
// will abort unfinished actions in the step body. Record such errors here.
if ((_result = result) !== null && _result !== void 0 && _result.timedOut) testInfo._failWithError(e);
throw e;
}
}, options.timeout ? (0, _utils.monotonicTime)() + options.timeout : 0);
if (result.timedOut) throw new _playwrightCore.errors.TimeoutError(`Step timeout of ${options.timeout}ms exceeded.`);
step.complete({});
return result.result;
} catch (error) {
step.complete({
error
});
throw error;
}
});
}
_extend(location, fixtures) {
if (fixtures[testTypeSymbol]) throw new Error(`test.extend() accepts fixtures object, not a test object.\nDid you mean to call mergeTests()?`);
const fixturesWithLocation = {
fixtures,
location
};
return new TestTypeImpl([...this.fixtures, fixturesWithLocation]).test;
}
}
exports.TestTypeImpl = TestTypeImpl;
function throwIfRunningInsideJest() {
if (process.env.JEST_WORKER_ID) {
const packageManagerCommand = (0, _utils.getPackageManagerExecCommand)();
throw new Error(`Playwright Test needs to be invoked via '${packageManagerCommand} playwright test' and excluded from Jest test runs.\n` + `Creating one directory for Playwright tests and one for Jest is the recommended way of doing it.\n` + `See https://playwright.dev/docs/intro for more information about Playwright Test.`);
}
}
function validateTestDetails(details) {
const annotations = Array.isArray(details.annotation) ? details.annotation : details.annotation ? [details.annotation] : [];
const tags = Array.isArray(details.tag) ? details.tag : details.tag ? [details.tag] : [];
for (const tag of tags) {
if (tag[0] !== '@') throw new Error(`Tag must start with "@" symbol, got "${tag}" instead.`);
}
return {
annotations,
tags
};
}
const rootTestType = exports.rootTestType = new TestTypeImpl([]);
function mergeTests(...tests) {
let result = rootTestType;
for (const t of tests) {
const testTypeImpl = t[testTypeSymbol];
if (!testTypeImpl) throw new Error(`mergeTests() accepts "test" functions as parameters.\nDid you mean to call test.extend() with fixtures instead?`);
// Filter out common ancestor fixtures.
const newFixtures = testTypeImpl.fixtures.filter(theirs => !result.fixtures.find(ours => ours.fixtures === theirs.fixtures));
result = new TestTypeImpl([...result.fixtures, ...newFixtures]);
}
return result.test;
}