@szymonrybczak/playwright-mcp 0.0.2 → 0.0.5
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/index.d.ts +20 -8
- package/lib/cjs/_virtual/_commonjsHelpers.js +9 -0
- package/lib/cjs/_virtual/browser.js +11 -0
- package/lib/cjs/_virtual/browser2.js +7 -0
- package/lib/cjs/cloudflare/package.json.js +10 -0
- package/lib/cjs/index.js +27 -0
- package/lib/cjs/node_modules/debug/src/browser.js +290 -0
- package/lib/cjs/node_modules/debug/src/common.js +307 -0
- package/lib/cjs/node_modules/ms/index.js +176 -0
- package/lib/cjs/package.js +9 -0
- package/lib/cjs/src/browserContextFactory.js +240 -0
- package/lib/cjs/src/config.js +77 -0
- package/lib/cjs/src/connection.js +74 -0
- package/lib/cjs/src/context.js +281 -0
- package/lib/cjs/src/fileUtils.js +25 -0
- package/lib/cjs/src/index.js +15 -0
- package/lib/cjs/src/javascript.js +41 -0
- package/lib/cjs/src/manualPromise.js +39 -0
- package/lib/cjs/src/pageSnapshot.js +35 -0
- package/lib/cjs/src/tab.js +91 -0
- package/lib/cjs/src/tools/common.js +60 -0
- package/lib/cjs/src/tools/console.js +36 -0
- package/lib/cjs/src/tools/dialogs.js +44 -0
- package/lib/cjs/src/tools/files.js +43 -0
- package/lib/cjs/src/tools/install.js +49 -0
- package/lib/cjs/src/tools/keyboard.js +38 -0
- package/lib/cjs/src/tools/navigate.js +85 -0
- package/lib/cjs/src/tools/network.js +43 -0
- package/lib/cjs/src/tools/pdf.js +42 -0
- package/lib/cjs/src/tools/screenshot.js +69 -0
- package/lib/cjs/src/tools/snapshot.js +195 -0
- package/lib/cjs/src/tools/tabs.js +110 -0
- package/lib/cjs/src/tools/testing.js +52 -0
- package/lib/cjs/src/tools/tool.js +9 -0
- package/lib/cjs/src/tools/utils.js +75 -0
- package/lib/cjs/src/tools/vision.js +181 -0
- package/lib/cjs/src/tools/wait.js +51 -0
- package/lib/cjs/src/tools.js +54 -0
- package/lib/esm/_virtual/_commonjsHelpers.js +5 -0
- package/lib/esm/_virtual/browser.js +7 -0
- package/lib/esm/_virtual/browser2.js +3 -0
- package/lib/esm/cloudflare/package.json.js +5 -0
- package/lib/esm/index.js +23 -0
- package/lib/esm/node_modules/debug/src/browser.js +286 -0
- package/lib/esm/node_modules/debug/src/common.js +303 -0
- package/lib/esm/node_modules/ms/index.js +172 -0
- package/lib/esm/package.js +5 -0
- package/lib/esm/src/browserContextFactory.js +216 -0
- package/lib/esm/src/config.js +72 -0
- package/lib/esm/src/connection.js +69 -0
- package/lib/esm/src/context.js +277 -0
- package/lib/esm/src/fileUtils.js +20 -0
- package/lib/esm/src/index.js +11 -0
- package/lib/esm/src/javascript.js +35 -0
- package/lib/esm/src/manualPromise.js +35 -0
- package/lib/esm/src/pageSnapshot.js +31 -0
- package/lib/esm/src/tab.js +87 -0
- package/lib/esm/src/tools/common.js +56 -0
- package/lib/esm/src/tools/console.js +32 -0
- package/lib/esm/src/tools/dialogs.js +40 -0
- package/lib/esm/src/tools/files.js +39 -0
- package/lib/esm/src/tools/install.js +45 -0
- package/lib/esm/src/tools/keyboard.js +34 -0
- package/lib/esm/src/tools/navigate.js +81 -0
- package/lib/esm/src/tools/network.js +39 -0
- package/lib/esm/src/tools/pdf.js +38 -0
- package/lib/esm/src/tools/screenshot.js +65 -0
- package/lib/esm/src/tools/snapshot.js +191 -0
- package/lib/esm/src/tools/tabs.js +106 -0
- package/lib/esm/src/tools/testing.js +48 -0
- package/lib/esm/src/tools/tool.js +5 -0
- package/lib/esm/src/tools/utils.js +68 -0
- package/lib/esm/src/tools/vision.js +177 -0
- package/lib/esm/src/tools/wait.js +47 -0
- package/lib/esm/src/tools.js +49 -0
- package/package.json +15 -44
- package/LICENSE +0 -202
- package/README.md +0 -508
- package/cli.js +0 -18
- package/config.d.ts +0 -128
- package/index.js +0 -19
- package/lib/browserContextFactory.js +0 -227
- package/lib/browserServer.js +0 -151
- package/lib/config.js +0 -189
- package/lib/connection.js +0 -82
- package/lib/context.js +0 -291
- package/lib/fileUtils.js +0 -32
- package/lib/httpServer.js +0 -201
- package/lib/index.js +0 -36
- package/lib/javascript.js +0 -49
- package/lib/manualPromise.js +0 -111
- package/lib/package.js +0 -20
- package/lib/pageSnapshot.js +0 -43
- package/lib/program.js +0 -72
- package/lib/server.js +0 -48
- package/lib/tab.js +0 -101
- package/lib/tools/common.js +0 -68
- package/lib/tools/console.js +0 -44
- package/lib/tools/dialogs.js +0 -52
- package/lib/tools/files.js +0 -51
- package/lib/tools/install.js +0 -57
- package/lib/tools/keyboard.js +0 -46
- package/lib/tools/navigate.js +0 -93
- package/lib/tools/network.js +0 -51
- package/lib/tools/pdf.js +0 -49
- package/lib/tools/screenshot.js +0 -77
- package/lib/tools/snapshot.js +0 -204
- package/lib/tools/tabs.js +0 -118
- package/lib/tools/testing.js +0 -60
- package/lib/tools/tool.js +0 -18
- package/lib/tools/utils.js +0 -80
- package/lib/tools/vision.js +0 -189
- package/lib/tools/wait.js +0 -59
- package/lib/tools.js +0 -61
- package/lib/transport.js +0 -133
package/lib/manualPromise.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
export class ManualPromise extends Promise {
|
|
17
|
-
_resolve;
|
|
18
|
-
_reject;
|
|
19
|
-
_isDone;
|
|
20
|
-
constructor() {
|
|
21
|
-
let resolve;
|
|
22
|
-
let reject;
|
|
23
|
-
super((f, r) => {
|
|
24
|
-
resolve = f;
|
|
25
|
-
reject = r;
|
|
26
|
-
});
|
|
27
|
-
this._isDone = false;
|
|
28
|
-
this._resolve = resolve;
|
|
29
|
-
this._reject = reject;
|
|
30
|
-
}
|
|
31
|
-
isDone() {
|
|
32
|
-
return this._isDone;
|
|
33
|
-
}
|
|
34
|
-
resolve(t) {
|
|
35
|
-
this._isDone = true;
|
|
36
|
-
this._resolve(t);
|
|
37
|
-
}
|
|
38
|
-
reject(e) {
|
|
39
|
-
this._isDone = true;
|
|
40
|
-
this._reject(e);
|
|
41
|
-
}
|
|
42
|
-
static get [Symbol.species]() {
|
|
43
|
-
return Promise;
|
|
44
|
-
}
|
|
45
|
-
get [Symbol.toStringTag]() {
|
|
46
|
-
return 'ManualPromise';
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export class LongStandingScope {
|
|
50
|
-
_terminateError;
|
|
51
|
-
_closeError;
|
|
52
|
-
_terminatePromises = new Map();
|
|
53
|
-
_isClosed = false;
|
|
54
|
-
reject(error) {
|
|
55
|
-
this._isClosed = true;
|
|
56
|
-
this._terminateError = error;
|
|
57
|
-
for (const p of this._terminatePromises.keys())
|
|
58
|
-
p.resolve(error);
|
|
59
|
-
}
|
|
60
|
-
close(error) {
|
|
61
|
-
this._isClosed = true;
|
|
62
|
-
this._closeError = error;
|
|
63
|
-
for (const [p, frames] of this._terminatePromises)
|
|
64
|
-
p.resolve(cloneError(error, frames));
|
|
65
|
-
}
|
|
66
|
-
isClosed() {
|
|
67
|
-
return this._isClosed;
|
|
68
|
-
}
|
|
69
|
-
static async raceMultiple(scopes, promise) {
|
|
70
|
-
return Promise.race(scopes.map(s => s.race(promise)));
|
|
71
|
-
}
|
|
72
|
-
async race(promise) {
|
|
73
|
-
return this._race(Array.isArray(promise) ? promise : [promise], false);
|
|
74
|
-
}
|
|
75
|
-
async safeRace(promise, defaultValue) {
|
|
76
|
-
return this._race([promise], true, defaultValue);
|
|
77
|
-
}
|
|
78
|
-
async _race(promises, safe, defaultValue) {
|
|
79
|
-
const terminatePromise = new ManualPromise();
|
|
80
|
-
const frames = captureRawStack();
|
|
81
|
-
if (this._terminateError)
|
|
82
|
-
terminatePromise.resolve(this._terminateError);
|
|
83
|
-
if (this._closeError)
|
|
84
|
-
terminatePromise.resolve(cloneError(this._closeError, frames));
|
|
85
|
-
this._terminatePromises.set(terminatePromise, frames);
|
|
86
|
-
try {
|
|
87
|
-
return await Promise.race([
|
|
88
|
-
terminatePromise.then(e => safe ? defaultValue : Promise.reject(e)),
|
|
89
|
-
...promises
|
|
90
|
-
]);
|
|
91
|
-
}
|
|
92
|
-
finally {
|
|
93
|
-
this._terminatePromises.delete(terminatePromise);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function cloneError(error, frames) {
|
|
98
|
-
const clone = new Error();
|
|
99
|
-
clone.name = error.name;
|
|
100
|
-
clone.message = error.message;
|
|
101
|
-
clone.stack = [error.name + ':' + error.message, ...frames].join('\n');
|
|
102
|
-
return clone;
|
|
103
|
-
}
|
|
104
|
-
function captureRawStack() {
|
|
105
|
-
const stackTraceLimit = Error.stackTraceLimit;
|
|
106
|
-
Error.stackTraceLimit = 50;
|
|
107
|
-
const error = new Error();
|
|
108
|
-
const stack = error.stack || '';
|
|
109
|
-
Error.stackTraceLimit = stackTraceLimit;
|
|
110
|
-
return stack.split('\n');
|
|
111
|
-
}
|
package/lib/package.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import fs from 'node:fs';
|
|
17
|
-
import url from 'node:url';
|
|
18
|
-
import path from 'node:path';
|
|
19
|
-
const __filename = url.fileURLToPath(import.meta.url);
|
|
20
|
-
export const packageJSON = JSON.parse(fs.readFileSync(path.join(path.dirname(__filename), '..', 'package.json'), 'utf8'));
|
package/lib/pageSnapshot.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { callOnPageNoTrace } from './tools/utils.js';
|
|
17
|
-
export class PageSnapshot {
|
|
18
|
-
_page;
|
|
19
|
-
_text;
|
|
20
|
-
constructor(page) {
|
|
21
|
-
this._page = page;
|
|
22
|
-
}
|
|
23
|
-
static async create(page) {
|
|
24
|
-
const snapshot = new PageSnapshot(page);
|
|
25
|
-
await snapshot._build();
|
|
26
|
-
return snapshot;
|
|
27
|
-
}
|
|
28
|
-
text() {
|
|
29
|
-
return this._text;
|
|
30
|
-
}
|
|
31
|
-
async _build() {
|
|
32
|
-
const snapshot = await callOnPageNoTrace(this._page, page => page._snapshotForAI());
|
|
33
|
-
this._text = [
|
|
34
|
-
`- Page Snapshot`,
|
|
35
|
-
'```yaml',
|
|
36
|
-
snapshot,
|
|
37
|
-
'```',
|
|
38
|
-
].join('\n');
|
|
39
|
-
}
|
|
40
|
-
refLocator(params) {
|
|
41
|
-
return this._page.locator(`aria-ref=${params.ref}`).describe(params.element);
|
|
42
|
-
}
|
|
43
|
-
}
|
package/lib/program.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { program } from 'commander';
|
|
17
|
-
// @ts-ignore
|
|
18
|
-
import { startTraceViewerServer } from '@szymonrybczak/patchright/lib/server';
|
|
19
|
-
import { startHttpServer, startHttpTransport, startStdioTransport } from './transport.js';
|
|
20
|
-
import { resolveCLIConfig } from './config.js';
|
|
21
|
-
import { Server } from './server.js';
|
|
22
|
-
import { packageJSON } from './package.js';
|
|
23
|
-
program
|
|
24
|
-
.version('Version ' + packageJSON.version)
|
|
25
|
-
.name(packageJSON.name)
|
|
26
|
-
.option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
|
27
|
-
.option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
|
28
|
-
.option('--block-service-workers', 'block service workers')
|
|
29
|
-
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
|
30
|
-
.option('--browser-agent <endpoint>', 'Use browser agent (experimental).')
|
|
31
|
-
.option('--caps <caps>', 'comma-separated list of capabilities to enable, possible values: tabs, pdf, history, wait, files, install. Default is all.')
|
|
32
|
-
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
|
33
|
-
.option('--config <path>', 'path to the configuration file.')
|
|
34
|
-
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
|
35
|
-
.option('--executable-path <path>', 'path to the browser executable.')
|
|
36
|
-
.option('--headless', 'run browser in headless mode, headed by default')
|
|
37
|
-
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
|
38
|
-
.option('--ignore-https-errors', 'ignore https errors')
|
|
39
|
-
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
|
40
|
-
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.')
|
|
41
|
-
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
|
|
42
|
-
.option('--output-dir <path>', 'path to the directory for output files.')
|
|
43
|
-
.option('--port <port>', 'port to listen on for SSE transport.')
|
|
44
|
-
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
|
45
|
-
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
|
46
|
-
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
|
|
47
|
-
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
|
48
|
-
.option('--user-agent <ua string>', 'specify user agent string')
|
|
49
|
-
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
|
50
|
-
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
|
51
|
-
.option('--vision', 'Run server that uses screenshots (Aria snapshots are used by default)')
|
|
52
|
-
.action(async (options) => {
|
|
53
|
-
const config = await resolveCLIConfig(options);
|
|
54
|
-
const httpServer = config.server.port !== undefined ? await startHttpServer(config.server) : undefined;
|
|
55
|
-
const server = new Server(config);
|
|
56
|
-
server.setupExitWatchdog();
|
|
57
|
-
if (httpServer)
|
|
58
|
-
startHttpTransport(httpServer, server);
|
|
59
|
-
else
|
|
60
|
-
await startStdioTransport(server);
|
|
61
|
-
if (config.saveTrace) {
|
|
62
|
-
const server = await startTraceViewerServer();
|
|
63
|
-
const urlPrefix = server.urlPrefix('human-readable');
|
|
64
|
-
const url = urlPrefix + '/trace/index.html?trace=' + config.browser.launchOptions.tracesDir + '/trace.json';
|
|
65
|
-
// eslint-disable-next-line no-console
|
|
66
|
-
console.error('\nTrace viewer listening on ' + url);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
function semicolonSeparatedList(value) {
|
|
70
|
-
return value.split(';').map(v => v.trim());
|
|
71
|
-
}
|
|
72
|
-
void program.parseAsync(process.argv);
|
package/lib/server.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { createConnection } from './connection.js';
|
|
17
|
-
import { contextFactory } from './browserContextFactory.js';
|
|
18
|
-
export class Server {
|
|
19
|
-
config;
|
|
20
|
-
_connectionList = [];
|
|
21
|
-
_browserConfig;
|
|
22
|
-
_contextFactory;
|
|
23
|
-
constructor(config) {
|
|
24
|
-
this.config = config;
|
|
25
|
-
this._browserConfig = config.browser;
|
|
26
|
-
this._contextFactory = contextFactory(this._browserConfig);
|
|
27
|
-
}
|
|
28
|
-
async createConnection(transport) {
|
|
29
|
-
const connection = createConnection(this.config, this._contextFactory);
|
|
30
|
-
this._connectionList.push(connection);
|
|
31
|
-
await connection.server.connect(transport);
|
|
32
|
-
return connection;
|
|
33
|
-
}
|
|
34
|
-
setupExitWatchdog() {
|
|
35
|
-
let isExiting = false;
|
|
36
|
-
const handleExit = async () => {
|
|
37
|
-
if (isExiting)
|
|
38
|
-
return;
|
|
39
|
-
isExiting = true;
|
|
40
|
-
setTimeout(() => process.exit(0), 15000);
|
|
41
|
-
await Promise.all(this._connectionList.map(connection => connection.close()));
|
|
42
|
-
process.exit(0);
|
|
43
|
-
};
|
|
44
|
-
process.stdin.on('close', handleExit);
|
|
45
|
-
process.on('SIGINT', handleExit);
|
|
46
|
-
process.on('SIGTERM', handleExit);
|
|
47
|
-
}
|
|
48
|
-
}
|
package/lib/tab.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { PageSnapshot } from './pageSnapshot.js';
|
|
17
|
-
import { callOnPageNoTrace } from './tools/utils.js';
|
|
18
|
-
export class Tab {
|
|
19
|
-
context;
|
|
20
|
-
page;
|
|
21
|
-
_consoleMessages = [];
|
|
22
|
-
_requests = new Map();
|
|
23
|
-
_snapshot;
|
|
24
|
-
_onPageClose;
|
|
25
|
-
constructor(context, page, onPageClose) {
|
|
26
|
-
this.context = context;
|
|
27
|
-
this.page = page;
|
|
28
|
-
this._onPageClose = onPageClose;
|
|
29
|
-
page.on('console', event => this._consoleMessages.push(event));
|
|
30
|
-
page.on('request', request => this._requests.set(request, null));
|
|
31
|
-
page.on('response', response => this._requests.set(response.request(), response));
|
|
32
|
-
page.on('close', () => this._onClose());
|
|
33
|
-
page.on('filechooser', chooser => {
|
|
34
|
-
this.context.setModalState({
|
|
35
|
-
type: 'fileChooser',
|
|
36
|
-
description: 'File chooser',
|
|
37
|
-
fileChooser: chooser,
|
|
38
|
-
}, this);
|
|
39
|
-
});
|
|
40
|
-
page.on('dialog', dialog => this.context.dialogShown(this, dialog));
|
|
41
|
-
page.on('download', download => {
|
|
42
|
-
void this.context.downloadStarted(this, download);
|
|
43
|
-
});
|
|
44
|
-
page.setDefaultNavigationTimeout(60000);
|
|
45
|
-
page.setDefaultTimeout(5000);
|
|
46
|
-
}
|
|
47
|
-
_clearCollectedArtifacts() {
|
|
48
|
-
this._consoleMessages.length = 0;
|
|
49
|
-
this._requests.clear();
|
|
50
|
-
}
|
|
51
|
-
_onClose() {
|
|
52
|
-
this._clearCollectedArtifacts();
|
|
53
|
-
this._onPageClose(this);
|
|
54
|
-
}
|
|
55
|
-
async title() {
|
|
56
|
-
return await callOnPageNoTrace(this.page, page => page.title());
|
|
57
|
-
}
|
|
58
|
-
async waitForLoadState(state, options) {
|
|
59
|
-
await callOnPageNoTrace(this.page, page => page.waitForLoadState(state, options).catch(() => { }));
|
|
60
|
-
}
|
|
61
|
-
async navigate(url) {
|
|
62
|
-
this._clearCollectedArtifacts();
|
|
63
|
-
const downloadEvent = callOnPageNoTrace(this.page, page => page.waitForEvent('download').catch(() => { }));
|
|
64
|
-
try {
|
|
65
|
-
await this.page.goto(url, { waitUntil: 'domcontentloaded' });
|
|
66
|
-
}
|
|
67
|
-
catch (_e) {
|
|
68
|
-
const e = _e;
|
|
69
|
-
const mightBeDownload = e.message.includes('net::ERR_ABORTED') // chromium
|
|
70
|
-
|| e.message.includes('Download is starting'); // firefox + webkit
|
|
71
|
-
if (!mightBeDownload)
|
|
72
|
-
throw e;
|
|
73
|
-
// on chromium, the download event is fired *after* page.goto rejects, so we wait a lil bit
|
|
74
|
-
const download = await Promise.race([
|
|
75
|
-
downloadEvent,
|
|
76
|
-
new Promise(resolve => setTimeout(resolve, 1000)),
|
|
77
|
-
]);
|
|
78
|
-
if (!download)
|
|
79
|
-
throw e;
|
|
80
|
-
}
|
|
81
|
-
// Cap load event to 5 seconds, the page is operational at this point.
|
|
82
|
-
await this.waitForLoadState('load', { timeout: 5000 });
|
|
83
|
-
}
|
|
84
|
-
hasSnapshot() {
|
|
85
|
-
return !!this._snapshot;
|
|
86
|
-
}
|
|
87
|
-
snapshotOrDie() {
|
|
88
|
-
if (!this._snapshot)
|
|
89
|
-
throw new Error('No snapshot available');
|
|
90
|
-
return this._snapshot;
|
|
91
|
-
}
|
|
92
|
-
consoleMessages() {
|
|
93
|
-
return this._consoleMessages;
|
|
94
|
-
}
|
|
95
|
-
requests() {
|
|
96
|
-
return this._requests;
|
|
97
|
-
}
|
|
98
|
-
async captureSnapshot() {
|
|
99
|
-
this._snapshot = await PageSnapshot.create(this.page);
|
|
100
|
-
}
|
|
101
|
-
}
|
package/lib/tools/common.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
import { defineTool } from './tool.js';
|
|
18
|
-
const close = defineTool({
|
|
19
|
-
capability: 'core',
|
|
20
|
-
schema: {
|
|
21
|
-
name: 'browser_close',
|
|
22
|
-
title: 'Close browser',
|
|
23
|
-
description: 'Close the page',
|
|
24
|
-
inputSchema: z.object({}),
|
|
25
|
-
type: 'readOnly',
|
|
26
|
-
},
|
|
27
|
-
handle: async (context) => {
|
|
28
|
-
await context.close();
|
|
29
|
-
return {
|
|
30
|
-
code: [`await page.close()`],
|
|
31
|
-
captureSnapshot: false,
|
|
32
|
-
waitForNetwork: false,
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
const resize = captureSnapshot => defineTool({
|
|
37
|
-
capability: 'core',
|
|
38
|
-
schema: {
|
|
39
|
-
name: 'browser_resize',
|
|
40
|
-
title: 'Resize browser window',
|
|
41
|
-
description: 'Resize the browser window',
|
|
42
|
-
inputSchema: z.object({
|
|
43
|
-
width: z.coerce.number().describe('Width of the browser window'),
|
|
44
|
-
height: z.coerce.number().describe('Height of the browser window'),
|
|
45
|
-
}),
|
|
46
|
-
type: 'readOnly',
|
|
47
|
-
},
|
|
48
|
-
handle: async (context, params) => {
|
|
49
|
-
const tab = context.currentTabOrDie();
|
|
50
|
-
const code = [
|
|
51
|
-
`// Resize browser window to ${params.width}x${params.height}`,
|
|
52
|
-
`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`
|
|
53
|
-
];
|
|
54
|
-
const action = async () => {
|
|
55
|
-
await tab.page.setViewportSize({ width: params.width, height: params.height });
|
|
56
|
-
};
|
|
57
|
-
return {
|
|
58
|
-
code,
|
|
59
|
-
action,
|
|
60
|
-
captureSnapshot,
|
|
61
|
-
waitForNetwork: true
|
|
62
|
-
};
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
export default (captureSnapshot) => [
|
|
66
|
-
close,
|
|
67
|
-
resize(captureSnapshot)
|
|
68
|
-
];
|
package/lib/tools/console.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
import { defineTool } from './tool.js';
|
|
18
|
-
const console = defineTool({
|
|
19
|
-
capability: 'core',
|
|
20
|
-
schema: {
|
|
21
|
-
name: 'browser_console_messages',
|
|
22
|
-
title: 'Get console messages',
|
|
23
|
-
description: 'Returns all console messages',
|
|
24
|
-
inputSchema: z.object({}),
|
|
25
|
-
type: 'readOnly',
|
|
26
|
-
},
|
|
27
|
-
handle: async (context) => {
|
|
28
|
-
const messages = context.currentTabOrDie().consoleMessages();
|
|
29
|
-
const log = messages.map(message => `[${message.type().toUpperCase()}] ${message.text()}`).join('\n');
|
|
30
|
-
return {
|
|
31
|
-
code: [`// <internal code to get console messages>`],
|
|
32
|
-
action: async () => {
|
|
33
|
-
return {
|
|
34
|
-
content: [{ type: 'text', text: log }]
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
captureSnapshot: false,
|
|
38
|
-
waitForNetwork: false,
|
|
39
|
-
};
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
export default [
|
|
43
|
-
console,
|
|
44
|
-
];
|
package/lib/tools/dialogs.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
import { defineTool } from './tool.js';
|
|
18
|
-
const handleDialog = captureSnapshot => defineTool({
|
|
19
|
-
capability: 'core',
|
|
20
|
-
schema: {
|
|
21
|
-
name: 'browser_handle_dialog',
|
|
22
|
-
title: 'Handle a dialog',
|
|
23
|
-
description: 'Handle a dialog',
|
|
24
|
-
inputSchema: z.object({
|
|
25
|
-
accept: z.coerce.boolean().describe('Whether to accept the dialog.'),
|
|
26
|
-
promptText: z.string().optional().describe('The text of the prompt in case of a prompt dialog.'),
|
|
27
|
-
}),
|
|
28
|
-
type: 'destructive',
|
|
29
|
-
},
|
|
30
|
-
handle: async (context, params) => {
|
|
31
|
-
const dialogState = context.modalStates().find(state => state.type === 'dialog');
|
|
32
|
-
if (!dialogState)
|
|
33
|
-
throw new Error('No dialog visible');
|
|
34
|
-
if (params.accept)
|
|
35
|
-
await dialogState.dialog.accept(params.promptText);
|
|
36
|
-
else
|
|
37
|
-
await dialogState.dialog.dismiss();
|
|
38
|
-
context.clearModalState(dialogState);
|
|
39
|
-
const code = [
|
|
40
|
-
`// <internal code to handle "${dialogState.dialog.type()}" dialog>`,
|
|
41
|
-
];
|
|
42
|
-
return {
|
|
43
|
-
code,
|
|
44
|
-
captureSnapshot,
|
|
45
|
-
waitForNetwork: false,
|
|
46
|
-
};
|
|
47
|
-
},
|
|
48
|
-
clearsModalState: 'dialog',
|
|
49
|
-
});
|
|
50
|
-
export default (captureSnapshot) => [
|
|
51
|
-
handleDialog(captureSnapshot),
|
|
52
|
-
];
|
package/lib/tools/files.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { z } from 'zod';
|
|
17
|
-
import { defineTool } from './tool.js';
|
|
18
|
-
const uploadFile = captureSnapshot => defineTool({
|
|
19
|
-
capability: 'files',
|
|
20
|
-
schema: {
|
|
21
|
-
name: 'browser_file_upload',
|
|
22
|
-
title: 'Upload files',
|
|
23
|
-
description: 'Upload one or multiple files',
|
|
24
|
-
inputSchema: z.object({
|
|
25
|
-
paths: z.array(z.string()).describe('The absolute paths to the files to upload. Can be a single file or multiple files.'),
|
|
26
|
-
}),
|
|
27
|
-
type: 'destructive',
|
|
28
|
-
},
|
|
29
|
-
handle: async (context, params) => {
|
|
30
|
-
const modalState = context.modalStates().find(state => state.type === 'fileChooser');
|
|
31
|
-
if (!modalState)
|
|
32
|
-
throw new Error('No file chooser visible');
|
|
33
|
-
const code = [
|
|
34
|
-
`// <internal code to chose files ${params.paths.join(', ')}`,
|
|
35
|
-
];
|
|
36
|
-
const action = async () => {
|
|
37
|
-
await modalState.fileChooser.setFiles(params.paths);
|
|
38
|
-
context.clearModalState(modalState);
|
|
39
|
-
};
|
|
40
|
-
return {
|
|
41
|
-
code,
|
|
42
|
-
action,
|
|
43
|
-
captureSnapshot,
|
|
44
|
-
waitForNetwork: true,
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
clearsModalState: 'fileChooser',
|
|
48
|
-
});
|
|
49
|
-
export default (captureSnapshot) => [
|
|
50
|
-
uploadFile(captureSnapshot),
|
|
51
|
-
];
|
package/lib/tools/install.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Microsoft Corporation.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { fork } from 'child_process';
|
|
17
|
-
import path from 'path';
|
|
18
|
-
import { z } from 'zod';
|
|
19
|
-
import { defineTool } from './tool.js';
|
|
20
|
-
import { fileURLToPath } from 'node:url';
|
|
21
|
-
const install = defineTool({
|
|
22
|
-
capability: 'install',
|
|
23
|
-
schema: {
|
|
24
|
-
name: 'browser_install',
|
|
25
|
-
title: 'Install the browser specified in the config',
|
|
26
|
-
description: 'Install the browser specified in the config. Call this if you get an error about the browser not being installed.',
|
|
27
|
-
inputSchema: z.object({}),
|
|
28
|
-
type: 'destructive',
|
|
29
|
-
},
|
|
30
|
-
handle: async (context) => {
|
|
31
|
-
const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? 'chrome';
|
|
32
|
-
const cliUrl = import.meta.resolve('@szymonrybczak/patchright/package.json');
|
|
33
|
-
const cliPath = path.join(fileURLToPath(cliUrl), '..', 'cli.js');
|
|
34
|
-
const child = fork(cliPath, ['install', channel], {
|
|
35
|
-
stdio: 'pipe',
|
|
36
|
-
});
|
|
37
|
-
const output = [];
|
|
38
|
-
child.stdout?.on('data', data => output.push(data.toString()));
|
|
39
|
-
child.stderr?.on('data', data => output.push(data.toString()));
|
|
40
|
-
await new Promise((resolve, reject) => {
|
|
41
|
-
child.on('close', code => {
|
|
42
|
-
if (code === 0)
|
|
43
|
-
resolve();
|
|
44
|
-
else
|
|
45
|
-
reject(new Error(`Failed to install browser: ${output.join('')}`));
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
return {
|
|
49
|
-
code: [`// Browser ${channel} installed`],
|
|
50
|
-
captureSnapshot: false,
|
|
51
|
-
waitForNetwork: false,
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
export default [
|
|
56
|
-
install,
|
|
57
|
-
];
|