<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: v1.33.0</li>
<li>Operating System: macOS 13.3.1</li>
<li>Browser: Chromium</li>
<li>Other info:</li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Config file</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// playwright.config.ts
const config = defineConfig({
  testDir: './e2e',
  /* Maximum time one test can run for - 30s */
  timeout: 30000,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 10000,
  },
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: IS_CI,
  /* Retry on CI only */
  retries: IS_CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: IS_CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: 'html',
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
    actionTimeout: 0,

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',

    screenshot: 'only-on-failure',
  },

  globalTeardown: './e2e/setup/global-teardown.js',
  globalSetup: './e2e/setup/global-setup.js',

  /* Configure projects for major browsers */
  projects,

  /* Run your local dev server before starting the tests */
  // webServer: {
  //   command: 'npm run start',
  //   url: 'http://127.0.0.1:3000',
  //   reuseExistingServer: !process.env.CI,
  // },
});"><pre class="notranslate"><span class="pl-c">// playwright.config.ts</span>
<span class="pl-k">const</span> <span class="pl-s1">config</span> <span class="pl-c1">=</span> <span class="pl-en">defineConfig</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">testDir</span>: <span class="pl-s">'./e2e'</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Maximum time one test can run for - 30s */</span>
  <span class="pl-c1">timeout</span>: <span class="pl-c1">30000</span><span class="pl-kos">,</span>
  <span class="pl-c1">expect</span>: <span class="pl-kos">{</span>
    <span class="pl-c">/**</span>
<span class="pl-c">     * Maximum time expect() should wait for the condition to be met.</span>
<span class="pl-c">     * For example in `await expect(locator).toHaveText();`</span>
<span class="pl-c">     */</span>
    <span class="pl-c1">timeout</span>: <span class="pl-c1">10000</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Run tests in files in parallel */</span>
  <span class="pl-c1">fullyParallel</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Fail the build on CI if you accidentally left test.only in the source code. */</span>
  <span class="pl-c1">forbidOnly</span>: <span class="pl-c1">IS_CI</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Retry on CI only */</span>
  <span class="pl-c1">retries</span>: <span class="pl-c1">IS_CI</span> ? <span class="pl-c1">2</span> : <span class="pl-c1">0</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Opt out of parallel tests on CI. */</span>
  <span class="pl-c1">workers</span>: <span class="pl-c1">IS_CI</span> ? <span class="pl-c1">1</span> : <span class="pl-c1">undefined</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Reporter to use. See https://playwright.dev/docs/test-reporters */</span>
  <span class="pl-c1">reporter</span>: <span class="pl-s">'html'</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */</span>
  <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
    <span class="pl-c">/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */</span>
    <span class="pl-c1">actionTimeout</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span>

    <span class="pl-c">/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */</span>
    <span class="pl-c1">trace</span>: <span class="pl-s">'on-first-retry'</span><span class="pl-kos">,</span>

    <span class="pl-c1">screenshot</span>: <span class="pl-s">'only-on-failure'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>

  <span class="pl-c1">globalTeardown</span>: <span class="pl-s">'./e2e/setup/global-teardown.js'</span><span class="pl-kos">,</span>
  <span class="pl-c1">globalSetup</span>: <span class="pl-s">'./e2e/setup/global-setup.js'</span><span class="pl-kos">,</span>

  <span class="pl-c">/* Configure projects for major browsers */</span>
  projects<span class="pl-kos">,</span>

  <span class="pl-c">/* Run your local dev server before starting the tests */</span>
  <span class="pl-c">// webServer: {</span>
  <span class="pl-c">//   command: 'npm run start',</span>
  <span class="pl-c">//   url: 'http://127.0.0.1:3000',</span>
  <span class="pl-c">//   reuseExistingServer: !process.env.CI,</span>
  <span class="pl-c">// },</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// global-setup.js
async function globalSetup() {
  console.log('SETUP....');
}

export default globalSetup;"><pre class="notranslate"><span class="pl-c">// global-setup.js</span>
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">globalSetup</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'SETUP....'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-s1">globalSetup</span><span class="pl-kos">;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// global-teardown.js
async function globalTeardown() {
  console.log('TEARDOWN....');
}

export default globalTeardown;"><pre class="notranslate"><span class="pl-c">// global-teardown.js</span>
<span class="pl-k">async</span> <span class="pl-k">function</span> <span class="pl-en">globalTeardown</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'TEARDOWN....'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-s1">globalTeardown</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>[Run any test]</li>
<li>Observe that the globalSetup will log <code class="notranslate">SETUP...</code></li>
<li>Observe that the globalTearDown will never run</li>
</ul>
<p dir="auto"><strong>Expected</strong><br>
globalTearDown should run after the test finishes</p>
<p dir="auto"><strong>Actual</strong><br>
globalTearDown never runs after the test finishes</p>
<p dir="auto">Screenshot:</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer nofollow" href="https://user-images.githubusercontent.com/5679671/236019461-e599e417-1882-4176-9d1e-97cc08699d83.png"><img width="762" alt="Screenshot 2023-05-03 at 15 54 33" src="https://user-images.githubusercontent.com/5679671/236019461-e599e417-1882-4176-9d1e-97cc08699d83.png" style="max-width: 100%;"></a></p>
<p dir="auto">[Describe actual behavior]</p>
<p dir="auto">I expect globalTeardown to run once all tests finish, but this is not happening.</p>
<p dir="auto">Any help on what I could be doing wrong would be much appreciated, but since globalSetup is running I believe it could be a bug.</p>
<p dir="auto"><strong>Context:</strong></p>
<ul dir="auto">
<li>Playwright Version: 1.22</li>
<li>Operating System: Mac with Docker</li>
<li>Node.js version: 14.19</li>
<li>Browser: All</li>
<li>Extra: We are using Playwright for Visual Regression</li>
</ul>


<p dir="auto"><strong>Code Snippet</strong></p>
<p dir="auto">Running command:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="docker run --rm --network=host --ipc=host -v $(pwd):/work/ mcr.microsoft.com/playwright:v1.22.0-focal bash -c 'cd work &amp;&amp; npx playwright install &amp;&amp; npx playwright test --update-snapshots'"><pre class="notranslate">docker run --rm --network=host --ipc=host -v <span class="pl-s"><span class="pl-pds">$(</span>pwd<span class="pl-pds">)</span></span>:/work/ mcr.microsoft.com/playwright:v1.22.0-focal bash -c <span class="pl-s"><span class="pl-pds">'</span>cd work &amp;&amp; npx playwright install &amp;&amp; npx playwright test --update-snapshots<span class="pl-pds">'</span></span></pre></div>
<p dir="auto"><code class="notranslate">playwright.config.ts</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/* eslint-disable no-console */
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';

/**
 * Read environment variables from file.
 * https://github.com/motdotla/dotenv
 */
// require('dotenv').config();

const port = global.process.env.PORT ? parseInt(global.process.env.PORT, 10) : 4200;
const url = `http://localhost:${port}`;

/**
 * See https://playwright.dev/docs/test-configuration.
 */
const config: PlaywrightTestConfig = {
  testDir: './tests',
  /* Maximum time one test can run for. */
  timeout: 100000,
  expect: {
    /**
     * Maximum time expect() should wait for the condition to be met.
     * For example in `await expect(locator).toHaveText();`
     */
    timeout: 100000,
  },
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: [['line'], ['html']],
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
    actionTimeout: 0,
    /* Base URL to use in actions like `await page.goto('/')`. */
    baseURL: url,

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
  },

  /* Configure projects for major browsers */
  projects: [
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
      },
    },

    {
      name: 'firefox',
      use: {
        ...devices['Desktop Firefox'],
      },
    },

    {
      name: 'webkit',
      use: {
        ...devices['Desktop Safari'],
      },
    },
    {
      name: 'Mobile Chrome Portrait',
      use: {
        ...devices['Pixel 5'],
      },
    },
    {
      name: 'Mobile Safari Portrait',
      use: {
        ...devices['iPhone 12'],
      },
    },
    {
      name: 'Tablet Safari Portrait',
      use: {
        ...devices['iPad (gen 7)'],
      },
    },
  ],

  /* Folder for test artifacts such as screenshots, videos, traces, etc. */
  // outputDir: 'test-results/',
  webServer: {
    command: `yarn start --port ${port}`,
    url,
    timeout: 300000,
  },
  /* Run your local dev server before starting the tests */
};

export default config;"><pre class="notranslate"><span class="pl-c">/* eslint-disable no-console */</span>
<span class="pl-k">import</span> <span class="pl-k">type</span> <span class="pl-kos">{</span> <span class="pl-smi">PlaywrightTestConfig</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'@playwright/test'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">devices</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'@playwright/test'</span><span class="pl-kos">;</span>

<span class="pl-c">/**</span>
<span class="pl-c"> * Read environment variables from file.</span>
<span class="pl-c"> * https://github.com/motdotla/dotenv</span>
<span class="pl-c"> */</span>
<span class="pl-c">// require('dotenv').config();</span>

<span class="pl-k">const</span> <span class="pl-s1">port</span> <span class="pl-c1">=</span> <span class="pl-s1">global</span><span class="pl-kos">.</span><span class="pl-c1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">PORT</span> ? <span class="pl-en">parseInt</span><span class="pl-kos">(</span><span class="pl-s1">global</span><span class="pl-kos">.</span><span class="pl-c1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">PORT</span><span class="pl-kos">,</span> <span class="pl-c1">10</span><span class="pl-kos">)</span> : <span class="pl-c1">4200</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">url</span> <span class="pl-c1">=</span> <span class="pl-s">`http://localhost:<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">port</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">;</span>

<span class="pl-c">/**</span>
<span class="pl-c"> * See https://playwright.dev/docs/test-configuration.</span>
<span class="pl-c"> */</span>
<span class="pl-k">const</span> <span class="pl-s1">config</span>: <span class="pl-smi">PlaywrightTestConfig</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  <span class="pl-c1">testDir</span>: <span class="pl-s">'./tests'</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Maximum time one test can run for. */</span>
  <span class="pl-c1">timeout</span>: <span class="pl-c1">100000</span><span class="pl-kos">,</span>
  <span class="pl-c1">expect</span>: <span class="pl-kos">{</span>
    <span class="pl-c">/**</span>
<span class="pl-c">     * Maximum time expect() should wait for the condition to be met.</span>
<span class="pl-c">     * For example in `await expect(locator).toHaveText();`</span>
<span class="pl-c">     */</span>
    <span class="pl-c1">timeout</span>: <span class="pl-c1">100000</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Fail the build on CI if you accidentally left test.only in the source code. */</span>
  <span class="pl-c1">forbidOnly</span>: <span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">CI</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Retry on CI only */</span>
  <span class="pl-c1">retries</span>: <span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">CI</span> ? <span class="pl-c1">2</span> : <span class="pl-c1">0</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Opt out of parallel tests on CI. */</span>
  <span class="pl-c1">workers</span>: <span class="pl-s1">process</span><span class="pl-kos">.</span><span class="pl-c1">env</span><span class="pl-kos">.</span><span class="pl-c1">CI</span> ? <span class="pl-c1">1</span> : <span class="pl-c1">undefined</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Reporter to use. See https://playwright.dev/docs/test-reporters */</span>
  <span class="pl-c1">reporter</span>: <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s">'line'</span><span class="pl-kos">]</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">'html'</span><span class="pl-kos">]</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */</span>
  <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
    <span class="pl-c">/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */</span>
    <span class="pl-c1">actionTimeout</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span>
    <span class="pl-c">/* Base URL to use in actions like `await page.goto('/')`. */</span>
    <span class="pl-c1">baseURL</span>: <span class="pl-s1">url</span><span class="pl-kos">,</span>

    <span class="pl-c">/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */</span>
    <span class="pl-c1">trace</span>: <span class="pl-s">'on-first-retry'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>

  <span class="pl-c">/* Configure projects for major browsers */</span>
  <span class="pl-c1">projects</span>: <span class="pl-kos">[</span>
    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'chromium'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'Desktop Chrome'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>

    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'firefox'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'Desktop Firefox'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>

    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'webkit'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'Desktop Safari'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'Mobile Chrome Portrait'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'Pixel 5'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'Mobile Safari Portrait'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'iPhone 12'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">{</span>
      <span class="pl-c1">name</span>: <span class="pl-s">'Tablet Safari Portrait'</span><span class="pl-kos">,</span>
      <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
        ...<span class="pl-s1">devices</span><span class="pl-kos">[</span><span class="pl-s">'iPad (gen 7)'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">]</span><span class="pl-kos">,</span>

  <span class="pl-c">/* Folder for test artifacts such as screenshots, videos, traces, etc. */</span>
  <span class="pl-c">// outputDir: 'test-results/',</span>
  <span class="pl-c1">webServer</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">command</span>: <span class="pl-s">`yarn start --port <span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">port</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">,</span>
    url<span class="pl-kos">,</span>
    <span class="pl-c1">timeout</span>: <span class="pl-c1">300000</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-c">/* Run your local dev server before starting the tests */</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-s1">config</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><code class="notranslate">urls.ts</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/* eslint-disable sonarjs/no-duplicate-string */
interface PlaywrightUrl {
  url: string;
  pageName: string;
  mask?: string[];
}

export const URLS: PlaywrightUrl[] = [
  {
    url: '/sign/in',
    pageName: 'sign-in',
  },
  {
    url: '/contact',
    pageName: 'contact',
  },
  {
    url: '/faq',
    pageName: 'faq',
    mask: ['app-faq-items'],
  },
  {
    url: '/dashboard?login-token=token-demo',
    pageName: 'dashboard',
    mask: ['.layout__main-content'],
  },
  {
    url: '/services/wizbii-drive/lessons?login-token=token-demo',
    pageName: 'wizbii-drive-lessons',
  },
  {
    url: '/services/wizbii-drive/series?login-token=token-demo',
    pageName: 'wizbii-drive-series',
    mask: ['.serie__action', '.serie__status'],
  },
  {
    url: '/services/wizbii-drive/series?mode=training&amp;login-token=token-demo',
    pageName: 'wizbii-drive-series-training',
    mask: ['.serie__action', '.serie__status'],
  },
  {
    url: '/services/wizbii-drive/series?group-by=thematics&amp;login-token=token-demo',
    pageName: 'wizbii-drive-thematics',
  },
  {
    url: '/services/wizbii-drive/series/thematics/l_legales?login-token=token-demo',
    pageName: 'wizbii-drive-series-theme',
    mask: ['.serie__action', '.serie__status'],
  },
  {
    url: '/services/wizbii-drive/series/thematics/l_legales?mode=training&amp;login-token=token-demo',
    pageName: 'wizbii-drive-series-theme-training',
    mask: ['.serie__action', '.serie__status'],
  },
  {
    url: '/services/wizbii-drive/progress?login-token=token-demo',
    pageName: 'wizbii-drive-progress',
    mask: ['.serie__action', '.serie__status', '.graph-section'],
  },
  {
    url: '/services/wizbii-drive/advices?login-token=token-demo',
    pageName: 'wizbii-drive-advices',
    mask: ['drive-advice-list-item'],
  },
  {
    url: '/services/wizbii-blog?login-token=token-demo',
    pageName: 'wizbii-blog-list',
    mask: ['app-article-item'],
  },
  {
    url: '/services/wizbii-blog?category=entrepreneuriat&amp;login-token=token-demo',
    pageName: 'wizbii-blog-list-category',
    mask: ['app-article-item'],
  },
];"><pre class="notranslate"><span class="pl-c">/* eslint-disable sonarjs/no-duplicate-string */</span>
<span class="pl-k">interface</span> <span class="pl-smi">PlaywrightUrl</span> <span class="pl-kos">{</span>
  <span class="pl-c1">url</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">pageName</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">mask</span>?: <span class="pl-smi">string</span><span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">const</span> <span class="pl-smi">URLS</span>: <span class="pl-smi">PlaywrightUrl</span><span class="pl-kos">[</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/sign/in'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'sign-in'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/contact'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'contact'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/faq'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'faq'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'app-faq-items'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/dashboard?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'dashboard'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.layout__main-content'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/lessons?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-lessons'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/series?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-series'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.serie__action'</span><span class="pl-kos">,</span> <span class="pl-s">'.serie__status'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/series?mode=training&amp;login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-series-training'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.serie__action'</span><span class="pl-kos">,</span> <span class="pl-s">'.serie__status'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/series?group-by=thematics&amp;login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-thematics'</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/series/thematics/l_legales?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-series-theme'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.serie__action'</span><span class="pl-kos">,</span> <span class="pl-s">'.serie__status'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/series/thematics/l_legales?mode=training&amp;login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-series-theme-training'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.serie__action'</span><span class="pl-kos">,</span> <span class="pl-s">'.serie__status'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/progress?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-progress'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'.serie__action'</span><span class="pl-kos">,</span> <span class="pl-s">'.serie__status'</span><span class="pl-kos">,</span> <span class="pl-s">'.graph-section'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-drive/advices?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-drive-advices'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'drive-advice-list-item'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-blog?login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-blog-list'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'app-article-item'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-kos">{</span>
    <span class="pl-c1">url</span>: <span class="pl-s">'/services/wizbii-blog?category=entrepreneuriat&amp;login-token=token-demo'</span><span class="pl-kos">,</span>
    <span class="pl-c1">pageName</span>: <span class="pl-s">'wizbii-blog-list-category'</span><span class="pl-kos">,</span>
    <span class="pl-c1">mask</span>: <span class="pl-kos">[</span><span class="pl-s">'app-article-item'</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
<span class="pl-kos">]</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><code class="notranslate">visual-testing.spec.ts</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { expect, test } from '@playwright/test';
import { URLS } from './urls';

test.describe.configure({ mode: 'parallel' });

URLS.forEach(({ url, pageName, mask }) =&gt; {
  test(`${pageName}`, async ({ page }) =&gt; {
    await page.goto(url);
    await page.waitForTimeout(5000);
    expect(
      await page.screenshot({
        fullPage: true,
        type: 'jpeg',
        quality: 50,
        ...(mask &amp;&amp; mask.length &gt; 0 ? { mask: mask.map((m) =&gt; page.locator(m)) } : {}),
      })
    ).toMatchSnapshot(`${pageName}.jpeg`, {
      threshold: 0.4,
    });
  });
});
"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">expect</span><span class="pl-kos">,</span> <span class="pl-s1">test</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'@playwright/test'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">URLS</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'./urls'</span><span class="pl-kos">;</span>

<span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-c1">describe</span><span class="pl-kos">.</span><span class="pl-en">configure</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">mode</span>: <span class="pl-s">'parallel'</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-smi">URLS</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-kos">{</span> url<span class="pl-kos">,</span> pageName<span class="pl-kos">,</span> mask <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-en">test</span><span class="pl-kos">(</span><span class="pl-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">pageName</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">,</span> <span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> page <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-s1">url</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">waitForTimeout</span><span class="pl-kos">(</span><span class="pl-c1">5000</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-en">expect</span><span class="pl-kos">(</span>
      <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">screenshot</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
        <span class="pl-c1">fullPage</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
        <span class="pl-c1">type</span>: <span class="pl-s">'jpeg'</span><span class="pl-kos">,</span>
        <span class="pl-c1">quality</span>: <span class="pl-c1">50</span><span class="pl-kos">,</span>
        ...<span class="pl-kos">(</span><span class="pl-s1">mask</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">mask</span><span class="pl-kos">.</span><span class="pl-c1">length</span> <span class="pl-c1">&gt;</span> <span class="pl-c1">0</span> ? <span class="pl-kos">{</span> <span class="pl-c1">mask</span>: <span class="pl-s1">mask</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">m</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">locator</span><span class="pl-kos">(</span><span class="pl-s1">m</span><span class="pl-kos">)</span><span class="pl-kos">)</span> <span class="pl-kos">}</span> : <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span>
    <span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toMatchSnapshot</span><span class="pl-kos">(</span><span class="pl-s">`<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">pageName</span><span class="pl-kos">}</span></span>.jpeg`</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
      <span class="pl-c1">threshold</span>: <span class="pl-c1">0.4</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Describe the bug</strong></p>
<p dir="auto">When I'm running the command to update the local screenshots, i have this error on some pages</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Error: maxMemoryUsageInMB limit exceeded by at least 6MB"><pre class="notranslate">Error: maxMemoryUsageInMB limit exceeded by at least 6MB</pre></div>
<p dir="auto">I'm guessing it's from <code class="notranslate">jpeg-js</code> but i don't know how to increase the memory limit to not have this bug :/</p>