<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.35.1] (latest docker container)</li>
<li>Operating System: [Ubuntu Gitlab Runner]</li>
<li>Browser: [Chromium]</li>
<li>Other info: Running on Gitlab Enterprise CI</li>
</ul>
<h3 dir="auto">Source code</h3>
<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="import { defineConfig, devices } from &quot;@playwright/test&quot;;

export default defineConfig({
  // Look for test files in the &quot;tests&quot; directory, relative to this configuration file.
  testDir: &quot;e2e&quot;,
  testIgnore: &quot;e2e/todo/**&quot;,

  timeout: 60000,

  // Run all tests in parallel.
  fullyParallel: true,

  //   // 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
  reporter: &quot;html&quot;,

  outputDir: &quot;test-results&quot;,

  use: {
    // Collect trace when retrying the failed test.
    trace: &quot;on&quot;,
    screenshot: &quot;only-on-failure&quot;,
  },
  // Configure projects for major browsers.
  projects: [
    // Setup project
    { name: &quot;setup&quot;, testMatch: /.*\.setup\.ts/ },
    {
      name: &quot;chromium&quot;,
      use: {
        ...devices[&quot;Desktop Chrome&quot;],
        storageState: &quot;playwright/.auth/keycloak.json&quot;,
      },
      dependencies: [&quot;setup&quot;],
    },
  ],
  // Run your local dev server before starting the tests.
  webServer: {
    command: &quot;npm run start&quot;,
    url: &quot;http://localhost:5173&quot;,
    reuseExistingServer: true,
  },
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">defineConfig</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-k">export</span> <span class="pl-k">default</span> <span class="pl-en">defineConfig</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c">// Look for test files in the "tests" directory, relative to this configuration file.</span>
  <span class="pl-c1">testDir</span>: <span class="pl-s">"e2e"</span><span class="pl-kos">,</span>
  <span class="pl-c1">testIgnore</span>: <span class="pl-s">"e2e/todo/**"</span><span class="pl-kos">,</span>

  <span class="pl-c1">timeout</span>: <span class="pl-c1">60000</span><span class="pl-kos">,</span>

  <span class="pl-c">// Run all tests 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-c">//   forbidOnly: !!process.env.CI,</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</span>
  <span class="pl-c1">reporter</span>: <span class="pl-s">"html"</span><span class="pl-kos">,</span>

  <span class="pl-c1">outputDir</span>: <span class="pl-s">"test-results"</span><span class="pl-kos">,</span>

  <span class="pl-c1">use</span>: <span class="pl-kos">{</span>
    <span class="pl-c">// Collect trace when retrying the failed test.</span>
    <span class="pl-c1">trace</span>: <span class="pl-s">"on"</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-c">// Configure projects for major browsers.</span>
  <span class="pl-c1">projects</span>: <span class="pl-kos">[</span>
    <span class="pl-c">// Setup project</span>
    <span class="pl-kos">{</span> <span class="pl-c1">name</span>: <span class="pl-s">"setup"</span><span class="pl-kos">,</span> <span class="pl-c1">testMatch</span>: <span class="pl-pds"><span class="pl-c1">/</span>.<span class="pl-c1">*</span><span class="pl-cce">\.</span>setup<span class="pl-cce">\.</span>ts<span class="pl-c1">/</span></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">"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-c1">storageState</span>: <span class="pl-s">"playwright/.auth/keycloak.json"</span><span class="pl-kos">,</span>
      <span class="pl-kos">}</span><span class="pl-kos">,</span>
      <span class="pl-c1">dependencies</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-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-c1">webServer</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">command</span>: <span class="pl-s">"npm run start"</span><span class="pl-kos">,</span>
    <span class="pl-c1">url</span>: <span class="pl-s">"http://localhost:5173"</span><span class="pl-kos">,</span>
    <span class="pl-c1">reuseExistingServer</span>: <span class="pl-c1">true</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>Test file (self-contained)</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { test, expect } from &quot;@playwright/test&quot;;
import { test_param_id } from &quot;./params&quot;;

const sc_options = {
  fullPage: true,
  maxDiffPixels: 100,
};

test.describe(&quot;Screenshot Tests&quot;, () =&gt; {
  test.beforeEach(async ({ page }) =&gt; {
    await page.goto(`http://localhost:5173/projects/load?ip=${test_param_id}`);
    await page.waitForURL(&quot;http://localhost:5173/steps/1&quot;);
    await page.setViewportSize({ width: 2560, height: 1800 });
    await expect(page.locator(&quot;.right-step-1&quot;)).toBeVisible();
  });

  test(&quot;step 1&quot;, async ({ page }) =&gt; {
    await expect(page).toHaveScreenshot(sc_options);
  });
  test(&quot;step 2&quot;, async ({ page }) =&gt; {
    await page.click(&quot;.right-step-1&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/2&quot;);
    await expect(page).toHaveScreenshot(sc_options);
  });
  test(&quot;step 3&quot;, async ({ page }) =&gt; {
    await page.click(&quot;.right-step-1&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/2&quot;);
    await page.click(&quot;.right-step-2&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/3&quot;);
    await expect(page).toHaveScreenshot(sc_options);
  });
  test(&quot;step 4&quot;, async ({ page }) =&gt; {
    await page.click(&quot;.right-step-1&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/2&quot;);
    await page.click(&quot;.right-step-2&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/3&quot;);
    await page.click(&quot;.right-step-3&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/4&quot;);
    await expect(page).toHaveScreenshot(sc_options);
  });
  test(&quot;step 5&quot;, async ({ page }) =&gt; {
    await page.click(&quot;.right-step-1&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/2&quot;);
    await page.click(&quot;.right-step-2&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/3&quot;);
    await page.click(&quot;.right-step-3&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/4&quot;);
    await page.click(&quot;.right-step-4&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/5&quot;);
    await expect(page).toHaveScreenshot(sc_options);
  });
  test(&quot;step 6&quot;, async ({ page }) =&gt; {
    test.setTimeout(180000);
    await page.click(&quot;.right-step-1&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/2&quot;);
    await page.click(&quot;.right-step-2&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/3&quot;);
    await page.click(&quot;.right-step-3&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/4&quot;);
    await page.click(&quot;.right-step-4&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/5&quot;);
    await page.click(&quot;.right-step-5&quot;);
    await page.waitForURL(&quot;http://localhost:5173/steps/6&quot;);
    // Wait for text &quot;Berechnungs­szenarium&quot; to appear
    await page.waitForSelector(&quot;text=Sturm&quot;, { timeout: 120000 });
    await expect(page).toHaveScreenshot({
      ...sc_options,
      maxDiffPixels: 12000,
    });
  });
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">test</span><span class="pl-kos">,</span> <span class="pl-s1">expect</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">test_param_id</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"./params"</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">sc_options</span> <span class="pl-c1">=</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">maxDiffPixels</span>: <span class="pl-c1">100</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">describe</span><span class="pl-kos">(</span><span class="pl-s">"Screenshot Tests"</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">beforeEach</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-s">`http://localhost:5173/projects/load?ip=<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">test_param_id</span><span class="pl-kos">}</span></span>`</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/1"</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">setViewportSize</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">width</span>: <span class="pl-c1">2560</span><span class="pl-kos">,</span> <span class="pl-c1">height</span>: <span class="pl-c1">1800</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</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-s">".right-step-1"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toBeVisible</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 1"</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-s1">sc_options</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 2"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-1"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/2"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-s1">sc_options</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 3"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-1"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/2"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-2"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/3"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-s1">sc_options</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 4"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-1"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/2"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-2"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/3"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-3"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/4"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-s1">sc_options</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 5"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-1"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/2"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-2"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/3"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-3"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/4"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-4"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/5"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-s1">sc_options</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">test</span><span class="pl-kos">(</span><span class="pl-s">"step 6"</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">setTimeout</span><span class="pl-kos">(</span><span class="pl-c1">180000</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-1"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/2"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-2"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/3"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-3"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/4"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-4"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/5"</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">click</span><span class="pl-kos">(</span><span class="pl-s">".right-step-5"</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">waitForURL</span><span class="pl-kos">(</span><span class="pl-s">"http://localhost:5173/steps/6"</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-c">// Wait for text "Berechnungs­szenarium" to appear</span>
    <span class="pl-k">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">waitForSelector</span><span class="pl-kos">(</span><span class="pl-s">"text=Sturm"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">timeout</span>: <span class="pl-c1">120000</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveScreenshot</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      ...<span class="pl-s1">sc_options</span><span class="pl-kos">,</span>
      <span class="pl-c1">maxDiffPixels</span>: <span class="pl-c1">12000</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>Gitlab CI</strong></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# test with screenshots
playwright-dev:
  rules:
    - if: $CI_PIPELINE_SOURCE == &quot;merge_request_event&quot;
      allow_failure: true
  stage: test
  image: mcr.microsoft.com/playwright
  script:
    - npm install
    - npx playwright install --with-deps chromium
    - npx playwright test
  artifacts:
    when: always  
    paths:  
      - playwright-report/  
      - test-results/  
    expire_in: 30 days
    untracked: true"><pre class="notranslate"><code class="notranslate"># test with screenshots
playwright-dev:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      allow_failure: true
  stage: test
  image: mcr.microsoft.com/playwright
  script:
    - npm install
    - npx playwright install --with-deps chromium
    - npx playwright test
  artifacts:
    when: always  
    paths:  
      - playwright-report/  
      - test-results/  
    expire_in: 30 days
    untracked: true
</code></pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>See Gitlab CI file</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">Visual Comparison between last commit (or pipeline run) and current commit to see visual changes between commits.</p>
<p dir="auto">Screenshot Snapshots are supposed to be accessible in cache between multiple pipeline (job) runs.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Snapshots don't exist and are only created within the scope of the current run. Because they cannot carry over from the previous run (where snapshots are created on first execution of <code class="notranslate">npx playwright text</code>), the visual comparison tests always fail.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Error: A snapshot doesn't exist at /builds/.../frontends/frontend-new/e2e/screenshots.spec.ts-snapshots/Screenshot-Tests-step-1-1-chromium-linux.png."><pre class="notranslate"><code class="notranslate">Error: A snapshot doesn't exist at /builds/.../frontends/frontend-new/e2e/screenshots.spec.ts-snapshots/Screenshot-Tests-step-1-1-chromium-linux.png.
</code></pre></div>
<p dir="auto">Hi,</p>
<p dir="auto">I read that if one of the tests in a suite fails - the <code class="notranslate">beforeAll</code> hook is running again (As the worker disposed)</p>
<p dir="auto">I have a case when my <code class="notranslate">beforeAll</code> hook used for a data preparation using API calls.<br>
In addition, my application has a limitation that I can't create a duplication of an entity.</p>
<p dir="auto">As mentioned, if one of the tests in a suite failed - <code class="notranslate">beforeAll</code> hook is running again and due to the duplication limitation, the <code class="notranslate">beforeAll</code> hook failed and all tests failed accordingly as well.</p>
<p dir="auto">I was wonder what could be the best practice in such case?<br>
Currently I implemented it using a fixture which is called only from the first test in the suite, but I feel it's not the best practice.</p>