ScuttleBot

scuttlebot / tests / e2e / node_modules / playwright / lib / worker / fixtureRunner.js
Source Blame History 262 lines
f7eb47b… lmata 1 "use strict";
f7eb47b… lmata 2 var __defProp = Object.defineProperty;
f7eb47b… lmata 3 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
f7eb47b… lmata 4 var __getOwnPropNames = Object.getOwnPropertyNames;
f7eb47b… lmata 5 var __hasOwnProp = Object.prototype.hasOwnProperty;
f7eb47b… lmata 6 var __export = (target, all) => {
f7eb47b… lmata 7 for (var name in all)
f7eb47b… lmata 8 __defProp(target, name, { get: all[name], enumerable: true });
f7eb47b… lmata 9 };
f7eb47b… lmata 10 var __copyProps = (to, from, except, desc) => {
f7eb47b… lmata 11 if (from && typeof from === "object" || typeof from === "function") {
f7eb47b… lmata 12 for (let key of __getOwnPropNames(from))
f7eb47b… lmata 13 if (!__hasOwnProp.call(to, key) && key !== except)
f7eb47b… lmata 14 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
f7eb47b… lmata 15 }
f7eb47b… lmata 16 return to;
f7eb47b… lmata 17 };
f7eb47b… lmata 18 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
f7eb47b… lmata 19 var fixtureRunner_exports = {};
f7eb47b… lmata 20 __export(fixtureRunner_exports, {
f7eb47b… lmata 21 FixtureRunner: () => FixtureRunner
f7eb47b… lmata 22 });
f7eb47b… lmata 23 module.exports = __toCommonJS(fixtureRunner_exports);
f7eb47b… lmata 24 var import_utils = require("playwright-core/lib/utils");
f7eb47b… lmata 25 var import_fixtures = require("../common/fixtures");
f7eb47b… lmata 26 var import_util = require("../util");
f7eb47b… lmata 27 class Fixture {
f7eb47b… lmata 28 constructor(runner, registration) {
f7eb47b… lmata 29 this.failed = false;
f7eb47b… lmata 30 this._deps = /* @__PURE__ */ new Set();
f7eb47b… lmata 31 this._usages = /* @__PURE__ */ new Set();
f7eb47b… lmata 32 this.runner = runner;
f7eb47b… lmata 33 this.registration = registration;
f7eb47b… lmata 34 this.value = null;
f7eb47b… lmata 35 const isUserFixture = this.registration.location && (0, import_util.filterStackFile)(this.registration.location.file);
f7eb47b… lmata 36 const title = this.registration.customTitle || this.registration.name;
f7eb47b… lmata 37 const location = isUserFixture ? this.registration.location : void 0;
f7eb47b… lmata 38 this._stepInfo = { title: `Fixture ${(0, import_utils.escapeWithQuotes)(title, '"')}`, category: "fixture", location };
f7eb47b… lmata 39 if (this.registration.box === "self")
f7eb47b… lmata 40 this._stepInfo = void 0;
f7eb47b… lmata 41 else if (this.registration.box)
f7eb47b… lmata 42 this._stepInfo.group = isUserFixture ? "configuration" : "internal";
f7eb47b… lmata 43 this._setupDescription = {
f7eb47b… lmata 44 title,
f7eb47b… lmata 45 phase: "setup",
f7eb47b… lmata 46 location,
f7eb47b… lmata 47 slot: this.registration.timeout !== void 0 ? {
f7eb47b… lmata 48 timeout: this.registration.timeout,
f7eb47b… lmata 49 elapsed: 0
f7eb47b… lmata 50 } : this.registration.scope === "worker" ? {
f7eb47b… lmata 51 timeout: this.runner.workerFixtureTimeout,
f7eb47b… lmata 52 elapsed: 0
f7eb47b… lmata 53 } : void 0
f7eb47b… lmata 54 };
f7eb47b… lmata 55 this._teardownDescription = { ...this._setupDescription, phase: "teardown" };
f7eb47b… lmata 56 }
f7eb47b… lmata 57 async setup(testInfo, runnable) {
f7eb47b… lmata 58 this.runner.instanceForId.set(this.registration.id, this);
f7eb47b… lmata 59 if (typeof this.registration.fn !== "function") {
f7eb47b… lmata 60 this.value = this.registration.fn;
f7eb47b… lmata 61 return;
f7eb47b… lmata 62 }
f7eb47b… lmata 63 const run = () => testInfo._runWithTimeout({ ...runnable, fixture: this._setupDescription }, () => this._setupInternal(testInfo));
f7eb47b… lmata 64 if (this._stepInfo)
f7eb47b… lmata 65 await testInfo._runAsStep(this._stepInfo, run);
f7eb47b… lmata 66 else
f7eb47b… lmata 67 await run();
f7eb47b… lmata 68 }
f7eb47b… lmata 69 async _setupInternal(testInfo) {
f7eb47b… lmata 70 const params = {};
f7eb47b… lmata 71 for (const name of this.registration.deps) {
f7eb47b… lmata 72 const registration = this.runner.pool.resolve(name, this.registration);
f7eb47b… lmata 73 const dep = this.runner.instanceForId.get(registration.id);
f7eb47b… lmata 74 if (!dep) {
f7eb47b… lmata 75 this.failed = true;
f7eb47b… lmata 76 return;
f7eb47b… lmata 77 }
f7eb47b… lmata 78 dep._usages.add(this);
f7eb47b… lmata 79 this._deps.add(dep);
f7eb47b… lmata 80 params[name] = dep.value;
f7eb47b… lmata 81 if (dep.failed) {
f7eb47b… lmata 82 this.failed = true;
f7eb47b… lmata 83 return;
f7eb47b… lmata 84 }
f7eb47b… lmata 85 }
f7eb47b… lmata 86 let called = false;
f7eb47b… lmata 87 const useFuncStarted = new import_utils.ManualPromise();
f7eb47b… lmata 88 const useFunc = async (value) => {
f7eb47b… lmata 89 if (called)
f7eb47b… lmata 90 throw new Error(`Cannot provide fixture value for the second time`);
f7eb47b… lmata 91 called = true;
f7eb47b… lmata 92 this.value = value;
f7eb47b… lmata 93 this._useFuncFinished = new import_utils.ManualPromise();
f7eb47b… lmata 94 useFuncStarted.resolve();
f7eb47b… lmata 95 await this._useFuncFinished;
f7eb47b… lmata 96 };
f7eb47b… lmata 97 const workerInfo = { config: testInfo.config, parallelIndex: testInfo.parallelIndex, workerIndex: testInfo.workerIndex, project: testInfo.project };
f7eb47b… lmata 98 const info = this.registration.scope === "worker" ? workerInfo : testInfo;
f7eb47b… lmata 99 this._selfTeardownComplete = (async () => {
f7eb47b… lmata 100 try {
f7eb47b… lmata 101 await this.registration.fn(params, useFunc, info);
f7eb47b… lmata 102 if (!useFuncStarted.isDone())
f7eb47b… lmata 103 throw new Error(`use() was not called in fixture "${this.registration.name}"`);
f7eb47b… lmata 104 } catch (error) {
f7eb47b… lmata 105 this.failed = true;
f7eb47b… lmata 106 if (!useFuncStarted.isDone())
f7eb47b… lmata 107 useFuncStarted.reject(error);
f7eb47b… lmata 108 else
f7eb47b… lmata 109 throw error;
f7eb47b… lmata 110 }
f7eb47b… lmata 111 })();
f7eb47b… lmata 112 await useFuncStarted;
f7eb47b… lmata 113 }
f7eb47b… lmata 114 async teardown(testInfo, runnable) {
f7eb47b… lmata 115 try {
f7eb47b… lmata 116 const fixtureRunnable = { ...runnable, fixture: this._teardownDescription };
f7eb47b… lmata 117 if (!testInfo._timeoutManager.isTimeExhaustedFor(fixtureRunnable)) {
f7eb47b… lmata 118 const run = () => testInfo._runWithTimeout(fixtureRunnable, () => this._teardownInternal());
f7eb47b… lmata 119 if (this._stepInfo)
f7eb47b… lmata 120 await testInfo._runAsStep(this._stepInfo, run);
f7eb47b… lmata 121 else
f7eb47b… lmata 122 await run();
f7eb47b… lmata 123 }
f7eb47b… lmata 124 } finally {
f7eb47b… lmata 125 for (const dep of this._deps)
f7eb47b… lmata 126 dep._usages.delete(this);
f7eb47b… lmata 127 this.runner.instanceForId.delete(this.registration.id);
f7eb47b… lmata 128 }
f7eb47b… lmata 129 }
f7eb47b… lmata 130 async _teardownInternal() {
f7eb47b… lmata 131 if (typeof this.registration.fn !== "function")
f7eb47b… lmata 132 return;
f7eb47b… lmata 133 if (this._usages.size !== 0) {
f7eb47b… lmata 134 console.error("Internal error: fixture integrity at", this._teardownDescription.title);
f7eb47b… lmata 135 this._usages.clear();
f7eb47b… lmata 136 }
f7eb47b… lmata 137 if (this._useFuncFinished) {
f7eb47b… lmata 138 this._useFuncFinished.resolve();
f7eb47b… lmata 139 this._useFuncFinished = void 0;
f7eb47b… lmata 140 await this._selfTeardownComplete;
f7eb47b… lmata 141 }
f7eb47b… lmata 142 }
f7eb47b… lmata 143 _collectFixturesInTeardownOrder(scope, collector) {
f7eb47b… lmata 144 if (this.registration.scope !== scope)
f7eb47b… lmata 145 return;
f7eb47b… lmata 146 for (const fixture of this._usages)
f7eb47b… lmata 147 fixture._collectFixturesInTeardownOrder(scope, collector);
f7eb47b… lmata 148 collector.add(this);
f7eb47b… lmata 149 }
f7eb47b… lmata 150 }
f7eb47b… lmata 151 class FixtureRunner {
f7eb47b… lmata 152 constructor() {
f7eb47b… lmata 153 this.testScopeClean = true;
f7eb47b… lmata 154 this.instanceForId = /* @__PURE__ */ new Map();
f7eb47b… lmata 155 this.workerFixtureTimeout = 0;
f7eb47b… lmata 156 }
f7eb47b… lmata 157 setPool(pool) {
f7eb47b… lmata 158 if (!this.testScopeClean)
f7eb47b… lmata 159 throw new Error("Did not teardown test scope");
f7eb47b… lmata 160 if (this.pool && pool.digest !== this.pool.digest) {
f7eb47b… lmata 161 throw new Error([
f7eb47b… lmata 162 `Playwright detected inconsistent test.use() options.`,
f7eb47b… lmata 163 `Most common mistakes that lead to this issue:`,
f7eb47b… lmata 164 ` - Calling test.use() outside of the test file, for example in a common helper.`,
f7eb47b… lmata 165 ` - One test file imports from another test file.`
f7eb47b… lmata 166 ].join("\n"));
f7eb47b… lmata 167 }
f7eb47b… lmata 168 this.pool = pool;
f7eb47b… lmata 169 }
f7eb47b… lmata 170 _collectFixturesInSetupOrder(registration, collector) {
f7eb47b… lmata 171 if (collector.has(registration))
f7eb47b… lmata 172 return;
f7eb47b… lmata 173 for (const name of registration.deps) {
f7eb47b… lmata 174 const dep = this.pool.resolve(name, registration);
f7eb47b… lmata 175 this._collectFixturesInSetupOrder(dep, collector);
f7eb47b… lmata 176 }
f7eb47b… lmata 177 collector.add(registration);
f7eb47b… lmata 178 }
f7eb47b… lmata 179 async teardownScope(scope, testInfo, runnable) {
f7eb47b… lmata 180 const fixtures = Array.from(this.instanceForId.values()).reverse();
f7eb47b… lmata 181 const collector = /* @__PURE__ */ new Set();
f7eb47b… lmata 182 for (const fixture of fixtures)
f7eb47b… lmata 183 fixture._collectFixturesInTeardownOrder(scope, collector);
f7eb47b… lmata 184 let firstError;
f7eb47b… lmata 185 for (const fixture of collector) {
f7eb47b… lmata 186 try {
f7eb47b… lmata 187 await fixture.teardown(testInfo, runnable);
f7eb47b… lmata 188 } catch (error) {
f7eb47b… lmata 189 firstError = firstError ?? error;
f7eb47b… lmata 190 }
f7eb47b… lmata 191 }
f7eb47b… lmata 192 if (scope === "test")
f7eb47b… lmata 193 this.testScopeClean = true;
f7eb47b… lmata 194 if (firstError)
f7eb47b… lmata 195 throw firstError;
f7eb47b… lmata 196 }
f7eb47b… lmata 197 async resolveParametersForFunction(fn, testInfo, autoFixtures, runnable) {
f7eb47b… lmata 198 const collector = /* @__PURE__ */ new Set();
f7eb47b… lmata 199 const auto = [];
f7eb47b… lmata 200 for (const registration of this.pool.autoFixtures()) {
f7eb47b… lmata 201 let shouldRun = true;
f7eb47b… lmata 202 if (autoFixtures === "all-hooks-only")
f7eb47b… lmata 203 shouldRun = registration.scope === "worker" || registration.auto === "all-hooks-included";
f7eb47b… lmata 204 else if (autoFixtures === "worker")
f7eb47b… lmata 205 shouldRun = registration.scope === "worker";
f7eb47b… lmata 206 if (shouldRun)
f7eb47b… lmata 207 auto.push(registration);
f7eb47b… lmata 208 }
f7eb47b… lmata 209 auto.sort((r1, r2) => (r1.scope === "worker" ? 0 : 1) - (r2.scope === "worker" ? 0 : 1));
f7eb47b… lmata 210 for (const registration of auto)
f7eb47b… lmata 211 this._collectFixturesInSetupOrder(registration, collector);
f7eb47b… lmata 212 const names = getRequiredFixtureNames(fn);
f7eb47b… lmata 213 for (const name of names)
f7eb47b… lmata 214 this._collectFixturesInSetupOrder(this.pool.resolve(name), collector);
f7eb47b… lmata 215 for (const registration of collector)
f7eb47b… lmata 216 await this._setupFixtureForRegistration(registration, testInfo, runnable);
f7eb47b… lmata 217 const params = {};
f7eb47b… lmata 218 for (const name of names) {
f7eb47b… lmata 219 const registration = this.pool.resolve(name);
f7eb47b… lmata 220 const fixture = this.instanceForId.get(registration.id);
f7eb47b… lmata 221 if (!fixture || fixture.failed)
f7eb47b… lmata 222 return null;
f7eb47b… lmata 223 params[name] = fixture.value;
f7eb47b… lmata 224 }
f7eb47b… lmata 225 return params;
f7eb47b… lmata 226 }
f7eb47b… lmata 227 async resolveParametersAndRunFunction(fn, testInfo, autoFixtures, runnable) {
f7eb47b… lmata 228 const params = await this.resolveParametersForFunction(fn, testInfo, autoFixtures, runnable);
f7eb47b… lmata 229 if (params === null) {
f7eb47b… lmata 230 return null;
f7eb47b… lmata 231 }
f7eb47b… lmata 232 await testInfo._runWithTimeout(runnable, () => fn(params, testInfo));
f7eb47b… lmata 233 }
f7eb47b… lmata 234 async _setupFixtureForRegistration(registration, testInfo, runnable) {
f7eb47b… lmata 235 if (registration.scope === "test")
f7eb47b… lmata 236 this.testScopeClean = false;
f7eb47b… lmata 237 let fixture = this.instanceForId.get(registration.id);
f7eb47b… lmata 238 if (fixture)
f7eb47b… lmata 239 return fixture;
f7eb47b… lmata 240 fixture = new Fixture(this, registration);
f7eb47b… lmata 241 await fixture.setup(testInfo, runnable);
f7eb47b… lmata 242 return fixture;
f7eb47b… lmata 243 }
f7eb47b… lmata 244 dependsOnWorkerFixturesOnly(fn, location) {
f7eb47b… lmata 245 const names = getRequiredFixtureNames(fn, location);
f7eb47b… lmata 246 for (const name of names) {
f7eb47b… lmata 247 const registration = this.pool.resolve(name);
f7eb47b… lmata 248 if (registration.scope !== "worker")
f7eb47b… lmata 249 return false;
f7eb47b… lmata 250 }
f7eb47b… lmata 251 return true;
f7eb47b… lmata 252 }
f7eb47b… lmata 253 }
f7eb47b… lmata 254 function getRequiredFixtureNames(fn, location) {
f7eb47b… lmata 255 return (0, import_fixtures.fixtureParameterNames)(fn, location ?? { file: "<unknown>", line: 1, column: 1 }, (e) => {
f7eb47b… lmata 256 throw new Error(`${(0, import_util.formatLocation)(e.location)}: ${e.message}`);
f7eb47b… lmata 257 });
f7eb47b… lmata 258 }
f7eb47b… lmata 259 // Annotate the CommonJS export names for ESM import in node:
f7eb47b… lmata 260 0 && (module.exports = {
f7eb47b… lmata 261 FixtureRunner
f7eb47b… lmata 262 });

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button