HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: /var/www/quadcode.com/node_modules/@playwright/test/lib/index.js
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports._baseTest = void 0;
Object.defineProperty(exports, "_store", {
  enumerable: true,
  get: function () {
    return _store.store;
  }
});
exports.default = void 0;
Object.defineProperty(exports, "expect", {
  enumerable: true,
  get: function () {
    return _expect.expect;
  }
});
exports.test = void 0;
var fs = _interopRequireWildcard(require("fs"));
var path = _interopRequireWildcard(require("path"));
var playwrightLibrary = _interopRequireWildcard(require("playwright-core"));
var _utils = require("playwright-core/lib/utils");
var _testType = require("./common/testType");
var _folders = require("./isomorphic/folders");
var _globals = require("./common/globals");
var _expect = require("./matchers/expect");
var _store = require("./store");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
/**
 * 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 _baseTest = _testType.rootTestType.test;
exports._baseTest = _baseTest;
(0, _utils.addInternalStackPrefix)(path.dirname(require.resolve('../package.json')));
if (process['__pw_initiator__']) {
  const originalStackTraceLimit = Error.stackTraceLimit;
  Error.stackTraceLimit = 200;
  try {
    throw new Error('Requiring @playwright/test second time, \nFirst:\n' + process['__pw_initiator__'] + '\n\nSecond: ');
  } finally {
    Error.stackTraceLimit = originalStackTraceLimit;
  }
} else {
  process['__pw_initiator__'] = new Error().stack;
}
const playwrightFixtures = {
  defaultBrowserType: ['chromium', {
    scope: 'worker',
    option: true
  }],
  browserName: [({
    defaultBrowserType
  }, use) => use(defaultBrowserType), {
    scope: 'worker',
    option: true
  }],
  playwright: [async ({}, use) => {
    await use(require('playwright-core'));
  }, {
    scope: 'worker',
    _hideStep: true
  }],
  headless: [({
    launchOptions
  }, use) => {
    var _launchOptions$headle;
    return use((_launchOptions$headle = launchOptions.headless) !== null && _launchOptions$headle !== void 0 ? _launchOptions$headle : true);
  }, {
    scope: 'worker',
    option: true
  }],
  channel: [({
    launchOptions
  }, use) => use(launchOptions.channel), {
    scope: 'worker',
    option: true
  }],
  launchOptions: [{}, {
    scope: 'worker',
    option: true
  }],
  connectOptions: [async ({}, use) => {
    // Usually, when connect options are specified (e.g, in the config or in the environment),
    // all launch() calls are turned into connect() calls.
    // However, when running in "reuse browser" mode and connecting to the reusable server,
    // only the default "browser" fixture should turn into reused browser.
    await use(process.env.PW_TEST_REUSE_CONTEXT ? undefined : connectOptionsFromEnv());
  }, {
    scope: 'worker',
    option: true
  }],
  screenshot: ['off', {
    scope: 'worker',
    option: true
  }],
  video: ['off', {
    scope: 'worker',
    option: true
  }],
  trace: ['off', {
    scope: 'worker',
    option: true
  }],
  _artifactsDir: [async ({}, use, workerInfo) => {
    let dir;
    await use(() => {
      if (!dir) {
        dir = path.join(workerInfo.project.outputDir, (0, _folders.artifactsFolderName)(workerInfo.workerIndex));
        fs.mkdirSync(dir, {
          recursive: true
        });
      }
      return dir;
    });
    if (dir) await (0, _utils.removeFolders)([dir]);
  }, {
    scope: 'worker',
    _title: 'playwright configuration'
  }],
  _browserOptions: [async ({
    playwright,
    headless,
    channel,
    launchOptions,
    connectOptions,
    _artifactsDir
  }, use) => {
    const options = {
      handleSIGINT: false,
      ...launchOptions
    };
    if (headless !== undefined) options.headless = headless;
    if (channel !== undefined) options.channel = channel;
    options.tracesDir = path.join(_artifactsDir(), 'traces');
    for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
      browserType._defaultLaunchOptions = options;
      browserType._defaultConnectOptions = connectOptions;
    }
    await use(options);
    for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
      browserType._defaultLaunchOptions = undefined;
      browserType._defaultConnectOptions = undefined;
    }
  }, {
    scope: 'worker',
    auto: true
  }],
  browser: [async ({
    playwright,
    browserName,
    _browserOptions
  }, use, testInfo) => {
    if (!['chromium', 'firefox', 'webkit'].includes(browserName)) throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);

    // Support for "reuse browser" mode.
    const connectOptions = connectOptionsFromEnv();
    if (connectOptions && process.env.PW_TEST_REUSE_CONTEXT) {
      const browser = await playwright[browserName].connect({
        ...connectOptions,
        headers: {
          'x-playwright-reuse-context': '1',
          // HTTP headers are ASCII only (not UTF-8).
          'x-playwright-launch-options': (0, _utils.jsonStringifyForceASCII)(_browserOptions),
          ...connectOptions.headers
        }
      });
      await use(browser);
      await browser._wrapApiCall(async () => {
        await browser.close();
      }, true);
      return;
    }
    const browser = await playwright[browserName].launch();
    await use(browser);
    await browser._wrapApiCall(async () => {
      await browser.close();
    }, true);
  }, {
    scope: 'worker',
    timeout: 0
  }],
  acceptDownloads: [({
    contextOptions
  }, use) => {
    var _contextOptions$accep;
    return use((_contextOptions$accep = contextOptions.acceptDownloads) !== null && _contextOptions$accep !== void 0 ? _contextOptions$accep : true);
  }, {
    option: true
  }],
  bypassCSP: [({
    contextOptions
  }, use) => {
    var _contextOptions$bypas;
    return use((_contextOptions$bypas = contextOptions.bypassCSP) !== null && _contextOptions$bypas !== void 0 ? _contextOptions$bypas : false);
  }, {
    option: true
  }],
  colorScheme: [({
    contextOptions
  }, use) => use(contextOptions.colorScheme === undefined ? 'light' : contextOptions.colorScheme), {
    option: true
  }],
  deviceScaleFactor: [({
    contextOptions
  }, use) => use(contextOptions.deviceScaleFactor), {
    option: true
  }],
  extraHTTPHeaders: [({
    contextOptions
  }, use) => use(contextOptions.extraHTTPHeaders), {
    option: true
  }],
  geolocation: [({
    contextOptions
  }, use) => use(contextOptions.geolocation), {
    option: true
  }],
  hasTouch: [({
    contextOptions
  }, use) => {
    var _contextOptions$hasTo;
    return use((_contextOptions$hasTo = contextOptions.hasTouch) !== null && _contextOptions$hasTo !== void 0 ? _contextOptions$hasTo : false);
  }, {
    option: true
  }],
  httpCredentials: [({
    contextOptions
  }, use) => use(contextOptions.httpCredentials), {
    option: true
  }],
  ignoreHTTPSErrors: [({
    contextOptions
  }, use) => {
    var _contextOptions$ignor;
    return use((_contextOptions$ignor = contextOptions.ignoreHTTPSErrors) !== null && _contextOptions$ignor !== void 0 ? _contextOptions$ignor : false);
  }, {
    option: true
  }],
  isMobile: [({
    contextOptions
  }, use) => {
    var _contextOptions$isMob;
    return use((_contextOptions$isMob = contextOptions.isMobile) !== null && _contextOptions$isMob !== void 0 ? _contextOptions$isMob : false);
  }, {
    option: true
  }],
  javaScriptEnabled: [({
    contextOptions
  }, use) => {
    var _contextOptions$javaS;
    return use((_contextOptions$javaS = contextOptions.javaScriptEnabled) !== null && _contextOptions$javaS !== void 0 ? _contextOptions$javaS : true);
  }, {
    option: true
  }],
  locale: [({
    contextOptions
  }, use) => {
    var _contextOptions$local;
    return use((_contextOptions$local = contextOptions.locale) !== null && _contextOptions$local !== void 0 ? _contextOptions$local : 'en-US');
  }, {
    option: true
  }],
  offline: [({
    contextOptions
  }, use) => {
    var _contextOptions$offli;
    return use((_contextOptions$offli = contextOptions.offline) !== null && _contextOptions$offli !== void 0 ? _contextOptions$offli : false);
  }, {
    option: true
  }],
  permissions: [({
    contextOptions
  }, use) => use(contextOptions.permissions), {
    option: true
  }],
  proxy: [({
    contextOptions
  }, use) => use(contextOptions.proxy), {
    option: true
  }],
  storageState: [({
    contextOptions
  }, use) => use(contextOptions.storageState), {
    option: true
  }],
  timezoneId: [({
    contextOptions
  }, use) => use(contextOptions.timezoneId), {
    option: true
  }],
  userAgent: [({
    contextOptions
  }, use) => use(contextOptions.userAgent), {
    option: true
  }],
  viewport: [({
    contextOptions
  }, use) => use(contextOptions.viewport === undefined ? {
    width: 1280,
    height: 720
  } : contextOptions.viewport), {
    option: true
  }],
  actionTimeout: [0, {
    option: true
  }],
  testIdAttribute: ['data-testid', {
    option: true
  }],
  navigationTimeout: [0, {
    option: true
  }],
  baseURL: [async ({}, use) => {
    await use(process.env.PLAYWRIGHT_TEST_BASE_URL);
  }, {
    option: true
  }],
  serviceWorkers: [({
    contextOptions
  }, use) => {
    var _contextOptions$servi;
    return use((_contextOptions$servi = contextOptions.serviceWorkers) !== null && _contextOptions$servi !== void 0 ? _contextOptions$servi : 'allow');
  }, {
    option: true
  }],
  contextOptions: [{}, {
    option: true
  }],
  _combinedContextOptions: async ({
    acceptDownloads,
    bypassCSP,
    colorScheme,
    deviceScaleFactor,
    extraHTTPHeaders,
    hasTouch,
    geolocation,
    httpCredentials,
    ignoreHTTPSErrors,
    isMobile,
    javaScriptEnabled,
    locale,
    offline,
    permissions,
    proxy,
    storageState,
    viewport,
    timezoneId,
    userAgent,
    baseURL,
    contextOptions,
    serviceWorkers
  }, use) => {
    const options = {};
    if (acceptDownloads !== undefined) options.acceptDownloads = acceptDownloads;
    if (bypassCSP !== undefined) options.bypassCSP = bypassCSP;
    if (colorScheme !== undefined) options.colorScheme = colorScheme;
    if (deviceScaleFactor !== undefined) options.deviceScaleFactor = deviceScaleFactor;
    if (extraHTTPHeaders !== undefined) options.extraHTTPHeaders = extraHTTPHeaders;
    if (geolocation !== undefined) options.geolocation = geolocation;
    if (hasTouch !== undefined) options.hasTouch = hasTouch;
    if (httpCredentials !== undefined) options.httpCredentials = httpCredentials;
    if (ignoreHTTPSErrors !== undefined) options.ignoreHTTPSErrors = ignoreHTTPSErrors;
    if (isMobile !== undefined) options.isMobile = isMobile;
    if (javaScriptEnabled !== undefined) options.javaScriptEnabled = javaScriptEnabled;
    if (locale !== undefined) options.locale = locale;
    if (offline !== undefined) options.offline = offline;
    if (permissions !== undefined) options.permissions = permissions;
    if (proxy !== undefined) options.proxy = proxy;
    if (storageState !== undefined) options.storageState = storageState;
    if (timezoneId !== undefined) options.timezoneId = timezoneId;
    if (userAgent !== undefined) options.userAgent = userAgent;
    if (viewport !== undefined) options.viewport = viewport;
    if (baseURL !== undefined) options.baseURL = baseURL;
    if (serviceWorkers !== undefined) options.serviceWorkers = serviceWorkers;
    await use({
      ...contextOptions,
      ...options
    });
  },
  _setupContextOptions: [async ({
    playwright,
    _combinedContextOptions,
    _artifactsDir,
    actionTimeout,
    navigationTimeout,
    testIdAttribute
  }, use, testInfo) => {
    if (testIdAttribute) playwrightLibrary.selectors.setTestIdAttribute(testIdAttribute);
    testInfo.snapshotSuffix = process.platform;
    if ((0, _utils.debugMode)()) testInfo.setTimeout(0);
    for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
      browserType._defaultContextOptions = _combinedContextOptions;
      browserType._defaultContextTimeout = actionTimeout || 0;
      browserType._defaultContextNavigationTimeout = navigationTimeout || 0;
    }
    playwright.request._defaultContextOptions = {
      ..._combinedContextOptions
    };
    playwright.request._defaultContextOptions.tracesDir = path.join(_artifactsDir(), 'traces');
    playwright.request._defaultContextOptions.timeout = actionTimeout || 0;
    await use();
    playwright.request._defaultContextOptions = undefined;
    for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
      browserType._defaultContextOptions = undefined;
      browserType._defaultContextTimeout = undefined;
      browserType._defaultContextNavigationTimeout = undefined;
    }
  }, {
    auto: 'all-hooks-included',
    _title: 'context configuration'
  }],
  _setupArtifacts: [async ({
    playwright,
    _artifactsDir,
    trace,
    screenshot
  }, use, testInfo) => {
    const artifactsRecorder = new ArtifactsRecorder(playwright, _artifactsDir(), trace, screenshot);
    await artifactsRecorder.willStartTest(testInfo);
    const csiListener = {
      onApiCallBegin: (apiName, params, stackTrace, wallTime, userData) => {
        const testInfo = (0, _globals.currentTestInfo)();
        if (!testInfo || apiName.startsWith('expect.') || apiName.includes('setTestIdAttribute')) return {
          userObject: null
        };
        const step = testInfo._addStep({
          location: stackTrace === null || stackTrace === void 0 ? void 0 : stackTrace.frames[0],
          category: 'pw:api',
          title: renderApiCall(apiName, params),
          apiName,
          params,
          wallTime,
          laxParent: true
        });
        userData.userObject = step;
      },
      onApiCallEnd: (userData, error) => {
        const step = userData.userObject;
        step === null || step === void 0 ? void 0 : step.complete({
          error
        });
      },
      onWillPause: () => {
        var _currentTestInfo;
        (_currentTestInfo = (0, _globals.currentTestInfo)()) === null || _currentTestInfo === void 0 ? void 0 : _currentTestInfo.setTimeout(0);
      },
      onDidCreateBrowserContext: async context => {
        await (artifactsRecorder === null || artifactsRecorder === void 0 ? void 0 : artifactsRecorder.didCreateBrowserContext(context));
        const testInfo = (0, _globals.currentTestInfo)();
        if (testInfo) attachConnectedHeaderIfNeeded(testInfo, context.browser());
      },
      onDidCreateRequestContext: async context => {
        await (artifactsRecorder === null || artifactsRecorder === void 0 ? void 0 : artifactsRecorder.didCreateRequestContext(context));
      },
      onWillCloseBrowserContext: async context => {
        await (artifactsRecorder === null || artifactsRecorder === void 0 ? void 0 : artifactsRecorder.willCloseBrowserContext(context));
      },
      onWillCloseRequestContext: async context => {
        await (artifactsRecorder === null || artifactsRecorder === void 0 ? void 0 : artifactsRecorder.willCloseRequestContext(context));
      }
    };
    const clientInstrumentation = playwright._instrumentation;
    clientInstrumentation.addListener(csiListener);
    await use();
    clientInstrumentation.removeListener(csiListener);
    await (artifactsRecorder === null || artifactsRecorder === void 0 ? void 0 : artifactsRecorder.didFinishTest());
  }, {
    auto: 'all-hooks-included',
    _title: 'trace recording'
  }],
  _contextFactory: [async ({
    browser,
    video,
    _artifactsDir,
    _reuseContext
  }, use, testInfo) => {
    const testInfoImpl = testInfo;
    const videoMode = normalizeVideoMode(video);
    const captureVideo = shouldCaptureVideo(videoMode, testInfo) && !_reuseContext;
    const contexts = new Map();
    await use(async options => {
      const hook = hookType(testInfoImpl);
      if (hook) {
        throw new Error([`"context" and "page" fixtures are not supported in "${hook}" since they are created on a per-test basis.`, `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.`, `If you would like to configure your page before each test, do that in beforeEach hook instead.`].join('\n'));
      }
      const videoOptions = captureVideo ? {
        recordVideo: {
          dir: _artifactsDir(),
          size: typeof video === 'string' ? undefined : video.size
        }
      } : {};
      const context = await browser.newContext({
        ...videoOptions,
        ...options
      });
      const contextData = {
        pagesWithVideo: []
      };
      contexts.set(context, contextData);
      if (captureVideo) context.on('page', page => contextData.pagesWithVideo.push(page));
      return context;
    });
    const prependToError = testInfoImpl._didTimeout ? formatPendingCalls(browser._connection.pendingProtocolCalls()) : '';
    let counter = 0;
    await Promise.all([...contexts.keys()].map(async context => {
      context[kStartedContextTearDown] = true;
      await context._wrapApiCall(async () => {
        await context.close();
      }, true);
      const testFailed = testInfo.status !== testInfo.expectedStatus;
      const preserveVideo = captureVideo && (videoMode === 'on' || testFailed && videoMode === 'retain-on-failure' || videoMode === 'on-first-retry' && testInfo.retry === 1);
      if (preserveVideo) {
        const {
          pagesWithVideo: pagesForVideo
        } = contexts.get(context);
        const videos = pagesForVideo.map(p => p.video()).filter(Boolean);
        await Promise.all(videos.map(async v => {
          try {
            const savedPath = testInfo.outputPath(`video${counter ? '-' + counter : ''}.webm`);
            ++counter;
            await v.saveAs(savedPath);
            testInfo.attachments.push({
              name: 'video',
              path: savedPath,
              contentType: 'video/webm'
            });
          } catch (e) {
            // Silent catch empty videos.
          }
        }));
      }
    }));
    if (prependToError) testInfo.errors.push({
      message: prependToError
    });
  }, {
    scope: 'test',
    _title: 'context'
  }],
  _contextReuseMode: process.env.PW_TEST_REUSE_CONTEXT === 'when-possible' ? 'when-possible' : process.env.PW_TEST_REUSE_CONTEXT ? 'force' : 'none',
  _reuseContext: [async ({
    video,
    _contextReuseMode
  }, use, testInfo) => {
    const reuse = _contextReuseMode === 'force' || _contextReuseMode === 'when-possible' && !shouldCaptureVideo(normalizeVideoMode(video), testInfo);
    await use(reuse);
  }, {
    scope: 'test',
    _title: 'context'
  }],
  context: async ({
    playwright,
    browser,
    _reuseContext,
    _contextFactory
  }, use, testInfo) => {
    attachConnectedHeaderIfNeeded(testInfo, browser);
    if (!_reuseContext) {
      await use(await _contextFactory());
      return;
    }
    const defaultContextOptions = playwright.chromium._defaultContextOptions;
    const context = await browser._newContextForReuse(defaultContextOptions);
    context[kIsReusedContext] = true;
    await use(context);
  },
  page: async ({
    context,
    _reuseContext
  }, use) => {
    if (!_reuseContext) {
      await use(await context.newPage());
      return;
    }

    // First time we are reusing the context, we should create the page.
    let [page] = context.pages();
    if (!page) page = await context.newPage();
    await use(page);
  },
  request: async ({
    playwright
  }, use) => {
    const request = await playwright.request.newContext();
    await use(request);
    request[kStartedContextTearDown] = true;
    await request.dispose();
  }
};
function formatPendingCalls(calls) {
  calls = calls.filter(call => !!call.apiName);
  if (!calls.length) return '';
  return 'Pending operations:\n' + calls.map(call => {
    const frame = call.frames && call.frames[0] ? ' at ' + formatStackFrame(call.frames[0]) : '';
    return `  - ${call.apiName}${frame}\n`;
  }).join('');
}
function formatStackFrame(frame) {
  const file = path.relative(process.cwd(), frame.file) || path.basename(frame.file);
  return `${file}:${frame.line || 1}:${frame.column || 1}`;
}
function hookType(testInfo) {
  const type = testInfo._timeoutManager.currentRunnableType();
  if (type === 'beforeAll' || type === 'afterAll') return type;
}
function normalizeVideoMode(video) {
  if (!video) return 'off';
  let videoMode = typeof video === 'string' ? video : video.mode;
  if (videoMode === 'retry-with-video') videoMode = 'on-first-retry';
  return videoMode;
}
function shouldCaptureVideo(videoMode, testInfo) {
  return videoMode === 'on' || videoMode === 'retain-on-failure' || videoMode === 'on-first-retry' && testInfo.retry === 1;
}
function normalizeTraceMode(trace) {
  if (!trace) return 'off';
  let traceMode = typeof trace === 'string' ? trace : trace.mode;
  if (traceMode === 'retry-with-trace') traceMode = 'on-first-retry';
  return traceMode;
}
function shouldCaptureTrace(traceMode, testInfo) {
  return traceMode === 'on' || traceMode === 'retain-on-failure' || traceMode === 'on-first-retry' && testInfo.retry === 1 || traceMode === 'on-all-retries' && testInfo.retry > 0;
}
function normalizeScreenshotMode(screenshot) {
  if (!screenshot) return 'off';
  return typeof screenshot === 'string' ? screenshot : screenshot.mode;
}
function attachConnectedHeaderIfNeeded(testInfo, browser) {
  const connectHeaders = browser === null || browser === void 0 ? void 0 : browser._connectHeaders;
  if (!connectHeaders) return;
  for (const header of connectHeaders) {
    if (header.name !== 'x-playwright-attachment') continue;
    const [name, value] = header.value.split('=');
    if (!name || !value) continue;
    if (testInfo.attachments.some(attachment => attachment.name === name)) continue;
    testInfo.attachments.push({
      name,
      contentType: 'text/plain',
      body: Buffer.from(value)
    });
  }
}
const kTracingStarted = Symbol('kTracingStarted');
const kIsReusedContext = Symbol('kReusedContext');
const kStartedContextTearDown = Symbol('kStartedContextTearDown');
function connectOptionsFromEnv() {
  const wsEndpoint = process.env.PW_TEST_CONNECT_WS_ENDPOINT;
  if (!wsEndpoint) return undefined;
  const headers = process.env.PW_TEST_CONNECT_HEADERS ? JSON.parse(process.env.PW_TEST_CONNECT_HEADERS) : undefined;
  return {
    wsEndpoint,
    headers,
    exposeNetwork: process.env.PW_TEST_CONNECT_EXPOSE_NETWORK
  };
}
class ArtifactsRecorder {
  constructor(playwright, artifactsDir, trace, screenshot) {
    this._testInfo = void 0;
    this._playwright = void 0;
    this._artifactsDir = void 0;
    this._screenshotMode = void 0;
    this._traceMode = void 0;
    this._captureTrace = false;
    this._screenshotOptions = void 0;
    this._traceOptions = void 0;
    this._temporaryTraceFiles = [];
    this._temporaryScreenshots = [];
    this._reusedContexts = new Set();
    this._traceOrdinal = 0;
    this._screenshotOrdinal = 0;
    this._screenshottedSymbol = void 0;
    this._startedCollectingArtifacts = void 0;
    this._playwright = playwright;
    this._artifactsDir = artifactsDir;
    this._screenshotMode = normalizeScreenshotMode(screenshot);
    this._screenshotOptions = typeof screenshot === 'string' ? undefined : screenshot;
    this._traceMode = normalizeTraceMode(trace);
    const defaultTraceOptions = {
      screenshots: true,
      snapshots: true,
      sources: true,
      attachments: true
    };
    this._traceOptions = typeof trace === 'string' ? defaultTraceOptions : {
      ...defaultTraceOptions,
      ...trace,
      mode: undefined
    };
    this._screenshottedSymbol = Symbol('screenshotted');
    this._startedCollectingArtifacts = Symbol('startedCollectingArtifacts');
  }
  async willStartTest(testInfo) {
    this._testInfo = testInfo;
    testInfo._onDidFinishTestFunction = () => this.didFinishTestFunction();
    this._captureTrace = shouldCaptureTrace(this._traceMode, testInfo) && !process.env.PW_TEST_DISABLE_TRACING;

    // Since beforeAll(s), test and afterAll(s) reuse the same TestInfo, make sure we do not
    // overwrite previous screenshots.
    this._screenshotOrdinal = testInfo.attachments.filter(a => a.name === 'screenshot').length;

    // Process existing contexts.
    for (const browserType of [this._playwright.chromium, this._playwright.firefox, this._playwright.webkit]) {
      const promises = [];
      const existingContexts = Array.from(browserType._contexts);
      for (const context of existingContexts) {
        if (context[kIsReusedContext]) this._reusedContexts.add(context);else promises.push(this.didCreateBrowserContext(context));
      }
      await Promise.all(promises);
    }
    {
      const existingApiRequests = Array.from(this._playwright.request._contexts);
      await Promise.all(existingApiRequests.map(c => this.didCreateRequestContext(c)));
    }
  }
  async didCreateBrowserContext(context) {
    await this._startTraceChunkOnContextCreation(context.tracing);
  }
  async willCloseBrowserContext(context) {
    // When reusing context, we get all previous contexts closed at the start of next test.
    // Do not record empty traces and useless screenshots for them.
    if (this._reusedContexts.has(context)) return;
    await this._stopTracing(context.tracing, context[kStartedContextTearDown]);
    if (this._screenshotMode === 'on' || this._screenshotMode === 'only-on-failure') {
      // Capture screenshot for now. We'll know whether we have to preserve them
      // after the test finishes.
      await Promise.all(context.pages().map(page => this._screenshotPage(page)));
    }
  }
  async didCreateRequestContext(context) {
    const tracing = context._tracing;
    await this._startTraceChunkOnContextCreation(tracing);
  }
  async willCloseRequestContext(context) {
    const tracing = context._tracing;
    await this._stopTracing(tracing, context[kStartedContextTearDown]);
  }
  async didFinishTestFunction() {
    if (this._testInfo._isFailure() && (this._screenshotMode === 'on' || this._screenshotMode === 'only-on-failure')) await this._screenshotOnTestFailure();
  }
  async didFinishTest() {
    const captureScreenshots = this._screenshotMode === 'on' || this._screenshotMode === 'only-on-failure' && this._testInfo.status !== this._testInfo.expectedStatus;
    const leftoverContexts = [];
    for (const browserType of [this._playwright.chromium, this._playwright.firefox, this._playwright.webkit]) leftoverContexts.push(...browserType._contexts);
    const leftoverApiRequests = Array.from(this._playwright.request._contexts);

    // Collect traces/screenshots for remaining contexts.
    await Promise.all(leftoverContexts.map(async context => {
      await this._stopTracing(context.tracing, true);
      if (captureScreenshots) {
        await Promise.all(context.pages().map(async page => {
          if (page[this._screenshottedSymbol]) return;
          try {
            const screenshotPath = this._createScreenshotAttachmentPath();
            // Pass caret=initial to avoid any evaluations that might slow down the screenshot
            // and let the page modify itself from the problematic state it had at the moment of failure.
            await page.screenshot({
              ...this._screenshotOptions,
              timeout: 5000,
              path: screenshotPath,
              caret: 'initial'
            });
            this._testInfo.attachments.push({
              name: 'screenshot',
              path: screenshotPath,
              contentType: 'image/png'
            });
          } catch {
            // Screenshot may fail, just ignore.
          }
        }));
      }
    }).concat(leftoverApiRequests.map(async context => {
      const tracing = context._tracing;
      await this._stopTracing(tracing, true);
    })));

    // Either remove or attach temporary screenshots for contexts closed before
    // collecting the test trace.
    await Promise.all(this._temporaryScreenshots.map(async file => {
      if (!captureScreenshots) {
        await fs.promises.unlink(file).catch(() => {});
        return;
      }
      try {
        const screenshotPath = this._createScreenshotAttachmentPath();
        await fs.promises.rename(file, screenshotPath);
        this._testInfo.attachments.push({
          name: 'screenshot',
          path: screenshotPath,
          contentType: 'image/png'
        });
      } catch {}
    }));

    // Collect test trace.
    if (this._preserveTrace()) {
      const events = this._testInfo._traceEvents;
      if (events.length) {
        if (!this._traceOptions.attachments) {
          for (const event of events) {
            if (event.type === 'after') delete event.attachments;
          }
        }
        const tracePath = path.join(this._artifactsDir, (0, _utils.createGuid)() + '.zip');
        this._temporaryTraceFiles.push(tracePath);
        await (0, _utils.saveTraceFile)(tracePath, events, this._traceOptions.sources);
      }
    }

    // Either remove or attach temporary traces for contexts closed before the
    // test has finished.
    if (this._preserveTrace() && this._temporaryTraceFiles.length) {
      const tracePath = this._testInfo.outputPath(`trace.zip`);
      // This could be: beforeHooks, or beforeHooks + test, etc.
      const beforeHooksHadTrace = fs.existsSync(tracePath);
      if (beforeHooksHadTrace) {
        await fs.promises.rename(tracePath, tracePath + '.tmp');
        this._temporaryTraceFiles.unshift(tracePath + '.tmp');
      }
      await (0, _utils.mergeTraceFiles)(tracePath, this._temporaryTraceFiles);
      // Do not add attachment twice.
      if (!beforeHooksHadTrace) this._testInfo.attachments.push({
        name: 'trace',
        path: tracePath,
        contentType: 'application/zip'
      });
    }
  }
  _createScreenshotAttachmentPath() {
    const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;
    const index = this._screenshotOrdinal + 1;
    ++this._screenshotOrdinal;
    const screenshotPath = this._testInfo.outputPath(`test-${testFailed ? 'failed' : 'finished'}-${index}.png`);
    return screenshotPath;
  }
  async _screenshotPage(page) {
    if (page[this._screenshottedSymbol]) return;
    page[this._screenshottedSymbol] = true;
    try {
      const screenshotPath = path.join(this._artifactsDir, (0, _utils.createGuid)() + '.png');
      // Pass caret=initial to avoid any evaluations that might slow down the screenshot
      // and let the page modify itself from the problematic state it had at the moment of failure.
      await page.screenshot({
        ...this._screenshotOptions,
        timeout: 5000,
        path: screenshotPath,
        caret: 'initial'
      }).catch(() => {});
      this._temporaryScreenshots.push(screenshotPath);
    } catch {
      // Screenshot may fail, just ignore.
    }
  }
  async _screenshotOnTestFailure() {
    const contexts = [];
    for (const browserType of [this._playwright.chromium, this._playwright.firefox, this._playwright.webkit]) contexts.push(...browserType._contexts);
    await Promise.all(contexts.map(ctx => Promise.all(ctx.pages().map(page => this._screenshotPage(page)))));
  }
  async _startTraceChunkOnContextCreation(tracing) {
    if (this._captureTrace) {
      const title = [path.relative(this._testInfo.project.testDir, this._testInfo.file) + ':' + this._testInfo.line, ...this._testInfo.titlePath.slice(1)].join(' › ');
      const ordinalSuffix = this._traceOrdinal ? `-context${this._traceOrdinal}` : '';
      ++this._traceOrdinal;
      const retrySuffix = this._testInfo.retry ? `-retry${this._testInfo.retry}` : '';
      const name = `${this._testInfo.testId}${retrySuffix}${ordinalSuffix}`;
      if (!tracing[kTracingStarted]) {
        await tracing.start({
          ...this._traceOptions,
          title,
          name
        });
        tracing[kTracingStarted] = true;
      } else {
        await tracing.startChunk({
          title,
          name
        });
      }
    } else {
      if (tracing[kTracingStarted]) {
        tracing[kTracingStarted] = false;
        await tracing.stop();
      }
    }
  }
  _preserveTrace() {
    const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;
    return this._captureTrace && (this._traceMode === 'on' || testFailed && this._traceMode === 'retain-on-failure' || this._traceMode === 'on-first-retry' && this._testInfo.retry === 1 || this._traceMode === 'on-all-retries' && this._testInfo.retry > 0);
  }
  async _stopTracing(tracing, contextTearDownStarted) {
    if (tracing[this._startedCollectingArtifacts]) return;
    tracing[this._startedCollectingArtifacts] = true;
    if (this._captureTrace) {
      let tracePath;
      // Create a trace file if we know that:
      // - it is's going to be used due to the config setting and the test status or
      // - we are inside a test or afterEach and the user manually closed the context.
      if (this._preserveTrace() || !contextTearDownStarted) {
        tracePath = path.join(this._artifactsDir, (0, _utils.createGuid)() + '.zip');
        this._temporaryTraceFiles.push(tracePath);
      }
      await tracing.stopChunk({
        path: tracePath
      });
    }
  }
}
const paramsToRender = ['url', 'selector', 'text', 'key'];
function renderApiCall(apiName, params) {
  const paramsArray = [];
  if (params) {
    for (const name of paramsToRender) {
      if (!(name in params)) continue;
      let value;
      if (name === 'selector' && (0, _utils.isString)(params[name]) && params[name].startsWith('internal:')) {
        const getter = (0, _utils.asLocator)('javascript', params[name], false, true);
        apiName = apiName.replace(/^locator\./, 'locator.' + getter + '.');
        apiName = apiName.replace(/^page\./, 'page.' + getter + '.');
        apiName = apiName.replace(/^frame\./, 'frame.' + getter + '.');
      } else {
        value = params[name];
        paramsArray.push(value);
      }
    }
  }
  const paramsText = paramsArray.length ? '(' + paramsArray.join(', ') + ')' : '';
  return apiName + paramsText;
}
const test = _baseTest.extend(playwrightFixtures);
exports.test = test;
var _default = test;
exports.default = _default;