ScuttleBot

Source Blame History 726 lines
f7eb47b… lmata 1 "use strict";
f7eb47b… lmata 2 var __create = Object.create;
f7eb47b… lmata 3 var __defProp = Object.defineProperty;
f7eb47b… lmata 4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
f7eb47b… lmata 5 var __getOwnPropNames = Object.getOwnPropertyNames;
f7eb47b… lmata 6 var __getProtoOf = Object.getPrototypeOf;
f7eb47b… lmata 7 var __hasOwnProp = Object.prototype.hasOwnProperty;
f7eb47b… lmata 8 var __export = (target, all) => {
f7eb47b… lmata 9 for (var name in all)
f7eb47b… lmata 10 __defProp(target, name, { get: all[name], enumerable: true });
f7eb47b… lmata 11 };
f7eb47b… lmata 12 var __copyProps = (to, from, except, desc) => {
f7eb47b… lmata 13 if (from && typeof from === "object" || typeof from === "function") {
f7eb47b… lmata 14 for (let key of __getOwnPropNames(from))
f7eb47b… lmata 15 if (!__hasOwnProp.call(to, key) && key !== except)
f7eb47b… lmata 16 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
f7eb47b… lmata 17 }
f7eb47b… lmata 18 return to;
f7eb47b… lmata 19 };
f7eb47b… lmata 20 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
f7eb47b… lmata 21 // If the importer is in node compatibility mode or this is not an ESM
f7eb47b… lmata 22 // file that has been converted to a CommonJS file using a Babel-
f7eb47b… lmata 23 // compatible transform (i.e. "__esModule" has not been set), then set
f7eb47b… lmata 24 // "default" to the CommonJS "module.exports" for node compatibility.
f7eb47b… lmata 25 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
f7eb47b… lmata 26 mod
f7eb47b… lmata 27 ));
f7eb47b… lmata 28 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
f7eb47b… lmata 29 var index_exports = {};
f7eb47b… lmata 30 __export(index_exports, {
f7eb47b… lmata 31 _baseTest: () => _baseTest,
f7eb47b… lmata 32 defineConfig: () => import_configLoader.defineConfig,
f7eb47b… lmata 33 expect: () => import_expect.expect,
f7eb47b… lmata 34 mergeExpects: () => import_expect2.mergeExpects,
f7eb47b… lmata 35 mergeTests: () => import_testType2.mergeTests,
f7eb47b… lmata 36 test: () => test
f7eb47b… lmata 37 });
f7eb47b… lmata 38 module.exports = __toCommonJS(index_exports);
f7eb47b… lmata 39 var import_fs = __toESM(require("fs"));
f7eb47b… lmata 40 var import_path = __toESM(require("path"));
f7eb47b… lmata 41 var playwrightLibrary = __toESM(require("playwright-core"));
f7eb47b… lmata 42 var import_utils = require("playwright-core/lib/utils");
f7eb47b… lmata 43 var import_globals = require("./common/globals");
f7eb47b… lmata 44 var import_testType = require("./common/testType");
f7eb47b… lmata 45 var import_browserBackend = require("./mcp/test/browserBackend");
f7eb47b… lmata 46 var import_expect = require("./matchers/expect");
f7eb47b… lmata 47 var import_configLoader = require("./common/configLoader");
f7eb47b… lmata 48 var import_testType2 = require("./common/testType");
f7eb47b… lmata 49 var import_expect2 = require("./matchers/expect");
f7eb47b… lmata 50 const _baseTest = import_testType.rootTestType.test;
f7eb47b… lmata 51 (0, import_utils.setBoxedStackPrefixes)([import_path.default.dirname(require.resolve("../package.json"))]);
f7eb47b… lmata 52 if (process["__pw_initiator__"]) {
f7eb47b… lmata 53 const originalStackTraceLimit = Error.stackTraceLimit;
f7eb47b… lmata 54 Error.stackTraceLimit = 200;
f7eb47b… lmata 55 try {
f7eb47b… lmata 56 throw new Error("Requiring @playwright/test second time, \nFirst:\n" + process["__pw_initiator__"] + "\n\nSecond: ");
f7eb47b… lmata 57 } finally {
f7eb47b… lmata 58 Error.stackTraceLimit = originalStackTraceLimit;
f7eb47b… lmata 59 }
f7eb47b… lmata 60 } else {
f7eb47b… lmata 61 process["__pw_initiator__"] = new Error().stack;
f7eb47b… lmata 62 }
f7eb47b… lmata 63 const playwrightFixtures = {
f7eb47b… lmata 64 defaultBrowserType: ["chromium", { scope: "worker", option: true, box: true }],
f7eb47b… lmata 65 browserName: [({ defaultBrowserType }, use) => use(defaultBrowserType), { scope: "worker", option: true, box: true }],
f7eb47b… lmata 66 playwright: [async ({}, use) => {
f7eb47b… lmata 67 await use(require("playwright-core"));
f7eb47b… lmata 68 }, { scope: "worker", box: true }],
f7eb47b… lmata 69 headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: "worker", option: true, box: true }],
f7eb47b… lmata 70 channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: "worker", option: true, box: true }],
f7eb47b… lmata 71 launchOptions: [{}, { scope: "worker", option: true, box: true }],
f7eb47b… lmata 72 connectOptions: [async ({ _optionConnectOptions }, use) => {
f7eb47b… lmata 73 await use(connectOptionsFromEnv() || _optionConnectOptions);
f7eb47b… lmata 74 }, { scope: "worker", option: true, box: true }],
f7eb47b… lmata 75 screenshot: ["off", { scope: "worker", option: true, box: true }],
f7eb47b… lmata 76 video: ["off", { scope: "worker", option: true, box: true }],
f7eb47b… lmata 77 trace: ["off", { scope: "worker", option: true, box: true }],
f7eb47b… lmata 78 _browserOptions: [async ({ playwright, headless, channel, launchOptions }, use) => {
f7eb47b… lmata 79 const options = {
f7eb47b… lmata 80 handleSIGINT: false,
f7eb47b… lmata 81 ...launchOptions,
f7eb47b… lmata 82 tracesDir: tracing().tracesDir()
f7eb47b… lmata 83 };
f7eb47b… lmata 84 if (headless !== void 0)
f7eb47b… lmata 85 options.headless = headless;
f7eb47b… lmata 86 if (channel !== void 0)
f7eb47b… lmata 87 options.channel = channel;
f7eb47b… lmata 88 playwright._defaultLaunchOptions = options;
f7eb47b… lmata 89 await use(options);
f7eb47b… lmata 90 playwright._defaultLaunchOptions = void 0;
f7eb47b… lmata 91 }, { scope: "worker", auto: true, box: true }],
f7eb47b… lmata 92 browser: [async ({ playwright, browserName, _browserOptions, connectOptions }, use) => {
f7eb47b… lmata 93 if (!["chromium", "firefox", "webkit"].includes(browserName))
f7eb47b… lmata 94 throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);
f7eb47b… lmata 95 if (connectOptions) {
f7eb47b… lmata 96 const browser2 = await playwright[browserName].connect({
f7eb47b… lmata 97 ...connectOptions,
f7eb47b… lmata 98 exposeNetwork: connectOptions.exposeNetwork ?? connectOptions._exposeNetwork,
f7eb47b… lmata 99 headers: {
f7eb47b… lmata 100 // HTTP headers are ASCII only (not UTF-8).
f7eb47b… lmata 101 "x-playwright-launch-options": (0, import_utils.jsonStringifyForceASCII)(_browserOptions),
f7eb47b… lmata 102 ...connectOptions.headers
f7eb47b… lmata 103 }
f7eb47b… lmata 104 });
f7eb47b… lmata 105 await use(browser2);
f7eb47b… lmata 106 await browser2.close({ reason: "Test ended." });
f7eb47b… lmata 107 return;
f7eb47b… lmata 108 }
f7eb47b… lmata 109 const browser = await playwright[browserName].launch();
f7eb47b… lmata 110 await use(browser);
f7eb47b… lmata 111 await browser.close({ reason: "Test ended." });
f7eb47b… lmata 112 }, { scope: "worker", timeout: 0 }],
f7eb47b… lmata 113 acceptDownloads: [({ contextOptions }, use) => use(contextOptions.acceptDownloads ?? true), { option: true, box: true }],
f7eb47b… lmata 114 bypassCSP: [({ contextOptions }, use) => use(contextOptions.bypassCSP ?? false), { option: true, box: true }],
f7eb47b… lmata 115 colorScheme: [({ contextOptions }, use) => use(contextOptions.colorScheme === void 0 ? "light" : contextOptions.colorScheme), { option: true, box: true }],
f7eb47b… lmata 116 deviceScaleFactor: [({ contextOptions }, use) => use(contextOptions.deviceScaleFactor), { option: true, box: true }],
f7eb47b… lmata 117 extraHTTPHeaders: [({ contextOptions }, use) => use(contextOptions.extraHTTPHeaders), { option: true, box: true }],
f7eb47b… lmata 118 geolocation: [({ contextOptions }, use) => use(contextOptions.geolocation), { option: true, box: true }],
f7eb47b… lmata 119 hasTouch: [({ contextOptions }, use) => use(contextOptions.hasTouch ?? false), { option: true, box: true }],
f7eb47b… lmata 120 httpCredentials: [({ contextOptions }, use) => use(contextOptions.httpCredentials), { option: true, box: true }],
f7eb47b… lmata 121 ignoreHTTPSErrors: [({ contextOptions }, use) => use(contextOptions.ignoreHTTPSErrors ?? false), { option: true, box: true }],
f7eb47b… lmata 122 isMobile: [({ contextOptions }, use) => use(contextOptions.isMobile ?? false), { option: true, box: true }],
f7eb47b… lmata 123 javaScriptEnabled: [({ contextOptions }, use) => use(contextOptions.javaScriptEnabled ?? true), { option: true, box: true }],
f7eb47b… lmata 124 locale: [({ contextOptions }, use) => use(contextOptions.locale ?? "en-US"), { option: true, box: true }],
f7eb47b… lmata 125 offline: [({ contextOptions }, use) => use(contextOptions.offline ?? false), { option: true, box: true }],
f7eb47b… lmata 126 permissions: [({ contextOptions }, use) => use(contextOptions.permissions), { option: true, box: true }],
f7eb47b… lmata 127 proxy: [({ contextOptions }, use) => use(contextOptions.proxy), { option: true, box: true }],
f7eb47b… lmata 128 storageState: [({ contextOptions }, use) => use(contextOptions.storageState), { option: true, box: true }],
f7eb47b… lmata 129 clientCertificates: [({ contextOptions }, use) => use(contextOptions.clientCertificates), { option: true, box: true }],
f7eb47b… lmata 130 timezoneId: [({ contextOptions }, use) => use(contextOptions.timezoneId), { option: true, box: true }],
f7eb47b… lmata 131 userAgent: [({ contextOptions }, use) => use(contextOptions.userAgent), { option: true, box: true }],
f7eb47b… lmata 132 viewport: [({ contextOptions }, use) => use(contextOptions.viewport === void 0 ? { width: 1280, height: 720 } : contextOptions.viewport), { option: true, box: true }],
f7eb47b… lmata 133 actionTimeout: [0, { option: true, box: true }],
f7eb47b… lmata 134 testIdAttribute: ["data-testid", { option: true, box: true }],
f7eb47b… lmata 135 navigationTimeout: [0, { option: true, box: true }],
f7eb47b… lmata 136 baseURL: [async ({}, use) => {
f7eb47b… lmata 137 await use(process.env.PLAYWRIGHT_TEST_BASE_URL);
f7eb47b… lmata 138 }, { option: true, box: true }],
f7eb47b… lmata 139 serviceWorkers: [({ contextOptions }, use) => use(contextOptions.serviceWorkers ?? "allow"), { option: true, box: true }],
f7eb47b… lmata 140 contextOptions: [{}, { option: true, box: true }],
f7eb47b… lmata 141 agentOptions: [void 0, { option: true, box: true }],
f7eb47b… lmata 142 _combinedContextOptions: [async ({
f7eb47b… lmata 143 acceptDownloads,
f7eb47b… lmata 144 bypassCSP,
f7eb47b… lmata 145 clientCertificates,
f7eb47b… lmata 146 colorScheme,
f7eb47b… lmata 147 deviceScaleFactor,
f7eb47b… lmata 148 extraHTTPHeaders,
f7eb47b… lmata 149 hasTouch,
f7eb47b… lmata 150 geolocation,
f7eb47b… lmata 151 httpCredentials,
f7eb47b… lmata 152 ignoreHTTPSErrors,
f7eb47b… lmata 153 isMobile,
f7eb47b… lmata 154 javaScriptEnabled,
f7eb47b… lmata 155 locale,
f7eb47b… lmata 156 offline,
f7eb47b… lmata 157 permissions,
f7eb47b… lmata 158 proxy,
f7eb47b… lmata 159 storageState,
f7eb47b… lmata 160 viewport,
f7eb47b… lmata 161 timezoneId,
f7eb47b… lmata 162 userAgent,
f7eb47b… lmata 163 baseURL,
f7eb47b… lmata 164 contextOptions,
f7eb47b… lmata 165 serviceWorkers
f7eb47b… lmata 166 }, use, testInfo) => {
f7eb47b… lmata 167 const options = {};
f7eb47b… lmata 168 if (acceptDownloads !== void 0)
f7eb47b… lmata 169 options.acceptDownloads = acceptDownloads;
f7eb47b… lmata 170 if (bypassCSP !== void 0)
f7eb47b… lmata 171 options.bypassCSP = bypassCSP;
f7eb47b… lmata 172 if (colorScheme !== void 0)
f7eb47b… lmata 173 options.colorScheme = colorScheme;
f7eb47b… lmata 174 if (deviceScaleFactor !== void 0)
f7eb47b… lmata 175 options.deviceScaleFactor = deviceScaleFactor;
f7eb47b… lmata 176 if (extraHTTPHeaders !== void 0)
f7eb47b… lmata 177 options.extraHTTPHeaders = extraHTTPHeaders;
f7eb47b… lmata 178 if (geolocation !== void 0)
f7eb47b… lmata 179 options.geolocation = geolocation;
f7eb47b… lmata 180 if (hasTouch !== void 0)
f7eb47b… lmata 181 options.hasTouch = hasTouch;
f7eb47b… lmata 182 if (httpCredentials !== void 0)
f7eb47b… lmata 183 options.httpCredentials = httpCredentials;
f7eb47b… lmata 184 if (ignoreHTTPSErrors !== void 0)
f7eb47b… lmata 185 options.ignoreHTTPSErrors = ignoreHTTPSErrors;
f7eb47b… lmata 186 if (isMobile !== void 0)
f7eb47b… lmata 187 options.isMobile = isMobile;
f7eb47b… lmata 188 if (javaScriptEnabled !== void 0)
f7eb47b… lmata 189 options.javaScriptEnabled = javaScriptEnabled;
f7eb47b… lmata 190 if (locale !== void 0)
f7eb47b… lmata 191 options.locale = locale;
f7eb47b… lmata 192 if (offline !== void 0)
f7eb47b… lmata 193 options.offline = offline;
f7eb47b… lmata 194 if (permissions !== void 0)
f7eb47b… lmata 195 options.permissions = permissions;
f7eb47b… lmata 196 if (proxy !== void 0)
f7eb47b… lmata 197 options.proxy = proxy;
f7eb47b… lmata 198 if (storageState !== void 0)
f7eb47b… lmata 199 options.storageState = storageState;
f7eb47b… lmata 200 if (clientCertificates?.length)
f7eb47b… lmata 201 options.clientCertificates = resolveClientCerticates(clientCertificates);
f7eb47b… lmata 202 if (timezoneId !== void 0)
f7eb47b… lmata 203 options.timezoneId = timezoneId;
f7eb47b… lmata 204 if (userAgent !== void 0)
f7eb47b… lmata 205 options.userAgent = userAgent;
f7eb47b… lmata 206 if (viewport !== void 0)
f7eb47b… lmata 207 options.viewport = viewport;
f7eb47b… lmata 208 if (baseURL !== void 0)
f7eb47b… lmata 209 options.baseURL = baseURL;
f7eb47b… lmata 210 if (serviceWorkers !== void 0)
f7eb47b… lmata 211 options.serviceWorkers = serviceWorkers;
f7eb47b… lmata 212 await use({
f7eb47b… lmata 213 ...contextOptions,
f7eb47b… lmata 214 ...options
f7eb47b… lmata 215 });
f7eb47b… lmata 216 }, { box: true }],
f7eb47b… lmata 217 _setupContextOptions: [async ({ playwright, actionTimeout, navigationTimeout, testIdAttribute }, use, testInfo) => {
f7eb47b… lmata 218 if (testIdAttribute)
f7eb47b… lmata 219 playwrightLibrary.selectors.setTestIdAttribute(testIdAttribute);
f7eb47b… lmata 220 testInfo.snapshotSuffix = process.platform;
f7eb47b… lmata 221 if ((0, import_utils.debugMode)() === "inspector")
f7eb47b… lmata 222 testInfo._setDebugMode();
f7eb47b… lmata 223 playwright._defaultContextTimeout = actionTimeout || 0;
f7eb47b… lmata 224 playwright._defaultContextNavigationTimeout = navigationTimeout || 0;
f7eb47b… lmata 225 await use();
f7eb47b… lmata 226 playwright._defaultContextTimeout = void 0;
f7eb47b… lmata 227 playwright._defaultContextNavigationTimeout = void 0;
f7eb47b… lmata 228 }, { auto: "all-hooks-included", title: "context configuration", box: true }],
f7eb47b… lmata 229 _setupArtifacts: [async ({ playwright, screenshot, _combinedContextOptions }, use, testInfo) => {
f7eb47b… lmata 230 testInfo.setTimeout(testInfo.project.timeout);
f7eb47b… lmata 231 const artifactsRecorder = new ArtifactsRecorder(playwright, tracing().artifactsDir(), screenshot);
f7eb47b… lmata 232 await artifactsRecorder.willStartTest(testInfo);
f7eb47b… lmata 233 const tracingGroupSteps = [];
f7eb47b… lmata 234 const csiListener = {
f7eb47b… lmata 235 onApiCallBegin: (data, channel) => {
f7eb47b… lmata 236 const testInfo2 = (0, import_globals.currentTestInfo)();
f7eb47b… lmata 237 if (!testInfo2 || data.apiName.includes("setTestIdAttribute") || data.apiName === "tracing.groupEnd")
f7eb47b… lmata 238 return;
f7eb47b… lmata 239 const zone = (0, import_utils.currentZone)().data("stepZone");
f7eb47b… lmata 240 const isExpectCall = data.apiName === "locator._expect" || data.apiName === "frame._expect" || data.apiName === "page._expectScreenshot";
f7eb47b… lmata 241 if (zone && zone.category === "expect" && isExpectCall) {
f7eb47b… lmata 242 if (zone.apiName)
f7eb47b… lmata 243 data.apiName = zone.apiName;
f7eb47b… lmata 244 if (zone.shortTitle || zone.title)
f7eb47b… lmata 245 data.title = zone.shortTitle ?? zone.title;
f7eb47b… lmata 246 data.stepId = zone.stepId;
f7eb47b… lmata 247 return;
f7eb47b… lmata 248 }
f7eb47b… lmata 249 const step = testInfo2._addStep({
f7eb47b… lmata 250 location: data.frames[0],
f7eb47b… lmata 251 category: "pw:api",
f7eb47b… lmata 252 title: renderTitle(channel.type, channel.method, channel.params, data.title),
f7eb47b… lmata 253 apiName: data.apiName,
f7eb47b… lmata 254 params: channel.params,
f7eb47b… lmata 255 group: (0, import_utils.getActionGroup)({ type: channel.type, method: channel.method })
f7eb47b… lmata 256 }, tracingGroupSteps[tracingGroupSteps.length - 1]);
f7eb47b… lmata 257 data.userData = step;
f7eb47b… lmata 258 data.stepId = step.stepId;
f7eb47b… lmata 259 if (data.apiName === "tracing.group")
f7eb47b… lmata 260 tracingGroupSteps.push(step);
f7eb47b… lmata 261 },
f7eb47b… lmata 262 onApiCallEnd: (data) => {
f7eb47b… lmata 263 if (data.apiName === "tracing.group")
f7eb47b… lmata 264 return;
f7eb47b… lmata 265 if (data.apiName === "tracing.groupEnd") {
f7eb47b… lmata 266 const step2 = tracingGroupSteps.pop();
f7eb47b… lmata 267 step2?.complete({ error: data.error });
f7eb47b… lmata 268 return;
f7eb47b… lmata 269 }
f7eb47b… lmata 270 const step = data.userData;
f7eb47b… lmata 271 step?.complete({ error: data.error });
f7eb47b… lmata 272 },
f7eb47b… lmata 273 onWillPause: ({ keepTestTimeout }) => {
f7eb47b… lmata 274 if (!keepTestTimeout)
f7eb47b… lmata 275 (0, import_globals.currentTestInfo)()?._setDebugMode();
f7eb47b… lmata 276 },
f7eb47b… lmata 277 runBeforeCreateBrowserContext: async (options) => {
f7eb47b… lmata 278 for (const [key, value] of Object.entries(_combinedContextOptions)) {
f7eb47b… lmata 279 if (!(key in options))
f7eb47b… lmata 280 options[key] = value;
f7eb47b… lmata 281 }
f7eb47b… lmata 282 },
f7eb47b… lmata 283 runBeforeCreateRequestContext: async (options) => {
f7eb47b… lmata 284 for (const [key, value] of Object.entries(_combinedContextOptions)) {
f7eb47b… lmata 285 if (!(key in options))
f7eb47b… lmata 286 options[key] = value;
f7eb47b… lmata 287 }
f7eb47b… lmata 288 },
f7eb47b… lmata 289 runAfterCreateBrowserContext: async (context) => {
f7eb47b… lmata 290 await artifactsRecorder.didCreateBrowserContext(context);
f7eb47b… lmata 291 const testInfo2 = (0, import_globals.currentTestInfo)();
f7eb47b… lmata 292 if (testInfo2)
f7eb47b… lmata 293 attachConnectedHeaderIfNeeded(testInfo2, context.browser());
f7eb47b… lmata 294 },
f7eb47b… lmata 295 runAfterCreateRequestContext: async (context) => {
f7eb47b… lmata 296 await artifactsRecorder.didCreateRequestContext(context);
f7eb47b… lmata 297 },
f7eb47b… lmata 298 runBeforeCloseBrowserContext: async (context) => {
f7eb47b… lmata 299 await artifactsRecorder.willCloseBrowserContext(context);
f7eb47b… lmata 300 },
f7eb47b… lmata 301 runBeforeCloseRequestContext: async (context) => {
f7eb47b… lmata 302 await artifactsRecorder.willCloseRequestContext(context);
f7eb47b… lmata 303 }
f7eb47b… lmata 304 };
f7eb47b… lmata 305 const clientInstrumentation = playwright._instrumentation;
f7eb47b… lmata 306 clientInstrumentation.addListener(csiListener);
f7eb47b… lmata 307 await use();
f7eb47b… lmata 308 clientInstrumentation.removeListener(csiListener);
f7eb47b… lmata 309 await artifactsRecorder.didFinishTest();
f7eb47b… lmata 310 }, { auto: "all-hooks-included", title: "trace recording", box: true, timeout: 0 }],
f7eb47b… lmata 311 _contextFactory: [async ({
f7eb47b… lmata 312 browser,
f7eb47b… lmata 313 video,
f7eb47b… lmata 314 _reuseContext,
f7eb47b… lmata 315 _combinedContextOptions
f7eb47b… lmata 316 /** mitigate dep-via-auto lack of traceability */
f7eb47b… lmata 317 }, use, testInfo) => {
f7eb47b… lmata 318 const testInfoImpl = testInfo;
f7eb47b… lmata 319 const videoMode = normalizeVideoMode(video);
f7eb47b… lmata 320 const captureVideo = shouldCaptureVideo(videoMode, testInfo) && !_reuseContext;
f7eb47b… lmata 321 const contexts = /* @__PURE__ */ new Map();
f7eb47b… lmata 322 let counter = 0;
f7eb47b… lmata 323 await use(async (options) => {
f7eb47b… lmata 324 const hook = testInfoImpl._currentHookType();
f7eb47b… lmata 325 if (hook === "beforeAll" || hook === "afterAll") {
f7eb47b… lmata 326 throw new Error([
f7eb47b… lmata 327 `"context" and "page" fixtures are not supported in "${hook}" since they are created on a per-test basis.`,
f7eb47b… lmata 328 `If you would like to reuse a single page between tests, create context manually with browser.newContext(). See https://aka.ms/playwright/reuse-page for details.`,
f7eb47b… lmata 329 `If you would like to configure your page before each test, do that in beforeEach hook instead.`
f7eb47b… lmata 330 ].join("\n"));
f7eb47b… lmata 331 }
f7eb47b… lmata 332 const videoOptions = captureVideo ? {
f7eb47b… lmata 333 recordVideo: {
f7eb47b… lmata 334 dir: tracing().artifactsDir(),
f7eb47b… lmata 335 size: typeof video === "string" ? void 0 : video.size
f7eb47b… lmata 336 }
f7eb47b… lmata 337 } : {};
f7eb47b… lmata 338 const context = await browser.newContext({ ...videoOptions, ...options });
f7eb47b… lmata 339 if (process.env.PW_CLOCK === "frozen") {
f7eb47b… lmata 340 await context._wrapApiCall(async () => {
f7eb47b… lmata 341 await context.clock.install({ time: 0 });
f7eb47b… lmata 342 await context.clock.pauseAt(1e3);
f7eb47b… lmata 343 }, { internal: true });
f7eb47b… lmata 344 } else if (process.env.PW_CLOCK === "realtime") {
f7eb47b… lmata 345 await context._wrapApiCall(async () => {
f7eb47b… lmata 346 await context.clock.install({ time: 0 });
f7eb47b… lmata 347 }, { internal: true });
f7eb47b… lmata 348 }
f7eb47b… lmata 349 let closed = false;
f7eb47b… lmata 350 const close = async () => {
f7eb47b… lmata 351 if (closed)
f7eb47b… lmata 352 return;
f7eb47b… lmata 353 closed = true;
f7eb47b… lmata 354 const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
f7eb47b… lmata 355 await context.close({ reason: closeReason });
f7eb47b… lmata 356 const testFailed = testInfo.status !== testInfo.expectedStatus;
f7eb47b… lmata 357 const preserveVideo = captureVideo && (videoMode === "on" || testFailed && videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1);
f7eb47b… lmata 358 if (preserveVideo) {
f7eb47b… lmata 359 const { pagesWithVideo: pagesForVideo } = contexts.get(context);
f7eb47b… lmata 360 const videos = pagesForVideo.map((p) => p.video()).filter((video2) => !!video2);
f7eb47b… lmata 361 await Promise.all(videos.map(async (v) => {
f7eb47b… lmata 362 try {
f7eb47b… lmata 363 const savedPath = testInfo.outputPath(`video${counter ? "-" + counter : ""}.webm`);
f7eb47b… lmata 364 ++counter;
f7eb47b… lmata 365 await v.saveAs(savedPath);
f7eb47b… lmata 366 testInfo.attachments.push({ name: "video", path: savedPath, contentType: "video/webm" });
f7eb47b… lmata 367 } catch (e) {
f7eb47b… lmata 368 }
f7eb47b… lmata 369 }));
f7eb47b… lmata 370 }
f7eb47b… lmata 371 };
f7eb47b… lmata 372 const contextData = { close, pagesWithVideo: [] };
f7eb47b… lmata 373 if (captureVideo)
f7eb47b… lmata 374 context.on("page", (page) => contextData.pagesWithVideo.push(page));
f7eb47b… lmata 375 contexts.set(context, contextData);
f7eb47b… lmata 376 return { context, close };
f7eb47b… lmata 377 });
f7eb47b… lmata 378 await Promise.all([...contexts.values()].map((data) => data.close()));
f7eb47b… lmata 379 }, { scope: "test", title: "context", box: true }],
f7eb47b… lmata 380 _optionContextReuseMode: ["none", { scope: "worker", option: true, box: true }],
f7eb47b… lmata 381 _optionConnectOptions: [void 0, { scope: "worker", option: true, box: true }],
f7eb47b… lmata 382 _reuseContext: [async ({ video, _optionContextReuseMode }, use) => {
f7eb47b… lmata 383 let mode = _optionContextReuseMode;
f7eb47b… lmata 384 if (process.env.PW_TEST_REUSE_CONTEXT)
f7eb47b… lmata 385 mode = "when-possible";
f7eb47b… lmata 386 const reuse = mode === "when-possible" && normalizeVideoMode(video) === "off";
f7eb47b… lmata 387 await use(reuse);
f7eb47b… lmata 388 }, { scope: "worker", title: "context", box: true }],
f7eb47b… lmata 389 context: async ({ browser, _reuseContext, _contextFactory }, use, testInfo) => {
f7eb47b… lmata 390 const browserImpl = browser;
f7eb47b… lmata 391 attachConnectedHeaderIfNeeded(testInfo, browserImpl);
f7eb47b… lmata 392 if (!_reuseContext) {
f7eb47b… lmata 393 const { context: context2, close } = await _contextFactory();
f7eb47b… lmata 394 testInfo._onCustomMessageCallback = (0, import_browserBackend.createCustomMessageHandler)(testInfo, context2);
f7eb47b… lmata 395 await use(context2);
f7eb47b… lmata 396 await close();
f7eb47b… lmata 397 return;
f7eb47b… lmata 398 }
f7eb47b… lmata 399 const context = await browserImpl._wrapApiCall(() => browserImpl._newContextForReuse(), { internal: true });
f7eb47b… lmata 400 testInfo._onCustomMessageCallback = (0, import_browserBackend.createCustomMessageHandler)(testInfo, context);
f7eb47b… lmata 401 await use(context);
f7eb47b… lmata 402 const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
f7eb47b… lmata 403 await browserImpl._wrapApiCall(() => browserImpl._disconnectFromReusedContext(closeReason), { internal: true });
f7eb47b… lmata 404 },
f7eb47b… lmata 405 page: async ({ context, _reuseContext }, use) => {
f7eb47b… lmata 406 if (!_reuseContext) {
f7eb47b… lmata 407 await use(await context.newPage());
f7eb47b… lmata 408 return;
f7eb47b… lmata 409 }
f7eb47b… lmata 410 let [page] = context.pages();
f7eb47b… lmata 411 if (!page)
f7eb47b… lmata 412 page = await context.newPage();
f7eb47b… lmata 413 await use(page);
f7eb47b… lmata 414 },
f7eb47b… lmata 415 agent: async ({ page, agentOptions }, use, testInfo) => {
f7eb47b… lmata 416 const testInfoImpl = testInfo;
f7eb47b… lmata 417 const cachePathTemplate = agentOptions?.cachePathTemplate ?? "{testDir}/{testFilePath}-cache.json";
f7eb47b… lmata 418 const resolvedCacheFile = testInfoImpl._applyPathTemplate(cachePathTemplate, "", ".json");
f7eb47b… lmata 419 const cacheFile = testInfoImpl.config.runAgents === "all" ? void 0 : await testInfoImpl._cloneStorage(resolvedCacheFile);
f7eb47b… lmata 420 const cacheOutFile = import_path.default.join(testInfoImpl.artifactsDir(), "agent-cache-" + (0, import_utils.createGuid)() + ".json");
f7eb47b… lmata 421 const provider = agentOptions?.provider && testInfo.config.runAgents !== "none" ? agentOptions.provider : void 0;
f7eb47b… lmata 422 if (provider)
f7eb47b… lmata 423 testInfo.setTimeout(0);
f7eb47b… lmata 424 const cache = {
f7eb47b… lmata 425 cacheFile,
f7eb47b… lmata 426 cacheOutFile
f7eb47b… lmata 427 };
f7eb47b… lmata 428 const agent = await page.agent({
f7eb47b… lmata 429 provider,
f7eb47b… lmata 430 cache,
f7eb47b… lmata 431 limits: agentOptions?.limits,
f7eb47b… lmata 432 secrets: agentOptions?.secrets,
f7eb47b… lmata 433 systemPrompt: agentOptions?.systemPrompt,
f7eb47b… lmata 434 expect: {
f7eb47b… lmata 435 timeout: testInfoImpl._projectInternal.expect?.timeout
f7eb47b… lmata 436 }
f7eb47b… lmata 437 });
f7eb47b… lmata 438 await use(agent);
f7eb47b… lmata 439 const usage = await agent.usage();
f7eb47b… lmata 440 if (usage.turns > 0)
f7eb47b… lmata 441 await testInfoImpl.attach("agent-usage", { contentType: "application/json", body: Buffer.from(JSON.stringify(usage, null, 2)) });
f7eb47b… lmata 442 if (!resolvedCacheFile || !cacheOutFile)
f7eb47b… lmata 443 return;
f7eb47b… lmata 444 if (testInfo.status !== "passed")
f7eb47b… lmata 445 return;
f7eb47b… lmata 446 await testInfoImpl._upstreamStorage(resolvedCacheFile, cacheOutFile);
f7eb47b… lmata 447 },
f7eb47b… lmata 448 request: async ({ playwright }, use) => {
f7eb47b… lmata 449 const request = await playwright.request.newContext();
f7eb47b… lmata 450 await use(request);
f7eb47b… lmata 451 const hook = test.info()._currentHookType();
f7eb47b… lmata 452 if (hook === "beforeAll") {
f7eb47b… lmata 453 await request.dispose({ reason: [
f7eb47b… lmata 454 `Fixture { request } from beforeAll cannot be reused in a test.`,
f7eb47b… lmata 455 ` - Recommended fix: use a separate { request } in the test.`,
f7eb47b… lmata 456 ` - Alternatively, manually create APIRequestContext in beforeAll and dispose it in afterAll.`,
f7eb47b… lmata 457 `See https://playwright.dev/docs/api-testing#sending-api-requests-from-ui-tests for more details.`
f7eb47b… lmata 458 ].join("\n") });
f7eb47b… lmata 459 } else {
f7eb47b… lmata 460 await request.dispose();
f7eb47b… lmata 461 }
f7eb47b… lmata 462 }
f7eb47b… lmata 463 };
f7eb47b… lmata 464 function normalizeVideoMode(video) {
f7eb47b… lmata 465 if (!video)
f7eb47b… lmata 466 return "off";
f7eb47b… lmata 467 let videoMode = typeof video === "string" ? video : video.mode;
f7eb47b… lmata 468 if (videoMode === "retry-with-video")
f7eb47b… lmata 469 videoMode = "on-first-retry";
f7eb47b… lmata 470 return videoMode;
f7eb47b… lmata 471 }
f7eb47b… lmata 472 function shouldCaptureVideo(videoMode, testInfo) {
f7eb47b… lmata 473 return videoMode === "on" || videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1;
f7eb47b… lmata 474 }
f7eb47b… lmata 475 function normalizeScreenshotMode(screenshot) {
f7eb47b… lmata 476 if (!screenshot)
f7eb47b… lmata 477 return "off";
f7eb47b… lmata 478 return typeof screenshot === "string" ? screenshot : screenshot.mode;
f7eb47b… lmata 479 }
f7eb47b… lmata 480 function attachConnectedHeaderIfNeeded(testInfo, browser) {
f7eb47b… lmata 481 const connectHeaders = browser?._connection.headers;
f7eb47b… lmata 482 if (!connectHeaders)
f7eb47b… lmata 483 return;
f7eb47b… lmata 484 for (const header of connectHeaders) {
f7eb47b… lmata 485 if (header.name !== "x-playwright-attachment")
f7eb47b… lmata 486 continue;
f7eb47b… lmata 487 const [name, value] = header.value.split("=");
f7eb47b… lmata 488 if (!name || !value)
f7eb47b… lmata 489 continue;
f7eb47b… lmata 490 if (testInfo.attachments.some((attachment) => attachment.name === name))
f7eb47b… lmata 491 continue;
f7eb47b… lmata 492 testInfo.attachments.push({ name, contentType: "text/plain", body: Buffer.from(value) });
f7eb47b… lmata 493 }
f7eb47b… lmata 494 }
f7eb47b… lmata 495 function resolveFileToConfig(file) {
f7eb47b… lmata 496 const config = test.info().config.configFile;
f7eb47b… lmata 497 if (!config || !file)
f7eb47b… lmata 498 return file;
f7eb47b… lmata 499 if (import_path.default.isAbsolute(file))
f7eb47b… lmata 500 return file;
f7eb47b… lmata 501 return import_path.default.resolve(import_path.default.dirname(config), file);
f7eb47b… lmata 502 }
f7eb47b… lmata 503 function resolveClientCerticates(clientCertificates) {
f7eb47b… lmata 504 for (const cert of clientCertificates) {
f7eb47b… lmata 505 cert.certPath = resolveFileToConfig(cert.certPath);
f7eb47b… lmata 506 cert.keyPath = resolveFileToConfig(cert.keyPath);
f7eb47b… lmata 507 cert.pfxPath = resolveFileToConfig(cert.pfxPath);
f7eb47b… lmata 508 }
f7eb47b… lmata 509 return clientCertificates;
f7eb47b… lmata 510 }
f7eb47b… lmata 511 const kTracingStarted = Symbol("kTracingStarted");
f7eb47b… lmata 512 function connectOptionsFromEnv() {
f7eb47b… lmata 513 const wsEndpoint = process.env.PW_TEST_CONNECT_WS_ENDPOINT;
f7eb47b… lmata 514 if (!wsEndpoint)
f7eb47b… lmata 515 return void 0;
f7eb47b… lmata 516 const headers = process.env.PW_TEST_CONNECT_HEADERS ? JSON.parse(process.env.PW_TEST_CONNECT_HEADERS) : void 0;
f7eb47b… lmata 517 return {
f7eb47b… lmata 518 wsEndpoint,
f7eb47b… lmata 519 headers,
f7eb47b… lmata 520 exposeNetwork: process.env.PW_TEST_CONNECT_EXPOSE_NETWORK
f7eb47b… lmata 521 };
f7eb47b… lmata 522 }
f7eb47b… lmata 523 class SnapshotRecorder {
f7eb47b… lmata 524 constructor(_artifactsRecorder, _mode, _name, _contentType, _extension, _doSnapshot) {
f7eb47b… lmata 525 this._artifactsRecorder = _artifactsRecorder;
f7eb47b… lmata 526 this._mode = _mode;
f7eb47b… lmata 527 this._name = _name;
f7eb47b… lmata 528 this._contentType = _contentType;
f7eb47b… lmata 529 this._extension = _extension;
f7eb47b… lmata 530 this._doSnapshot = _doSnapshot;
f7eb47b… lmata 531 this._ordinal = 0;
f7eb47b… lmata 532 this._temporary = [];
f7eb47b… lmata 533 }
f7eb47b… lmata 534 fixOrdinal() {
f7eb47b… lmata 535 this._ordinal = this.testInfo.attachments.filter((a) => a.name === this._name).length;
f7eb47b… lmata 536 }
f7eb47b… lmata 537 shouldCaptureUponFinish() {
f7eb47b… lmata 538 return this._mode === "on" || this._mode === "only-on-failure" && this.testInfo._isFailure() || this._mode === "on-first-failure" && this.testInfo._isFailure() && this.testInfo.retry === 0;
f7eb47b… lmata 539 }
f7eb47b… lmata 540 async maybeCapture() {
f7eb47b… lmata 541 if (!this.shouldCaptureUponFinish())
f7eb47b… lmata 542 return;
f7eb47b… lmata 543 await Promise.all(this._artifactsRecorder._playwright._allPages().map((page) => this._snapshotPage(page, false)));
f7eb47b… lmata 544 }
f7eb47b… lmata 545 async persistTemporary() {
f7eb47b… lmata 546 if (this.shouldCaptureUponFinish()) {
f7eb47b… lmata 547 await Promise.all(this._temporary.map(async (file) => {
f7eb47b… lmata 548 try {
f7eb47b… lmata 549 const path2 = this._createAttachmentPath();
f7eb47b… lmata 550 await import_fs.default.promises.rename(file, path2);
f7eb47b… lmata 551 this._attach(path2);
f7eb47b… lmata 552 } catch {
f7eb47b… lmata 553 }
f7eb47b… lmata 554 }));
f7eb47b… lmata 555 }
f7eb47b… lmata 556 }
f7eb47b… lmata 557 async captureTemporary(context) {
f7eb47b… lmata 558 if (this._mode === "on" || this._mode === "only-on-failure" || this._mode === "on-first-failure" && this.testInfo.retry === 0)
f7eb47b… lmata 559 await Promise.all(context.pages().map((page) => this._snapshotPage(page, true)));
f7eb47b… lmata 560 }
f7eb47b… lmata 561 _attach(screenshotPath) {
f7eb47b… lmata 562 this.testInfo.attachments.push({ name: this._name, path: screenshotPath, contentType: this._contentType });
f7eb47b… lmata 563 }
f7eb47b… lmata 564 _createAttachmentPath() {
f7eb47b… lmata 565 const testFailed = this.testInfo._isFailure();
f7eb47b… lmata 566 const index = this._ordinal + 1;
f7eb47b… lmata 567 ++this._ordinal;
f7eb47b… lmata 568 const path2 = this.testInfo.outputPath(`test-${testFailed ? "failed" : "finished"}-${index}${this._extension}`);
f7eb47b… lmata 569 return path2;
f7eb47b… lmata 570 }
f7eb47b… lmata 571 _createTemporaryArtifact(...name) {
f7eb47b… lmata 572 const file = import_path.default.join(this._artifactsRecorder._artifactsDir, ...name);
f7eb47b… lmata 573 return file;
f7eb47b… lmata 574 }
f7eb47b… lmata 575 async _snapshotPage(page, temporary) {
f7eb47b… lmata 576 if (page[this.testInfo._uniqueSymbol])
f7eb47b… lmata 577 return;
f7eb47b… lmata 578 page[this.testInfo._uniqueSymbol] = true;
f7eb47b… lmata 579 try {
f7eb47b… lmata 580 const path2 = temporary ? this._createTemporaryArtifact((0, import_utils.createGuid)() + this._extension) : this._createAttachmentPath();
f7eb47b… lmata 581 await this._doSnapshot(page, path2);
f7eb47b… lmata 582 if (temporary)
f7eb47b… lmata 583 this._temporary.push(path2);
f7eb47b… lmata 584 else
f7eb47b… lmata 585 this._attach(path2);
f7eb47b… lmata 586 } catch {
f7eb47b… lmata 587 }
f7eb47b… lmata 588 }
f7eb47b… lmata 589 get testInfo() {
f7eb47b… lmata 590 return this._artifactsRecorder._testInfo;
f7eb47b… lmata 591 }
f7eb47b… lmata 592 }
f7eb47b… lmata 593 class ArtifactsRecorder {
f7eb47b… lmata 594 constructor(playwright, artifactsDir, screenshot) {
f7eb47b… lmata 595 this._playwright = playwright;
f7eb47b… lmata 596 this._artifactsDir = artifactsDir;
f7eb47b… lmata 597 const screenshotOptions = typeof screenshot === "string" ? void 0 : screenshot;
f7eb47b… lmata 598 this._startedCollectingArtifacts = Symbol("startedCollectingArtifacts");
f7eb47b… lmata 599 this._screenshotRecorder = new SnapshotRecorder(this, normalizeScreenshotMode(screenshot), "screenshot", "image/png", ".png", async (page, path2) => {
f7eb47b… lmata 600 await page._wrapApiCall(async () => {
f7eb47b… lmata 601 await page.screenshot({ ...screenshotOptions, timeout: 5e3, path: path2, caret: "initial" });
f7eb47b… lmata 602 }, { internal: true });
f7eb47b… lmata 603 });
f7eb47b… lmata 604 }
f7eb47b… lmata 605 async willStartTest(testInfo) {
f7eb47b… lmata 606 this._testInfo = testInfo;
f7eb47b… lmata 607 testInfo._onDidFinishTestFunctionCallback = () => this.didFinishTestFunction();
f7eb47b… lmata 608 this._screenshotRecorder.fixOrdinal();
f7eb47b… lmata 609 await Promise.all(this._playwright._allContexts().map((context) => this.didCreateBrowserContext(context)));
f7eb47b… lmata 610 const existingApiRequests = Array.from(this._playwright.request._contexts);
f7eb47b… lmata 611 await Promise.all(existingApiRequests.map((c) => this.didCreateRequestContext(c)));
f7eb47b… lmata 612 }
f7eb47b… lmata 613 async didCreateBrowserContext(context) {
f7eb47b… lmata 614 await this._startTraceChunkOnContextCreation(context, context.tracing);
f7eb47b… lmata 615 }
f7eb47b… lmata 616 async willCloseBrowserContext(context) {
f7eb47b… lmata 617 await this._stopTracing(context, context.tracing);
f7eb47b… lmata 618 await this._screenshotRecorder.captureTemporary(context);
f7eb47b… lmata 619 await this._takePageSnapshot(context);
f7eb47b… lmata 620 }
f7eb47b… lmata 621 async _takePageSnapshot(context) {
f7eb47b… lmata 622 if (process.env.PLAYWRIGHT_NO_COPY_PROMPT)
f7eb47b… lmata 623 return;
f7eb47b… lmata 624 if (this._testInfo.errors.length === 0)
f7eb47b… lmata 625 return;
f7eb47b… lmata 626 if (this._pageSnapshot)
f7eb47b… lmata 627 return;
f7eb47b… lmata 628 const page = context.pages()[0];
f7eb47b… lmata 629 if (!page)
f7eb47b… lmata 630 return;
f7eb47b… lmata 631 try {
f7eb47b… lmata 632 await page._wrapApiCall(async () => {
f7eb47b… lmata 633 this._pageSnapshot = (await page._snapshotForAI({ timeout: 5e3 })).full;
f7eb47b… lmata 634 }, { internal: true });
f7eb47b… lmata 635 } catch {
f7eb47b… lmata 636 }
f7eb47b… lmata 637 }
f7eb47b… lmata 638 async didCreateRequestContext(context) {
f7eb47b… lmata 639 await this._startTraceChunkOnContextCreation(context, context._tracing);
f7eb47b… lmata 640 }
f7eb47b… lmata 641 async willCloseRequestContext(context) {
f7eb47b… lmata 642 await this._stopTracing(context, context._tracing);
f7eb47b… lmata 643 }
f7eb47b… lmata 644 async didFinishTestFunction() {
f7eb47b… lmata 645 await this._screenshotRecorder.maybeCapture();
f7eb47b… lmata 646 }
f7eb47b… lmata 647 async didFinishTest() {
f7eb47b… lmata 648 await this.didFinishTestFunction();
f7eb47b… lmata 649 const leftoverContexts = this._playwright._allContexts();
f7eb47b… lmata 650 const leftoverApiRequests = Array.from(this._playwright.request._contexts);
f7eb47b… lmata 651 await Promise.all(leftoverContexts.map(async (context2) => {
f7eb47b… lmata 652 await this._stopTracing(context2, context2.tracing);
f7eb47b… lmata 653 }).concat(leftoverApiRequests.map(async (context2) => {
f7eb47b… lmata 654 await this._stopTracing(context2, context2._tracing);
f7eb47b… lmata 655 })));
f7eb47b… lmata 656 await this._screenshotRecorder.persistTemporary();
f7eb47b… lmata 657 const context = leftoverContexts[0];
f7eb47b… lmata 658 if (context)
f7eb47b… lmata 659 await this._takePageSnapshot(context);
f7eb47b… lmata 660 if (this._pageSnapshot && this._testInfo.errors.length > 0 && !this._testInfo.attachments.some((a) => a.name === "error-context")) {
f7eb47b… lmata 661 const lines = [
f7eb47b… lmata 662 "# Page snapshot",
f7eb47b… lmata 663 "",
f7eb47b… lmata 664 "```yaml",
f7eb47b… lmata 665 this._pageSnapshot,
f7eb47b… lmata 666 "```"
f7eb47b… lmata 667 ];
f7eb47b… lmata 668 const filePath = this._testInfo.outputPath("error-context.md");
f7eb47b… lmata 669 await import_fs.default.promises.writeFile(filePath, lines.join("\n"), "utf8");
f7eb47b… lmata 670 this._testInfo._attach({
f7eb47b… lmata 671 name: "error-context",
f7eb47b… lmata 672 contentType: "text/markdown",
f7eb47b… lmata 673 path: filePath
f7eb47b… lmata 674 }, void 0);
f7eb47b… lmata 675 }
f7eb47b… lmata 676 }
f7eb47b… lmata 677 async _startTraceChunkOnContextCreation(channelOwner, tracing2) {
f7eb47b… lmata 678 await channelOwner._wrapApiCall(async () => {
f7eb47b… lmata 679 const options = this._testInfo._tracing.traceOptions();
f7eb47b… lmata 680 if (options) {
f7eb47b… lmata 681 const title = this._testInfo._tracing.traceTitle();
f7eb47b… lmata 682 const name = this._testInfo._tracing.generateNextTraceRecordingName();
f7eb47b… lmata 683 if (!tracing2[kTracingStarted]) {
f7eb47b… lmata 684 await tracing2.start({ ...options, title, name });
f7eb47b… lmata 685 tracing2[kTracingStarted] = true;
f7eb47b… lmata 686 } else {
f7eb47b… lmata 687 await tracing2.startChunk({ title, name });
f7eb47b… lmata 688 }
f7eb47b… lmata 689 } else {
f7eb47b… lmata 690 if (tracing2[kTracingStarted]) {
f7eb47b… lmata 691 tracing2[kTracingStarted] = false;
f7eb47b… lmata 692 await tracing2.stop();
f7eb47b… lmata 693 }
f7eb47b… lmata 694 }
f7eb47b… lmata 695 }, { internal: true });
f7eb47b… lmata 696 }
f7eb47b… lmata 697 async _stopTracing(channelOwner, tracing2) {
f7eb47b… lmata 698 await channelOwner._wrapApiCall(async () => {
f7eb47b… lmata 699 if (tracing2[this._startedCollectingArtifacts])
f7eb47b… lmata 700 return;
f7eb47b… lmata 701 tracing2[this._startedCollectingArtifacts] = true;
f7eb47b… lmata 702 if (this._testInfo._tracing.traceOptions() && tracing2[kTracingStarted])
f7eb47b… lmata 703 await tracing2.stopChunk({ path: this._testInfo._tracing.maybeGenerateNextTraceRecordingPath() });
f7eb47b… lmata 704 }, { internal: true });
f7eb47b… lmata 705 }
f7eb47b… lmata 706 }
f7eb47b… lmata 707 function renderTitle(type, method, params, title) {
f7eb47b… lmata 708 const prefix = (0, import_utils.renderTitleForCall)({ title, type, method, params });
f7eb47b… lmata 709 let selector;
f7eb47b… lmata 710 if (params?.["selector"] && typeof params.selector === "string")
f7eb47b… lmata 711 selector = (0, import_utils.asLocatorDescription)("javascript", params.selector);
f7eb47b… lmata 712 return prefix + (selector ? ` ${selector}` : "");
f7eb47b… lmata 713 }
f7eb47b… lmata 714 function tracing() {
f7eb47b… lmata 715 return test.info()._tracing;
f7eb47b… lmata 716 }
f7eb47b… lmata 717 const test = _baseTest.extend(playwrightFixtures);
f7eb47b… lmata 718 // Annotate the CommonJS export names for ESM import in node:
f7eb47b… lmata 719 0 && (module.exports = {
f7eb47b… lmata 720 _baseTest,
f7eb47b… lmata 721 defineConfig,
f7eb47b… lmata 722 expect,
f7eb47b… lmata 723 mergeExpects,
f7eb47b… lmata 724 mergeTests,
f7eb47b… lmata 725 test
f7eb47b… lmata 726 });

Keyboard Shortcuts

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