<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: 1.36.0</li>
<li>Operating System: macOS 13.0</li>
<li>Browser: Chromium</li>
<li>Other info: Running on Google Chrome</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>Script</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import {chromium } from 'playwright'

(async () =&gt; {
    console.log('connecting');
    const browser = await chromium.connectOverCDP('http://localhost:9222');
    console.log('connected');
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto('https://news.ycombinator.com');
   
    browser.on('disconnected', () =&gt; {
        console.log('disconnected');
    });
})();"><pre class="notranslate"><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-k">from</span> <span class="pl-s">'playwright'</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-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'connecting'</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">connectOverCDP</span><span class="pl-kos">(</span><span class="pl-s">'http://localhost:9222'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'connected'</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">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">'https://news.ycombinator.com'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
   
    <span class="pl-s1">browser</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">'disconnected'</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-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s">'disconnected'</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>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from playwright.sync_api import sync_playwright
from playwright._impl._browser import Browser, prepare_browser_context_params


print('starting')

def run(playwright):
    print('connecting')
    chromium = playwright.chromium
    browser = chromium.connect_over_cdp('ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29')
    print('connected')
    
    context = browser.new_context()
    page = context.new_page()
    page.goto('https://harvard.edu')

with sync_playwright() as playwright:
    run(playwright)"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">playwright</span>.<span class="pl-s1">sync_api</span> <span class="pl-k">import</span> <span class="pl-s1">sync_playwright</span>
<span class="pl-k">from</span> <span class="pl-s1">playwright</span>.<span class="pl-s1">_impl</span>.<span class="pl-s1">_browser</span> <span class="pl-k">import</span> <span class="pl-v">Browser</span>, <span class="pl-s1">prepare_browser_context_params</span>


<span class="pl-en">print</span>(<span class="pl-s">'starting'</span>)

<span class="pl-k">def</span> <span class="pl-en">run</span>(<span class="pl-s1">playwright</span>):
    <span class="pl-en">print</span>(<span class="pl-s">'connecting'</span>)
    <span class="pl-s1">chromium</span> <span class="pl-c1">=</span> <span class="pl-s1">playwright</span>.<span class="pl-s1">chromium</span>
    <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-s1">chromium</span>.<span class="pl-en">connect_over_cdp</span>(<span class="pl-s">'ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29'</span>)
    <span class="pl-en">print</span>(<span class="pl-s">'connected'</span>)
    
    <span class="pl-s1">context</span> <span class="pl-c1">=</span> <span class="pl-s1">browser</span>.<span class="pl-en">new_context</span>()
    <span class="pl-s1">page</span> <span class="pl-c1">=</span> <span class="pl-s1">context</span>.<span class="pl-en">new_page</span>()
    <span class="pl-s1">page</span>.<span class="pl-en">goto</span>(<span class="pl-s">'https://harvard.edu'</span>)

<span class="pl-k">with</span> <span class="pl-en">sync_playwright</span>() <span class="pl-k">as</span> <span class="pl-s1">playwright</span>:
    <span class="pl-en">run</span>(<span class="pl-s1">playwright</span>)</pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li><code class="notranslate">open -a "Google Chrome" --args --profile-directory=Default --remote-debugging-port=9222</code></li>
<li>
<ul dir="auto">
<li>Leave the chrome open for 12hrs+`</li>
</ul>
</li>
<li>visit localhost:9222 and get CDP Url</li>
<li>Run python or js script</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">Playwright scripts connect to available CDP port and executes.</p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">Playwright scripts cannot connect and timeout. Browser able to display remote debugging port info and receive CDP commands:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
   &quot;Browser&quot;: &quot;Chrome/114.0.5735.198&quot;,
   &quot;Protocol-Version&quot;: &quot;1.3&quot;,
   &quot;User-Agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36&quot;,
   &quot;V8-Version&quot;: &quot;11.4.183.25&quot;,
   &quot;WebKit-Version&quot;: &quot;537.36 (@c3029382d11c5f499e4fc317353a43d411a5ce1c)&quot;,
   &quot;webSocketDebuggerUrl&quot;: &quot;ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29&quot;
}"><pre class="notranslate"><code class="notranslate">{
   "Browser": "Chrome/114.0.5735.198",
   "Protocol-Version": "1.3",
   "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
   "V8-Version": "11.4.183.25",
   "WebKit-Version": "537.36 (@c3029382d11c5f499e4fc317353a43d411a5ce1c)",
   "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29"
}
</code></pre></div>
<p dir="auto">this works without any issues, but playwright scripts don't work.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import WebSocket from 'ws';
const client = new WebSocket(
    'ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29'
);
client.on('open', function open() {
    client.send(
    JSON.stringify({
        id: 1, // Unique identifier for the request
        method: 'Target.createTarget',
        params: {
        url: 'https://yale.edu' // URL of the new target
        }
    })
    );
});
client.on('message', function incoming(data) {
    console.log(data);
});"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-v">WebSocket</span> <span class="pl-k">from</span> <span class="pl-s">'ws'</span><span class="pl-kos">;</span>
<span class="pl-k">const</span> <span class="pl-s1">client</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">WebSocket</span><span class="pl-kos">(</span>
    <span class="pl-s">'ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29'</span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-s1">client</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">'open'</span><span class="pl-kos">,</span> <span class="pl-k">function</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-s1">client</span><span class="pl-kos">.</span><span class="pl-en">send</span><span class="pl-kos">(</span>
    <span class="pl-c1">JSON</span><span class="pl-kos">.</span><span class="pl-en">stringify</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
        <span class="pl-c1">id</span>: <span class="pl-c1">1</span><span class="pl-kos">,</span> <span class="pl-c">// Unique identifier for the request</span>
        <span class="pl-c1">method</span>: <span class="pl-s">'Target.createTarget'</span><span class="pl-kos">,</span>
        <span class="pl-c1">params</span>: <span class="pl-kos">{</span>
        <span class="pl-c1">url</span>: <span class="pl-s">'https://yale.edu'</span> <span class="pl-c">// URL of the new target</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-s1">client</span><span class="pl-kos">.</span><span class="pl-en">on</span><span class="pl-kos">(</span><span class="pl-s">'message'</span><span class="pl-kos">,</span> <span class="pl-k">function</span> <span class="pl-en">incoming</span><span class="pl-kos">(</span><span class="pl-s1">data</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">data</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">the playwright python script throws this error</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="(tmp-cdp) ➜  playwright-connect python playwright-test.py 
starting
connecting
Traceback (most recent call last):
  File &quot;/Users/harshg/code/playwright-connect/playwright-test.py&quot;, line 15, in &lt;module&gt;
    run(playwright)
  File &quot;/Users/harshg/code/playwright-connect/playwright-test.py&quot;, line 8, in run
    browser = chromium.connect_over_cdp('ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29')
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/sync_api/_generated.py&quot;, line 15094, in connect_over_cdp
    self._sync(
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_sync_base.py&quot;, line 109, in _sync
    return task.result()
           ^^^^^^^^^^^^^
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_browser_type.py&quot;, line 172, in connect_over_cdp
    response = await self._channel.send_return_as_dict(&quot;connectOverCDP&quot;, params)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py&quot;, line 66, in send_return_as_dict
    return await self._connection.wrap_api_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py&quot;, line 482, in wrap_api_call
    return await cb()
           ^^^^^^^^^^
  File &quot;/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py&quot;, line 97, in inner_send
    result = next(iter(done)).result()
             ^^^^^^^^^^^^^^^^^^^^^^^^^
playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
=========================== logs ===========================
&lt;ws connecting&gt; ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29
&lt;ws connected&gt; ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29
============================================================"><pre class="notranslate"><code class="notranslate">(tmp-cdp) ➜  playwright-connect python playwright-test.py 
starting
connecting
Traceback (most recent call last):
  File "/Users/harshg/code/playwright-connect/playwright-test.py", line 15, in &lt;module&gt;
    run(playwright)
  File "/Users/harshg/code/playwright-connect/playwright-test.py", line 8, in run
    browser = chromium.connect_over_cdp('ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29')
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/sync_api/_generated.py", line 15094, in connect_over_cdp
    self._sync(
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_sync_base.py", line 109, in _sync
    return task.result()
           ^^^^^^^^^^^^^
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_browser_type.py", line 172, in connect_over_cdp
    response = await self._channel.send_return_as_dict("connectOverCDP", params)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py", line 66, in send_return_as_dict
    return await self._connection.wrap_api_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py", line 482, in wrap_api_call
    return await cb()
           ^^^^^^^^^^
  File "/Users/harshg/miniconda3/envs/tmp-cdp/lib/python3.11/site-packages/playwright/_impl/_connection.py", line 97, in inner_send
    result = next(iter(done)).result()
             ^^^^^^^^^^^^^^^^^^^^^^^^^
playwright._impl._api_types.TimeoutError: Timeout 30000ms exceeded.
=========================== logs ===========================
&lt;ws connecting&gt; ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29
&lt;ws connected&gt; ws://localhost:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29
============================================================
</code></pre></div>
<p dir="auto">Other info:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import puppeteer from 'puppeteer-core';

(async () =&gt; {
    const browser = await puppeteer.connect({
        browserWSEndpoint: 'ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29'
    });
    const newPage = await browser.newPage();
    await newPage.goto('https://harvard.edu');
})();"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">puppeteer</span> <span class="pl-k">from</span> <span class="pl-s">'puppeteer-core'</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">const</span> <span class="pl-s1">browser</span> <span class="pl-c1">=</span> <span class="pl-k">await</span> <span class="pl-s1">puppeteer</span><span class="pl-kos">.</span><span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
        <span class="pl-c1">browserWSEndpoint</span>: <span class="pl-s">'ws://127.0.0.1:9222/devtools/browser/7f40aaee-1efb-4dc1-9e80-c6e3063c7e29'</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">newPage</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">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">newPage</span><span class="pl-kos">.</span><span class="pl-en">goto</span><span class="pl-kos">(</span><span class="pl-s">'https://harvard.edu'</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">This puppeteer script is able to connect sporadically. Tried running 20 times, connected 4 times.</p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: [v1.34.0]</li>
<li>Operating System: [All]</li>
<li>Browser: [All]</li>
</ul>
<h3 dir="auto">Source code</h3>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="public async waitWidgetsLoaded(seconds: number) {
        const loadingDots = await this.widgetRefreshOverlay.all();
        for (const dot of loadingDots) {
            await dot.waitFor({ state: 'hidden', timeout: seconds * 1000 });
        }
        for (const dot of loadingDots) {
            await expect(async () =&gt; {
                const isDotContainsAttribute = (await dot.getAttribute('class'))!.includes('widget-loading');
                expect(isDotContainsAttribute).toBeFalsy();
            }).toPass({ timeout: seconds * 1000, intervals: [0.1 * 1000] });
        }
    }"><pre class="notranslate"><code class="notranslate">public async waitWidgetsLoaded(seconds: number) {
        const loadingDots = await this.widgetRefreshOverlay.all();
        for (const dot of loadingDots) {
            await dot.waitFor({ state: 'hidden', timeout: seconds * 1000 });
        }
        for (const dot of loadingDots) {
            await expect(async () =&gt; {
                const isDotContainsAttribute = (await dot.getAttribute('class'))!.includes('widget-loading');
                expect(isDotContainsAttribute).toBeFalsy();
            }).toPass({ timeout: seconds * 1000, intervals: [0.1 * 1000] });
        }
    }
</code></pre></div>
<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>[Run the test] that contains step with polling</li>
</ul>
<p dir="auto">Note: polling triggers several times in period of time (condition <strong>is passed</strong> and it's passed <strong>not on 1st polling call</strong>)</p>
<p dir="auto"><strong>Expected</strong><br>
Step with polling is marked as <strong>passed</strong> (Green checkmark) in the html report</p>
<p dir="auto"><strong>Actual</strong><br>
Step with polling is marked as <strong>failed</strong> (Red checkmark) in the html report</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/13851264/241193978-c0e5447a-65b9-4703-a3d6-d21004c4ad07.png"><img src="https://user-images.githubusercontent.com/13851264/241193978-c0e5447a-65b9-4703-a3d6-d21004c4ad07.png" alt="image" style="max-width: 100%;"></a></p>