refactor: add sleep utility, reduce extension wait to 1s, add comments for CDP race condition
This commit is contained in:
@@ -5,6 +5,10 @@ import type { ExtensionCommandMessage, ExtensionResponseMessage } from 'playwrit
|
||||
|
||||
const RELAY_URL = 'ws://localhost:19988/extension'
|
||||
|
||||
function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
let ws: WebSocket | null = null
|
||||
let childSessions: Map<string, number> = new Map()
|
||||
let nextSessionId = 1
|
||||
@@ -224,7 +228,7 @@ async function handleCommand(msg: ExtensionCommandMessage): Promise<any> {
|
||||
}
|
||||
try {
|
||||
await chrome.debugger.sendCommand(debuggee, 'Runtime.disable')
|
||||
await new Promise((resolve) => setTimeout(resolve, 200))
|
||||
await sleep(200)
|
||||
} catch (e) {
|
||||
logger.debug('Error disabling Runtime (ignoring):', e)
|
||||
}
|
||||
@@ -237,7 +241,7 @@ async function handleCommand(msg: ExtensionCommandMessage): Promise<any> {
|
||||
const tab = await chrome.tabs.create({ url, active: false })
|
||||
if (!tab.id) throw new Error('Failed to create tab')
|
||||
logger.debug('Created tab:', tab.id, 'waiting for it to load...')
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
await sleep(100)
|
||||
const targetInfo = await attachTab(tab.id)
|
||||
return { targetId: targetInfo.targetId } satisfies Protocol.Target.CreateTargetResponse
|
||||
}
|
||||
@@ -350,7 +354,7 @@ async function attachTab(tabId: number): Promise<Protocol.Target.TargetInfo> {
|
||||
await chrome.debugger.attach(debuggee, '1.3')
|
||||
logger.debug('Debugger attached successfully to tab:', tabId)
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 400))
|
||||
await sleep(400)
|
||||
|
||||
const result = (await chrome.debugger.sendCommand(
|
||||
debuggee,
|
||||
@@ -495,7 +499,7 @@ async function ensureConnection(): Promise<void> {
|
||||
break
|
||||
} catch {
|
||||
logger.debug('Server not available, retrying in 1 second...')
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
await sleep(1000)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-15
@@ -11,7 +11,7 @@ import { fileURLToPath } from 'node:url'
|
||||
import vm from 'node:vm'
|
||||
import dedent from 'string-dedent'
|
||||
import { createPatch } from 'diff'
|
||||
import { getCdpUrl, LOG_FILE_PATH, VERSION } from './utils.js'
|
||||
import { getCdpUrl, LOG_FILE_PATH, VERSION, sleep } from './utils.js'
|
||||
import { killPortProcess } from 'kill-port-process'
|
||||
import { waitForPageLoad, WaitForPageLoadOptions, WaitForPageLoadResult } from './wait-for-page-load.js'
|
||||
import { getCDPSessionForPage, CDPSession } from './cdp-session.js'
|
||||
@@ -111,12 +111,6 @@ async function setDeviceScaleFactorForMacOS(context: BrowserContext): Promise<vo
|
||||
return
|
||||
}
|
||||
options.deviceScaleFactor = 2
|
||||
// for (const page of context.pages()) {
|
||||
// const delegate = (page as any)._delegate
|
||||
// if (delegate?.updateEmulatedViewportSize) {
|
||||
// await delegate.updateEmulatedViewportSize().catch(() => {})
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
async function preserveSystemColorScheme(context: BrowserContext): Promise<void> {
|
||||
@@ -127,11 +121,6 @@ async function preserveSystemColorScheme(context: BrowserContext): Promise<void>
|
||||
options.colorScheme = 'no-override'
|
||||
options.reducedMotion = 'no-override'
|
||||
options.forcedColors = 'no-override'
|
||||
// await Promise.all(
|
||||
// context.pages().map((page) => {
|
||||
// return page.emulateMedia({ colorScheme: null, reducedMotion: null, forcedColors: null }).catch(() => {})
|
||||
// }),
|
||||
// )
|
||||
}
|
||||
|
||||
function isRegExp(value: any): value is RegExp {
|
||||
@@ -182,7 +171,7 @@ async function getServerVersion(port: number): Promise<string | null> {
|
||||
async function killRelayServer(port: number): Promise<void> {
|
||||
try {
|
||||
await killPortProcess(port)
|
||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||
await sleep(500)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
@@ -210,11 +199,11 @@ async function ensureRelayServer(): Promise<void> {
|
||||
serverProcess.unref()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||
await sleep(500)
|
||||
const newVersion = await getServerVersion(RELAY_PORT)
|
||||
if (newVersion === VERSION) {
|
||||
console.error('CDP relay server started successfully, waiting for extension to connect...')
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000))
|
||||
await sleep(1000)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -249,6 +238,10 @@ async function ensureConnection(): Promise<{ browser: Browser; page: Page }> {
|
||||
// Set up console listener for all existing pages
|
||||
context.pages().forEach((p) => setupPageConsoleListener(p))
|
||||
|
||||
// These functions only set context-level options, they do NOT send CDP commands to pages.
|
||||
// Sending CDP commands (like Emulation.setEmulatedMedia or setDeviceMetricsOverride) to pages
|
||||
// immediately after connectOverCDP causes pages to render white/blank with about:blank URLs,
|
||||
// because pages may not be fully initialized yet. Playwright applies these settings lazily.
|
||||
await preserveSystemColorScheme(context)
|
||||
await setDeviceScaleFactorForMacOS(context)
|
||||
|
||||
|
||||
@@ -12,3 +12,7 @@ export const LOG_FILE_PATH = path.join(os.tmpdir(), 'playwriter', 'relay-server.
|
||||
|
||||
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')
|
||||
export const VERSION = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')).version as string
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Page } from 'playwright-core'
|
||||
import { sleep } from './utils.js'
|
||||
|
||||
const FILTERED_DOMAINS = [
|
||||
'doubleclick',
|
||||
@@ -130,7 +131,7 @@ export async function waitForPageLoad(options: WaitForPageLoadOptions): Promise<
|
||||
return result
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, minWait))
|
||||
await sleep(minWait)
|
||||
|
||||
while (Date.now() - startTime < timeout) {
|
||||
try {
|
||||
@@ -158,7 +159,7 @@ export async function waitForPageLoad(options: WaitForPageLoadOptions): Promise<
|
||||
}
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, pollInterval))
|
||||
await sleep(pollInterval)
|
||||
}
|
||||
|
||||
timedOut = true
|
||||
|
||||
Reference in New Issue
Block a user