mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 12:55:09 +00:00
121 lines
2.6 KiB
TypeScript
121 lines
2.6 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 BrowserOS
|
|
*/
|
|
import logger from 'debug';
|
|
import type {Browser} from 'puppeteer';
|
|
import puppeteer from 'puppeteer';
|
|
import type {HTTPRequest, HTTPResponse} from 'puppeteer-core';
|
|
|
|
import {McpContext} from '../src/McpContext.js';
|
|
import {McpResponse} from '../src/McpResponse.js';
|
|
|
|
let browser: Browser | undefined;
|
|
|
|
export async function withBrowser(
|
|
cb: (response: McpResponse, context: McpContext) => Promise<void>,
|
|
options: {debug?: boolean} = {},
|
|
) {
|
|
const {debug = false} = options;
|
|
if (!browser) {
|
|
browser = await puppeteer.launch({
|
|
executablePath: process.env.PUPPETEER_EXECUTABLE_PATH,
|
|
headless: !debug,
|
|
defaultViewport: null,
|
|
});
|
|
}
|
|
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'));
|
|
|
|
await cb(response, context);
|
|
}
|
|
|
|
export function getMockRequest(
|
|
options: {
|
|
method?: string;
|
|
response?: HTTPResponse;
|
|
failure?: HTTPRequest['failure'];
|
|
resourceType?: string;
|
|
hasPostData?: boolean;
|
|
postData?: string;
|
|
fetchPostData?: Promise<string>;
|
|
} = {},
|
|
): 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 [];
|
|
},
|
|
} 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>`;
|
|
}
|