patchright-bun 1.58.2 → 1.59.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.
Files changed (108) hide show
  1. package/ThirdPartyNotices.txt +10 -1133
  2. package/lib/agents/generateAgents.js +2 -4
  3. package/lib/common/config.js +4 -5
  4. package/lib/common/expectBundleImpl.js +221 -221
  5. package/lib/common/process.js +1 -0
  6. package/lib/common/test.js +10 -1
  7. package/lib/common/testType.js +3 -0
  8. package/lib/common/validators.js +38 -38
  9. package/lib/errorContext.js +121 -0
  10. package/lib/index.js +98 -60
  11. package/lib/isomorphic/teleReceiver.js +26 -9
  12. package/lib/isomorphic/testServerConnection.js +3 -5
  13. package/lib/matchers/matchers.js +2 -0
  14. package/lib/matchers/toMatchAriaSnapshot.js +5 -1
  15. package/lib/matchers/toMatchSnapshot.js +42 -35
  16. package/lib/mcp/test/browserBackend.js +45 -22
  17. package/lib/mcp/test/generatorTools.js +9 -9
  18. package/lib/mcp/test/plannerTools.js +17 -17
  19. package/lib/mcp/test/testBackend.js +27 -27
  20. package/lib/mcp/test/testContext.js +6 -8
  21. package/lib/mcp/test/testTools.js +9 -9
  22. package/lib/plugins/webServerPlugin.js +2 -1
  23. package/lib/program.js +34 -212
  24. package/lib/reportActions.js +80 -0
  25. package/lib/reporters/base.js +4 -5
  26. package/lib/reporters/blob.js +2 -2
  27. package/lib/reporters/github.js +1 -2
  28. package/lib/reporters/html.js +64 -31
  29. package/lib/reporters/junit.js +104 -15
  30. package/lib/reporters/line.js +1 -1
  31. package/lib/reporters/list.js +2 -3
  32. package/lib/reporters/merge.js +47 -26
  33. package/lib/reporters/multiplexer.js +6 -2
  34. package/lib/reporters/teleEmitter.js +2 -0
  35. package/lib/runner/dispatcher.js +6 -14
  36. package/lib/runner/loadUtils.js +11 -5
  37. package/lib/runner/projectUtils.js +1 -1
  38. package/lib/runner/reporters.js +5 -0
  39. package/lib/runner/tasks.js +11 -8
  40. package/lib/runner/testRunner.js +2 -2
  41. package/lib/runner/workerHost.js +0 -3
  42. package/lib/testActions.js +220 -0
  43. package/lib/transform/babelBundle.js +0 -3
  44. package/lib/transform/babelBundleImpl.js +134 -134
  45. package/lib/transform/compilationCache.js +0 -2
  46. package/lib/transform/esmLoader.js +8 -6
  47. package/lib/transform/transform.js +3 -10
  48. package/lib/utilsBundle.js +0 -7
  49. package/lib/utilsBundleImpl.js +48 -51
  50. package/lib/worker/fixtureRunner.js +2 -2
  51. package/lib/worker/testInfo.js +10 -14
  52. package/lib/worker/testTracing.js +12 -6
  53. package/lib/worker/timeoutManager.js +14 -3
  54. package/lib/worker/workerMain.js +24 -21
  55. package/package.json +2 -6
  56. package/types/test.d.ts +83 -12
  57. package/lib/mcp/browser/browserContextFactory.js +0 -329
  58. package/lib/mcp/browser/browserServerBackend.js +0 -84
  59. package/lib/mcp/browser/config.js +0 -421
  60. package/lib/mcp/browser/context.js +0 -244
  61. package/lib/mcp/browser/response.js +0 -278
  62. package/lib/mcp/browser/sessionLog.js +0 -75
  63. package/lib/mcp/browser/tab.js +0 -343
  64. package/lib/mcp/browser/tools/common.js +0 -65
  65. package/lib/mcp/browser/tools/console.js +0 -46
  66. package/lib/mcp/browser/tools/dialogs.js +0 -60
  67. package/lib/mcp/browser/tools/evaluate.js +0 -61
  68. package/lib/mcp/browser/tools/files.js +0 -58
  69. package/lib/mcp/browser/tools/form.js +0 -63
  70. package/lib/mcp/browser/tools/install.js +0 -72
  71. package/lib/mcp/browser/tools/keyboard.js +0 -107
  72. package/lib/mcp/browser/tools/mouse.js +0 -107
  73. package/lib/mcp/browser/tools/navigate.js +0 -71
  74. package/lib/mcp/browser/tools/network.js +0 -63
  75. package/lib/mcp/browser/tools/open.js +0 -57
  76. package/lib/mcp/browser/tools/pdf.js +0 -49
  77. package/lib/mcp/browser/tools/runCode.js +0 -78
  78. package/lib/mcp/browser/tools/screenshot.js +0 -93
  79. package/lib/mcp/browser/tools/snapshot.js +0 -173
  80. package/lib/mcp/browser/tools/tabs.js +0 -67
  81. package/lib/mcp/browser/tools/tool.js +0 -47
  82. package/lib/mcp/browser/tools/tracing.js +0 -74
  83. package/lib/mcp/browser/tools/utils.js +0 -94
  84. package/lib/mcp/browser/tools/verify.js +0 -143
  85. package/lib/mcp/browser/tools/wait.js +0 -63
  86. package/lib/mcp/browser/tools.js +0 -84
  87. package/lib/mcp/browser/watchdog.js +0 -44
  88. package/lib/mcp/config.d.js +0 -16
  89. package/lib/mcp/extension/cdpRelay.js +0 -351
  90. package/lib/mcp/extension/extensionContextFactory.js +0 -76
  91. package/lib/mcp/extension/protocol.js +0 -28
  92. package/lib/mcp/index.js +0 -61
  93. package/lib/mcp/log.js +0 -35
  94. package/lib/mcp/program.js +0 -111
  95. package/lib/mcp/sdk/exports.js +0 -28
  96. package/lib/mcp/sdk/http.js +0 -152
  97. package/lib/mcp/sdk/inProcessTransport.js +0 -71
  98. package/lib/mcp/sdk/server.js +0 -223
  99. package/lib/mcp/sdk/tool.js +0 -47
  100. package/lib/mcp/terminal/cli.js +0 -296
  101. package/lib/mcp/terminal/command.js +0 -56
  102. package/lib/mcp/terminal/commands.js +0 -333
  103. package/lib/mcp/terminal/daemon.js +0 -129
  104. package/lib/mcp/terminal/help.json +0 -32
  105. package/lib/mcp/terminal/helpGenerator.js +0 -88
  106. package/lib/mcp/terminal/socketConnection.js +0 -80
  107. package/lib/runner/storage.js +0 -91
  108. package/lib/transform/md.js +0 -221
@@ -1,129 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var daemon_exports = {};
30
- __export(daemon_exports, {
31
- startMcpDaemonServer: () => startMcpDaemonServer
32
- });
33
- module.exports = __toCommonJS(daemon_exports);
34
- var import_promises = __toESM(require("fs/promises"));
35
- var import_net = __toESM(require("net"));
36
- var import_os = __toESM(require("os"));
37
- var import_path = __toESM(require("path"));
38
- var import_url = __toESM(require("url"));
39
- var import_utilsBundle = require("patchright-bun-core/lib/utilsBundle");
40
- var import_socketConnection = require("./socketConnection");
41
- var import_commands = require("./commands");
42
- var import_command = require("./command");
43
- const daemonDebug = (0, import_utilsBundle.debug)("pw:daemon");
44
- async function socketExists(socketPath) {
45
- try {
46
- const stat = await import_promises.default.stat(socketPath);
47
- if (stat?.isSocket())
48
- return true;
49
- } catch (e) {
50
- }
51
- return false;
52
- }
53
- async function startMcpDaemonServer(socketPath, serverBackendFactory) {
54
- if (import_os.default.platform() !== "win32" && await socketExists(socketPath)) {
55
- daemonDebug(`Socket already exists, removing: ${socketPath}`);
56
- try {
57
- await import_promises.default.unlink(socketPath);
58
- } catch (error) {
59
- daemonDebug(`Failed to remove existing socket: ${error}`);
60
- throw error;
61
- }
62
- }
63
- const backend = serverBackendFactory.create();
64
- const cwd = import_url.default.pathToFileURL(process.cwd()).href;
65
- await backend.initialize?.({
66
- name: "playwright-cli",
67
- version: "1.0.0",
68
- roots: [{
69
- uri: cwd,
70
- name: "cwd"
71
- }],
72
- timestamp: Date.now()
73
- });
74
- await import_promises.default.mkdir(import_path.default.dirname(socketPath), { recursive: true });
75
- const server = import_net.default.createServer((socket) => {
76
- daemonDebug("new client connection");
77
- const connection = new import_socketConnection.SocketConnection(socket);
78
- connection.onclose = () => {
79
- daemonDebug("client disconnected");
80
- };
81
- connection.onmessage = async (message) => {
82
- const { id, method, params } = message;
83
- try {
84
- daemonDebug("received command", method);
85
- if (method === "runCliCommand") {
86
- const { toolName, toolParams } = parseCliCommand(params.args);
87
- const response = await backend.callTool(toolName, toolParams, () => {
88
- });
89
- await connection.send({ id, result: formatResult(response) });
90
- } else {
91
- throw new Error(`Unknown method: ${method}`);
92
- }
93
- } catch (e) {
94
- daemonDebug("command failed", e);
95
- await connection.send({ id, error: e.message });
96
- }
97
- };
98
- });
99
- return new Promise((resolve, reject) => {
100
- server.on("error", (error) => {
101
- daemonDebug(`server error: ${error.message}`);
102
- reject(error);
103
- });
104
- server.listen(socketPath, () => {
105
- daemonDebug(`daemon server listening on ${socketPath}`);
106
- resolve(socketPath);
107
- });
108
- });
109
- }
110
- function formatResult(result) {
111
- const lines = [];
112
- for (const content of result.content) {
113
- if (content.type === "text")
114
- lines.push(content.text);
115
- else
116
- lines.push(`<${content.type} content>`);
117
- }
118
- return lines.join("\n");
119
- }
120
- function parseCliCommand(args) {
121
- const command = import_commands.commands[args._[0]];
122
- if (!command)
123
- throw new Error("Command is required");
124
- return (0, import_command.parseCommand)(command, args);
125
- }
126
- // Annotate the CommonJS export names for ESM import in node:
127
- 0 && (module.exports = {
128
- startMcpDaemonServer
129
- });
@@ -1,32 +0,0 @@
1
- {
2
- "global": "Usage: playwright-cli <command> [options]\nCommands:\n click <ref> perform click on a web page\n close close the page\n dblclick <ref> perform double click on a web page\n console <level> returns all console messages\n drag <startRef> <endRef> perform drag and drop between two elements\n evaluate <function> <ref> evaluate javascript expression on page or element\n upload-file upload one or multiple files\n handle-dialog <accept> <promptText> handle a dialog\n hover <ref> hover over element on page\n open <url> open url\n go-back go back to the previous page\n network-requests returns all network requests since loading the page\n press <key> press a key on the keyboard\n resize <width> <height> resize the browser window\n run-code <code> run playwright code snippet\n select-option <ref> <values> select an option in a dropdown\n snapshot capture accessibility snapshot of the current page, this is better than screenshot\n screenshot <ref> take a screenshot of the current page. you can't perform actions based on the screenshot, use browser_snapshot for actions.\n type <text> type text into editable element\n wait-for wait for text to appear or disappear or a specified time to pass\n tab <action> <index> close a browser tab\n mouse-click-xy <x> <y> click left mouse button at a given position\n mouse-drag-xy <startX> <startY> <endX> <endY> drag left mouse button to a given position\n mouse-move-xy <x> <y> move mouse to a given position\n pdf-save save page as pdf\n start-tracing start trace recording\n stop-tracing stop trace recording",
3
- "commands": {
4
- "click": "playwright-cli click <ref>\n\nPerform click on a web page\n\nArguments:\n <ref>\tExact target element reference from the page snapshot\nOptions:\n --button\tbutton to click, defaults to left\n --modifiers\tmodifier keys to press",
5
- "close": "playwright-cli close \n\nClose the page\n",
6
- "dblclick": "playwright-cli dblclick <ref>\n\nPerform double click on a web page\n\nArguments:\n <ref>\tExact target element reference from the page snapshot\nOptions:\n --button\tbutton to click, defaults to left\n --modifiers\tmodifier keys to press",
7
- "console": "playwright-cli console <level>\n\nReturns all console messages\n\nArguments:\n <level>\tLevel of the console messages to return. Each level includes the messages of more severe levels. Defaults to \"info\".",
8
- "drag": "playwright-cli drag <startRef> <endRef>\n\nPerform drag and drop between two elements\n\nArguments:\n <startRef>\tExact source element reference from the page snapshot\n <endRef>\tExact target element reference from the page snapshot\nOptions:\n --headed\trun browser in headed mode",
9
- "evaluate": "playwright-cli evaluate <function> <ref>\n\nEvaluate JavaScript expression on page or element\n\nArguments:\n <function>\t() => { /* code */ } or (element) => { /* code */ } when element is provided\n <ref>\tExact target element reference from the page snapshot",
10
- "upload-file": "playwright-cli upload-file \n\nUpload one or multiple files\n\nOptions:\n --paths\tthe absolute paths to the files to upload. can be single file or multiple files. if omitted, file chooser is cancelled.",
11
- "handle-dialog": "playwright-cli handle-dialog <accept> <promptText>\n\nHandle a dialog\n\nArguments:\n <accept>\tWhether to accept the dialog.\n <promptText>\tThe text of the prompt in case of a prompt dialog.",
12
- "hover": "playwright-cli hover <ref>\n\nHover over element on page\n\nArguments:\n <ref>\tExact target element reference from the page snapshot",
13
- "open": "playwright-cli open <url>\n\nOpen URL\n\nArguments:\n <url>\tThe URL to navigate to\nOptions:\n --headed\trun browser in headed mode",
14
- "go-back": "playwright-cli go-back \n\nGo back to the previous page\n",
15
- "network-requests": "playwright-cli network-requests \n\nReturns all network requests since loading the page\n\nOptions:\n --includeStatic\twhether to include successful static resources like images, fonts, scripts, etc. defaults to false.",
16
- "press": "playwright-cli press <key>\n\nPress a key on the keyboard\n\nArguments:\n <key>\tName of the key to press or a character to generate, such as `ArrowLeft` or `a`",
17
- "resize": "playwright-cli resize <width> <height>\n\nResize the browser window\n\nArguments:\n <width>\tWidth of the browser window\n <height>\tHeight of the browser window",
18
- "run-code": "playwright-cli run-code <code>\n\nRun Playwright code snippet\n\nArguments:\n <code>\tA JavaScript function containing Playwright code to execute. It will be invoked with a single argument, page, which you can use for any page interaction.",
19
- "select-option": "playwright-cli select-option <ref> <values>\n\nSelect an option in a dropdown\n\nArguments:\n <ref>\tExact target element reference from the page snapshot\n <values>\tArray of values to select in the dropdown. This can be a single value or multiple values.",
20
- "snapshot": "playwright-cli snapshot \n\nCapture accessibility snapshot of the current page, this is better than screenshot\n\nOptions:\n --filename\tsave snapshot to markdown file instead of returning it in the response.",
21
- "screenshot": "playwright-cli screenshot <ref>\n\nTake a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.\n\nArguments:\n <ref>\tExact target element reference from the page snapshot.\nOptions:\n --filename\tfile name to save the screenshot to. defaults to `page-{timestamp}.{png|jpeg}` if not specified.\n --fullPage\twhen true, takes a screenshot of the full scrollable page, instead of the currently visible viewport.",
22
- "type": "playwright-cli type <text>\n\nType text into editable element\n\nArguments:\n <text>\tText to type into the element\nOptions:\n --submit\twhether to submit entered text (press enter after)",
23
- "wait-for": "playwright-cli wait-for \n\nWait for text to appear or disappear or a specified time to pass\n\nOptions:\n --time\tthe time to wait in seconds\n --text\tthe text to wait for\n --textGone\tthe text to wait for to disappear",
24
- "tab": "playwright-cli tab <action> <index>\n\nClose a browser tab\n\nArguments:\n <action>\tAction to perform on tabs, 'list' | 'new' | 'close' | 'select'\n <index>\tTab index. If omitted, current tab is closed.",
25
- "mouse-click-xy": "playwright-cli mouse-click-xy <x> <y>\n\nClick left mouse button at a given position\n\nArguments:\n <x>\tX coordinate\n <y>\tY coordinate",
26
- "mouse-drag-xy": "playwright-cli mouse-drag-xy <startX> <startY> <endX> <endY>\n\nDrag left mouse button to a given position\n\nArguments:\n <startX>\tStart X coordinate\n <startY>\tStart Y coordinate\n <endX>\tEnd X coordinate\n <endY>\tEnd Y coordinate",
27
- "mouse-move-xy": "playwright-cli mouse-move-xy <x> <y>\n\nMove mouse to a given position\n\nArguments:\n <x>\tX coordinate\n <y>\tY coordinate",
28
- "pdf-save": "playwright-cli pdf-save \n\nSave page as PDF\n\nOptions:\n --filename\tfile name to save the pdf to. defaults to `page-{timestamp}.pdf` if not specified.",
29
- "start-tracing": "playwright-cli start-tracing \n\nStart trace recording\n",
30
- "stop-tracing": "playwright-cli stop-tracing \n\nStop trace recording\n"
31
- }
32
- }
@@ -1,88 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
- var import_fs = __toESM(require("fs"));
25
- var import_path = __toESM(require("path"));
26
- var import_commands = require("./commands");
27
- function generateCommandHelp(command) {
28
- const args = [];
29
- const shape = command.args ? command.args.shape : {};
30
- for (const [name, schema] of Object.entries(shape)) {
31
- const zodSchema = schema;
32
- const description = zodSchema.description ?? "";
33
- args.push({ name, description });
34
- }
35
- const lines = [
36
- `playwright-cli ${command.name} ${Object.keys(shape).map((k) => `<${k}>`).join(" ")}`,
37
- "",
38
- command.description,
39
- ""
40
- ];
41
- if (args.length) {
42
- lines.push("Arguments:");
43
- lines.push(...args.map(({ name, description }) => ` <${name}> ${description}`));
44
- }
45
- if (command.options) {
46
- lines.push("Options:");
47
- const optionsShape = command.options.shape;
48
- for (const [name, schema] of Object.entries(optionsShape)) {
49
- const zodSchema = schema;
50
- const description = (zodSchema.description ?? "").toLowerCase();
51
- lines.push(` --${name} ${description}`);
52
- }
53
- }
54
- return lines.join("\n");
55
- }
56
- function generateHelp() {
57
- const lines = [];
58
- lines.push("Usage: playwright-cli <command> [options]");
59
- lines.push("Commands:");
60
- for (const command of Object.values(import_commands.commands))
61
- lines.push(" " + generateHelpEntry(command));
62
- return lines.join("\n");
63
- }
64
- function generateHelpEntry(command) {
65
- const args = [];
66
- const shape = command.args.shape;
67
- for (const [name, schema] of Object.entries(shape)) {
68
- const zodSchema = schema;
69
- const description = zodSchema.description ?? "";
70
- args.push({ name, description });
71
- }
72
- const prefix = `${command.name} ${Object.keys(shape).map((k) => `<${k}>`).join(" ")}`;
73
- const suffix = command.description.toLowerCase();
74
- const padding = " ".repeat(Math.max(1, 40 - prefix.length));
75
- return prefix + padding + suffix;
76
- }
77
- async function main() {
78
- const help = {
79
- global: generateHelp(),
80
- commands: Object.fromEntries(
81
- Object.entries(import_commands.commands).map(([name, command]) => [name, generateCommandHelp(command)])
82
- )
83
- };
84
- const fileName = import_path.default.resolve(__dirname, "help.json").replace("lib", "src");
85
- console.log("Writing ", import_path.default.relative(process.cwd(), fileName));
86
- await import_fs.default.promises.writeFile(fileName, JSON.stringify(help, null, 2));
87
- }
88
- void main();
@@ -1,80 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var socketConnection_exports = {};
20
- __export(socketConnection_exports, {
21
- SocketConnection: () => SocketConnection
22
- });
23
- module.exports = __toCommonJS(socketConnection_exports);
24
- var import_utilsBundle = require("patchright-bun-core/lib/utilsBundle");
25
- const daemonDebug = (0, import_utilsBundle.debug)("pw:daemon");
26
- class SocketConnection {
27
- constructor(socket) {
28
- this._pendingBuffers = [];
29
- this._socket = socket;
30
- socket.on("data", (buffer) => this._onData(buffer));
31
- socket.on("close", () => {
32
- this.onclose?.();
33
- });
34
- socket.on("error", (e) => daemonDebug(`error: ${e.message}`));
35
- }
36
- async send(message) {
37
- await new Promise((resolve, reject) => {
38
- this._socket.write(`${JSON.stringify(message)}
39
- `, (error) => {
40
- if (error)
41
- reject(error);
42
- else
43
- resolve(void 0);
44
- });
45
- });
46
- }
47
- close() {
48
- this._socket.destroy();
49
- }
50
- _onData(buffer) {
51
- let end = buffer.indexOf("\n");
52
- if (end === -1) {
53
- this._pendingBuffers.push(buffer);
54
- return;
55
- }
56
- this._pendingBuffers.push(buffer.slice(0, end));
57
- const message = Buffer.concat(this._pendingBuffers).toString();
58
- this._dispatchMessage(message);
59
- let start = end + 1;
60
- end = buffer.indexOf("\n", start);
61
- while (end !== -1) {
62
- const message2 = buffer.toString(void 0, start, end);
63
- this._dispatchMessage(message2);
64
- start = end + 1;
65
- end = buffer.indexOf("\n", start);
66
- }
67
- this._pendingBuffers = [buffer.slice(start)];
68
- }
69
- _dispatchMessage(message) {
70
- try {
71
- this.onmessage?.(JSON.parse(message));
72
- } catch (e) {
73
- daemonDebug("failed to dispatch message", e);
74
- }
75
- }
76
- }
77
- // Annotate the CommonJS export names for ESM import in node:
78
- 0 && (module.exports = {
79
- SocketConnection
80
- });
@@ -1,91 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var storage_exports = {};
30
- __export(storage_exports, {
31
- Storage: () => Storage
32
- });
33
- module.exports = __toCommonJS(storage_exports);
34
- var import_fs = __toESM(require("fs"));
35
- var import_path = __toESM(require("path"));
36
- var import_utils = require("patchright-bun-core/lib/utils");
37
- class Storage {
38
- static {
39
- this._storages = /* @__PURE__ */ new Map();
40
- }
41
- static {
42
- this._serializeQueue = Promise.resolve();
43
- }
44
- static clone(storageFile, outputDir) {
45
- return Storage._withStorage(storageFile, (storage) => storage._clone(outputDir));
46
- }
47
- static upstream(storageFile, storageOutFile) {
48
- return Storage._withStorage(storageFile, (storage) => storage._upstream(storageOutFile));
49
- }
50
- static _withStorage(fileName, runnable) {
51
- this._serializeQueue = this._serializeQueue.then(() => {
52
- let storage = Storage._storages.get(fileName);
53
- if (!storage) {
54
- storage = new Storage(fileName);
55
- Storage._storages.set(fileName, storage);
56
- }
57
- return runnable(storage);
58
- });
59
- return this._serializeQueue;
60
- }
61
- constructor(fileName) {
62
- this._fileName = fileName;
63
- }
64
- async _clone(outputDir) {
65
- const entries = await this._load();
66
- if (this._lastSnapshotFileName)
67
- return this._lastSnapshotFileName;
68
- const snapshotFile = import_path.default.join(outputDir, `pw-storage-${(0, import_utils.createGuid)()}.json`);
69
- await import_fs.default.promises.writeFile(snapshotFile, JSON.stringify(entries, null, 2)).catch(() => {
70
- });
71
- this._lastSnapshotFileName = snapshotFile;
72
- return snapshotFile;
73
- }
74
- async _upstream(storageOutFile) {
75
- const entries = await this._load();
76
- const newEntries = await import_fs.default.promises.readFile(storageOutFile, "utf8").then(JSON.parse).catch(() => ({}));
77
- for (const [key, newValue] of Object.entries(newEntries))
78
- entries[key] = newValue;
79
- this._lastSnapshotFileName = void 0;
80
- await import_fs.default.promises.writeFile(this._fileName, JSON.stringify(entries, null, 2));
81
- }
82
- async _load() {
83
- if (!this._entriesPromise)
84
- this._entriesPromise = import_fs.default.promises.readFile(this._fileName, "utf8").then(JSON.parse).catch(() => ({}));
85
- return this._entriesPromise;
86
- }
87
- }
88
- // Annotate the CommonJS export names for ESM import in node:
89
- 0 && (module.exports = {
90
- Storage
91
- });
@@ -1,221 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var md_exports = {};
30
- __export(md_exports, {
31
- transformMDToTS: () => transformMDToTS
32
- });
33
- module.exports = __toCommonJS(md_exports);
34
- var import_fs = __toESM(require("fs"));
35
- var import_path = __toESM(require("path"));
36
- var import_utilsBundle = require("../utilsBundle");
37
- var import_babelBundle = require("./babelBundle");
38
- function transformMDToTS(code, filename) {
39
- const parsed = parseSpec(code, filename);
40
- let fixtures = resolveFixtures(filename, parsed.props.find((prop) => prop[0] === "fixtures")?.[1]);
41
- const seed = parsed.props.find((prop) => prop[0] === "seed")?.[1];
42
- if (seed) {
43
- const seedFile = import_path.default.resolve(import_path.default.dirname(filename), seed.text);
44
- const seedContents = import_fs.default.readFileSync(seedFile, "utf-8");
45
- const parsedSeed = parseSpec(seedContents, seedFile);
46
- if (parsedSeed.tests.length !== 1)
47
- throw new Error(`while parsing ${seedFile}: seed file must contain exactly one test`);
48
- if (parsedSeed.tests[0].props.length)
49
- throw new Error(`while parsing ${seedFile}: seed test must not have properties`);
50
- for (const test of parsed.tests)
51
- test.lines = parsedSeed.tests[0].lines.concat(test.lines);
52
- const seedFixtures = resolveFixtures(seedFile, parsedSeed.props.find((prop) => prop[0] === "fixtures")?.[1]);
53
- if (seedFixtures && fixtures)
54
- throw new Error(`while parsing ${filename}: either seed or test can specify fixtures, but not both`);
55
- fixtures ??= seedFixtures;
56
- }
57
- const map = new import_babelBundle.genMapping.GenMapping({});
58
- const lines = [];
59
- const addLine = (line) => {
60
- lines.push(line.text);
61
- if (line.source) {
62
- import_babelBundle.genMapping.addMapping(map, {
63
- generated: { line: lines.length, column: 0 },
64
- source: line.source.filename,
65
- original: { line: line.source.line, column: line.source.column - 1 }
66
- });
67
- }
68
- };
69
- if (fixtures)
70
- addLine({ text: `import { test, expect } from ${escapeString(import_path.default.relative(import_path.default.dirname(filename), fixtures.text))};`, source: fixtures.source });
71
- else
72
- addLine({ text: `import { test, expect } from '@playwright/test';` });
73
- addLine({ text: `test.describe(${escapeString(parsed.describe.text)}, () => {`, source: parsed.describe.source });
74
- for (const test of parsed.tests) {
75
- const tags = [];
76
- const annotations = [];
77
- for (const [key, value] of test.props) {
78
- if (key === "tag") {
79
- tags.push(...value.text.split(" ").map((s) => s.trim()).filter((s) => !!s));
80
- } else if (key === "annotation") {
81
- if (!value.text.includes("="))
82
- throw new Error(`while parsing ${filename}: annotation must be in format "type=description", found "${value}"`);
83
- const [type, description] = value.text.split("=").map((s) => s.trim());
84
- annotations.push({ type, description });
85
- }
86
- }
87
- let props = "";
88
- if (tags.length || annotations.length) {
89
- props = "{ ";
90
- if (tags.length)
91
- props += `tag: [${tags.map((tag) => escapeString(tag)).join(", ")}], `;
92
- if (annotations.length)
93
- props += `annotation: [${annotations.map((a) => `{ type: ${escapeString(a.type)}, description: ${escapeString(a.description)} }`).join(", ")}], `;
94
- props += "}, ";
95
- }
96
- addLine({ text: ` test(${escapeString(test.title.text)}, ${props}async ({ page, agent }) => {`, source: test.title.source });
97
- for (const line of test.lines)
98
- addLine({ text: " " + line.text, source: line.source });
99
- addLine({ text: ` });`, source: test.title.source });
100
- }
101
- addLine({ text: `});`, source: parsed.describe.source });
102
- addLine({ text: `` });
103
- const encodedMap = import_babelBundle.genMapping.toEncodedMap(map);
104
- const result = lines.join("\n");
105
- return { code: result, map: encodedMap };
106
- }
107
- function resolveFixtures(filename, prop) {
108
- if (!prop)
109
- return;
110
- return { text: import_path.default.resolve(import_path.default.dirname(filename), prop.text), source: prop.source };
111
- }
112
- function escapeString(s) {
113
- return `'` + s.replace(/\n/g, " ").replace(/'/g, `\\'`) + `'`;
114
- }
115
- function parsingError(filename, node, message) {
116
- const position = node?.position?.start ? ` at ${node.position.start.line}:${node.position.start.column}` : "";
117
- return new Error(`while parsing ${filename}${position}: ${message}`);
118
- }
119
- function asText(filename, node, errorMessage, skipChild) {
120
- let children = node.children.filter((child) => child !== skipChild);
121
- while (children.length === 1 && children[0].type === "paragraph")
122
- children = children[0].children;
123
- if (children.length !== 1 || children[0].type !== "text")
124
- throw parsingError(filename, node, errorMessage);
125
- return { text: children[0].value, source: node.position ? { filename, line: node.position.start.line, column: node.position.start.column } : void 0 };
126
- }
127
- function parseSpec(content, filename) {
128
- const root = (0, import_utilsBundle.parseMarkdown)(content);
129
- const props = [];
130
- const children = [...root.children];
131
- const describeNode = children[0];
132
- children.shift();
133
- if (describeNode?.type !== "heading" || describeNode.depth !== 2)
134
- throw parsingError(filename, describeNode, `describe title must be ##`);
135
- const describe = asText(filename, describeNode, `describe title must be ##`);
136
- if (children[0]?.type === "list") {
137
- parseProps(filename, children[0], props);
138
- children.shift();
139
- }
140
- const tests = [];
141
- while (children.length) {
142
- let nextIndex = children.findIndex((n, i) => i > 0 && n.type === "heading" && n.depth === 3);
143
- if (nextIndex === -1)
144
- nextIndex = children.length;
145
- const testNodes = children.splice(0, nextIndex);
146
- tests.push(parseTest(filename, testNodes));
147
- }
148
- return { describe, tests, props };
149
- }
150
- function parseProp(filename, node, props) {
151
- const propText = asText(filename, node, `property must be a list item without children`);
152
- const match = propText.text.match(/^([^:]+):(.*)$/);
153
- if (!match)
154
- throw parsingError(filename, node, `property must be in format "key: value"`);
155
- props.push([match[1].trim(), { text: match[2].trim(), source: propText.source }]);
156
- }
157
- function parseProps(filename, node, props) {
158
- for (const prop of node.children || []) {
159
- if (prop.type !== "listItem")
160
- throw parsingError(filename, prop, `property must be a list item without children`);
161
- parseProp(filename, prop, props);
162
- }
163
- }
164
- function parseTest(filename, nodes) {
165
- const titleNode = nodes[0];
166
- nodes.shift();
167
- if (titleNode.type !== "heading" || titleNode.depth !== 3)
168
- throw parsingError(filename, titleNode, `test title must be ###`);
169
- const title = asText(filename, titleNode, `test title must be ###`);
170
- const props = [];
171
- let handlingProps = true;
172
- const lines = [];
173
- const visit = (node, indent) => {
174
- if (node.type === "list") {
175
- for (const child of node.children)
176
- visit(child, indent);
177
- return;
178
- }
179
- if (node.type === "listItem") {
180
- const listItem = node;
181
- const lastChild = listItem.children[listItem.children.length - 1];
182
- if (lastChild?.type === "code") {
183
- handlingProps = false;
184
- const { text, source } = asText(filename, listItem, `code step must be a list item with a single code block`, lastChild);
185
- lines.push({ text: `${indent}await test.step(${escapeString(text)}, async () => {`, source });
186
- for (const [index, code] of lastChild.value.split("\n").entries())
187
- lines.push({ text: indent + " " + code, source: lastChild.position ? { filename, line: lastChild.position.start.line + 1 + index, column: lastChild.position.start.column } : void 0 });
188
- lines.push({ text: `${indent}});`, source });
189
- } else {
190
- const { text, source } = asText(filename, listItem, `step must contain a single instruction`, lastChild?.type === "list" ? lastChild : void 0);
191
- let isGroup = false;
192
- if (handlingProps && lastChild?.type !== "list" && ["tag:", "annotation:"].some((prefix) => text.startsWith(prefix))) {
193
- parseProp(filename, listItem, props);
194
- } else if (text.startsWith("group:")) {
195
- isGroup = true;
196
- lines.push({ text: `${indent}await test.step(${escapeString(text.substring("group:".length).trim())}, async () => {`, source });
197
- } else if (text.startsWith("expect:")) {
198
- handlingProps = false;
199
- const assertion = text.substring("expect:".length).trim();
200
- lines.push({ text: `${indent}await agent.expect(${escapeString(assertion)});`, source });
201
- } else if (!text.startsWith("//")) {
202
- handlingProps = false;
203
- lines.push({ text: `${indent}await agent.perform(${escapeString(text)});`, source });
204
- }
205
- if (lastChild?.type === "list")
206
- visit(lastChild, indent + (isGroup ? " " : ""));
207
- if (isGroup)
208
- lines.push({ text: `${indent}});`, source });
209
- }
210
- } else {
211
- throw parsingError(filename, node, `test step must be a markdown list item`);
212
- }
213
- };
214
- for (const node of nodes)
215
- visit(node, "");
216
- return { title, lines, props };
217
- }
218
- // Annotate the CommonJS export names for ESM import in node:
219
- 0 && (module.exports = {
220
- transformMDToTS
221
- });