<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.XX]</li>
<li>Operating System: [All, Windows 11, Ubuntu 20, macOS 13.2, etc.]</li>
<li>Browser: [All, Chromium, Firefox, WebKit]</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>Link to the GitHub repository with the repro</strong></p>
<p dir="auto">[https://github.com/your_profile/playwright_issue_title]</p>
<p dir="auto">or</p>
<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 { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  globalSetup: require.resolve('./global-setup'),
  use: {
    testIdAttribute: 'data-test-id',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'], },
    },
});"><pre class="notranslate"><span class="pl-c">// playwright.config.ts</span>
<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-c1">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">'./global-setup'</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">testIdAttribute</span>: <span class="pl-s">'data-test-id'</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-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-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="// global-setup.ts
import { chromium, expect } from '@playwright/test';

async function globalSetup() {
  const browser = await chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  try {
    await context.tracing.start({ screenshots: true, snapshots: true });
    await page.setContent(
      `&lt;input id='checkbox' data-test-id=&quot;test&quot; type='checkbox'&gt;&lt;/input&gt;`
    );
    await expect(page.getByTestId('test')).toBeVisible(); //unable to find it
    await context.tracing.stop({
      path: './test-results/setup-trace.zip',
    });
    await browser.close();
  } catch (error) {
    await context.tracing.stop({
      path: './test-results/failed-setup-trace.zip',
    });
    await browser.close();
    throw error;
  }
}

export default globalSetup;
"><pre class="notranslate"><span class="pl-c">// global-setup.ts</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">chromium</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">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-k">const</span> <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">chromium</span><span class="pl-kos">.</span><span class="pl-en">launch</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">context</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">newContext</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">page</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-en">newPage</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-k">try</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-c1">tracing</span><span class="pl-kos">.</span><span class="pl-en">start</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">screenshots</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span> <span class="pl-c1">snapshots</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">await</span> <span class="pl-s1">page</span><span class="pl-kos">.</span><span class="pl-en">setContent</span><span class="pl-kos">(</span>
      <span class="pl-s">`&lt;input id='checkbox' data-test-id="test" type='checkbox'&gt;&lt;/input&gt;`</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">getByTestId</span><span class="pl-kos">(</span><span class="pl-s">'test'</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-c">//unable to find it</span>
    <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-c1">tracing</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-c1">path</span>: <span class="pl-s">'./test-results/setup-trace.zip'</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">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">close</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">catch</span> <span class="pl-kos">(</span><span class="pl-s1">error</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">await</span> <span class="pl-s1">context</span><span class="pl-kos">.</span><span class="pl-c1">tracing</span><span class="pl-kos">.</span><span class="pl-en">stop</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-c1">path</span>: <span class="pl-s">'./test-results/failed-setup-trace.zip'</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">await</span> <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">close</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-k">throw</span> <span class="pl-s1">error</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>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>[Run the test]</li>
<li>[...]</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">The global setup should respect the testIdAttribute set in the config file.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">The global setup does not pick up the testIdAttribute set in the config file.</p>
<p dir="auto">use case: in sapui5 applications, there's usually a duplicated invisible version of every element on the page, meaning that to interact with most fields we need to add additional logic to make sure it's getting the right selector:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const handle = (await page.querySelectorAll(selector).find(element =&gt; element.isVisible())
await page.click(handle)"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-s1">handle</span> <span class="pl-c1">=</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">querySelectorAll</span><span class="pl-kos">(</span><span class="pl-s1">selector</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">find</span><span class="pl-kos">(</span><span class="pl-s1">element</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">element</span><span class="pl-kos">.</span><span class="pl-en">isVisible</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">page</span><span class="pl-kos">.</span><span class="pl-en">click</span><span class="pl-kos">(</span><span class="pl-s1">handle</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">it would be nice if there was an option in the methods that take selectors to filter out invisible ones, ie:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="await page.click(selector, {includeInvisible: false})"><pre class="notranslate"><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-s1">selector</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-c1">includeInvisible</span>: <span class="pl-c1">false</span><span class="pl-kos">}</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">or alternatively, if <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="1007324659" data-permission-text="Title is private" data-url="https://github.com/microsoft/playwright/issues/9153" data-hovercard-type="issue" data-hovercard-url="/microsoft/playwright/issues/9153/hovercard" href="https://github.com/microsoft/playwright/issues/9153">#9153</a> is implemented it would be as simple as adding <code class="notranslate">:not(:matches-css(display: none))</code> to the selector</p>