playwriter 0.0.26 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.js +1 -1
- package/dist/bippy.js +966 -0
- package/dist/{extension/cdp-relay.d.ts → cdp-relay.d.ts} +3 -2
- package/dist/cdp-relay.d.ts.map +1 -0
- package/dist/{extension/cdp-relay.js → cdp-relay.js} +101 -3
- package/dist/cdp-relay.js.map +1 -0
- package/dist/cdp-session.d.ts +1 -1
- package/dist/cdp-session.d.ts.map +1 -1
- package/dist/cdp-session.js +4 -4
- package/dist/cdp-session.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +71 -0
- package/dist/cli.js.map +1 -0
- package/dist/debugger-examples-types.d.ts +18 -0
- package/dist/debugger-examples-types.d.ts.map +1 -0
- package/dist/debugger-examples-types.js +2 -0
- package/dist/debugger-examples-types.js.map +1 -0
- package/dist/debugger-examples.d.ts +6 -0
- package/dist/debugger-examples.d.ts.map +1 -0
- package/dist/debugger-examples.js +53 -0
- package/dist/debugger-examples.js.map +1 -0
- package/dist/debugger-examples.ts +66 -0
- package/dist/debugger.d.ts +380 -0
- package/dist/debugger.d.ts.map +1 -0
- package/dist/debugger.js +631 -0
- package/dist/debugger.js.map +1 -0
- package/dist/editor-examples.d.ts +11 -0
- package/dist/editor-examples.d.ts.map +1 -0
- package/dist/editor-examples.js +124 -0
- package/dist/editor-examples.js.map +1 -0
- package/dist/editor.d.ts +203 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +335 -0
- package/dist/editor.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-client.d.ts +5 -1
- package/dist/mcp-client.d.ts.map +1 -1
- package/dist/mcp-client.js +13 -9
- package/dist/mcp-client.js.map +1 -1
- package/dist/mcp.d.ts +4 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +170 -29
- package/dist/mcp.js.map +1 -1
- package/dist/mcp.test.d.ts.map +1 -1
- package/dist/mcp.test.js +886 -182
- package/dist/mcp.test.js.map +1 -1
- package/dist/prompt.md +86 -6
- package/dist/{extension/protocol.d.ts → protocol.d.ts} +1 -1
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js.map +1 -0
- package/dist/react-source.d.ts +13 -0
- package/dist/react-source.d.ts.map +1 -0
- package/dist/react-source.js +66 -0
- package/dist/react-source.js.map +1 -0
- package/dist/selector-generator.js +7065 -18
- package/dist/start-relay-server.d.ts +4 -2
- package/dist/start-relay-server.d.ts.map +1 -1
- package/dist/start-relay-server.js +3 -3
- package/dist/start-relay-server.js.map +1 -1
- package/dist/styles.d.ts +27 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +232 -0
- package/dist/styles.js.map +1 -0
- package/dist/utils.d.ts +3 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -3
- package/dist/utils.js.map +1 -1
- package/dist/wait-for-page-load.d.ts.map +1 -1
- package/dist/wait-for-page-load.js +3 -2
- package/dist/wait-for-page-load.js.map +1 -1
- package/package.json +4 -2
- package/src/{extension/cdp-relay.ts → cdp-relay.ts} +109 -5
- package/src/cdp-session.ts +4 -4
- package/src/cdp-timing.md +128 -0
- package/src/cli.ts +85 -0
- package/src/debugger-examples-types.ts +10 -0
- package/src/debugger-examples.ts +66 -0
- package/src/debugger.ts +711 -0
- package/src/editor-examples.ts +148 -0
- package/src/editor.ts +389 -0
- package/src/index.ts +1 -1
- package/src/mcp-client.ts +14 -9
- package/src/mcp.test.ts +1053 -196
- package/src/mcp.ts +195 -30
- package/src/prompt.md +86 -6
- package/src/{extension/protocol.ts → protocol.ts} +1 -1
- package/src/react-source.ts +92 -0
- package/src/snapshots/shadcn-ui-accessibility.md +57 -57
- package/src/start-relay-server.ts +3 -3
- package/src/styles.ts +343 -0
- package/src/utils.ts +8 -3
- package/src/wait-for-page-load.ts +3 -2
- package/dist/extension/cdp-relay.d.ts.map +0 -1
- package/dist/extension/cdp-relay.js.map +0 -1
- package/dist/extension/protocol.d.ts.map +0 -1
- package/dist/extension/protocol.js.map +0 -1
- /package/dist/{extension/protocol.js → protocol.js} +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export declare function startServer({ port }?: {
|
|
1
|
+
export declare function startServer({ port, host, token }?: {
|
|
2
2
|
port?: number;
|
|
3
|
-
|
|
3
|
+
host?: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
}): Promise<import("./cdp-relay.js").RelayServer>;
|
|
4
6
|
//# sourceMappingURL=start-relay-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-relay-server.d.ts","sourceRoot":"","sources":["../src/start-relay-server.ts"],"names":[],"mappings":"AAsBA,wBAAsB,WAAW,CAAC,EAAE,IAAY,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"start-relay-server.d.ts","sourceRoot":"","sources":["../src/start-relay-server.ts"],"names":[],"mappings":"AAsBA,wBAAsB,WAAW,CAAC,EAAE,IAAY,EAAE,IAAkB,EAAE,KAAK,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,iDAmBnI"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { startPlayWriterCDPRelayServer } from './
|
|
1
|
+
import { startPlayWriterCDPRelayServer } from './cdp-relay.js';
|
|
2
2
|
import { createFileLogger } from './create-logger.js';
|
|
3
3
|
process.title = 'playwriter-ws-server';
|
|
4
4
|
const logger = createFileLogger();
|
|
@@ -13,8 +13,8 @@ process.on('unhandledRejection', async (reason) => {
|
|
|
13
13
|
process.on('exit', async (code) => {
|
|
14
14
|
await logger.log(`Process exiting with code: ${code}`);
|
|
15
15
|
});
|
|
16
|
-
export async function startServer({ port = 19988 } = {}) {
|
|
17
|
-
const server = await startPlayWriterCDPRelayServer({ port, logger });
|
|
16
|
+
export async function startServer({ port = 19988, host = '127.0.0.1', token } = {}) {
|
|
17
|
+
const server = await startPlayWriterCDPRelayServer({ port, host, token, logger });
|
|
18
18
|
console.log('CDP Relay Server running. Press Ctrl+C to stop.');
|
|
19
19
|
console.log('Logs are being written to:', logger.logFilePath);
|
|
20
20
|
process.on('SIGINT', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-relay-server.js","sourceRoot":"","sources":["../src/start-relay-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"start-relay-server.js","sourceRoot":"","sources":["../src/start-relay-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,CAAC,KAAK,GAAG,sBAAsB,CAAA;AAEtC,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAA;AAEjC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IAC5C,MAAM,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAChD,MAAM,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAChC,MAAM,MAAM,CAAC,GAAG,CAAC,8BAA8B,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAGH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAE,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,WAAW,EAAE,KAAK,KAAuD,EAAE;IAClI,MAAM,MAAM,GAAG,MAAM,6BAA6B,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;IAEjF,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;IAC9D,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;IAE7D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QACjC,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;QACjC,MAAM,CAAC,KAAK,EAAE,CAAA;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AACD,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA"}
|
package/dist/styles.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { CDPSession } from './cdp-session.js';
|
|
2
|
+
import type { Locator } from 'playwright-core';
|
|
3
|
+
export interface StyleSource {
|
|
4
|
+
url: string;
|
|
5
|
+
line: number;
|
|
6
|
+
column: number;
|
|
7
|
+
}
|
|
8
|
+
export type StyleDeclarations = Record<string, string>;
|
|
9
|
+
export interface StyleRule {
|
|
10
|
+
selector: string;
|
|
11
|
+
source: StyleSource | null;
|
|
12
|
+
origin: 'regular' | 'user-agent' | 'injected' | 'inspector';
|
|
13
|
+
declarations: StyleDeclarations;
|
|
14
|
+
inheritedFrom: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface StylesResult {
|
|
17
|
+
element: string;
|
|
18
|
+
inlineStyle: StyleDeclarations | null;
|
|
19
|
+
rules: StyleRule[];
|
|
20
|
+
}
|
|
21
|
+
export declare function getStylesForLocator({ locator, cdp, includeUserAgentStyles, }: {
|
|
22
|
+
locator: Locator;
|
|
23
|
+
cdp: CDPSession;
|
|
24
|
+
includeUserAgentStyles?: boolean;
|
|
25
|
+
}): Promise<StylesResult>;
|
|
26
|
+
export declare function formatStylesAsText(styles: StylesResult): string;
|
|
27
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE9C,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEtD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAA;IAC3D,YAAY,EAAE,iBAAiB,CAAA;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACrC,KAAK,EAAE,SAAS,EAAE,CAAA;CACnB;AA2CD,wBAAsB,mBAAmB,CAAC,EACxC,OAAO,EACP,GAAG,EACH,sBAA8B,GAC/B,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,UAAU,CAAA;IACf,sBAAsB,CAAC,EAAE,OAAO,CAAA;CACjC,GAAG,OAAO,CAAC,YAAY,CAAC,CAgKxB;AA+CD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA6D/D"}
|
package/dist/styles.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
export async function getStylesForLocator({ locator, cdp, includeUserAgentStyles = false, }) {
|
|
2
|
+
await cdp.send('DOM.enable');
|
|
3
|
+
await cdp.send('CSS.enable');
|
|
4
|
+
const elementHandle = await locator.elementHandle();
|
|
5
|
+
if (!elementHandle) {
|
|
6
|
+
throw new Error('Could not get element handle from locator');
|
|
7
|
+
}
|
|
8
|
+
const remoteObject = elementHandle._channel?.objectId
|
|
9
|
+
? { objectId: elementHandle._channel.objectId }
|
|
10
|
+
: null;
|
|
11
|
+
let backendNodeId;
|
|
12
|
+
if (remoteObject?.objectId) {
|
|
13
|
+
const nodeInfo = await cdp.send('DOM.describeNode', {
|
|
14
|
+
objectId: remoteObject.objectId,
|
|
15
|
+
});
|
|
16
|
+
backendNodeId = nodeInfo.node.backendNodeId;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const box = await elementHandle.boundingBox();
|
|
20
|
+
if (!box) {
|
|
21
|
+
throw new Error('Element has no bounding box');
|
|
22
|
+
}
|
|
23
|
+
const docResult = await cdp.send('DOM.getDocument', { depth: 0 });
|
|
24
|
+
const nodeAtPoint = await cdp.send('DOM.getNodeForLocation', {
|
|
25
|
+
x: Math.round(box.x + box.width / 2),
|
|
26
|
+
y: Math.round(box.y + box.height / 2),
|
|
27
|
+
});
|
|
28
|
+
backendNodeId = nodeAtPoint.backendNodeId;
|
|
29
|
+
}
|
|
30
|
+
const pushResult = await cdp.send('DOM.pushNodesByBackendIdsToFrontend', {
|
|
31
|
+
backendNodeIds: [backendNodeId],
|
|
32
|
+
});
|
|
33
|
+
const nodeId = pushResult.nodeIds[0];
|
|
34
|
+
if (!nodeId) {
|
|
35
|
+
throw new Error('Could not get nodeId for element');
|
|
36
|
+
}
|
|
37
|
+
const nodeInfo = await cdp.send('DOM.describeNode', { nodeId });
|
|
38
|
+
const elementDescription = formatElementDescription(nodeInfo.node);
|
|
39
|
+
const matchedStyles = await cdp.send('CSS.getMatchedStylesForNode', { nodeId });
|
|
40
|
+
const stylesheetUrls = new Map();
|
|
41
|
+
const processStyleSheetId = async (styleSheetId) => {
|
|
42
|
+
if (!styleSheetId) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (!stylesheetUrls.has(styleSheetId)) {
|
|
46
|
+
try {
|
|
47
|
+
const header = await cdp.send('CSS.getStyleSheetText', { styleSheetId });
|
|
48
|
+
stylesheetUrls.set(styleSheetId, '');
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
stylesheetUrls.set(styleSheetId, '');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
const rules = [];
|
|
57
|
+
if (matchedStyles.matchedCSSRules) {
|
|
58
|
+
for (const ruleMatch of matchedStyles.matchedCSSRules) {
|
|
59
|
+
const rule = ruleMatch.rule;
|
|
60
|
+
const sourceRange = rule.selectorList?.range;
|
|
61
|
+
const styleSheetId = rule.styleSheetId;
|
|
62
|
+
let source = null;
|
|
63
|
+
if (styleSheetId && sourceRange) {
|
|
64
|
+
const styleSheet = matchedStyles.cssStyleSheetHeaders?.find((h) => h.styleSheetId === styleSheetId);
|
|
65
|
+
const url = styleSheet?.sourceURL || rule.origin === 'user-agent' ? 'user-agent' : `stylesheet:${styleSheetId}`;
|
|
66
|
+
source = {
|
|
67
|
+
url: rule.styleSheetId ? await getStylesheetUrl(cdp, styleSheetId) : 'user-agent',
|
|
68
|
+
line: sourceRange.startLine + 1,
|
|
69
|
+
column: sourceRange.startColumn,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
rules.push({
|
|
73
|
+
selector: rule.selectorList.text,
|
|
74
|
+
source,
|
|
75
|
+
origin: rule.origin,
|
|
76
|
+
declarations: extractDeclarations(rule.style),
|
|
77
|
+
inheritedFrom: null,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (matchedStyles.inherited) {
|
|
82
|
+
for (let i = 0; i < matchedStyles.inherited.length; i++) {
|
|
83
|
+
const inheritedEntry = matchedStyles.inherited[i];
|
|
84
|
+
const ancestorDesc = `ancestor[${i + 1}]`;
|
|
85
|
+
if (inheritedEntry.inlineStyle) {
|
|
86
|
+
const declarations = extractDeclarations(inheritedEntry.inlineStyle);
|
|
87
|
+
if (Object.keys(declarations).length > 0) {
|
|
88
|
+
rules.push({
|
|
89
|
+
selector: 'element.style',
|
|
90
|
+
source: null,
|
|
91
|
+
origin: 'regular',
|
|
92
|
+
declarations,
|
|
93
|
+
inheritedFrom: ancestorDesc,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
for (const ruleMatch of inheritedEntry.matchedCSSRules) {
|
|
98
|
+
const rule = ruleMatch.rule;
|
|
99
|
+
const sourceRange = rule.selectorList?.range;
|
|
100
|
+
const styleSheetId = rule.styleSheetId;
|
|
101
|
+
let source = null;
|
|
102
|
+
if (styleSheetId && sourceRange) {
|
|
103
|
+
source = {
|
|
104
|
+
url: await getStylesheetUrl(cdp, styleSheetId),
|
|
105
|
+
line: sourceRange.startLine + 1,
|
|
106
|
+
column: sourceRange.startColumn,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const declarations = extractDeclarations(rule.style);
|
|
110
|
+
if (Object.keys(declarations).length > 0) {
|
|
111
|
+
rules.push({
|
|
112
|
+
selector: rule.selectorList.text,
|
|
113
|
+
source,
|
|
114
|
+
origin: rule.origin,
|
|
115
|
+
declarations,
|
|
116
|
+
inheritedFrom: ancestorDesc,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
let inlineStyle = null;
|
|
123
|
+
if (matchedStyles.inlineStyle) {
|
|
124
|
+
const declarations = extractDeclarations(matchedStyles.inlineStyle);
|
|
125
|
+
if (Object.keys(declarations).length > 0) {
|
|
126
|
+
inlineStyle = declarations;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const filteredRules = includeUserAgentStyles
|
|
130
|
+
? rules
|
|
131
|
+
: rules.filter((r) => r.origin !== 'user-agent');
|
|
132
|
+
return {
|
|
133
|
+
element: elementDescription,
|
|
134
|
+
inlineStyle,
|
|
135
|
+
rules: filteredRules,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function extractDeclarations(style) {
|
|
139
|
+
if (!style?.cssProperties) {
|
|
140
|
+
return {};
|
|
141
|
+
}
|
|
142
|
+
const result = {};
|
|
143
|
+
for (const prop of style.cssProperties) {
|
|
144
|
+
if (!prop.value || prop.value === 'initial' || prop.name.startsWith('-webkit-')) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const value = prop.important ? `${prop.value} !important` : prop.value;
|
|
148
|
+
result[prop.name] = value;
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
function formatElementDescription(node) {
|
|
153
|
+
let desc = node.localName || node.nodeName?.toLowerCase() || 'element';
|
|
154
|
+
if (node.attributes) {
|
|
155
|
+
const attrs = {};
|
|
156
|
+
for (let i = 0; i < node.attributes.length; i += 2) {
|
|
157
|
+
attrs[node.attributes[i]] = node.attributes[i + 1];
|
|
158
|
+
}
|
|
159
|
+
if (attrs.id) {
|
|
160
|
+
desc += `#${attrs.id}`;
|
|
161
|
+
}
|
|
162
|
+
if (attrs.class) {
|
|
163
|
+
desc += `.${attrs.class.split(' ').join('.')}`;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return desc;
|
|
167
|
+
}
|
|
168
|
+
async function getStylesheetUrl(cdp, styleSheetId) {
|
|
169
|
+
try {
|
|
170
|
+
await cdp.send('CSS.getStyleSheetText', { styleSheetId });
|
|
171
|
+
return `stylesheet:${styleSheetId}`;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return `stylesheet:${styleSheetId}`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export function formatStylesAsText(styles) {
|
|
178
|
+
const lines = [];
|
|
179
|
+
lines.push(`Element: ${styles.element}`);
|
|
180
|
+
lines.push('');
|
|
181
|
+
if (styles.inlineStyle) {
|
|
182
|
+
lines.push('Inline styles:');
|
|
183
|
+
for (const [prop, value] of Object.entries(styles.inlineStyle)) {
|
|
184
|
+
lines.push(` ${prop}: ${value}`);
|
|
185
|
+
}
|
|
186
|
+
lines.push('');
|
|
187
|
+
}
|
|
188
|
+
const directRules = styles.rules.filter((r) => !r.inheritedFrom);
|
|
189
|
+
const inheritedRules = styles.rules.filter((r) => r.inheritedFrom);
|
|
190
|
+
if (directRules.length > 0) {
|
|
191
|
+
lines.push('Matched rules:');
|
|
192
|
+
for (const rule of directRules) {
|
|
193
|
+
lines.push(` ${rule.selector} {`);
|
|
194
|
+
const sourceInfo = rule.source ? ` /* ${rule.source.url}:${rule.source.line}:${rule.source.column} */` : '';
|
|
195
|
+
if (sourceInfo) {
|
|
196
|
+
lines.push(` ${sourceInfo}`);
|
|
197
|
+
}
|
|
198
|
+
for (const [prop, value] of Object.entries(rule.declarations)) {
|
|
199
|
+
lines.push(` ${prop}: ${value};`);
|
|
200
|
+
}
|
|
201
|
+
lines.push(' }');
|
|
202
|
+
}
|
|
203
|
+
lines.push('');
|
|
204
|
+
}
|
|
205
|
+
if (inheritedRules.length > 0) {
|
|
206
|
+
const byAncestor = new Map();
|
|
207
|
+
for (const rule of inheritedRules) {
|
|
208
|
+
const key = rule.inheritedFrom;
|
|
209
|
+
if (!byAncestor.has(key)) {
|
|
210
|
+
byAncestor.set(key, []);
|
|
211
|
+
}
|
|
212
|
+
byAncestor.get(key).push(rule);
|
|
213
|
+
}
|
|
214
|
+
for (const [ancestor, rules] of byAncestor) {
|
|
215
|
+
lines.push(`Inherited from ${ancestor}:`);
|
|
216
|
+
for (const rule of rules) {
|
|
217
|
+
lines.push(` ${rule.selector} {`);
|
|
218
|
+
const sourceInfo = rule.source ? ` /* ${rule.source.url}:${rule.source.line}:${rule.source.column} */` : '';
|
|
219
|
+
if (sourceInfo) {
|
|
220
|
+
lines.push(` ${sourceInfo}`);
|
|
221
|
+
}
|
|
222
|
+
for (const [prop, value] of Object.entries(rule.declarations)) {
|
|
223
|
+
lines.push(` ${prop}: ${value};`);
|
|
224
|
+
}
|
|
225
|
+
lines.push(' }');
|
|
226
|
+
}
|
|
227
|
+
lines.push('');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return lines.join('\n');
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export declare function getCdpUrl({ port, host }?: {
|
|
1
|
+
export declare function getCdpUrl({ port, host, token }?: {
|
|
2
2
|
port?: number;
|
|
3
3
|
host?: string;
|
|
4
|
+
token?: string;
|
|
4
5
|
}): string;
|
|
5
6
|
export declare const LOG_FILE_PATH: string;
|
|
6
7
|
export declare const VERSION: string;
|
|
8
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
7
9
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,EAAE,IAAY,EAAE,IAAkB,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,EAAE,IAAY,EAAE,IAAkB,EAAE,KAAK,EAAE,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,UAI3H;AAED,eAAO,MAAM,aAAa,QAAmG,CAAA;AAG7H,eAAO,MAAM,OAAO,EAAoE,MAAM,CAAA;AAE9F,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
|
package/dist/utils.js
CHANGED
|
@@ -2,11 +2,15 @@ import fs from 'node:fs';
|
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
export function getCdpUrl({ port = 19988, host = '127.0.0.1' } = {}) {
|
|
5
|
+
export function getCdpUrl({ port = 19988, host = '127.0.0.1', token } = {}) {
|
|
6
6
|
const id = `${Math.random().toString(36).substring(2, 15)}_${Date.now()}`;
|
|
7
|
-
|
|
7
|
+
const queryString = token ? `?token=${token}` : '';
|
|
8
|
+
return `ws://${host}:${port}/cdp/${id}${queryString}`;
|
|
8
9
|
}
|
|
9
|
-
export const LOG_FILE_PATH = path.join(os.tmpdir(), 'playwriter', 'relay-server.log');
|
|
10
|
+
export const LOG_FILE_PATH = process.env.PLAYWRITER_LOG_FILE_PATH || path.join(os.tmpdir(), 'playwriter', 'relay-server.log');
|
|
10
11
|
const packageJsonPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
11
12
|
export const VERSION = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')).version;
|
|
13
|
+
export function sleep(ms) {
|
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
12
16
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,WAAW,EAAE,KAAK,KAAuD,EAAE;IAC1H,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAA;IACzE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAClD,OAAO,QAAQ,IAAI,IAAI,IAAI,QAAQ,EAAE,GAAG,WAAW,EAAE,CAAA;AACvD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAA;AAE7H,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAA;AACrG,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,OAAiB,CAAA;AAE9F,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAC1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait-for-page-load.d.ts","sourceRoot":"","sources":["../src/wait-for-page-load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"wait-for-page-load.d.ts","sourceRoot":"","sources":["../src/wait-for-page-load.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AA2C3C,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAmHrG"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { sleep } from './utils.js';
|
|
1
2
|
const FILTERED_DOMAINS = [
|
|
2
3
|
'doubleclick',
|
|
3
4
|
'googlesyndication',
|
|
@@ -86,7 +87,7 @@ export async function waitForPageLoad(options) {
|
|
|
86
87
|
});
|
|
87
88
|
return result;
|
|
88
89
|
};
|
|
89
|
-
await
|
|
90
|
+
await sleep(minWait);
|
|
90
91
|
while (Date.now() - startTime < timeout) {
|
|
91
92
|
try {
|
|
92
93
|
const { ready, readyState, pendingRequests } = await checkPageReady();
|
|
@@ -112,7 +113,7 @@ export async function waitForPageLoad(options) {
|
|
|
112
113
|
timedOut: false,
|
|
113
114
|
};
|
|
114
115
|
}
|
|
115
|
-
await
|
|
116
|
+
await sleep(pollInterval);
|
|
116
117
|
}
|
|
117
118
|
timedOut = true;
|
|
118
119
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait-for-page-load.js","sourceRoot":"","sources":["../src/wait-for-page-load.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wait-for-page-load.js","sourceRoot":"","sources":["../src/wait-for-page-load.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwriter",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.29",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"repository": "https://github.com/remorses/playwriter",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "rm -rf dist *.tsbuildinfo && mkdir dist && cp src/resource.md src/prompt.md dist/ &&
|
|
10
|
+
"build": "rm -rf dist *.tsbuildinfo && mkdir dist && cp src/resource.md src/prompt.md src/debugger-examples.ts dist/ && bun scripts/build-selector-generator.ts && bun scripts/build-bippy.ts && tsc",
|
|
11
11
|
"prepublishOnly": "pnpm build",
|
|
12
12
|
"watch": "tsc -w",
|
|
13
13
|
"typecheck": "tsc --noEmit",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"@types/node": "^24.10.1",
|
|
33
33
|
"@types/ws": "^8.18.1",
|
|
34
34
|
"@vitest/ui": "^4.0.8",
|
|
35
|
+
"bippy": "^0.5.27",
|
|
35
36
|
"image-size": "^2.0.2",
|
|
36
37
|
"mcp-extension": "workspace:*",
|
|
37
38
|
"vite-node": "^5.0.0",
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
"@hono/node-server": "^1.19.6",
|
|
42
43
|
"@hono/node-ws": "^1.2.0",
|
|
43
44
|
"@modelcontextprotocol/sdk": "^1.21.1",
|
|
45
|
+
"cac": "^6.7.14",
|
|
44
46
|
"chalk": "^5.6.2",
|
|
45
47
|
"devtools-protocol": "^0.0.1543509",
|
|
46
48
|
"diff": "^8.0.2",
|
|
@@ -2,12 +2,12 @@ import { Hono } from 'hono'
|
|
|
2
2
|
import { serve } from '@hono/node-server'
|
|
3
3
|
import { createNodeWebSocket } from '@hono/node-ws'
|
|
4
4
|
import type { WSContext } from 'hono/ws'
|
|
5
|
-
import type { Protocol } from '
|
|
6
|
-
import type { CDPCommand, CDPResponseBase, CDPEventBase, CDPEventFor, RelayServerEvents } from '
|
|
5
|
+
import type { Protocol } from './cdp-types.js'
|
|
6
|
+
import type { CDPCommand, CDPResponseBase, CDPEventBase, CDPEventFor, RelayServerEvents } from './cdp-types.js'
|
|
7
7
|
import type { ExtensionMessage, ExtensionEventMessage } from './protocol.js'
|
|
8
8
|
import chalk from 'chalk'
|
|
9
9
|
import { EventEmitter } from 'node:events'
|
|
10
|
-
import { VERSION } from '
|
|
10
|
+
import { VERSION } from './utils.js'
|
|
11
11
|
|
|
12
12
|
type ConnectedTarget = {
|
|
13
13
|
sessionId: string
|
|
@@ -29,7 +29,7 @@ export type RelayServer = {
|
|
|
29
29
|
off<K extends keyof RelayServerEvents>(event: K, listener: RelayServerEvents[K]): void
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.0.0.1', logger }: { port?: number; host?: string; logger?: { log(...args: any[]): void; error(...args: any[]): void } } = {}): Promise<RelayServer> {
|
|
32
|
+
export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.0.0.1', token, logger }: { port?: number; host?: string; token?: string; logger?: { log(...args: any[]): void; error(...args: any[]): void } } = {}): Promise<RelayServer> {
|
|
33
33
|
const emitter = new EventEmitter()
|
|
34
34
|
const connectedTargets = new Map<string, ConnectedTarget>()
|
|
35
35
|
|
|
@@ -262,6 +262,37 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|
|
262
262
|
params: { method, params }
|
|
263
263
|
})
|
|
264
264
|
}
|
|
265
|
+
|
|
266
|
+
case 'Runtime.enable': {
|
|
267
|
+
if (!sessionId) {
|
|
268
|
+
break
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const contextCreatedPromise = new Promise<void>((resolve) => {
|
|
272
|
+
const handler = ({ event }: { event: CDPEventBase }) => {
|
|
273
|
+
if (event.method === 'Runtime.executionContextCreated' && event.sessionId === sessionId) {
|
|
274
|
+
clearTimeout(timeout)
|
|
275
|
+
emitter.off('cdp:event', handler)
|
|
276
|
+
resolve()
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const timeout = setTimeout(() => {
|
|
280
|
+
emitter.off('cdp:event', handler)
|
|
281
|
+
logger?.log(chalk.yellow(`IMPORTANT: Runtime.enable timed out waiting for executionContextCreated (sessionId: ${sessionId}). This may cause pages to not be visible immediately.`))
|
|
282
|
+
resolve()
|
|
283
|
+
}, 3000)
|
|
284
|
+
emitter.on('cdp:event', handler)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
const result = await sendToExtension({
|
|
288
|
+
method: 'forwardCDPCommand',
|
|
289
|
+
params: { sessionId, method, params }
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
await contextCreatedPromise
|
|
293
|
+
|
|
294
|
+
return result
|
|
295
|
+
}
|
|
265
296
|
}
|
|
266
297
|
|
|
267
298
|
return await sendToExtension({
|
|
@@ -281,6 +312,10 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|
|
281
312
|
return c.json({ version: VERSION })
|
|
282
313
|
})
|
|
283
314
|
|
|
315
|
+
app.get('/extension/status', (c) => {
|
|
316
|
+
return c.json({ connected: extensionWs !== null })
|
|
317
|
+
})
|
|
318
|
+
|
|
284
319
|
app.post('/mcp-log', async (c) => {
|
|
285
320
|
try {
|
|
286
321
|
const { level, args } = await c.req.json()
|
|
@@ -293,7 +328,16 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|
|
293
328
|
}
|
|
294
329
|
})
|
|
295
330
|
|
|
296
|
-
app.get('/cdp/:clientId?',
|
|
331
|
+
app.get('/cdp/:clientId?', (c, next) => {
|
|
332
|
+
if (token) {
|
|
333
|
+
const url = new URL(c.req.url, 'http://localhost')
|
|
334
|
+
const providedToken = url.searchParams.get('token')
|
|
335
|
+
if (providedToken !== token) {
|
|
336
|
+
return c.text('Unauthorized', 401)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return next()
|
|
340
|
+
}, upgradeWebSocket((c) => {
|
|
297
341
|
const clientId = c.req.param('clientId') || 'default'
|
|
298
342
|
|
|
299
343
|
return {
|
|
@@ -544,6 +588,23 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|
|
544
588
|
} as CDPEventBase,
|
|
545
589
|
source: 'extension'
|
|
546
590
|
})
|
|
591
|
+
} else if (method === 'Target.targetCrashed') {
|
|
592
|
+
const crashParams = params as Protocol.Target.TargetCrashedEvent
|
|
593
|
+
for (const [sid, target] of connectedTargets.entries()) {
|
|
594
|
+
if (target.targetId === crashParams.targetId) {
|
|
595
|
+
connectedTargets.delete(sid)
|
|
596
|
+
logger?.log(chalk.red('[Server] Target crashed, removing:'), crashParams.targetId)
|
|
597
|
+
break
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
sendToPlaywright({
|
|
602
|
+
message: {
|
|
603
|
+
method: 'Target.targetCrashed',
|
|
604
|
+
params: crashParams
|
|
605
|
+
} as CDPEventBase,
|
|
606
|
+
source: 'extension'
|
|
607
|
+
})
|
|
547
608
|
} else if (method === 'Target.targetInfoChanged') {
|
|
548
609
|
const infoParams = params as Protocol.Target.TargetInfoChangedEvent
|
|
549
610
|
for (const target of connectedTargets.values()) {
|
|
@@ -560,6 +621,49 @@ export async function startPlayWriterCDPRelayServer({ port = 19988, host = '127.
|
|
|
560
621
|
} as CDPEventBase,
|
|
561
622
|
source: 'extension'
|
|
562
623
|
})
|
|
624
|
+
} else if (method === 'Page.frameNavigated') {
|
|
625
|
+
const frameParams = params as Protocol.Page.FrameNavigatedEvent
|
|
626
|
+
if (!frameParams.frame.parentId && sessionId) {
|
|
627
|
+
const target = connectedTargets.get(sessionId)
|
|
628
|
+
if (target) {
|
|
629
|
+
target.targetInfo = {
|
|
630
|
+
...target.targetInfo,
|
|
631
|
+
url: frameParams.frame.url,
|
|
632
|
+
title: frameParams.frame.name || target.targetInfo.title,
|
|
633
|
+
}
|
|
634
|
+
logger?.log(chalk.magenta('[Server] Updated target URL from Page.frameNavigated:'), frameParams.frame.url)
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
sendToPlaywright({
|
|
639
|
+
message: {
|
|
640
|
+
sessionId,
|
|
641
|
+
method,
|
|
642
|
+
params
|
|
643
|
+
} as CDPEventBase,
|
|
644
|
+
source: 'extension'
|
|
645
|
+
})
|
|
646
|
+
} else if (method === 'Page.navigatedWithinDocument') {
|
|
647
|
+
const navParams = params as Protocol.Page.NavigatedWithinDocumentEvent
|
|
648
|
+
if (sessionId) {
|
|
649
|
+
const target = connectedTargets.get(sessionId)
|
|
650
|
+
if (target) {
|
|
651
|
+
target.targetInfo = {
|
|
652
|
+
...target.targetInfo,
|
|
653
|
+
url: navParams.url,
|
|
654
|
+
}
|
|
655
|
+
logger?.log(chalk.magenta('[Server] Updated target URL from Page.navigatedWithinDocument:'), navParams.url)
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
sendToPlaywright({
|
|
660
|
+
message: {
|
|
661
|
+
sessionId,
|
|
662
|
+
method,
|
|
663
|
+
params
|
|
664
|
+
} as CDPEventBase,
|
|
665
|
+
source: 'extension'
|
|
666
|
+
})
|
|
563
667
|
} else {
|
|
564
668
|
sendToPlaywright({
|
|
565
669
|
message: {
|
package/src/cdp-session.ts
CHANGED
|
@@ -101,7 +101,7 @@ export class CDPSession {
|
|
|
101
101
|
this.eventListeners.get(event)?.delete(callback as (params: unknown) => void)
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
close() {
|
|
105
105
|
try {
|
|
106
106
|
for (const pending of this.pendingRequests.values()) {
|
|
107
107
|
pending.reject(new Error('CDPSession detached'))
|
|
@@ -128,7 +128,7 @@ export async function getCDPSessionForPage({ page, wsUrl }: { page: Page; wsUrl:
|
|
|
128
128
|
const pages = page.context().pages()
|
|
129
129
|
const pageIndex = pages.indexOf(page)
|
|
130
130
|
if (pageIndex === -1) {
|
|
131
|
-
cdp.
|
|
131
|
+
cdp.close()
|
|
132
132
|
throw new Error('Page not found in context')
|
|
133
133
|
}
|
|
134
134
|
|
|
@@ -136,13 +136,13 @@ export async function getCDPSessionForPage({ page, wsUrl }: { page: Page; wsUrl:
|
|
|
136
136
|
const pageTargets = targetInfos.filter((t) => t.type === 'page')
|
|
137
137
|
|
|
138
138
|
if (pageIndex >= pageTargets.length) {
|
|
139
|
-
cdp.
|
|
139
|
+
cdp.close()
|
|
140
140
|
throw new Error(`Page index ${pageIndex} out of bounds (${pageTargets.length} targets)`)
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
const target = pageTargets[pageIndex]
|
|
144
144
|
if (target.url !== page.url()) {
|
|
145
|
-
cdp.
|
|
145
|
+
cdp.close()
|
|
146
146
|
throw new Error(`URL mismatch: page has "${page.url()}" but target has "${target.url}"`)
|
|
147
147
|
}
|
|
148
148
|
|