-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathMcpResponse.test.ts
More file actions
249 lines (235 loc) · 7.68 KB
/
McpResponse.test.ts
File metadata and controls
249 lines (235 loc) · 7.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {describe, it} from 'node:test';
import assert from 'assert';
import {getMockRequest, html, withBrowser} from './utils.js';
describe('McpResponse', () => {
it('list pages', async () => {
await withBrowser(async (response, context) => {
response.setIncludePages(true);
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.deepStrictEqual(
result[0].text,
`# test response
## Pages
0: about:blank [selected]`,
);
});
});
it('allows response text lines to be added', async () => {
await withBrowser(async (response, context) => {
response.appendResponseLine('Testing 1');
response.appendResponseLine('Testing 2');
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.deepStrictEqual(
result[0].text,
`# test response
Testing 1
Testing 2`,
);
});
});
it('does not include anything in response if snapshot is null', async () => {
await withBrowser(async (response, context) => {
const page = context.getSelectedPage();
page.accessibility.snapshot = async () => null;
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.deepStrictEqual(result[0].text, `# test response`);
});
});
it('returns correctly formatted snapshot for a simple tree', async () => {
await withBrowser(async (response, context) => {
const page = context.getSelectedPage();
await page.setContent(`<!DOCTYPE html>
<button>Click me</button><input type="text" value="Input">`);
await page.focus('button');
response.setIncludeSnapshot(true);
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.strictEqual(
result[0].text,
`# test response
## Page content
uid=1_0 RootWebArea ""
uid=1_1 button "Click me" focusable focused
uid=1_2 textbox "" value="Input"
`,
);
});
});
it('returns values for textboxes', async () => {
await withBrowser(async (response, context) => {
const page = context.getSelectedPage();
await page.setContent(
html`<label
>username<input
name="username"
value="mcp"
/></label>`,
);
await page.focus('input');
response.setIncludeSnapshot(true);
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.strictEqual(
result[0].text,
`# test response
## Page content
uid=1_0 RootWebArea "My test page"
uid=1_1 StaticText "username"
uid=1_2 textbox "username" value="mcp" focusable focused
`,
);
});
});
it('adds throttling setting when it is not null', async () => {
await withBrowser(async (response, context) => {
context.setNetworkConditions('Slow 3G');
const result = await response.handle('test', context);
assert.equal(result[0].type, 'text');
assert.strictEqual(
result[0].text,
`# test response
## Network emulation
Emulating: Slow 3G
Navigation timeout set to 100000 ms`,
);
});
});
it('does not include throttling setting when it is null', async () => {
await withBrowser(async (response, context) => {
const result = await response.handle('test', context);
context.setNetworkConditions(null);
assert.equal(result[0].type, 'text');
assert.strictEqual(result[0].text, `# test response`);
});
});
it('adds image when image is attached', async () => {
await withBrowser(async (response, context) => {
response.attachImage({data: 'imageBase64', mimeType: 'image/png'});
const result = await response.handle('test', context);
assert.strictEqual(result[0].text, `# test response`);
assert.equal(result[1].type, 'image');
assert.strictEqual(result[1].data, 'imageBase64');
assert.strictEqual(result[1].mimeType, 'image/png');
});
});
it('adds cpu throttling setting when it is over 1', async () => {
await withBrowser(async (response, context) => {
context.setCpuThrottlingRate(4);
const result = await response.handle('test', context);
assert.strictEqual(
result[0].text,
`# test response
## CPU emulation
Emulating: 4x slowdown`,
);
});
});
it('does not include cpu throttling setting when it is 1', async () => {
await withBrowser(async (response, context) => {
context.setCpuThrottlingRate(1);
const result = await response.handle('test', context);
assert.strictEqual(result[0].text, `# test response`);
});
});
it('adds a dialog', async () => {
await withBrowser(async (response, context) => {
const page = context.getSelectedPage();
const dialogPromise = new Promise<void>(resolve => {
page.on('dialog', () => {
resolve();
});
});
page.evaluate(() => {
alert('test');
});
await dialogPromise;
const result = await response.handle('test', context);
await context.getDialog()?.dismiss();
assert.strictEqual(
result[0].text,
`# test response
# Open dialog
alert: test (default value: test).
Call browser_handle_dialog to handle it before continuing.`,
);
});
});
it('add network requests when setting is true', async () => {
await withBrowser(async (response, context) => {
response.setIncludeNetworkRequests(true);
context.getNetworkRequests = () => {
return [getMockRequest()];
};
const result = await response.handle('test', context);
assert.strictEqual(
result[0].text,
`# test response
## Network requests
http://example.com GET [pending]`,
);
});
});
it('does not include network requests when setting is false', async () => {
await withBrowser(async (response, context) => {
response.setIncludeNetworkRequests(false);
context.getNetworkRequests = () => {
return [getMockRequest()];
};
const result = await response.handle('test', context);
assert.strictEqual(result[0].text, `# test response`);
});
});
it('add network request when attached', async () => {
await withBrowser(async (response, context) => {
response.setIncludeNetworkRequests(true);
const request = getMockRequest();
context.getNetworkRequests = () => {
return [request];
};
response.attachNetworkRequest(request.url());
const result = await response.handle('test', context);
assert.strictEqual(
result[0].text,
`# test response
## Request http://example.com
Status: [pending]
### Request Headers
- content-size:10
## Network requests
http://example.com GET [pending]`,
);
});
});
it('adds console messages when the setting is true', async () => {
await withBrowser(async (response, context) => {
response.setIncludeConsoleData(true);
const page = context.getSelectedPage();
const consoleMessagePromise = new Promise<void>(resolve => {
page.on('console', () => {
resolve();
});
});
page.evaluate(() => {
console.log('Hello from the test');
});
await consoleMessagePromise;
const result = await response.handle('test', context);
assert.ok(result[0].text);
// Cannot check the full text because it contains local file path
assert.ok(
result[0].text.toString().startsWith(`# test response
## Console messages
Log>`),
);
assert.ok(result[0].text.toString().includes('Hello from the test'));
});
});
});