@playwright-repl/browser-extension 0.24.0
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/LICENSE +21 -0
- package/README.md +176 -0
- package/dist/background.js +162567 -0
- package/dist/background.js.map +1 -0
- package/dist/content/recorder.js +479 -0
- package/dist/content/trace-loader.js +12 -0
- package/dist/devtools/console.html +17 -0
- package/dist/devtools/console.js +44 -0
- package/dist/devtools/console.js.map +1 -0
- package/dist/devtools/devtools.html +8 -0
- package/dist/devtools/devtools.js +7 -0
- package/dist/devtools/devtools.js.map +1 -0
- package/dist/icons/dramaturg_icon_128.png +0 -0
- package/dist/icons/dramaturg_icon_16.png +0 -0
- package/dist/icons/dramaturg_icon_32.png +0 -0
- package/dist/icons/dramaturg_icon_48.png +0 -0
- package/dist/index.css +1353 -0
- package/dist/index.js +12462 -0
- package/dist/index.js.map +1 -0
- package/dist/index2.js +27328 -0
- package/dist/index2.js.map +1 -0
- package/dist/manifest.json +49 -0
- package/dist/modulepreload-polyfill.js +30 -0
- package/dist/modulepreload-polyfill.js.map +1 -0
- package/dist/offscreen/offscreen.html +6 -0
- package/dist/offscreen/offscreen.js +151 -0
- package/dist/offscreen/offscreen.js.map +1 -0
- package/dist/panel/panel.html +16 -0
- package/dist/panel/panel.js +2258 -0
- package/dist/panel/panel.js.map +1 -0
- package/dist/preferences/preferences.html +14 -0
- package/dist/preferences/preferences.js +102 -0
- package/dist/preferences/preferences.js.map +1 -0
- package/dist/settings.js +13 -0
- package/dist/settings.js.map +1 -0
- package/dist/sw-debugger-core.js +1139 -0
- package/dist/sw-debugger-core.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest_version": 3,
|
|
3
|
+
"name": "Dramaturg",
|
|
4
|
+
"version": "0.24.0",
|
|
5
|
+
"description": "Playwright engineer's companion — console, editor, runner, debugger, and recorder in a Chrome side panel.",
|
|
6
|
+
"permissions": [
|
|
7
|
+
"activeTab",
|
|
8
|
+
"tabs",
|
|
9
|
+
"sidePanel",
|
|
10
|
+
"debugger",
|
|
11
|
+
"storage",
|
|
12
|
+
"windows",
|
|
13
|
+
"alarms",
|
|
14
|
+
"offscreen",
|
|
15
|
+
"scripting",
|
|
16
|
+
"tabCapture",
|
|
17
|
+
"downloads"
|
|
18
|
+
],
|
|
19
|
+
"host_permissions": [
|
|
20
|
+
"<all_urls>"
|
|
21
|
+
],
|
|
22
|
+
"options_ui": {
|
|
23
|
+
"page": "preferences/preferences.html",
|
|
24
|
+
"open_in_tab": false
|
|
25
|
+
},
|
|
26
|
+
"action": {
|
|
27
|
+
"default_title": "Dramaturg",
|
|
28
|
+
"default_icon": {
|
|
29
|
+
"16": "icons/dramaturg_icon_16.png",
|
|
30
|
+
"32": "icons/dramaturg_icon_32.png",
|
|
31
|
+
"48": "icons/dramaturg_icon_48.png",
|
|
32
|
+
"128": "icons/dramaturg_icon_128.png"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"devtools_page": "devtools/devtools.html",
|
|
36
|
+
"side_panel": {
|
|
37
|
+
"default_path": "panel/panel.html"
|
|
38
|
+
},
|
|
39
|
+
"background": {
|
|
40
|
+
"service_worker": "background.js",
|
|
41
|
+
"type": "module"
|
|
42
|
+
},
|
|
43
|
+
"icons": {
|
|
44
|
+
"16": "icons/dramaturg_icon_16.png",
|
|
45
|
+
"32": "icons/dramaturg_icon_32.png",
|
|
46
|
+
"48": "icons/dramaturg_icon_48.png",
|
|
47
|
+
"128": "icons/dramaturg_icon_128.png"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
(function polyfill() {
|
|
2
|
+
const relList = document.createElement("link").relList;
|
|
3
|
+
if (relList && relList.supports && relList.supports("modulepreload")) return;
|
|
4
|
+
for (const link of document.querySelectorAll('link[rel="modulepreload"]')) processPreload(link);
|
|
5
|
+
new MutationObserver((mutations) => {
|
|
6
|
+
for (const mutation of mutations) {
|
|
7
|
+
if (mutation.type !== "childList") continue;
|
|
8
|
+
for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
|
|
9
|
+
}
|
|
10
|
+
}).observe(document, {
|
|
11
|
+
childList: true,
|
|
12
|
+
subtree: true
|
|
13
|
+
});
|
|
14
|
+
function getFetchOpts(link) {
|
|
15
|
+
const fetchOpts = {};
|
|
16
|
+
if (link.integrity) fetchOpts.integrity = link.integrity;
|
|
17
|
+
if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
|
|
18
|
+
if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
|
|
19
|
+
else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
|
|
20
|
+
else fetchOpts.credentials = "same-origin";
|
|
21
|
+
return fetchOpts;
|
|
22
|
+
}
|
|
23
|
+
function processPreload(link) {
|
|
24
|
+
if (link.ep) return;
|
|
25
|
+
link.ep = true;
|
|
26
|
+
const fetchOpts = getFetchOpts(link);
|
|
27
|
+
fetch(link.href, fetchOpts);
|
|
28
|
+
}
|
|
29
|
+
})();
|
|
30
|
+
//# sourceMappingURL=modulepreload-polyfill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modulepreload-polyfill.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html><head><meta charset="utf-8"><title>Bridge Executor</title> <script type="module" crossorigin src="../offscreen/offscreen.js"></script>
|
|
3
|
+
<link rel="modulepreload" crossorigin href="../modulepreload-polyfill.js">
|
|
4
|
+
</head>
|
|
5
|
+
<body></body>
|
|
6
|
+
</html>
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import "../modulepreload-polyfill.js";
|
|
2
|
+
let recorder;
|
|
3
|
+
let recordedChunks = [];
|
|
4
|
+
let lastBlobUrl = null;
|
|
5
|
+
function revokeLastBlob() {
|
|
6
|
+
if (lastBlobUrl) {
|
|
7
|
+
URL.revokeObjectURL(lastBlobUrl);
|
|
8
|
+
lastBlobUrl = null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
async function startVideoCapture(streamId) {
|
|
12
|
+
if (recorder?.state === "recording") {
|
|
13
|
+
throw new Error("Already recording");
|
|
14
|
+
}
|
|
15
|
+
revokeLastBlob();
|
|
16
|
+
const media = await navigator.mediaDevices.getUserMedia({
|
|
17
|
+
audio: {
|
|
18
|
+
mandatory: {
|
|
19
|
+
chromeMediaSource: "tab",
|
|
20
|
+
chromeMediaSourceId: streamId
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
video: {
|
|
24
|
+
mandatory: {
|
|
25
|
+
chromeMediaSource: "tab",
|
|
26
|
+
chromeMediaSourceId: streamId
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
const output = new AudioContext();
|
|
31
|
+
const source = output.createMediaStreamSource(media);
|
|
32
|
+
source.connect(output.destination);
|
|
33
|
+
recorder = new MediaRecorder(media, { mimeType: "video/webm" });
|
|
34
|
+
recorder.ondataavailable = (event) => recordedChunks.push(event.data);
|
|
35
|
+
recorder.start();
|
|
36
|
+
window.location.hash = "recording";
|
|
37
|
+
}
|
|
38
|
+
async function stopVideoCapture() {
|
|
39
|
+
if (!recorder || recorder.state !== "recording") {
|
|
40
|
+
throw new Error("Not recording");
|
|
41
|
+
}
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
recorder.onstop = () => {
|
|
44
|
+
const blob = new Blob(recordedChunks, { type: "video/webm" });
|
|
45
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
46
|
+
lastBlobUrl = blobUrl;
|
|
47
|
+
const size = blob.size;
|
|
48
|
+
recorder = void 0;
|
|
49
|
+
recordedChunks = [];
|
|
50
|
+
window.location.hash = "";
|
|
51
|
+
resolve({ blobUrl, size });
|
|
52
|
+
};
|
|
53
|
+
recorder.stop();
|
|
54
|
+
recorder.stream.getTracks().forEach((t) => t.stop());
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
let ws = null;
|
|
58
|
+
let reconnectTimer = null;
|
|
59
|
+
let reconnecting = false;
|
|
60
|
+
async function reconnect() {
|
|
61
|
+
if (reconnecting) return;
|
|
62
|
+
if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) return;
|
|
63
|
+
reconnecting = true;
|
|
64
|
+
try {
|
|
65
|
+
const port = await chrome.runtime.sendMessage({ type: "get-bridge-port" });
|
|
66
|
+
connect(port || 9876);
|
|
67
|
+
} catch {
|
|
68
|
+
scheduleReconnect();
|
|
69
|
+
} finally {
|
|
70
|
+
reconnecting = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function scheduleReconnect() {
|
|
74
|
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
75
|
+
reconnectTimer = setTimeout(() => reconnect(), 3e3);
|
|
76
|
+
}
|
|
77
|
+
setInterval(() => {
|
|
78
|
+
if (!ws || ws.readyState === WebSocket.CLOSED) {
|
|
79
|
+
reconnect();
|
|
80
|
+
}
|
|
81
|
+
}, 1e4);
|
|
82
|
+
function connect(port) {
|
|
83
|
+
try {
|
|
84
|
+
ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
85
|
+
ws.onopen = () => {
|
|
86
|
+
chrome.runtime.sendMessage({ type: "bridge-attach" }).then((result) => {
|
|
87
|
+
if (ws?.readyState === WebSocket.OPEN && result?.url)
|
|
88
|
+
ws.send(JSON.stringify({ _event: true, type: "tab-attached", url: result.url }));
|
|
89
|
+
}).catch(() => {
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
ws.onmessage = async (e) => {
|
|
93
|
+
const msg = JSON.parse(e.data);
|
|
94
|
+
try {
|
|
95
|
+
const runtimeMsg = {
|
|
96
|
+
type: "bridge-command",
|
|
97
|
+
command: msg.command,
|
|
98
|
+
scriptType: msg.type,
|
|
99
|
+
language: msg.language
|
|
100
|
+
};
|
|
101
|
+
if (msg.includeSnapshot) runtimeMsg.includeSnapshot = true;
|
|
102
|
+
const result = await chrome.runtime.sendMessage(runtimeMsg);
|
|
103
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
104
|
+
ws.send(JSON.stringify({ id: msg.id, ...result }));
|
|
105
|
+
}
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
108
|
+
ws.send(JSON.stringify({ id: msg.id, text: String(err), isError: true }));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
ws.onclose = () => {
|
|
113
|
+
ws = null;
|
|
114
|
+
scheduleReconnect();
|
|
115
|
+
};
|
|
116
|
+
ws.onerror = () => {
|
|
117
|
+
};
|
|
118
|
+
} catch {
|
|
119
|
+
scheduleReconnect();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
chrome.runtime.sendMessage({ type: "get-bridge-port" }).then((port) => {
|
|
123
|
+
connect(port || 9876);
|
|
124
|
+
});
|
|
125
|
+
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
|
|
126
|
+
if (msg.type === "bridge-port-changed") {
|
|
127
|
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
128
|
+
if (ws) {
|
|
129
|
+
ws.onclose = null;
|
|
130
|
+
ws.close();
|
|
131
|
+
}
|
|
132
|
+
connect(msg.port);
|
|
133
|
+
}
|
|
134
|
+
if (msg.type === "video-capture-start") {
|
|
135
|
+
startVideoCapture(msg.streamId).then(() => sendResponse({ ok: true })).catch((e) => sendResponse({ ok: false, error: e.message }));
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
if (msg.type === "video-capture-stop") {
|
|
139
|
+
stopVideoCapture().then(({ blobUrl, size }) => sendResponse({ ok: true, blobUrl, size })).catch((e) => sendResponse({ ok: false, error: e.message }));
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
if (msg.type === "video-revoke") {
|
|
143
|
+
revokeLastBlob();
|
|
144
|
+
}
|
|
145
|
+
if (msg.type === "tab-attached" || msg.type === "recorded-action" || msg.type === "recorded-fill-update") {
|
|
146
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
147
|
+
ws.send(JSON.stringify({ _event: true, ...msg }));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=offscreen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offscreen.js","sources":["../../src/offscreen/offscreen.ts"],"sourcesContent":["// ─── CLI Bridge (offscreen document) ──────────────────────────────────────────\r\n// Maintains WebSocket connection to the bridge server + handles video capture.\r\n// This runs independently of the side panel — MCP works without the panel open.\r\n\r\n// ─── Video Capture (tabCapture + MediaRecorder) ─────────────────────────────\r\n\r\nlet recorder: MediaRecorder | undefined;\r\nlet recordedChunks: Blob[] = [];\r\nlet lastBlobUrl: string | null = null;\r\n\r\nfunction revokeLastBlob() {\r\n if (lastBlobUrl) {\r\n URL.revokeObjectURL(lastBlobUrl);\r\n lastBlobUrl = null;\r\n }\r\n}\r\n\r\nasync function startVideoCapture(streamId: string) {\r\n if (recorder?.state === 'recording') {\r\n throw new Error('Already recording');\r\n }\r\n revokeLastBlob();\r\n\r\n const media = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n mandatory: {\r\n chromeMediaSource: 'tab',\r\n chromeMediaSourceId: streamId,\r\n },\r\n } as any,\r\n video: {\r\n mandatory: {\r\n chromeMediaSource: 'tab',\r\n chromeMediaSourceId: streamId,\r\n },\r\n } as any,\r\n });\r\n\r\n // Continue playing captured audio to the user\r\n const output = new AudioContext();\r\n const source = output.createMediaStreamSource(media);\r\n source.connect(output.destination);\r\n\r\n recorder = new MediaRecorder(media, { mimeType: 'video/webm' });\r\n recorder.ondataavailable = (event) => recordedChunks.push(event.data);\r\n recorder.start();\r\n\r\n // Track recording state in URL hash (survives SW restarts)\r\n window.location.hash = 'recording';\r\n}\r\n\r\nasync function stopVideoCapture(): Promise<{ blobUrl: string; size: number }> {\r\n if (!recorder || recorder.state !== 'recording') {\r\n throw new Error('Not recording');\r\n }\r\n\r\n return new Promise<{ blobUrl: string; size: number }>((resolve) => {\r\n recorder!.onstop = () => {\r\n const blob = new Blob(recordedChunks, { type: 'video/webm' });\r\n const blobUrl = URL.createObjectURL(blob);\r\n lastBlobUrl = blobUrl;\r\n const size = blob.size;\r\n\r\n // Clean up\r\n recorder = undefined;\r\n recordedChunks = [];\r\n window.location.hash = '';\r\n\r\n resolve({ blobUrl, size });\r\n };\r\n\r\n // Stop recording and release tab capture\r\n recorder!.stop();\r\n recorder!.stream.getTracks().forEach((t) => t.stop());\r\n });\r\n}\r\n\r\n// ─── Bridge WebSocket (command relay) ────────────────────────────────────────\r\n\r\nlet ws: WebSocket | null = null;\r\nlet reconnectTimer: ReturnType<typeof setTimeout> | null = null;\r\nlet reconnecting = false;\r\n\r\nasync function reconnect() {\r\n if (reconnecting) return;\r\n if (ws && (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING)) return;\r\n reconnecting = true;\r\n try {\r\n const port: number = await chrome.runtime.sendMessage({ type: 'get-bridge-port' });\r\n connect(port || 9876);\r\n } catch {\r\n scheduleReconnect();\r\n } finally {\r\n reconnecting = false;\r\n }\r\n}\r\n\r\nfunction scheduleReconnect() {\r\n if (reconnectTimer) clearTimeout(reconnectTimer);\r\n reconnectTimer = setTimeout(() => reconnect(), 3000);\r\n}\r\n\r\n// Periodic health check — reconnect if WebSocket is dead.\r\n// Catches cases where setTimeout gets throttled or the offscreen doc restarts.\r\nsetInterval(() => {\r\n if (!ws || ws.readyState === WebSocket.CLOSED) {\r\n reconnect();\r\n }\r\n}, 10000);\r\n\r\nfunction connect(port: number) {\r\n try {\r\n ws = new WebSocket(`ws://127.0.0.1:${port}`);\r\n\r\n ws.onopen = () => {\r\n // Trigger auto-attach so the CLI knows which tab is connected\r\n chrome.runtime.sendMessage({ type: 'bridge-attach' }).then((result: any) => {\r\n if (ws?.readyState === WebSocket.OPEN && result?.url)\r\n ws.send(JSON.stringify({ _event: true, type: 'tab-attached', url: result.url }));\r\n }).catch(() => {});\r\n };\r\n\r\n ws.onmessage = async (e) => {\r\n const msg = JSON.parse(e.data as string) as {\r\n id: string;\r\n command: string;\r\n type?: 'command' | 'script';\r\n language?: 'pw' | 'javascript';\r\n includeSnapshot?: boolean;\r\n };\r\n\r\n try {\r\n const runtimeMsg: Record<string, unknown> = {\r\n type: 'bridge-command',\r\n command: msg.command,\r\n scriptType: msg.type,\r\n language: msg.language,\r\n };\r\n if (msg.includeSnapshot) runtimeMsg.includeSnapshot = true;\r\n const result = await chrome.runtime.sendMessage(runtimeMsg);\r\n\r\n if (ws?.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ id: msg.id, ...result }));\r\n }\r\n } catch (err) {\r\n if (ws?.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ id: msg.id, text: String(err), isError: true }));\r\n }\r\n }\r\n };\r\n\r\n ws.onclose = () => {\r\n ws = null;\r\n scheduleReconnect();\r\n };\r\n\r\n ws.onerror = () => {};\r\n } catch {\r\n scheduleReconnect();\r\n }\r\n}\r\n\r\nchrome.runtime.sendMessage({ type: 'get-bridge-port' }).then((port: number) => {\r\n connect(port || 9876);\r\n});\r\n\r\n// ─── Message routing from background SW ─────────────────────────────────────\r\n\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nchrome.runtime.onMessage.addListener((msg: any, _sender: any, sendResponse: any) => {\r\n if (msg.type === 'bridge-port-changed') {\r\n if (reconnectTimer) clearTimeout(reconnectTimer);\r\n if (ws) { ws.onclose = null; ws.close(); }\r\n connect(msg.port as number);\r\n }\r\n\r\n // Video capture messages\r\n if (msg.type === 'video-capture-start') {\r\n startVideoCapture(msg.streamId as string)\r\n .then(() => sendResponse({ ok: true }))\r\n .catch((e: Error) => sendResponse({ ok: false, error: e.message }));\r\n return true;\r\n }\r\n if (msg.type === 'video-capture-stop') {\r\n stopVideoCapture()\r\n .then(({ blobUrl, size }) => sendResponse({ ok: true, blobUrl, size }))\r\n .catch((e: Error) => sendResponse({ ok: false, error: e.message }));\r\n return true;\r\n }\r\n if (msg.type === 'video-revoke') {\r\n revokeLastBlob();\r\n }\r\n\r\n // Forward events to the bridge client (CLI/MCP/VS Code)\r\n if (msg.type === 'tab-attached' || msg.type === 'recorded-action' || msg.type === 'recorded-fill-update') {\r\n if (ws?.readyState === WebSocket.OPEN) {\r\n ws.send(JSON.stringify({ _event: true, ...msg }));\r\n }\r\n }\r\n});\r\n\r\nexport {};\r\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<script type="module" crossorigin src="../panel/panel.js"></script>
|
|
6
|
+
<link rel="modulepreload" crossorigin href="../modulepreload-polyfill.js">
|
|
7
|
+
<link rel="modulepreload" crossorigin href="../index.js">
|
|
8
|
+
<link rel="modulepreload" crossorigin href="../sw-debugger-core.js">
|
|
9
|
+
<link rel="modulepreload" crossorigin href="../index2.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="../settings.js">
|
|
11
|
+
<link rel="stylesheet" crossorigin href="../index.css">
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|