豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit d845ad4

Browse files
gernbergOrKoN
andauthored
feat: Add ability to inject script to run on page load (#568)
Adds a parameter "initScript" to be used to inject a script into the page load before other scripts execute. [Page.evaluateOnNewDocument](https://pptr.dev/api/puppeteer.page.evaluateonnewdocument) See #567 --------- Co-authored-by: Alex Rudenko <alexrudenko@chromium.org>
1 parent 7e279f1 commit d845ad4

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

docs/tool-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157

158158
- **handleBeforeUnload** (enum: "accept", "decline") _(optional)_: Whether to auto accept or beforeunload dialogs triggered by this navigation. Default is accept.
159159
- **ignoreCache** (boolean) _(optional)_: Whether to ignore cache on reload.
160+
- **initScript** (string) _(optional)_: A JavaScript script to be executed on each new document before any other scripts for the next navigation.
160161
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
161162
- **type** (enum: "url", "back", "forward", "reload") _(optional)_: Navigate the page by URL, back or forward in history, or reload.
162163
- **url** (string) _(optional)_: Target URL (only type=url)

src/tools/pages.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ export const navigatePage = defineTool({
133133
.describe(
134134
'Whether to auto accept or beforeunload dialogs triggered by this navigation. Default is accept.',
135135
),
136+
initScript: zod
137+
.string()
138+
.optional()
139+
.describe(
140+
'A JavaScript script to be executed on each new document before any other scripts for the next navigation.',
141+
),
136142
...timeoutSchema,
137143
},
138144
handler: async (request, response, context) => {
@@ -163,6 +169,15 @@ export const navigatePage = defineTool({
163169
context.clearDialog();
164170
}
165171
};
172+
173+
let initScriptId: string | undefined;
174+
if (request.params.initScript) {
175+
const {identifier} = await page.evaluateOnNewDocument(
176+
request.params.initScript,
177+
);
178+
initScriptId = identifier;
179+
}
180+
166181
page.on('dialog', dialogHandler);
167182

168183
try {
@@ -224,6 +239,13 @@ export const navigatePage = defineTool({
224239
});
225240
} finally {
226241
page.off('dialog', dialogHandler);
242+
if (initScriptId) {
243+
await page
244+
.removeScriptToEvaluateOnNewDocument(initScriptId)
245+
.catch(error => {
246+
logger(`Failed to remove init script`, error);
247+
});
248+
}
227249
}
228250

229251
response.setIncludePages(true);

tests/tools/pages.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,28 @@ describe('pages', () => {
297297
assert.ok(response.includePages);
298298
});
299299
});
300+
it('navigates to correct page with initScript', async () => {
301+
await withMcpContext(async (response, context) => {
302+
await navigatePage.handler(
303+
{
304+
params: {
305+
url: 'data:text/html,<div>Hello MCP</div>',
306+
initScript: 'window.initScript = "completed"',
307+
},
308+
},
309+
response,
310+
context,
311+
);
312+
const page = context.getSelectedPage();
313+
314+
// wait for up to 1s for the global variable to set by the initScript to exist
315+
await page.waitForFunction("window.initScript==='completed'", {
316+
timeout: 1000,
317+
});
318+
319+
assert.ok(response.includePages);
320+
});
321+
});
300322
});
301323
describe('resize', () => {
302324
it('resize the page', async () => {

0 commit comments

Comments
 (0)