-
Notifications
You must be signed in to change notification settings - Fork 107
Description
I face an issue when navigating to a website while being attached to the page.
simple demo:
import { crx } from './playwright-crx/lib/index.mjs';
const urls = {
// with service worker
amazon: 'https://www.amazon.com/',
// without service worker
shufersal: 'https://www.shufersal.co.il/online/he/search?text=%D7%97%D7%9C%D7%91',
// with service worker
servicenow: 'some-service-now-id(removed mine privacywise)'
};
let crxApp = null;
async function navigateTo(url) {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (!tab) return;
// Start crx if not already started
console.log('Starting crx');
if (!crxApp) {
crxApp = await crx.start({ slowMo: 0 });
}
// Attach to tab
console.log('Attaching to tab');
const page = await crxApp.attach(tab.id);
console.log('Attached to tab');
// Navigate using chrome.tabs API
console.log('Navigating to url');
await chrome.tabs.update(tab.id, { url });
console.log('Navigated to url');
// (Optional: use `page` for any Playwright automation here)
// Detach when done
console.log('Detaching from tab');
await crxApp.detach(tab.id);
console.log('Detached from tab');
}
document.getElementById('amazon').addEventListener('click', () => {
navigateTo(urls.amazon);
});
document.getElementById('shufersal').addEventListener('click', () => {
navigateTo(urls.shufersal);
});
document.getElementById('servicenow').addEventListener('click', () => {
navigateTo(urls.servicenow);
});I think I found out the root cause.
Its in CrxTransport.ts file, in line 93 when excluding the service worker:
else if (message.method === 'Target.setAutoAttach') {
const [, versionStr] = navigator.userAgent.match(/Chrome\/([0-9]+)./) ?? [];
// we need to exclude service workers, see:
// https://github.com/ruifigueira/playwright-crx/issues/1
// https://chromedevtools.github.io/devtools-protocol/tot/Target/#method-setAutoAttach
result = await this._send(debuggee, message.method, { ...message.params, filter: [
{ exclude: true, type: 'service_worker' },
// and these are the defaults:
// https://chromedevtools.github.io/devtools-protocol/tot/Target/#type-TargetFilter
{ exclude: true, type: 'browser' },
{ exclude: true, type: 'tab' },
// in versions prior to 126, this fallback doesn't work,
// but it is necessary for oopif frames to be discoverable in version 126 or greater
...(versionStr && parseInt(versionStr, 10) >= 126 ? [{}] : []),
] });
}This setAutoAttach is running with waitForDebuggerOnStart: true option, That causes all the auto attached targets to wait for a Runtime.runIfWaitingForDebugger command. Playwright sends those commands after a setup he does (adding inspectors to the target etc...).
The issue is when excluding a target type, for some reason the target is still waiting for runIfWaitingForDebugger! Seems like a Chrome Debugger API bug actually.
So, when excluding the service_worker type but sending the Target.setAutoAttach, with waitForDebuggerOnStart: true, we are facing the issue and it looks like the tab is being stuck with a loading state, and the page is not changing. because the service_worker is waiting for runIfWaitingForDebugger, but it will never get it so it will never be loaded. and because we are waiting for all "child" targets (even the excluded - the chrome bug), we are waiting for the service_worker.
After a minute or two it gets a timeout and it continues as usual.
I found out that removing the "{ exclude: true, type: 'service_worker' }," in CrxTransport.ts file will solve the issue because in that way the service_worker will notify with runIfWaitingForDebugger.
I saw that the same line actually solve some issue in the past but I dont really get it... (#1), maybe its irrelevant today.
Would love to hear from you,
Thanks anyway :)