项目文件夹

文件
dependabot[bot] e8394ab113 chore(deps-dev): bump the bundled group with 2 updates (#481)
Bumps the bundled group with 2 updates:
[@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk)
and [puppeteer](https://github.com/puppeteer/puppeteer).

Updates `@modelcontextprotocol/sdk` from 1.20.1 to 1.20.2
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/modelcontextprotocol/typescript-sdk/commit/7098bff073d78cfaee40869897d84a5929c29570"><code>7098bff</code></a>
chore: bump version for weekly release (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/1042">#1042</a>)</li>
<li><a
href="https://github.com/modelcontextprotocol/typescript-sdk/commit/c54309598505007c4467f78fa7dfb3e7c763679c"><code>c543095</code></a>
fix: Zod to JSONSchema pipe strategies (<a
href="https://redirect.github.com/modelcontextprotocol/typescript-sdk/issues/962">#962</a>)</li>
<li>See full diff in <a
href="https://github.com/modelcontextprotocol/typescript-sdk/compare/1.20.1...1.20.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `puppeteer` from 24.26.0 to 24.26.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/releases">puppeteer's
releases</a>.</em></p>
<blockquote>
<h2>puppeteer-core: v24.26.1</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v24.26.0...puppeteer-core-v24.26.1">24.26.1</a>
(2025-10-22)</h2>
<h3>🛠️ Fixes</h3>
<ul>
<li><strong>a11y:</strong> expose the url property for links (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14357">#14357</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/93d098b060771dbd1e6875f4664273604022f3bd">93d098b</a>)</li>
<li>roll to Chrome 141.0.7390.122 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14360">#14360</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/f2fef816f234bd30a13bb86dfc654f29f5cb2f6b">f2fef81</a>)</li>
</ul>
<h2>puppeteer: v24.26.1</h2>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v24.26.0...puppeteer-v24.26.1">24.26.1</a>
(2025-10-22)</h2>
<h3>♻️ Chores</h3>
<ul>
<li><strong>puppeteer:</strong> Synchronize puppeteer versions</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li>puppeteer-core bumped from 24.26.0 to 24.26.1</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md">puppeteer's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v24.26.0...puppeteer-v24.26.1">24.26.1</a>
(2025-10-22)</h2>
<h3>♻️ Chores</h3>
<ul>
<li><strong>puppeteer:</strong> Synchronize puppeteer versions</li>
</ul>
<h3>Dependencies</h3>
<ul>
<li>The following workspace dependencies were updated
<ul>
<li>dependencies
<ul>
<li>puppeteer-core bumped from 24.26.0 to 24.26.1</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>🛠️ Fixes</h3>
<ul>
<li><strong>a11y:</strong> expose the url property for links (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14357">#14357</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/93d098b060771dbd1e6875f4664273604022f3bd">93d098b</a>)</li>
<li>roll to Chrome 141.0.7390.122 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14360">#14360</a>)
(<a
href="https://github.com/puppeteer/puppeteer/commit/f2fef816f234bd30a13bb86dfc654f29f5cb2f6b">f2fef81</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/6e2348c27e3493e53b609122888e0950d342e4d2"><code>6e2348c</code></a>
chore: release main (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14359">#14359</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/21f309239909548b390b7e851d481ff832899e35"><code>21f3092</code></a>
test: fix move to ESM (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14362">#14362</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/5fe1333769dd7bf28b239db308d67f3402633da2"><code>5fe1333</code></a>
test: move to ESM (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14358">#14358</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/f2fef816f234bd30a13bb86dfc654f29f5cb2f6b"><code>f2fef81</code></a>
fix: roll to Chrome 141.0.7390.122 (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14360">#14360</a>)</li>
<li><a
href="https://github.com/puppeteer/puppeteer/commit/93d098b060771dbd1e6875f4664273604022f3bd"><code>93d098b</code></a>
fix(a11y): expose the url property for links (<a
href="https://redirect.github.com/puppeteer/puppeteer/issues/14357">#14357</a>)</li>
<li>See full diff in <a
href="https://github.com/puppeteer/puppeteer/compare/puppeteer-v24.26.0...puppeteer-v24.26.1">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nikolay Vitkov <nvitkov@chromium.org>
2025-10-27 14:08:01 +00:00

178 行
4.4 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import logger from 'debug';
import type {Browser} from 'puppeteer';
import puppeteer, {Locator} from 'puppeteer';
import type {
Frame,
HTTPRequest,
HTTPResponse,
LaunchOptions,
} from 'puppeteer-core';
import {McpContext} from '../src/McpContext.js';
import {McpResponse} from '../src/McpResponse.js';
import {stableIdSymbol} from '../src/PageCollector.js';
const browsers = new Map<string, Browser>();
export async function withBrowser(
cb: (response: McpResponse, context: McpContext) => Promise<void>,
options: {debug?: boolean; autoOpenDevTools?: boolean} = {},
) {
const launchOptions: LaunchOptions = {
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
headless: !options.debug,
defaultViewport: null,
devtools: options.autoOpenDevTools ?? false,
pipe: true,
handleDevToolsAsPage: true,
};
const key = JSON.stringify(launchOptions);
let browser = browsers.get(key);
if (!browser) {
browser = await puppeteer.launch(launchOptions);
browsers.set(key, browser);
}
const newPage = await browser.newPage();
// Close other pages.
await Promise.all(
(await browser.pages()).map(async page => {
if (page !== newPage) {
await page.close();
}
}),
);
const response = new McpResponse();
const context = await McpContext.from(
browser,
logger('test'),
{
experimentalDevToolsDebugging: false,
},
Locator,
);
await cb(response, context);
}
export function getMockRequest(
options: {
method?: string;
response?: HTTPResponse;
failure?: HTTPRequest['failure'];
resourceType?: string;
hasPostData?: boolean;
postData?: string;
fetchPostData?: Promise<string>;
stableId?: number;
navigationRequest?: boolean;
frame?: Frame;
} = {},
): HTTPRequest {
return {
url() {
return 'http://example.com';
},
method() {
return options.method ?? 'GET';
},
fetchPostData() {
return options.fetchPostData ?? Promise.reject();
},
hasPostData() {
return options.hasPostData ?? false;
},
postData() {
return options.postData;
},
response() {
return options.response ?? null;
},
failure() {
return options.failure?.() ?? null;
},
resourceType() {
return options.resourceType ?? 'document';
},
headers(): Record<string, string> {
return {
'content-size': '10',
};
},
redirectChain(): HTTPRequest[] {
return [];
},
isNavigationRequest() {
return options.navigationRequest ?? false;
},
frame() {
return options.frame ?? ({} as Frame);
},
[stableIdSymbol]: options.stableId ?? 1,
} as unknown as HTTPRequest;
}
export function getMockResponse(
options: {
status?: number;
} = {},
): HTTPResponse {
return {
status() {
return options.status ?? 200;
},
} as HTTPResponse;
}
export function html(
strings: TemplateStringsArray,
...values: unknown[]
): string {
const bodyContent = strings.reduce((acc, str, i) => {
return acc + str + (values[i] || '');
}, '');
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My test page</title>
</head>
<body>
${bodyContent}
</body>
</html>`;
}
export function stabilizeResponseOutput(text: unknown) {
if (typeof text !== 'string') {
throw new Error('Input must be string');
}
let output = text;
const dateRegEx = /.{3}, \d{2} .{3} \d{4} \d{2}:\d{2}:\d{2} [A-Z]{3}/g;
output = output.replaceAll(dateRegEx, '<long date>');
const localhostRegEx = /http:\/\/localhost:\d{5}\//g;
output = output.replaceAll(localhostRegEx, 'http://localhost:<port>/');
const userAgentRegEx = /user-agent:.*\n/g;
output = output.replaceAll(userAgentRegEx, 'user-agent:<user-agent>\n');
const chUaRegEx = /sec-ch-ua:"Chromium";v="\d{3}"/g;
output = output.replaceAll(chUaRegEx, 'sec-ch-ua:"Chromium";v="<version>"');
// sec-ch-ua-platform:"Linux"
const chUaPlatformRegEx = /sec-ch-ua-platform:"[a-zA-Z]*"/g;
output = output.replaceAll(chUaPlatformRegEx, 'sec-ch-ua-platform:"<os>"');
const savedSnapshot = /Saved snapshot to (.*)/g;
output = output.replaceAll(savedSnapshot, 'Saved snapshot to <file>');
return output;
}