@smoothdeploy/playwright 1.57.1 → 1.58.1-beta-1770383926000
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.
Potentially problematic release.
This version of @smoothdeploy/playwright might be problematic. Click here for more details.
- package/ThirdPartyNotices.txt +1188 -65
- package/lib/agents/agentParser.js +89 -0
- package/lib/agents/generateAgents.js +27 -74
- package/lib/agents/generateAgents.js.map +7 -0
- package/lib/agents/playwright-test-planner.agent.md +1 -0
- package/lib/common/config.js +6 -4
- package/lib/common/config.js.map +7 -0
- package/lib/common/configLoader.js.map +7 -0
- package/lib/common/esmLoaderHost.js +2 -0
- package/lib/common/esmLoaderHost.js.map +7 -0
- package/lib/common/expectBundle.js +2 -17
- package/lib/common/expectBundle.js.map +7 -0
- package/lib/common/expectBundleImpl.js +132 -132
- package/lib/common/expectBundleImpl.js.map +7 -0
- package/lib/common/fixtures.js.map +7 -0
- package/lib/common/globals.js.map +7 -0
- package/lib/common/ipc.js.map +7 -0
- package/lib/common/poolBuilder.js.map +7 -0
- package/lib/common/process.js +28 -0
- package/lib/common/process.js.map +7 -0
- package/lib/common/suiteUtils.js.map +7 -0
- package/lib/common/test.js.map +7 -0
- package/lib/common/testLoader.js.map +7 -0
- package/lib/common/testType.js.map +7 -0
- package/lib/common/validators.js +10 -10
- package/lib/common/validators.js.map +7 -0
- package/lib/fsWatcher.js.map +7 -0
- package/lib/index.js +205 -12
- package/lib/index.js.map +7 -0
- package/lib/internalsForTest.js.map +7 -0
- package/lib/isomorphic/events.js.map +7 -0
- package/lib/isomorphic/folders.js.map +7 -0
- package/lib/isomorphic/stringInternPool.js.map +7 -0
- package/lib/isomorphic/teleReceiver.js +15 -2
- package/lib/isomorphic/teleReceiver.js.map +7 -0
- package/lib/isomorphic/teleSuiteUpdater.js +24 -4
- package/lib/isomorphic/teleSuiteUpdater.js.map +7 -0
- package/lib/isomorphic/testServerConnection.js.map +7 -0
- package/lib/isomorphic/testServerInterface.js.map +7 -0
- package/lib/isomorphic/testTree.js +13 -18
- package/lib/isomorphic/testTree.js.map +7 -0
- package/lib/isomorphic/types.d.js.map +7 -0
- package/lib/loader/loaderMain.js.map +7 -0
- package/lib/matchers/expect.js +2 -15
- package/lib/matchers/expect.js.map +7 -0
- package/lib/matchers/matcherHint.js +1 -44
- package/lib/matchers/matcherHint.js.map +7 -0
- package/lib/matchers/matchers.js +3 -2
- package/lib/matchers/matchers.js.map +7 -0
- package/lib/matchers/toBeTruthy.js +5 -3
- package/lib/matchers/toBeTruthy.js.map +7 -0
- package/lib/matchers/toEqual.js +4 -3
- package/lib/matchers/toEqual.js.map +7 -0
- package/lib/matchers/toHaveURL.js +5 -6
- package/lib/matchers/toHaveURL.js.map +7 -0
- package/lib/matchers/toMatchAriaSnapshot.js +5 -5
- package/lib/matchers/toMatchAriaSnapshot.js.map +7 -0
- package/lib/matchers/toMatchSnapshot.js +9 -8
- package/lib/matchers/toMatchSnapshot.js.map +7 -0
- package/lib/matchers/toMatchText.js +9 -9
- package/lib/matchers/toMatchText.js.map +7 -0
- package/lib/mcp/browser/actions.d.js.map +7 -0
- package/lib/mcp/browser/browserContextFactory.js +62 -29
- package/lib/mcp/browser/browserContextFactory.js.map +7 -0
- package/lib/mcp/browser/browserServerBackend.js +17 -9
- package/lib/mcp/browser/browserServerBackend.js.map +7 -0
- package/lib/mcp/browser/codegen.js.map +7 -0
- package/lib/mcp/browser/config.js +65 -12
- package/lib/mcp/browser/config.js.map +7 -0
- package/lib/mcp/browser/context.js +71 -94
- package/lib/mcp/browser/context.js.map +7 -0
- package/lib/mcp/browser/response.js +172 -131
- package/lib/mcp/browser/response.js.map +7 -0
- package/lib/mcp/browser/sessionLog.js +19 -104
- package/lib/mcp/browser/sessionLog.js.map +7 -0
- package/lib/mcp/browser/tab.js +92 -41
- package/lib/mcp/browser/tab.js.map +7 -0
- package/lib/mcp/browser/tools/common.js +8 -6
- package/lib/mcp/browser/tools/common.js.map +7 -0
- package/lib/mcp/browser/tools/console.js +7 -5
- package/lib/mcp/browser/tools/console.js.map +7 -0
- package/lib/mcp/browser/tools/dialogs.js +4 -4
- package/lib/mcp/browser/tools/dialogs.js.map +7 -0
- package/lib/mcp/browser/tools/evaluate.js +11 -19
- package/lib/mcp/browser/tools/evaluate.js.map +7 -0
- package/lib/mcp/browser/tools/files.js +3 -3
- package/lib/mcp/browser/tools/files.js.map +7 -0
- package/lib/mcp/browser/tools/form.js +9 -19
- package/lib/mcp/browser/tools/form.js.map +7 -0
- package/lib/mcp/browser/tools/install.js +6 -3
- package/lib/mcp/browser/tools/install.js.map +7 -0
- package/lib/mcp/browser/tools/keyboard.js +34 -11
- package/lib/mcp/browser/tools/keyboard.js.map +7 -0
- package/lib/mcp/browser/tools/mouse.js +11 -11
- package/lib/mcp/browser/tools/mouse.js.map +7 -0
- package/lib/mcp/browser/tools/navigate.js +14 -5
- package/lib/mcp/browser/tools/navigate.js.map +7 -0
- package/lib/mcp/browser/tools/network.js +20 -11
- package/lib/mcp/browser/tools/network.js.map +7 -0
- package/lib/mcp/browser/tools/open.js +57 -0
- package/lib/mcp/browser/tools/pdf.js +9 -19
- package/lib/mcp/browser/tools/pdf.js.map +7 -0
- package/lib/mcp/browser/tools/runCode.js +11 -8
- package/lib/mcp/browser/tools/runCode.js.map +7 -0
- package/lib/mcp/browser/tools/screenshot.js +16 -29
- package/lib/mcp/browser/tools/screenshot.js.map +7 -0
- package/lib/mcp/browser/tools/snapshot.js +21 -29
- package/lib/mcp/browser/tools/snapshot.js.map +7 -0
- package/lib/mcp/browser/tools/tabs.js +12 -12
- package/lib/mcp/browser/tools/tabs.js.map +7 -0
- package/lib/mcp/browser/tools/tool.js +2 -4
- package/lib/mcp/browser/tools/tool.js.map +7 -0
- package/lib/mcp/browser/tools/tracing.js +6 -6
- package/lib/mcp/browser/tools/tracing.js.map +7 -0
- package/lib/mcp/browser/tools/utils.js +49 -44
- package/lib/mcp/browser/tools/utils.js.map +7 -0
- package/lib/mcp/browser/tools/verify.js +24 -34
- package/lib/mcp/browser/tools/verify.js.map +7 -0
- package/lib/mcp/browser/tools/wait.js +6 -6
- package/lib/mcp/browser/tools/wait.js.map +7 -0
- package/lib/mcp/browser/tools.js +3 -1
- package/lib/mcp/browser/tools.js.map +7 -0
- package/lib/mcp/browser/watchdog.js.map +7 -0
- package/lib/mcp/config.d.js.map +7 -0
- package/lib/mcp/extension/cdpRelay.js +1 -1
- package/lib/mcp/extension/cdpRelay.js.map +7 -0
- package/lib/mcp/extension/extensionContextFactory.js +6 -5
- package/lib/mcp/extension/extensionContextFactory.js.map +7 -0
- package/lib/mcp/extension/protocol.js.map +7 -0
- package/lib/mcp/index.js.map +7 -0
- package/lib/mcp/log.js.map +7 -0
- package/lib/mcp/program.js +15 -20
- package/lib/mcp/program.js.map +7 -0
- package/lib/mcp/sdk/bundle.js.map +7 -0
- package/lib/mcp/sdk/exports.js +0 -2
- package/lib/mcp/sdk/exports.js.map +7 -0
- package/lib/mcp/sdk/http.js +20 -55
- package/lib/mcp/sdk/http.js.map +7 -0
- package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
- package/lib/mcp/sdk/proxyBackend.js.map +7 -0
- package/lib/mcp/sdk/server.js +29 -4
- package/lib/mcp/sdk/server.js.map +7 -0
- package/lib/mcp/sdk/tool.js +2 -2
- package/lib/mcp/sdk/tool.js.map +7 -0
- package/lib/mcp/terminal/cli.js +296 -0
- package/lib/mcp/terminal/command.js +56 -0
- package/lib/mcp/terminal/commands.js +333 -0
- package/lib/mcp/terminal/daemon.js +129 -0
- package/lib/mcp/terminal/help.json +32 -0
- package/lib/mcp/terminal/helpGenerator.js +88 -0
- package/lib/mcp/terminal/socketConnection.js +80 -0
- package/lib/mcp/test/browserBackend.js +3 -13
- package/lib/mcp/test/browserBackend.js.map +7 -0
- package/lib/mcp/test/generatorTools.js +9 -9
- package/lib/mcp/test/generatorTools.js.map +7 -0
- package/lib/mcp/test/plannerTools.js +23 -22
- package/lib/mcp/test/plannerTools.js.map +7 -0
- package/lib/mcp/test/seed.js.map +7 -0
- package/lib/mcp/test/streams.js.map +7 -0
- package/lib/mcp/test/testBackend.js +6 -6
- package/lib/mcp/test/testBackend.js.map +7 -0
- package/lib/mcp/test/testContext.js +9 -3
- package/lib/mcp/test/testContext.js.map +7 -0
- package/lib/mcp/test/testTool.js.map +7 -0
- package/lib/mcp/test/testTools.js +12 -10
- package/lib/mcp/test/testTools.js.map +7 -0
- package/lib/mcpBundleImpl.js.map +7 -0
- package/lib/plugins/gitCommitInfoPlugin.js.map +7 -0
- package/lib/plugins/index.js.map +7 -0
- package/lib/plugins/webServerPlugin.js.map +7 -0
- package/lib/program.js +18 -4
- package/lib/program.js.map +7 -0
- package/lib/reporters/base.js +29 -4
- package/lib/reporters/base.js.map +7 -0
- package/lib/reporters/blob.js +3 -0
- package/lib/reporters/blob.js.map +7 -0
- package/lib/reporters/dot.js +17 -0
- package/lib/reporters/dot.js.map +7 -0
- package/lib/reporters/empty.js.map +7 -0
- package/lib/reporters/github.js.map +7 -0
- package/lib/reporters/html.js +13 -3
- package/lib/reporters/html.js.map +7 -0
- package/lib/reporters/internalReporter.js +6 -0
- package/lib/reporters/internalReporter.js.map +7 -0
- package/lib/reporters/json.js.map +7 -0
- package/lib/reporters/junit.js.map +7 -0
- package/lib/reporters/line.js +18 -0
- package/lib/reporters/line.js.map +7 -0
- package/lib/reporters/list.js +22 -0
- package/lib/reporters/list.js.map +7 -0
- package/lib/reporters/listModeReporter.js.map +7 -0
- package/lib/reporters/markdown.js.map +7 -0
- package/lib/reporters/merge.js +25 -8
- package/lib/reporters/merge.js.map +7 -0
- package/lib/reporters/multiplexer.js +8 -0
- package/lib/reporters/multiplexer.js.map +7 -0
- package/lib/reporters/reporterV2.js.map +7 -0
- package/lib/reporters/smoothdeploy.js +191 -0
- package/lib/reporters/teleEmitter.js +22 -4
- package/lib/reporters/teleEmitter.js.map +7 -0
- package/lib/reporters/versions/blobV1.js.map +7 -0
- package/lib/runner/dispatcher.js +20 -4
- package/lib/runner/dispatcher.js.map +7 -0
- package/lib/runner/failureTracker.js.map +7 -0
- package/lib/runner/lastRun.js.map +7 -0
- package/lib/runner/loadUtils.js +2 -2
- package/lib/runner/loadUtils.js.map +7 -0
- package/lib/runner/loaderHost.js.map +7 -0
- package/lib/runner/processHost.js +19 -0
- package/lib/runner/processHost.js.map +7 -0
- package/lib/runner/projectUtils.js +1 -1
- package/lib/runner/projectUtils.js.map +7 -0
- package/lib/runner/rebase.js.map +7 -0
- package/lib/runner/reporters.js +3 -1
- package/lib/runner/reporters.js.map +7 -0
- package/lib/runner/sigIntWatcher.js.map +7 -0
- package/lib/runner/storage.js +91 -0
- package/lib/runner/taskRunner.js.map +7 -0
- package/lib/runner/tasks.js.map +7 -0
- package/lib/runner/testGroups.js +14 -6
- package/lib/runner/testGroups.js.map +7 -0
- package/lib/runner/testRunner.js +13 -4
- package/lib/runner/testRunner.js.map +7 -0
- package/lib/runner/testServer.js +2 -2
- package/lib/runner/testServer.js.map +7 -0
- package/lib/runner/uiModeReporter.js.map +7 -0
- package/lib/runner/vcs.js.map +7 -0
- package/lib/runner/watchMode.js +2 -1
- package/lib/runner/watchMode.js.map +7 -0
- package/lib/runner/workerHost.js +6 -0
- package/lib/runner/workerHost.js.map +7 -0
- package/lib/third_party/pirates.js.map +7 -0
- package/lib/third_party/tsconfig-loader.js.map +7 -0
- package/lib/transform/babelBundle.js +3 -0
- package/lib/transform/babelBundle.js.map +7 -0
- package/lib/transform/babelBundleImpl.js +134 -134
- package/lib/transform/babelBundleImpl.js.map +7 -0
- package/lib/transform/compilationCache.js +2 -0
- package/lib/transform/compilationCache.js.map +7 -0
- package/lib/transform/esmLoader.js +10 -11
- package/lib/transform/esmLoader.js.map +7 -0
- package/lib/transform/md.js +221 -0
- package/lib/transform/portTransport.js.map +7 -0
- package/lib/transform/transform.js +18 -8
- package/lib/transform/transform.js.map +7 -0
- package/lib/util.js +3 -6
- package/lib/util.js.map +7 -0
- package/lib/utilsBundle.js +7 -0
- package/lib/utilsBundle.js.map +7 -0
- package/lib/utilsBundleImpl.js +51 -48
- package/lib/utilsBundleImpl.js.map +7 -0
- package/lib/worker/fixtureRunner.js +6 -2
- package/lib/worker/fixtureRunner.js.map +7 -0
- package/lib/worker/testInfo.js +39 -19
- package/lib/worker/testInfo.js.map +7 -0
- package/lib/worker/testTracing.js.map +7 -0
- package/lib/worker/timeoutManager.js.map +7 -0
- package/lib/worker/util.js.map +7 -0
- package/lib/worker/workerMain.js +17 -16
- package/lib/worker/workerMain.js.map +7 -0
- package/package.json +2 -2
- package/test.mjs +1 -0
- package/types/test.d.ts +26 -6
- package/types/testReporter.d.ts +1 -0
|
@@ -28,19 +28,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var context_exports = {};
|
|
30
30
|
__export(context_exports, {
|
|
31
|
-
Context: () => Context
|
|
32
|
-
InputRecorder: () => InputRecorder
|
|
31
|
+
Context: () => Context
|
|
33
32
|
});
|
|
34
33
|
module.exports = __toCommonJS(context_exports);
|
|
35
|
-
var import_fs = __toESM(require("fs"));
|
|
36
|
-
var import_path = __toESM(require("path"));
|
|
37
34
|
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
|
35
|
+
var import_utils = require("playwright-core/lib/utils");
|
|
38
36
|
var import_playwright_core = require("playwright-core");
|
|
37
|
+
var import_url = require("url");
|
|
38
|
+
var import_os = __toESM(require("os"));
|
|
39
39
|
var import_log = require("../log");
|
|
40
40
|
var import_tab = require("./tab");
|
|
41
41
|
var import_config = require("./config");
|
|
42
|
-
var codegen = __toESM(require("./codegen"));
|
|
43
|
-
var import_utils = require("./tools/utils");
|
|
44
42
|
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
|
45
43
|
class Context {
|
|
46
44
|
constructor(options) {
|
|
@@ -68,14 +66,13 @@ class Context {
|
|
|
68
66
|
}
|
|
69
67
|
currentTabOrDie() {
|
|
70
68
|
if (!this._currentTab)
|
|
71
|
-
throw new Error(
|
|
69
|
+
throw new Error("No open pages available.");
|
|
72
70
|
return this._currentTab;
|
|
73
71
|
}
|
|
74
72
|
async newTab() {
|
|
75
|
-
const { browserContext } = await this._ensureBrowserContext();
|
|
73
|
+
const { browserContext } = await this._ensureBrowserContext({});
|
|
76
74
|
const page = await browserContext.newPage();
|
|
77
75
|
this._currentTab = this._tabs.find((t) => t.page === page);
|
|
78
|
-
await this._currentTab.initializedPromise;
|
|
79
76
|
return this._currentTab;
|
|
80
77
|
}
|
|
81
78
|
async selectTab(index) {
|
|
@@ -86,8 +83,8 @@ class Context {
|
|
|
86
83
|
this._currentTab = tab;
|
|
87
84
|
return tab;
|
|
88
85
|
}
|
|
89
|
-
async ensureTab() {
|
|
90
|
-
const { browserContext } = await this._ensureBrowserContext();
|
|
86
|
+
async ensureTab(options = {}) {
|
|
87
|
+
const { browserContext } = await this._ensureBrowserContext(options);
|
|
91
88
|
if (!this._currentTab)
|
|
92
89
|
await browserContext.newPage();
|
|
93
90
|
return this._currentTab;
|
|
@@ -137,31 +134,11 @@ class Context {
|
|
|
137
134
|
testDebug("close context");
|
|
138
135
|
const promise = this._browserContextPromise;
|
|
139
136
|
this._browserContextPromise = void 0;
|
|
137
|
+
this._browserContextOption = void 0;
|
|
140
138
|
await promise.then(async ({ browserContext, close }) => {
|
|
141
139
|
if (this.config.saveTrace)
|
|
142
140
|
await browserContext.tracing.stop();
|
|
143
|
-
|
|
144
|
-
await close(async () => {
|
|
145
|
-
for (const video of videos) {
|
|
146
|
-
const name = await this.outputFile((0, import_utils.dateAsFileName)("webm"), { origin: "code", reason: "Saving video" });
|
|
147
|
-
await import_fs.default.promises.mkdir(import_path.default.dirname(name), { recursive: true });
|
|
148
|
-
const p = await video.path();
|
|
149
|
-
if (import_fs.default.existsSync(p)) {
|
|
150
|
-
try {
|
|
151
|
-
await import_fs.default.promises.rename(p, name);
|
|
152
|
-
} catch (e) {
|
|
153
|
-
if (e.code !== "EXDEV")
|
|
154
|
-
(0, import_log.logUnhandledError)(e);
|
|
155
|
-
try {
|
|
156
|
-
await import_fs.default.promises.copyFile(p, name);
|
|
157
|
-
await import_fs.default.promises.unlink(p);
|
|
158
|
-
} catch (e2) {
|
|
159
|
-
(0, import_log.logUnhandledError)(e2);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
});
|
|
141
|
+
await close();
|
|
165
142
|
});
|
|
166
143
|
}
|
|
167
144
|
async dispose() {
|
|
@@ -169,28 +146,45 @@ class Context {
|
|
|
169
146
|
await this.closeBrowserContext();
|
|
170
147
|
Context._allContexts.delete(this);
|
|
171
148
|
}
|
|
172
|
-
async
|
|
173
|
-
|
|
149
|
+
async _setupRequestInterception(context) {
|
|
150
|
+
if (this.config.network?.allowedOrigins?.length) {
|
|
151
|
+
await context.route("**", (route) => route.abort("blockedbyclient"));
|
|
152
|
+
for (const origin of this.config.network.allowedOrigins)
|
|
153
|
+
await context.route(originOrHostGlob(origin), (route) => route.continue());
|
|
154
|
+
}
|
|
155
|
+
if (this.config.network?.blockedOrigins?.length) {
|
|
156
|
+
for (const origin of this.config.network.blockedOrigins)
|
|
157
|
+
await context.route(originOrHostGlob(origin), (route) => route.abort("blockedbyclient"));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async ensureBrowserContext(options = {}) {
|
|
161
|
+
const { browserContext } = await this._ensureBrowserContext(options);
|
|
174
162
|
return browserContext;
|
|
175
163
|
}
|
|
176
|
-
_ensureBrowserContext() {
|
|
177
|
-
if (
|
|
178
|
-
this._browserContextPromise
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
164
|
+
_ensureBrowserContext(options) {
|
|
165
|
+
if (this._browserContextPromise && (options.forceHeadless === void 0 || this._browserContextOption?.forceHeadless === options.forceHeadless))
|
|
166
|
+
return this._browserContextPromise;
|
|
167
|
+
const closePrework = this._browserContextPromise ? this.closeBrowserContext() : Promise.resolve();
|
|
168
|
+
this._browserContextPromise = closePrework.then(() => this._setupBrowserContext(options));
|
|
169
|
+
this._browserContextPromise.catch(() => {
|
|
170
|
+
this._browserContextPromise = void 0;
|
|
171
|
+
this._browserContextOption = void 0;
|
|
172
|
+
});
|
|
173
|
+
this._browserContextOption = options;
|
|
183
174
|
return this._browserContextPromise;
|
|
184
175
|
}
|
|
185
|
-
async _setupBrowserContext() {
|
|
176
|
+
async _setupBrowserContext(options) {
|
|
186
177
|
if (this._closeBrowserContextPromise)
|
|
187
178
|
throw new Error("Another browser context is being closed.");
|
|
188
179
|
if (this.config.testIdAttribute)
|
|
189
180
|
import_playwright_core.selectors.setTestIdAttribute(this.config.testIdAttribute);
|
|
190
|
-
const result = await this._browserContextFactory.createContext(this._clientInfo, this._abortController.signal, this._runningToolName);
|
|
181
|
+
const result = await this._browserContextFactory.createContext(this._clientInfo, this._abortController.signal, { toolName: this._runningToolName, ...options });
|
|
191
182
|
const { browserContext } = result;
|
|
192
|
-
if (this.
|
|
193
|
-
|
|
183
|
+
if (!this.config.allowUnrestrictedFileAccess) {
|
|
184
|
+
browserContext._setAllowedProtocols(["http:", "https:", "about:", "data:"]);
|
|
185
|
+
browserContext._setAllowedDirectories(allRootPaths(this._clientInfo));
|
|
186
|
+
}
|
|
187
|
+
await this._setupRequestInterception(browserContext);
|
|
194
188
|
for (const page of browserContext.pages())
|
|
195
189
|
this._onPageCreated(page);
|
|
196
190
|
browserContext.on("page", (page) => this._onPageCreated(page));
|
|
@@ -206,62 +200,45 @@ class Context {
|
|
|
206
200
|
}
|
|
207
201
|
lookupSecret(secretName) {
|
|
208
202
|
if (!this.config.secrets?.[secretName])
|
|
209
|
-
return { value: secretName, code:
|
|
203
|
+
return { value: secretName, code: (0, import_utils.escapeWithQuotes)(secretName, "'") };
|
|
210
204
|
return {
|
|
211
205
|
value: this.config.secrets[secretName],
|
|
212
206
|
code: `process.env['${secretName}']`
|
|
213
207
|
};
|
|
214
208
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
constructor(context, browserContext) {
|
|
218
|
-
this._context = context;
|
|
219
|
-
this._browserContext = browserContext;
|
|
220
|
-
}
|
|
221
|
-
static async create(context, browserContext) {
|
|
222
|
-
const recorder = new InputRecorder(context, browserContext);
|
|
223
|
-
await recorder._initialize();
|
|
224
|
-
return recorder;
|
|
209
|
+
firstRootPath() {
|
|
210
|
+
return allRootPaths(this._clientInfo)[0];
|
|
225
211
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return;
|
|
242
|
-
const tab = import_tab.Tab.forPage(page);
|
|
243
|
-
if (tab)
|
|
244
|
-
sessionLog.logUserAction(data.action, tab, code, true);
|
|
245
|
-
},
|
|
246
|
-
signalAdded: (page, data) => {
|
|
247
|
-
if (this._context.isRunningTool())
|
|
248
|
-
return;
|
|
249
|
-
if (data.signal.name !== "navigation")
|
|
250
|
-
return;
|
|
251
|
-
const tab = import_tab.Tab.forPage(page);
|
|
252
|
-
const navigateAction = {
|
|
253
|
-
name: "navigate",
|
|
254
|
-
url: data.signal.url,
|
|
255
|
-
signals: []
|
|
256
|
-
};
|
|
257
|
-
if (tab)
|
|
258
|
-
sessionLog.logUserAction(navigateAction, tab, `await page.goto('${data.signal.url}');`, false);
|
|
259
|
-
}
|
|
260
|
-
});
|
|
212
|
+
}
|
|
213
|
+
function allRootPaths(clientInfo) {
|
|
214
|
+
const paths = [];
|
|
215
|
+
for (const root of clientInfo.roots) {
|
|
216
|
+
const url = new URL(root.uri);
|
|
217
|
+
let rootPath;
|
|
218
|
+
try {
|
|
219
|
+
rootPath = (0, import_url.fileURLToPath)(url);
|
|
220
|
+
} catch (e) {
|
|
221
|
+
if (e.code === "ERR_INVALID_FILE_URL_PATH" && import_os.default.platform() === "win32")
|
|
222
|
+
rootPath = decodeURIComponent(url.pathname);
|
|
223
|
+
}
|
|
224
|
+
if (!rootPath)
|
|
225
|
+
continue;
|
|
226
|
+
paths.push(rootPath);
|
|
261
227
|
}
|
|
228
|
+
if (paths.length === 0)
|
|
229
|
+
paths.push(process.cwd());
|
|
230
|
+
return paths;
|
|
231
|
+
}
|
|
232
|
+
function originOrHostGlob(originOrHost) {
|
|
233
|
+
try {
|
|
234
|
+
const url = new URL(originOrHost);
|
|
235
|
+
if (url.origin !== "null")
|
|
236
|
+
return `${url.origin}/**`;
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
return `*://${originOrHost}/**`;
|
|
262
240
|
}
|
|
263
241
|
// Annotate the CommonJS export names for ESM import in node:
|
|
264
242
|
0 && (module.exports = {
|
|
265
|
-
Context
|
|
266
|
-
InputRecorder
|
|
243
|
+
Context
|
|
267
244
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/mcp/browser/context.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { debug } from 'playwright-core/lib/utilsBundle';\nimport { selectors } from 'playwright-core';\n\nimport { logUnhandledError } from '../log';\nimport { Tab } from './tab';\nimport { outputFile } from './config';\nimport * as codegen from './codegen';\nimport { dateAsFileName } from './tools/utils';\n\nimport type * as playwright from '../../../types/test';\nimport type { FullConfig } from './config';\nimport type { BrowserContextFactory, BrowserContextFactoryResult } from './browserContextFactory';\nimport type * as actions from './actions';\nimport type { SessionLog } from './sessionLog';\nimport type { Tracing } from '../../../../playwright-core/src/client/tracing';\nimport type { ClientInfo } from '../sdk/server';\n\nconst testDebug = debug('pw:mcp:test');\n\ntype ContextOptions = {\n config: FullConfig;\n browserContextFactory: BrowserContextFactory;\n sessionLog: SessionLog | undefined;\n clientInfo: ClientInfo;\n};\n\nexport class Context {\n readonly config: FullConfig;\n readonly sessionLog: SessionLog | undefined;\n readonly options: ContextOptions;\n private _browserContextPromise: Promise<BrowserContextFactoryResult> | undefined;\n private _browserContextFactory: BrowserContextFactory;\n private _tabs: Tab[] = [];\n private _currentTab: Tab | undefined;\n private _clientInfo: ClientInfo;\n\n private static _allContexts: Set<Context> = new Set();\n private _closeBrowserContextPromise: Promise<void> | undefined;\n private _runningToolName: string | undefined;\n private _abortController = new AbortController();\n\n constructor(options: ContextOptions) {\n this.config = options.config;\n this.sessionLog = options.sessionLog;\n this.options = options;\n this._browserContextFactory = options.browserContextFactory;\n this._clientInfo = options.clientInfo;\n testDebug('create context');\n Context._allContexts.add(this);\n }\n\n static async disposeAll() {\n await Promise.all([...Context._allContexts].map(context => context.dispose()));\n }\n\n tabs(): Tab[] {\n return this._tabs;\n }\n\n currentTab(): Tab | undefined {\n return this._currentTab;\n }\n\n currentTabOrDie(): Tab {\n if (!this._currentTab)\n throw new Error('No open pages available. Use the \"browser_navigate\" tool to navigate to a page first.');\n return this._currentTab;\n }\n\n async newTab(): Promise<Tab> {\n const { browserContext } = await this._ensureBrowserContext();\n const page = await browserContext.newPage();\n this._currentTab = this._tabs.find(t => t.page === page)!;\n await this._currentTab.initializedPromise;\n return this._currentTab;\n }\n\n async selectTab(index: number) {\n const tab = this._tabs[index];\n if (!tab)\n throw new Error(`Tab ${index} not found`);\n await tab.page.bringToFront();\n this._currentTab = tab;\n return tab;\n }\n\n async ensureTab(): Promise<Tab> {\n const { browserContext } = await this._ensureBrowserContext();\n if (!this._currentTab)\n await browserContext.newPage();\n return this._currentTab!;\n }\n\n async closeTab(index: number | undefined): Promise<string> {\n const tab = index === undefined ? this._currentTab : this._tabs[index];\n if (!tab)\n throw new Error(`Tab ${index} not found`);\n const url = tab.page.url();\n await tab.page.close();\n return url;\n }\n\n async outputFile(fileName: string, options: { origin: 'code' | 'llm' | 'web', reason: string }): Promise<string> {\n return outputFile(this.config, this._clientInfo, fileName, options);\n }\n\n private _onPageCreated(page: playwright.Page) {\n const tab = new Tab(this, page, tab => this._onPageClosed(tab));\n this._tabs.push(tab);\n if (!this._currentTab)\n this._currentTab = tab;\n }\n\n private _onPageClosed(tab: Tab) {\n const index = this._tabs.indexOf(tab);\n if (index === -1)\n return;\n this._tabs.splice(index, 1);\n\n if (this._currentTab === tab)\n this._currentTab = this._tabs[Math.min(index, this._tabs.length - 1)];\n if (!this._tabs.length)\n void this.closeBrowserContext();\n }\n\n async closeBrowserContext() {\n if (!this._closeBrowserContextPromise)\n this._closeBrowserContextPromise = this._closeBrowserContextImpl().catch(logUnhandledError);\n await this._closeBrowserContextPromise;\n this._closeBrowserContextPromise = undefined;\n }\n\n isRunningTool() {\n return this._runningToolName !== undefined;\n }\n\n setRunningTool(name: string | undefined) {\n this._runningToolName = name;\n }\n\n private async _closeBrowserContextImpl() {\n if (!this._browserContextPromise)\n return;\n\n testDebug('close context');\n\n const promise = this._browserContextPromise;\n this._browserContextPromise = undefined;\n\n await promise.then(async ({ browserContext, close }) => {\n if (this.config.saveTrace)\n await browserContext.tracing.stop();\n const videos = this.config.saveVideo ? browserContext.pages().map(page => page.video()).filter(video => !!video) : [];\n await close(async () => {\n for (const video of videos) {\n const name = await this.outputFile(dateAsFileName('webm'), { origin: 'code', reason: 'Saving video' });\n await fs.promises.mkdir(path.dirname(name), { recursive: true });\n const p = await video.path();\n // video.saveAs() does not work for persistent contexts.\n if (fs.existsSync(p)) {\n try {\n await fs.promises.rename(p, name);\n } catch (e) {\n if (e.code !== 'EXDEV')\n logUnhandledError(e);\n // Retry operation (possibly cross-fs) with copy and unlink\n try {\n await fs.promises.copyFile(p, name);\n await fs.promises.unlink(p);\n } catch (e) {\n logUnhandledError(e);\n }\n }\n }\n }\n });\n });\n }\n\n async dispose() {\n this._abortController.abort('MCP context disposed');\n await this.closeBrowserContext();\n Context._allContexts.delete(this);\n }\n\n async ensureBrowserContext(): Promise<playwright.BrowserContext> {\n const { browserContext } = await this._ensureBrowserContext();\n return browserContext;\n }\n\n private _ensureBrowserContext() {\n if (!this._browserContextPromise) {\n this._browserContextPromise = this._setupBrowserContext();\n this._browserContextPromise.catch(() => {\n this._browserContextPromise = undefined;\n });\n }\n return this._browserContextPromise;\n }\n\n private async _setupBrowserContext(): Promise<BrowserContextFactoryResult> {\n if (this._closeBrowserContextPromise)\n throw new Error('Another browser context is being closed.');\n // TODO: move to the browser context factory to make it based on isolation mode.\n\n if (this.config.testIdAttribute)\n selectors.setTestIdAttribute(this.config.testIdAttribute);\n const result = await this._browserContextFactory.createContext(this._clientInfo, this._abortController.signal, this._runningToolName);\n const { browserContext } = result;\n if (this.sessionLog)\n await InputRecorder.create(this, browserContext);\n for (const page of browserContext.pages())\n this._onPageCreated(page);\n browserContext.on('page', page => this._onPageCreated(page));\n if (this.config.saveTrace) {\n await (browserContext.tracing as Tracing).start({\n name: 'trace-' + Date.now(),\n screenshots: true,\n snapshots: true,\n _live: true,\n });\n }\n return result;\n }\n\n lookupSecret(secretName: string): { value: string, code: string } {\n if (!this.config.secrets?.[secretName])\n return { value: secretName, code: codegen.quote(secretName) };\n return {\n value: this.config.secrets[secretName]!,\n code: `process.env['${secretName}']`,\n };\n }\n}\n\nexport class InputRecorder {\n private _context: Context;\n private _browserContext: playwright.BrowserContext;\n\n private constructor(context: Context, browserContext: playwright.BrowserContext) {\n this._context = context;\n this._browserContext = browserContext;\n }\n\n static async create(context: Context, browserContext: playwright.BrowserContext) {\n const recorder = new InputRecorder(context, browserContext);\n await recorder._initialize();\n return recorder;\n }\n\n private async _initialize() {\n const sessionLog = this._context.sessionLog!;\n await (this._browserContext as any)._enableRecorder({\n mode: 'recording',\n recorderMode: 'api',\n }, {\n actionAdded: (page: playwright.Page, data: actions.ActionInContext, code: string) => {\n if (this._context.isRunningTool())\n return;\n const tab = Tab.forPage(page);\n if (tab)\n sessionLog.logUserAction(data.action, tab, code, false);\n },\n actionUpdated: (page: playwright.Page, data: actions.ActionInContext, code: string) => {\n if (this._context.isRunningTool())\n return;\n const tab = Tab.forPage(page);\n if (tab)\n sessionLog.logUserAction(data.action, tab, code, true);\n },\n signalAdded: (page: playwright.Page, data: actions.SignalInContext) => {\n if (this._context.isRunningTool())\n return;\n if (data.signal.name !== 'navigation')\n return;\n const tab = Tab.forPage(page);\n const navigateAction: actions.Action = {\n name: 'navigate',\n url: data.signal.url,\n signals: [],\n };\n if (tab)\n sessionLog.logUserAction(navigateAction, tab, `await page.goto('${data.signal.url}');`, false);\n },\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["tab", "fs", "path", "e"]
|
|
7
|
+
}
|