Fix Editor/Debugger script listing after page load
This commit is contained in:
@@ -1,5 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- **Fixed Editor/Debugger script listing after page load**: `listScripts()` and `list()` now work correctly even when called after page has loaded
|
||||
- `enable()` now disables first then re-enables to force CDP to emit `scriptParsed` and `styleSheetAdded` events
|
||||
- Added 100ms debounced wait for events to arrive before returning
|
||||
- `listScripts()` and `list()` are now async and auto-call `enable()`
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "playwriter",
|
||||
"description": "",
|
||||
"version": "0.0.28",
|
||||
"version": "0.0.29",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
|
||||
@@ -6,7 +6,7 @@ async function listScriptsAndSetBreakpoint() {
|
||||
const dbg = createDebugger({ cdp })
|
||||
await dbg.enable()
|
||||
|
||||
const scripts = dbg.listScripts({ search: 'app' })
|
||||
const scripts = await dbg.listScripts({ search: 'app' })
|
||||
console.log(scripts)
|
||||
|
||||
if (scripts.length > 0) {
|
||||
|
||||
@@ -108,9 +108,28 @@ export class Debugger {
|
||||
if (this.debuggerEnabled) {
|
||||
return
|
||||
}
|
||||
await this.cdp.send('Debugger.disable')
|
||||
await this.cdp.send('Runtime.disable')
|
||||
this.scripts.clear()
|
||||
const scriptsReady = new Promise<void>((resolve) => {
|
||||
let timeout: ReturnType<typeof setTimeout>
|
||||
const listener = () => {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => {
|
||||
this.cdp.off('Debugger.scriptParsed', listener)
|
||||
resolve()
|
||||
}, 100)
|
||||
}
|
||||
this.cdp.on('Debugger.scriptParsed', listener)
|
||||
timeout = setTimeout(() => {
|
||||
this.cdp.off('Debugger.scriptParsed', listener)
|
||||
resolve()
|
||||
}, 100)
|
||||
})
|
||||
await this.cdp.send('Debugger.enable')
|
||||
await this.cdp.send('Runtime.enable')
|
||||
await this.cdp.send('Runtime.runIfWaitingForDebugger')
|
||||
await scriptsReady
|
||||
this.debuggerEnabled = true
|
||||
}
|
||||
|
||||
@@ -493,8 +512,7 @@ export class Debugger {
|
||||
|
||||
/**
|
||||
* Lists available scripts where breakpoints can be set.
|
||||
* Scripts are collected from Debugger.scriptParsed events after enable() is called.
|
||||
* Reload the page after enabling to capture all scripts.
|
||||
* Automatically enables the debugger if not already enabled.
|
||||
*
|
||||
* @param options - Options
|
||||
* @param options.search - Optional string to filter scripts by URL (case-insensitive)
|
||||
@@ -503,15 +521,16 @@ export class Debugger {
|
||||
* @example
|
||||
* ```ts
|
||||
* // List all scripts
|
||||
* const scripts = dbg.listScripts()
|
||||
* const scripts = await dbg.listScripts()
|
||||
* // [{ scriptId: '1', url: 'https://example.com/app.js' }, ...]
|
||||
*
|
||||
* // Search for specific files
|
||||
* const handlers = dbg.listScripts({ search: 'handler' })
|
||||
* const handlers = await dbg.listScripts({ search: 'handler' })
|
||||
* // [{ scriptId: '5', url: 'https://example.com/handlers.js' }]
|
||||
* ```
|
||||
*/
|
||||
listScripts({ search }: { search?: string } = {}): ScriptInfo[] {
|
||||
async listScripts({ search }: { search?: string } = {}): Promise<ScriptInfo[]> {
|
||||
await this.enable()
|
||||
const scripts = Array.from(this.scripts.values())
|
||||
const filtered = search
|
||||
? scripts.filter((s) => s.url.toLowerCase().includes(search.toLowerCase()))
|
||||
|
||||
@@ -107,7 +107,7 @@ async function readStylesheet() {
|
||||
const editor = createEditor({ cdp })
|
||||
await editor.enable()
|
||||
|
||||
const stylesheets = editor.list({ pattern: /\.css/ })
|
||||
const stylesheets = await editor.list({ pattern: /\.css/ })
|
||||
console.log('Stylesheets:', stylesheets)
|
||||
|
||||
if (stylesheets.length > 0) {
|
||||
|
||||
@@ -86,9 +86,33 @@ export class Editor {
|
||||
if (this.enabled) {
|
||||
return
|
||||
}
|
||||
await this.cdp.send('Debugger.disable')
|
||||
await this.cdp.send('CSS.disable')
|
||||
this.scripts.clear()
|
||||
this.stylesheets.clear()
|
||||
this.sourceCache.clear()
|
||||
const resourcesReady = new Promise<void>((resolve) => {
|
||||
let timeout: ReturnType<typeof setTimeout>
|
||||
const listener = () => {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => {
|
||||
this.cdp.off('Debugger.scriptParsed', listener)
|
||||
this.cdp.off('CSS.styleSheetAdded', listener)
|
||||
resolve()
|
||||
}, 100)
|
||||
}
|
||||
this.cdp.on('Debugger.scriptParsed', listener)
|
||||
this.cdp.on('CSS.styleSheetAdded', listener)
|
||||
timeout = setTimeout(() => {
|
||||
this.cdp.off('Debugger.scriptParsed', listener)
|
||||
this.cdp.off('CSS.styleSheetAdded', listener)
|
||||
resolve()
|
||||
}, 100)
|
||||
})
|
||||
await this.cdp.send('Debugger.enable')
|
||||
await this.cdp.send('DOM.enable')
|
||||
await this.cdp.send('CSS.enable')
|
||||
await resourcesReady
|
||||
this.enabled = true
|
||||
}
|
||||
|
||||
@@ -108,6 +132,7 @@ export class Editor {
|
||||
|
||||
/**
|
||||
* Lists available script and stylesheet URLs. Use pattern to filter by regex.
|
||||
* Automatically enables the editor if not already enabled.
|
||||
*
|
||||
* @param options - Options
|
||||
* @param options.pattern - Optional regex to filter URLs
|
||||
@@ -116,19 +141,20 @@ export class Editor {
|
||||
* @example
|
||||
* ```ts
|
||||
* // List all scripts and stylesheets
|
||||
* const urls = editor.list()
|
||||
* const urls = await editor.list()
|
||||
*
|
||||
* // List only JS files
|
||||
* const jsFiles = editor.list({ pattern: /\.js/ })
|
||||
* const jsFiles = await editor.list({ pattern: /\.js/ })
|
||||
*
|
||||
* // List only CSS files
|
||||
* const cssFiles = editor.list({ pattern: /\.css/ })
|
||||
* const cssFiles = await editor.list({ pattern: /\.css/ })
|
||||
*
|
||||
* // Search for specific scripts
|
||||
* const appScripts = editor.list({ pattern: /app/ })
|
||||
* const appScripts = await editor.list({ pattern: /app/ })
|
||||
* ```
|
||||
*/
|
||||
list({ pattern }: { pattern?: RegExp } = {}): string[] {
|
||||
async list({ pattern }: { pattern?: RegExp } = {}): Promise<string[]> {
|
||||
await this.enable()
|
||||
const urls = [...Array.from(this.scripts.keys()), ...Array.from(this.stylesheets.keys())]
|
||||
|
||||
if (!pattern) {
|
||||
@@ -319,7 +345,7 @@ export class Editor {
|
||||
await this.enable()
|
||||
|
||||
const matches: SearchMatch[] = []
|
||||
const urls = this.list({ pattern })
|
||||
const urls = await this.list({ pattern })
|
||||
|
||||
for (const url of urls) {
|
||||
let source: string
|
||||
|
||||
@@ -2094,19 +2094,12 @@ describe('CDP Session Tests', () => {
|
||||
const cdpSession = await getCDPSessionForPage({ page: cdpPage!, wsUrl })
|
||||
const dbg = new Debugger({ cdp: cdpSession })
|
||||
|
||||
await dbg.enable()
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
if (dbg.listScripts().length > 0) break
|
||||
await new Promise(r => setTimeout(r, 100))
|
||||
}
|
||||
|
||||
const scripts = dbg.listScripts()
|
||||
const scripts = await dbg.listScripts()
|
||||
expect(scripts.length).toBeGreaterThan(0)
|
||||
expect(scripts[0]).toHaveProperty('scriptId')
|
||||
expect(scripts[0]).toHaveProperty('url')
|
||||
|
||||
const dataScripts = dbg.listScripts({ search: 'data:' })
|
||||
const dataScripts = await dbg.listScripts({ search: 'data:' })
|
||||
expect(dataScripts.length).toBeGreaterThan(0)
|
||||
|
||||
cdpSession.close()
|
||||
@@ -2698,8 +2691,7 @@ describe('CDP Session Tests', () => {
|
||||
`,
|
||||
})
|
||||
await new Promise(r => setTimeout(r, 100))
|
||||
|
||||
const scripts = editor.list()
|
||||
const scripts = await editor.list()
|
||||
expect(scripts.length).toBeGreaterThan(0)
|
||||
|
||||
const matches = await editor.grep({ regex: /greetUser/ })
|
||||
@@ -2766,8 +2758,7 @@ describe('CDP Session Tests', () => {
|
||||
`,
|
||||
})
|
||||
await new Promise(r => setTimeout(r, 100))
|
||||
|
||||
const stylesheets = editor.list({ pattern: /inline-css:/ })
|
||||
const stylesheets = await editor.list({ pattern: /inline-css:/ })
|
||||
expect(stylesheets.length).toBeGreaterThan(0)
|
||||
|
||||
const cssMatches = await editor.grep({ regex: /editor-test-element/, pattern: /inline-css:/ })
|
||||
|
||||
Reference in New Issue
Block a user