<p dir="auto"><strong>Context:</strong></p>
<ul dir="auto">
<li>Playwright Version: 1.2.1</li>
<li>Operating System: Mac</li>
<li>Node version: 12.14.1</li>
<li>Browser: Firefox, Webkit</li>
</ul>
<p dir="auto"><strong>Code Snippet</strong><br>
<a href="https://github.com/benoitjchevalier/playwright-focus">https://github.com/benoitjchevalier/playwright-focus</a></p>
<p dir="auto">npm install<br>
node run.js</p>
<p dir="auto">Observe lack of focus ring on some FF screenshots</p>
<p dir="auto"><strong>Describe the bug</strong></p>
<p dir="auto">Hello there <g-emoji class="g-emoji" alias="wave" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f44b.png">👋</g-emoji> . We're building an in-house visual regression tool using playwright which has been a huge help for us. I've recently come across an edge case on Firefox and sometimes Webkit.</p>
<p dir="auto">When running multiple pages (each with a unique context) of the same browser in parallel and taking screenshots of a focused element then on FF the screenshot will miss the focus ring.</p>
<p dir="auto">Chrome always behaves and I've seen rare occurrences where webkit would also suffer from the focusringlessness.<br>
The element itself is correctly identified as active by the browser when testing through <code class="notranslate">element === (document|shadowRoot).activeElement</code>, before and after the screenshot.</p>
<p dir="auto">I've created a small repro in the above repo. Please note that this repo does everything from the node context where our tool runs the tests in the browser context and the notifies the node context when a screenshot should be taken. So the difference is that we focus from the browser context where the reproduction focuses from the playwright elementHandle. That said the results are similar.</p>
<p dir="auto">I'm hoping this can be fixed at the playwright level and isn't a limitation at the browser level :)</p>
<p dir="auto"><strong>Context:</strong></p>
<ul dir="auto">
<li>Playwright Version: 1.3.0</li>
<li>Operating System: Linux/Docker</li>
<li>Node.js version: 14</li>
<li>Browser: Firefox</li>
<li>Extra: <a href="https://try.playwright.tech/?s=nsosu" rel="nofollow">https://try.playwright.tech/?s=nsosu</a></li>
</ul>
<p dir="auto"><strong>Code Snippet</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// @ts-check
const playwright = require(&quot;playwright&quot;);

(async () =&gt; {
  for (const browserType of ['chromium', 'webkit', 'firefox']) {
    /** @type {import('playwright').Browser} */
    const browser = await playwright[browserType].launch();
    const page1 = await (await browser.newContext()).newPage();
    const page2 = await (await browser.newContext()).newPage();
    await page1.setContent(`&lt;button id=&quot;foo&quot; onfocus=&quot;window.gotFocus=true&quot;&gt;foo&lt;/button&gt;`)
    await page2.setContent(`&lt;button id=&quot;foo&quot; onfocus=&quot;window.gotFocus=true&quot;&gt;foo&lt;/button&gt;`)
    await page1.focus(&quot;#foo&quot;)
    await page2.focus(&quot;#foo&quot;)
    console.log(browserType, &quot;page1&quot;, await page1.evaluate(() =&gt; !!window[&quot;gotFocus&quot;]))
    console.log(browserType, &quot;page2&quot;, await page2.evaluate(() =&gt; !!window[&quot;gotFocus&quot;]))
    await browser.close();
  }
})();"><pre class="notranslate"><span class="pl-c">// <span class="pl-k">@ts</span>-check</span>
<span class="pl-k">const</span> <span class="pl-s1">playwright</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"playwright"</span><span class="pl-kos">)</span><span class="pl-kos">;</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-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">for</span> <span class="pl-kos">(</span><span class="pl-k">const</span> <span class="pl-s1">browserType</span> <span class="pl-k">of</span> <span class="pl-kos">[</span><span class="pl-s">'chromium'</span><span class="pl-kos">,</span> <span class="pl-s">'webkit'</span><span class="pl-kos">,</span> <span class="pl-s">'firefox'</span><span class="pl-kos">]</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c">/** <span class="pl-k">@type</span> {import('playwright').Browser} */</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">playwright</span><span class="pl-kos">[</span><span class="pl-s1">browserType</span><span class="pl-kos">]</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">page1</span> <span class="pl-c1">=</span> <span class="pl-k">await</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">newContext</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">newPage</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">page2</span> <span class="pl-c1">=</span> <span class="pl-k">await</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">newContext</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">newPage</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">page1</span><span class="pl-kos">.</span><span class="pl-en">setContent</span><span class="pl-kos">(</span><span class="pl-s">`&lt;button id="foo" onfocus="window.gotFocus=true"&gt;foo&lt;/button&gt;`</span><span class="pl-kos">)</span>
    <span class="pl-k">await</span> <span class="pl-s1">page2</span><span class="pl-kos">.</span><span class="pl-en">setContent</span><span class="pl-kos">(</span><span class="pl-s">`&lt;button id="foo" onfocus="window.gotFocus=true"&gt;foo&lt;/button&gt;`</span><span class="pl-kos">)</span>
    <span class="pl-k">await</span> <span class="pl-s1">page1</span><span class="pl-kos">.</span><span class="pl-en">focus</span><span class="pl-kos">(</span><span class="pl-s">"#foo"</span><span class="pl-kos">)</span>
    <span class="pl-k">await</span> <span class="pl-s1">page2</span><span class="pl-kos">.</span><span class="pl-en">focus</span><span class="pl-kos">(</span><span class="pl-s">"#foo"</span><span class="pl-kos">)</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">browserType</span><span class="pl-kos">,</span> <span class="pl-s">"page1"</span><span class="pl-kos">,</span> <span class="pl-k">await</span> <span class="pl-s1">page1</span><span class="pl-kos">.</span><span class="pl-en">evaluate</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-c1">!</span><span class="pl-c1">!</span><span class="pl-smi">window</span><span class="pl-kos">[</span><span class="pl-s">"gotFocus"</span><span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">browserType</span><span class="pl-kos">,</span> <span class="pl-s">"page2"</span><span class="pl-kos">,</span> <span class="pl-k">await</span> <span class="pl-s1">page2</span><span class="pl-kos">.</span><span class="pl-en">evaluate</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-c1">!</span><span class="pl-c1">!</span><span class="pl-smi">window</span><span class="pl-kos">[</span><span class="pl-s">"gotFocus"</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-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Describe the bug</strong></p>
<p dir="auto">Actual: <code class="notranslate">firefox page1 false</code><br>
Expected: <code class="notranslate">firefox page1 true</code></p>
<p dir="auto">Reported via Slack: <a href="https://playwright.slack.com/archives/CSUHZPVLM/p1597434617186900" rel="nofollow">https://playwright.slack.com/archives/CSUHZPVLM/p1597434617186900</a></p>