<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.32]</li>
<li>Operating System: [macOS 13.2]</li>
<li>Browser: [All]</li>
<li>Other info: Storage State / Authentication state enabled through globalSetup</li>
</ul>
<p dir="auto"><strong>Config file</strong></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// playwright.config.ts
 globalSetup: require.resolve(&quot;./src/e2e/tests/global-setup&quot;),
    storageState: './src/e2e/tests/state.json',
    actionTimeout: 0,
    screenshot: 'only-on-failure',
    trace: 'on-first-retry',
  },"><pre class="notranslate"><span class="pl-c">// playwright.config.ts</span>
 <span class="pl-s1">globalSetup</span>: <span class="pl-en">require</span><span class="pl-kos">.</span><span class="pl-en">resolve</span><span class="pl-kos">(</span><span class="pl-s">"./src/e2e/tests/global-setup"</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
    <span class="pl-s1">storageState</span>: <span class="pl-s">'./src/e2e/tests/state.json'</span><span class="pl-kos">,</span>
    <span class="pl-s1">actionTimeout</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span>
    <span class="pl-s1">screenshot</span>: <span class="pl-s">'only-on-failure'</span><span class="pl-kos">,</span>
    <span class="pl-s1">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></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="test.beforeEach(async ({ page }) =&gt; {
  // Runs before each test and signs in each page.
  const assetsPage = new AnyPage(page);
  const loginPage = new LoginPage(page);
  await loginPage.visit()
  await assetsPage.menuTopNavComponent.clickAnyMenuItemNav(); 
  });

test('Creating an Element - Any Type', async ({ page }) =&gt; {
  const anyPage = new AnyPage(page);
  await anyPage.anyGridLoads()
  await anyPage.createElementAnyType();
});"><pre class="notranslate"><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-c">// Runs before each test and signs in each page.</span>
  <span class="pl-k">const</span> <span class="pl-s1">assetsPage</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">AnyPage</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-k">const</span> <span class="pl-s1">loginPage</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">LoginPage</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-k">await</span> <span class="pl-s1">loginPage</span><span class="pl-kos">.</span><span class="pl-en">visit</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
  <span class="pl-k">await</span> <span class="pl-s1">assetsPage</span><span class="pl-kos">.</span><span class="pl-c1">menuTopNavComponent</span><span class="pl-kos">.</span><span class="pl-en">clickAnyMenuItemNav</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">'Creating an Element - Any Type'</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">const</span> <span class="pl-s1">anyPage</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">AnyPage</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-k">await</span> <span class="pl-s1">anyPage</span><span class="pl-kos">.</span><span class="pl-en">anyGridLoads</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
  <span class="pl-k">await</span> <span class="pl-s1">anyPage</span><span class="pl-kos">.</span><span class="pl-en">createElementAnyType</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>Pre-condition</strong></p>
<ul dir="auto">
<li>Having Storage state enabled and being used to sign in during the beforeEach hook</li>
</ul>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>Run the test with the new flag --ui</li>
<li>npx playwright test --ui</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">UI Should be displayed as per the new feature is intended to work</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">After executing the command with the new flag --ui, terminal  shows the following error:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:159
    this._page.mainFrame().evaluateExpression(dispatchFuncSource, true, message).catch(e =&gt; this._originalStderr(String(e)));
               ^

TypeError: Cannot read properties of undefined (reading 'mainFrame')
    at UIMode._dispatchEvent (/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:159:16)
    at Timeout._onTimeout (/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:69:14)
    at listOnTimeout (node:internal/timers:564:17)
    at processTimers (node:internal/timers:507:7)

Node.js v19.4.0"><pre class="notranslate"><code class="notranslate">/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:159
    this._page.mainFrame().evaluateExpression(dispatchFuncSource, true, message).catch(e =&gt; this._originalStderr(String(e)));
               ^

TypeError: Cannot read properties of undefined (reading 'mainFrame')
    at UIMode._dispatchEvent (/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:159:16)
    at Timeout._onTimeout (/Users/clundstedt/Documents/zf-playwright/node_modules/@playwright/test/lib/runner/uiMode.js:69:14)
    at listOnTimeout (node:internal/timers:564:17)
    at processTimers (node:internal/timers:507:7)

Node.js v19.4.0
</code></pre></div>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.33.0]</li>
<li>Operating System: Ubuntu 22.04.2 LTS</li>
<li>Browser: Chromium</li>
<li>Other info: Confirmed on Chromium but I think it likely affects all browsers</li>
</ul>
<p dir="auto"><strong>Note: OP has been edited for clarity</strong>.</p>
<h3 dir="auto">Source code</h3>
<p dir="auto">implementation details</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// open browser, inject needed Carted window object, and wait for graphQL responses
async open(waitForApi = true) {
  const graphQlResponses = waitForResponses(this.page, 4);

  await this.injectCarted();
  // note no await
  this.page.goto(ClientData.baseUrl + '/index.html');

  // workarounds that fix the issue:
  // 1. await this.page.goto(ClientData.baseUrl + '/index.html');
  // 2. this.page.goto(ClientData.baseUrl + '/index.html', { waitUntil: 'commit' });

  if (waitForApi) {
    await graphQlResponses;
  }
}

// example page object class getter - `this.self` is itself a locator that scopes
// the CSS query, while OrderStatusCardSelectors.confirmationHeader is a CSS string
get confirmationHeader() {
  return this.self.locator(OrderStatusCardSelectors.confirmationHeader);
}"><pre class="notranslate"><span class="pl-c">// open browser, inject needed Carted window object, and wait for graphQL responses</span>
<span class="pl-en">async</span> <span class="pl-s1">open</span><span class="pl-kos">(</span><span class="pl-s1">waitForApi</span> <span class="pl-c1">=</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-k">const</span> <span class="pl-s1">graphQlResponses</span> <span class="pl-c1">=</span> <span class="pl-en">waitForResponses</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">page</span><span class="pl-kos">,</span> <span class="pl-c1">4</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-k">await</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">injectCarted</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c">// note no await</span>
  <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">page</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-smi">ClientData</span><span class="pl-kos">.</span><span class="pl-c1">baseUrl</span> <span class="pl-c1">+</span> <span class="pl-s">'/index.html'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-c">// workarounds that fix the issue:</span>
  <span class="pl-c">// 1. await this.page.goto(ClientData.baseUrl + '/index.html');</span>
  <span class="pl-c">// 2. this.page.goto(ClientData.baseUrl + '/index.html', { waitUntil: 'commit' });</span>

  <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">waitForApi</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-s1">graphQlResponses</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-c">// example page object class getter - `this.self` is itself a locator that scopes</span>
<span class="pl-c">// the CSS query, while OrderStatusCardSelectors.confirmationHeader is a CSS string</span>
<span class="pl-s1">get</span><span class="pl-kos"></span> <span class="pl-en">confirmationHeader</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">return</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">self</span><span class="pl-kos">.</span><span class="pl-en">locator</span><span class="pl-kos">(</span><span class="pl-smi">OrderStatusCardSelectors</span><span class="pl-kos">.</span><span class="pl-c1">confirmationHeader</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">test.spec.ts</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import { Page, test } from '@playwright/test';
import { Browser, Page } from '@playwright/test';

// graphql helper
import CartedSession from '../../graphql';
// extended test and expect
import { expect, test } from '../fixtures';
// page objects
import {
  CreditCard,
  FloatingCartButton,
  OrderStatusCard,
  ShoppingCart,
} from '../page-objects';
// support
import { cleanUp, getState, sendResults, setUp } from '../support';
// test data
import {
  adidasBackpack,
  ccDetailsTestCard,
  plushToy,
  staticUSShippingDetails,
} from '../test-data';

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

test.describe('Order Confirmation', () =&gt; {
  const cartedSession = new CartedSession('order-confirmation');
  let page: Page;
  let testBrowser: Browser;
  let cart: ShoppingCart;
  let floatingCartButton: FloatingCartButton;
  let payment: CreditCard;
  let orderStatus: OrderStatusCard;

  test.beforeAll(async ({ browser }, testInfo) =&gt; {
    // use the GraphAPI directly set session state, loading needed fixtures (if any)
    // all these requests happens before the browser even opens, so we can seed some state
    await cartedSession.loadFixture();
    await cartedSession.fetchProduct(plushToy);
    await cartedSession.fetchProduct(adidasBackpack);
    await cartedSession.addToCart(plushToy);
    await cartedSession.addToCart(adidasBackpack, 2);
    await cartedSession.startCheckout();
    await cartedSession.setAddress(staticUSShippingDetails);
    await cartedSession.setShippingOptions([
      { vendorName: plushToy.vendor, label: 'Economy' },
      { vendorName: adidasBackpack.vendor, label: 'Standard' },
    ]);

    // fetch local storage state object
    const state = getState([cartedSession.localStorageObject]);
    const mockOptions = {
      fixtureName: 'order-confirmation',
      storageState: state,
      sessionId: cartedSession.sessionId,
    };

    // now we create a page and setup calls
    // browser.newPage({ storageState }) at some point
    [page, testBrowser] = await setUp(browser, testInfo, mockOptions);

    // init page objects
    cart = new ShoppingCart(page);
    floatingCartButton = new FloatingCartButton(page);
    payment = new CreditCard(page);
    orderStatus = new OrderStatusCard(page);

    // launch the browser, open the cart, confirm payment
    await payment.open();
    await floatingCartButton.openCart();
    await payment.enterCreditCardDetails(ccDetailsTestCard);
    await cart.confirmPurchase();
  });

  test.afterEach(async ({}, testInfo) =&gt; {
    await sendResults(page, testInfo);
  });

  test.afterAll(async ({}) =&gt; {
    await cleanUp(page, testBrowser, { fixtureName: 'order-confirmation' });
  });

  test('shows the order confrimation header', () =&gt; {
    expect(orderStatus.confirmationHeader).toBeVisible();
  });

  test('displays correct email in thank you summary', () =&gt; {
    expect(orderStatus.emailSummary).toContainText(
      staticUSShippingDetails.email
    );
  });

  test('displays Order Placed for the first item', () =&gt; {
    // set order status card to equal plushtoy vendor
    orderStatus.merchantName = plushToy.vendor;
    expect(orderStatus.badge).toHaveText('Order Placed');
  });

  test('displays correct title for first item', () =&gt; {
    expect(orderStatus.title).toHaveText(plushToy.title);
  });

  test.fixme('displays correct image for first item ', () =&gt; {
    expect(orderStatus.image).toHaveScreenshot();
  });

  test('displays correct vendor name for first item ', () =&gt; {
    expect(orderStatus.vendor).toContainText(plushToy.vendor);
  });

  test('displays Order Placed for the second item', () =&gt; {
    // set order status card to equal backpack vendor
    orderStatus.merchantName = adidasBackpack.vendor;
    expect(orderStatus.badge).toHaveText('Order Placed');
  });

  test('displays correct title for second item', () =&gt; {
    expect(orderStatus.title).toHaveText(adidasBackpack.title);
  });

  test('displays correct vendor name for second item ', () =&gt; {
    expect(orderStatus.vendor).toContainText(adidasBackpack.vendor);
  });

  test.fixme('displays correct image for second item ', () =&gt; {
    expect(orderStatus.image).toHaveScreenshot();
  });
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">Page</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">Browser</span><span class="pl-kos">,</span> <span class="pl-smi">Page</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">// graphql helper</span>
<span class="pl-k">import</span> <span class="pl-smi">CartedSession</span> <span class="pl-k">from</span> <span class="pl-s">'../../graphql'</span><span class="pl-kos">;</span>
<span class="pl-c">// extended test and expect</span>
<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">'../fixtures'</span><span class="pl-kos">;</span>
<span class="pl-c">// page objects</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span>
  <span class="pl-smi">CreditCard</span><span class="pl-kos">,</span>
  <span class="pl-smi">FloatingCartButton</span><span class="pl-kos">,</span>
  <span class="pl-smi">OrderStatusCard</span><span class="pl-kos">,</span>
  <span class="pl-smi">ShoppingCart</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'../page-objects'</span><span class="pl-kos">;</span>
<span class="pl-c">// support</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">cleanUp</span><span class="pl-kos">,</span> <span class="pl-s1">getState</span><span class="pl-kos">,</span> <span class="pl-s1">sendResults</span><span class="pl-kos">,</span> <span class="pl-s1">setUp</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'../support'</span><span class="pl-kos">;</span>
<span class="pl-c">// test data</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span>
  <span class="pl-s1">adidasBackpack</span><span class="pl-kos">,</span>
  <span class="pl-s1">ccDetailsTestCard</span><span class="pl-kos">,</span>
  <span class="pl-s1">plushToy</span><span class="pl-kos">,</span>
  <span class="pl-s1">staticUSShippingDetails</span><span class="pl-kos">,</span>
<span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'../test-data'</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">'serial'</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">'Order Confirmation'</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-k">const</span> <span class="pl-s1">cartedSession</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">CartedSession</span><span class="pl-kos">(</span><span class="pl-s">'order-confirmation'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">page</span>: <span class="pl-smi">Page</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">testBrowser</span>: <span class="pl-smi">Browser</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">cart</span>: <span class="pl-smi">ShoppingCart</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">floatingCartButton</span>: <span class="pl-smi">FloatingCartButton</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">payment</span>: <span class="pl-smi">CreditCard</span><span class="pl-kos">;</span>
  <span class="pl-k">let</span> <span class="pl-s1">orderStatus</span>: <span class="pl-smi">OrderStatusCard</span><span class="pl-kos">;</span>

  <span class="pl-s1">test</span><span class="pl-kos">.</span><span class="pl-en">beforeAll</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> browser <span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-c">// use the GraphAPI directly set session state, loading needed fixtures (if any)</span>
    <span class="pl-c">// all these requests happens before the browser even opens, so we can seed some state</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">loadFixture</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-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">fetchProduct</span><span class="pl-kos">(</span><span class="pl-s1">plushToy</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">fetchProduct</span><span class="pl-kos">(</span><span class="pl-s1">adidasBackpack</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">addToCart</span><span class="pl-kos">(</span><span class="pl-s1">plushToy</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">addToCart</span><span class="pl-kos">(</span><span class="pl-s1">adidasBackpack</span><span class="pl-kos">,</span> <span class="pl-c1">2</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">startCheckout</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-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">setAddress</span><span class="pl-kos">(</span><span class="pl-s1">staticUSShippingDetails</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-en">setShippingOptions</span><span class="pl-kos">(</span><span class="pl-kos">[</span>
      <span class="pl-kos">{</span> <span class="pl-c1">vendorName</span>: <span class="pl-s1">plushToy</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">,</span> <span class="pl-c1">label</span>: <span class="pl-s">'Economy'</span> <span class="pl-kos">}</span><span class="pl-kos">,</span>
      <span class="pl-kos">{</span> <span class="pl-c1">vendorName</span>: <span class="pl-s1">adidasBackpack</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">,</span> <span class="pl-c1">label</span>: <span class="pl-s">'Standard'</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">// fetch local storage state object</span>
    <span class="pl-k">const</span> <span class="pl-s1">state</span> <span class="pl-c1">=</span> <span class="pl-en">getState</span><span class="pl-kos">(</span><span class="pl-kos">[</span><span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-c1">localStorageObject</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">const</span> <span class="pl-s1">mockOptions</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">fixtureName</span>: <span class="pl-s">'order-confirmation'</span><span class="pl-kos">,</span>
      <span class="pl-c1">storageState</span>: <span class="pl-s1">state</span><span class="pl-kos">,</span>
      <span class="pl-c1">sessionId</span>: <span class="pl-s1">cartedSession</span><span class="pl-kos">.</span><span class="pl-c1">sessionId</span><span class="pl-kos">,</span>
    <span class="pl-kos">}</span><span class="pl-kos">;</span>

    <span class="pl-c">// now we create a page and setup calls</span>
    <span class="pl-c">// browser.newPage({ storageState }) at some point</span>
    <span class="pl-kos">[</span><span class="pl-s1">page</span><span class="pl-kos">,</span> <span class="pl-s1">testBrowser</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-en">setUp</span><span class="pl-kos">(</span><span class="pl-s1">browser</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</span><span class="pl-kos">,</span> <span class="pl-s1">mockOptions</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-c">// init page objects</span>
    <span class="pl-s1">cart</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">ShoppingCart</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-s1">floatingCartButton</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">FloatingCartButton</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-s1">payment</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">CreditCard</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-s1">orderStatus</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">OrderStatusCard</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-c">// launch the browser, open the cart, confirm payment</span>
    <span class="pl-k">await</span> <span class="pl-s1">payment</span><span class="pl-kos">.</span><span class="pl-en">open</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-s1">floatingCartButton</span><span class="pl-kos">.</span><span class="pl-en">openCart</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-s1">payment</span><span class="pl-kos">.</span><span class="pl-en">enterCreditCardDetails</span><span class="pl-kos">(</span><span class="pl-s1">ccDetailsTestCard</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">await</span> <span class="pl-s1">cart</span><span class="pl-kos">.</span><span class="pl-en">confirmPurchase</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">afterEach</span><span class="pl-kos">(</span><span class="pl-k">async</span> <span class="pl-kos">(</span><span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</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">sendResults</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">,</span> <span class="pl-s1">testInfo</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">afterAll</span><span class="pl-kos">(</span><span class="pl-k">async</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">=&gt;</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-en">cleanUp</span><span class="pl-kos">(</span><span class="pl-s1">page</span><span class="pl-kos">,</span> <span class="pl-s1">testBrowser</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">fixtureName</span>: <span class="pl-s">'order-confirmation'</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">'shows the order confrimation header'</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">confirmationHeader</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">'displays correct email in thank you summary'</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">emailSummary</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toContainText</span><span class="pl-kos">(</span>
      <span class="pl-s1">staticUSShippingDetails</span><span class="pl-kos">.</span><span class="pl-c1">email</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">'displays Order Placed for the first item'</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-c">// set order status card to equal plushtoy vendor</span>
    <span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">merchantName</span> <span class="pl-c1">=</span> <span class="pl-s1">plushToy</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">;</span>
    <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">badge</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveText</span><span class="pl-kos">(</span><span class="pl-s">'Order Placed'</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">'displays correct title for first item'</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">title</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveText</span><span class="pl-kos">(</span><span class="pl-s1">plushToy</span><span class="pl-kos">.</span><span class="pl-c1">title</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">fixme</span><span class="pl-kos">(</span><span class="pl-s">'displays correct image for first item '</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">image</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-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">'displays correct vendor name for first item '</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toContainText</span><span class="pl-kos">(</span><span class="pl-s1">plushToy</span><span class="pl-kos">.</span><span class="pl-c1">vendor</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">'displays Order Placed for the second item'</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-c">// set order status card to equal backpack vendor</span>
    <span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">merchantName</span> <span class="pl-c1">=</span> <span class="pl-s1">adidasBackpack</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">;</span>
    <span class="pl-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">badge</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveText</span><span class="pl-kos">(</span><span class="pl-s">'Order Placed'</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">'displays correct title for second item'</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">title</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toHaveText</span><span class="pl-kos">(</span><span class="pl-s1">adidasBackpack</span><span class="pl-kos">.</span><span class="pl-c1">title</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">'displays correct vendor name for second item '</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">vendor</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toContainText</span><span class="pl-kos">(</span><span class="pl-s1">adidasBackpack</span><span class="pl-kos">.</span><span class="pl-c1">vendor</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-s1">test</span><span class="pl-kos">.</span><span class="pl-en">fixme</span><span class="pl-kos">(</span><span class="pl-s">'displays correct image for second item '</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-en">expect</span><span class="pl-kos">(</span><span class="pl-s1">orderStatus</span><span class="pl-kos">.</span><span class="pl-c1">image</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-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">index.html</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;meta name=&quot;description&quot; content=&quot;Test File&quot; /&gt;
    &lt;title&gt;Publisher Page&lt;/title&gt;
    &lt;script&gt;
      // if thing defined don't overwrite it
      if (!window['thing']) {
          window['thing'] = {
          environment: 'sandbox',
          apiKey: 'default',
          onMessage: console.debug,
          displayName: 'PlayWright Tester',
        };
      }
      // actual index test file imports a module using scripts src='url' defer
      // this module registers a custom component which calls our graphQL api 
  &lt;/script&gt;
    &lt;style&gt;
      * { box-sizing: border-box; }
      body { margin: 0; padding: 2rem; }
      main { max-width: min(100%, 58rem); margin: 0 auto; }
      carted-product-card { contain: size layout paint; }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;main&gt;
      &lt;article&gt;

        &lt;h2&gt;Hello world!&lt;/h2&gt;
        &lt;p&gt;This is me, life can be: fun for everyone&lt;/p&gt;
        &lt;custom-component src='url'&gt;&lt;/custom-component&gt;
      &lt;/article&gt;
    &lt;/main&gt;
  &lt;/body&gt;
&lt;/html&gt;"><pre class="notranslate"><span class="pl-c1">&lt;!DOCTYPE html<span class="pl-kos">&gt;</span></span>
<span class="pl-kos">&lt;</span><span class="pl-ent">html</span> <span class="pl-c1">lang</span>="<span class="pl-s">en</span>"<span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">head</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">meta</span> <span class="pl-c1">charset</span>="<span class="pl-s">utf-8</span>" /&gt;
    <span class="pl-kos">&lt;</span><span class="pl-ent">meta</span> <span class="pl-c1">http-equiv</span>="<span class="pl-s">X-UA-Compatible</span>" <span class="pl-c1">content</span>="<span class="pl-s">IE=edge</span>" /&gt;
    <span class="pl-kos">&lt;</span><span class="pl-ent">meta</span> <span class="pl-c1">name</span>="<span class="pl-s">viewport</span>" <span class="pl-c1">content</span>="<span class="pl-s">width=device-width, initial-scale=1.0</span>" /&gt;
    <span class="pl-kos">&lt;</span><span class="pl-ent">meta</span> <span class="pl-c1">name</span>="<span class="pl-s">description</span>" <span class="pl-c1">content</span>="<span class="pl-s">Test File</span>" /&gt;
    <span class="pl-kos">&lt;</span><span class="pl-ent">title</span><span class="pl-kos">&gt;</span>Publisher Page<span class="pl-kos">&lt;/</span><span class="pl-ent">title</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">script</span><span class="pl-kos">&gt;</span>
      <span class="pl-c">// if thing defined don't overwrite it</span>
      <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-smi">window</span><span class="pl-kos">[</span><span class="pl-s">'thing'</span><span class="pl-kos">]</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
          <span class="pl-smi">window</span><span class="pl-kos">[</span><span class="pl-s">'thing'</span><span class="pl-kos">]</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
          <span class="pl-c1">environment</span>: <span class="pl-s">'sandbox'</span><span class="pl-kos">,</span>
          <span class="pl-c1">apiKey</span>: <span class="pl-s">'default'</span><span class="pl-kos">,</span>
          <span class="pl-c1">onMessage</span>: <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-c1">debug</span><span class="pl-kos">,</span>
          <span class="pl-c1">displayName</span>: <span class="pl-s">'PlayWright Tester'</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">// actual index test file imports a module using scripts src='url' defer</span>
      <span class="pl-c">// this module registers a custom component which calls our graphQL api </span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">script</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">style</span><span class="pl-kos">&gt;</span>
      <span class="pl-ent"><span class="pl-c1">*</span></span> { <span class="pl-c1">box-sizing</span><span class="pl-kos">:</span> border-box; }
      <span class="pl-ent">body</span> { <span class="pl-c1">margin</span><span class="pl-kos">:</span> <span class="pl-c1">0</span>; <span class="pl-c1">padding</span><span class="pl-kos">:</span> <span class="pl-c1">2<span class="pl-smi">rem</span></span>; }
      <span class="pl-ent">main</span> { <span class="pl-c1">max-width</span><span class="pl-kos">:</span> <span class="pl-en">min</span>(<span class="pl-c1">100<span class="pl-smi">%</span></span><span class="pl-kos">,</span> <span class="pl-c1">58<span class="pl-smi">rem</span></span>); <span class="pl-c1">margin</span><span class="pl-kos">:</span> <span class="pl-c1">0</span> auto; }
      <span class="pl-ent">carted-product-card</span> { <span class="pl-c1">contain</span><span class="pl-kos">:</span> size layout paint; }
    <span class="pl-kos">&lt;/</span><span class="pl-ent">style</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">head</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;</span><span class="pl-ent">body</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;</span><span class="pl-ent">main</span><span class="pl-kos">&gt;</span>
      <span class="pl-kos">&lt;</span><span class="pl-ent">article</span><span class="pl-kos">&gt;</span>

        <span class="pl-kos">&lt;</span><span class="pl-ent">h2</span><span class="pl-kos">&gt;</span>Hello world!<span class="pl-kos">&lt;/</span><span class="pl-ent">h2</span><span class="pl-kos">&gt;</span>
        <span class="pl-kos">&lt;</span><span class="pl-ent">p</span><span class="pl-kos">&gt;</span>This is me, life can be: fun for everyone<span class="pl-kos">&lt;/</span><span class="pl-ent">p</span><span class="pl-kos">&gt;</span>
        <span class="pl-kos">&lt;</span><span class="pl-ent">custom-component</span> <span class="pl-c1">src</span>='<span class="pl-s">url</span>'<span class="pl-kos">&gt;</span><span class="pl-kos">&lt;/</span><span class="pl-ent">custom-component</span><span class="pl-kos">&gt;</span>
      <span class="pl-kos">&lt;/</span><span class="pl-ent">article</span><span class="pl-kos">&gt;</span>
    <span class="pl-kos">&lt;/</span><span class="pl-ent">main</span><span class="pl-kos">&gt;</span>
  <span class="pl-kos">&lt;/</span><span class="pl-ent">body</span><span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;/</span><span class="pl-ent">html</span><span class="pl-kos">&gt;</span></pre></div>
<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
import type { PlaywrightTestConfig } from '@playwright/test';
import dotenv from 'dotenv';

// read .env file values
dotenv.config();

// this config sets the browserstack env var to false
process.env.BROWSERSTACK = 'false';

const config: PlaywrightTestConfig = {
  name: 'Local Config',
  globalSetup: './playwright/global-setup.ts', // only thing this does is remove all files in the dist directory
  testDir: './playwright/integration',
  timeout: 100_000,
  reporter: [['html', { outputFolder: 'dist/playwright/reports' }]],
  outputDir: 'dist/playwright/test-results/',
  retries: 0,
  expect: {
    timeout: 10_000,
    toHaveScreenshot: {
      threshold: 0.2,
      maxDiffPixelRatio: 0.1,
      maxDiffPixels: 5,
    },
  },
  use: {
    actionTimeout: 0,
    screenshot: 'only-on-failure',
    trace: 'on',
    video: 'off',
    contextOptions: {
      recordVideo: {
        dir: 'dist/playwright/videos',
      },
    },
  },
  projects: [
    {
      name: 'chromium',
      use: {
        browserName: 'chromium',
        channel: 'chromium',
      },
    },
  ],
};

export default config;
});"><pre class="notranslate"><span class="pl-c">// playwright.config.ts</span>
<span class="pl-k">import</span> <span class="pl-s1">type</span> <span class="pl-kos">{</span> <span class="pl-v">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-s1">dotenv</span> <span class="pl-k">from</span> <span class="pl-s">'dotenv'</span><span class="pl-kos">;</span>

<span class="pl-c">// read .env file values</span>
<span class="pl-s1">dotenv</span><span class="pl-kos">.</span><span class="pl-en">config</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// this config sets the browserstack env var to false</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">BROWSERSTACK</span> <span class="pl-c1">=</span> <span class="pl-s">'false'</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-s1">config</span>: <span class="pl-v">PlaywrightTestConfig</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  <span class="pl-c1">name</span>: <span class="pl-s">'Local Config'</span><span class="pl-kos">,</span>
  <span class="pl-c1">globalSetup</span>: <span class="pl-s">'./playwright/global-setup.ts'</span><span class="pl-kos">,</span> <span class="pl-c">// only thing this does is remove all files in the dist directory</span>
  <span class="pl-c1">testDir</span>: <span class="pl-s">'./playwright/integration'</span><span class="pl-kos">,</span>
  <span class="pl-c1">timeout</span>: <span class="pl-c1">100_000</span><span class="pl-kos">,</span>
  <span class="pl-c1">reporter</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-c1">outputFolder</span>: <span class="pl-s">'dist/playwright/reports'</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">outputDir</span>: <span class="pl-s">'dist/playwright/test-results/'</span><span class="pl-kos">,</span>
  <span class="pl-c1">retries</span>: <span class="pl-c1">0</span><span class="pl-kos">,</span>
  <span class="pl-c1">expect</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">timeout</span>: <span class="pl-c1">10_000</span><span class="pl-kos">,</span>
    <span class="pl-c1">toHaveScreenshot</span>: <span class="pl-kos">{</span>
      <span class="pl-c1">threshold</span>: <span class="pl-c1">0.2</span><span class="pl-kos">,</span>
      <span class="pl-c1">maxDiffPixelRatio</span>: <span class="pl-c1">0.1</span><span class="pl-kos">,</span>
      <span class="pl-c1">maxDiffPixels</span>: <span class="pl-c1">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-c1">use</span>: <span class="pl-kos">{</span>
    <span class="pl-c1">actionTimeout</span>: <span class="pl-c1">0</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-c1">trace</span>: <span class="pl-s">'on'</span><span class="pl-kos">,</span>
    <span class="pl-c1">video</span>: <span class="pl-s">'off'</span><span class="pl-kos">,</span>
    <span class="pl-c1">contextOptions</span>: <span class="pl-kos">{</span>
      <span class="pl-c1">recordVideo</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">dir</span>: <span class="pl-s">'dist/playwright/videos'</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">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-c1">browserName</span>: <span class="pl-s">'chromium'</span><span class="pl-kos">,</span>
        <span class="pl-c1">channel</span>: <span class="pl-s">'chromium'</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-k">export</span> <span class="pl-k">default</span> <span class="pl-s1">config</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>Steps</strong></p>
<ol dir="auto">
<li>Run the test</li>
<li>I rarely see this bug occur when running a single test, create a bunch of dummy test files and run them in parallel to boost the chances of seeing the bug</li>
</ol>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">No "page goto failed: page was closed error" is thrown</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Fails 33% of the time on my machine. I don't know for sure but after verifying the valid load state <a href="https://github.com/microsoft/playwright/blob/10ce7af411edf5c31a4e81fd0f96bfde47de8c24/packages/playwright-core/src/client/frame.ts#L457">here</a> it seems like eventually the private server <a href="https://github.com/microsoft/playwright/blob/10ce7af411edf5c31a4e81fd0f96bfde47de8c24/packages/playwright-core/src/server/frames.ts#L657">_goToAction</a> method will be called, which on line <a href="https://github.com/microsoft/playwright/blob/10ce7af411edf5c31a4e81fd0f96bfde47de8c24/packages/playwright-core/src/server/frames.ts#L693">693</a> awaits an extra <code class="notranslate">LifecycleEvent</code> event promise.</p>
<p dir="auto">My suspicion is that the file protocol is behaving differently (due to how the browser treats local html files) - or that it is perhaps just faster than the typical http/https file that, under normal circumstances, is served up by a server which is therefore exposing some raciness.</p>
<p dir="auto">Mileage may vary, I believe the above code reproduces the issue, I had to take a whole lot of IP and other work related stuff out that over complicates things, but wanted to leave stuff like <code class="notranslate">dotenv</code> to mirror our code as close as possible.</p>
<p dir="auto">What I can confirm is that setting the wait until option to <code class="notranslate">commit</code> fixes the issue for us.</p>