chore: parse response in tests (#796)
This commit is contained in:
@@ -93,8 +93,8 @@ export class Context {
|
||||
|
||||
if (!this._tabs.length) {
|
||||
return [
|
||||
'### No open tabs',
|
||||
'Use the "browser_navigate" tool to navigate to a page first.',
|
||||
'### Open tabs',
|
||||
'No open tabs. Use the "browser_navigate" tool to navigate to a page first.',
|
||||
'',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -88,12 +88,12 @@ export function createServer(backend: ServerBackend, runHeartbeat: boolean): Ser
|
||||
}
|
||||
|
||||
const errorResult = (...messages: string[]) => ({
|
||||
content: [{ type: 'text', text: messages.join('\n') }],
|
||||
content: [{ type: 'text', text: '### Result\n' + messages.join('\n') }],
|
||||
isError: true,
|
||||
});
|
||||
const tool = tools.find(tool => tool.name === request.params.name) as ToolSchema<any>;
|
||||
if (!tool)
|
||||
return errorResult(`Tool "${request.params.name}" not found`);
|
||||
return errorResult(`Error: Tool "${request.params.name}" not found`);
|
||||
|
||||
try {
|
||||
return await backend.callTool(tool, tool.inputSchema.parse(request.params.arguments || {}));
|
||||
|
||||
@@ -28,6 +28,7 @@ export class Response {
|
||||
|
||||
readonly toolName: string;
|
||||
readonly toolArgs: Record<string, any>;
|
||||
private _isError: boolean | undefined;
|
||||
|
||||
constructor(context: Context, toolName: string, toolArgs: Record<string, any>) {
|
||||
this._context = context;
|
||||
@@ -39,6 +40,11 @@ export class Response {
|
||||
this._result.push(result);
|
||||
}
|
||||
|
||||
addError(error: string) {
|
||||
this._result.push(`Error: ${error}`);
|
||||
this._isError = true;
|
||||
}
|
||||
|
||||
result() {
|
||||
return this._result.join('\n');
|
||||
}
|
||||
@@ -77,7 +83,7 @@ export class Response {
|
||||
return this._snapshot;
|
||||
}
|
||||
|
||||
async serialize(): Promise<{ content: (TextContent | ImageContent)[] }> {
|
||||
async serialize(): Promise<{ content: (TextContent | ImageContent)[], isError?: boolean }> {
|
||||
const response: string[] = [];
|
||||
|
||||
// Start with command result.
|
||||
@@ -116,6 +122,6 @@ ${this._code.join('\n')}
|
||||
content.push({ type: 'image', data: image.data.toString('base64'), mimeType: image.contentType });
|
||||
}
|
||||
|
||||
return { content };
|
||||
return { content, isError: this._isError };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ const resize = defineTabTool({
|
||||
},
|
||||
|
||||
handle: async (tab, params, response) => {
|
||||
response.addCode(`// Resize browser window to ${params.width}x${params.height}`);
|
||||
response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);
|
||||
|
||||
await tab.waitForCompletion(async () => {
|
||||
|
||||
@@ -67,11 +67,9 @@ const type = defineTabTool({
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.slowly) {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Press "${params.text}" sequentially into "${params.element}"`);
|
||||
response.addCode(`await page.${await generateLocator(locator)}.pressSequentially(${javascript.quote(params.text)});`);
|
||||
await locator.pressSequentially(params.text);
|
||||
} else {
|
||||
response.addCode(`// Fill "${params.text}" into "${params.element}"`);
|
||||
response.addCode(`await page.${await generateLocator(locator)}.fill(${javascript.quote(params.text)});`);
|
||||
await locator.fill(params.text);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ const navigate = defineTool({
|
||||
await tab.navigate(params.url);
|
||||
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Navigate to ${params.url}`);
|
||||
response.addCode(`await page.goto('${params.url}');`);
|
||||
},
|
||||
});
|
||||
@@ -53,7 +52,6 @@ const goBack = defineTabTool({
|
||||
handle: async (tab, params, response) => {
|
||||
await tab.page.goBack();
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Navigate back`);
|
||||
response.addCode(`await page.goBack();`);
|
||||
},
|
||||
});
|
||||
@@ -70,7 +68,6 @@ const goForward = defineTabTool({
|
||||
handle: async (tab, params, response) => {
|
||||
await tab.page.goForward();
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Navigate forward`);
|
||||
response.addCode(`await page.goForward();`);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -37,7 +37,6 @@ const pdf = defineTabTool({
|
||||
|
||||
handle: async (tab, params, response) => {
|
||||
const fileName = await outputFile(tab.context.config, params.filename ?? `page-${new Date().toISOString()}.pdf`);
|
||||
response.addCode(`// Save page as ${fileName}`);
|
||||
response.addCode(`await page.pdf(${javascript.formatObject({ path: fileName })});`);
|
||||
response.addResult(`Saved page as ${fileName}`);
|
||||
await tab.page.pdf({ path: fileName });
|
||||
|
||||
@@ -63,13 +63,11 @@ const click = defineTabTool({
|
||||
const button = params.button;
|
||||
const buttonAttr = button ? `{ button: '${button}' }` : '';
|
||||
|
||||
if (params.doubleClick) {
|
||||
response.addCode(`// Double click ${params.element}`);
|
||||
if (params.doubleClick)
|
||||
response.addCode(`await page.${await generateLocator(locator)}.dblclick(${buttonAttr});`);
|
||||
} else {
|
||||
response.addCode(`// Click ${params.element}`);
|
||||
else
|
||||
response.addCode(`await page.${await generateLocator(locator)}.click(${buttonAttr});`);
|
||||
}
|
||||
|
||||
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.doubleClick)
|
||||
@@ -151,7 +149,6 @@ const selectOption = defineTabTool({
|
||||
response.setIncludeSnapshot();
|
||||
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addCode(`// Select options [${params.values.join(', ')}] in ${params.element}`);
|
||||
response.addCode(`await page.${await generateLocator(locator)}.selectOption(${javascript.formatObject(params.values)});`);
|
||||
|
||||
await tab.waitForCompletion(async () => {
|
||||
|
||||
@@ -60,10 +60,11 @@ export function defineTabTool<Input extends z.Schema>(tool: TabTool<Input>): Too
|
||||
const tab = context.currentTabOrDie();
|
||||
const modalStates = tab.modalStates().map(state => state.type);
|
||||
if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState))
|
||||
throw new Error(`The tool "${tool.schema.name}" can only be used when there is related modal state present.\n` + tab.modalStatesMarkdown().join('\n'));
|
||||
if (!tool.clearsModalState && modalStates.length)
|
||||
throw new Error(`Tool "${tool.schema.name}" does not handle the modal state.\n` + tab.modalStatesMarkdown().join('\n'));
|
||||
return tool.handle(tab, params, response);
|
||||
response.addError(`The tool "${tool.schema.name}" can only be used when there is related modal state present.\n` + tab.modalStatesMarkdown().join('\n'));
|
||||
else if (!tool.clearsModalState && modalStates.length)
|
||||
response.addError(`Tool "${tool.schema.name}" does not handle the modal state.\n` + tab.modalStatesMarkdown().join('\n'));
|
||||
else
|
||||
return tool.handle(tab, params, response);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user