Skip to content

Commit f537e11

Browse files
author
Natallia Harshunova
committed
Refactor tests
1 parent 5a9d24a commit f537e11

2 files changed

Lines changed: 244 additions & 0 deletions

File tree

tests/security_policies.test.ts

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Google LLC
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
import assert from 'node:assert/strict';
8+
import {describe, it} from 'node:test';
9+
10+
import {lighthouseAudit} from '../src/tools/lighthouse.js';
11+
import {navigatePage} from '../src/tools/pages.js';
12+
import {evaluateScript} from '../src/tools/script.js';
13+
14+
import {serverHooks} from './server.js';
15+
import {withMcpContext} from './utils.js';
16+
17+
describe('Security Policies Integration', () => {
18+
const server = serverHooks();
19+
20+
it('blocks URLs in blocklist', async () => {
21+
server.addHtmlRoute('/allowed.html', '<html><body>Allowed</body></html>');
22+
server.addHtmlRoute('/blocked.html', '<html><body>Blocked</body></html>');
23+
24+
await withMcpContext(
25+
async (response, context) => {
26+
const allowedUrl = server.getRoute('/allowed.html');
27+
await navigatePage().handler(
28+
{
29+
params: {url: allowedUrl},
30+
page: context.getSelectedMcpPage(),
31+
},
32+
response,
33+
context,
34+
);
35+
assert.strictEqual(
36+
response.responseLines[0],
37+
`Successfully navigated to ${allowedUrl}.`,
38+
);
39+
40+
response.resetResponseLineForTesting();
41+
await evaluateScript().handler(
42+
{
43+
params: {function: String(() => document.body.textContent)},
44+
},
45+
response,
46+
context,
47+
);
48+
assert.strictEqual(
49+
JSON.parse(response.responseLines.at(2)!),
50+
'Allowed',
51+
);
52+
53+
const blockedUrl = server.getRoute('/blocked.html');
54+
response.resetResponseLineForTesting();
55+
await evaluateScript().handler(
56+
{
57+
params: {
58+
function: `async () => {
59+
try {
60+
await fetch("${blockedUrl}");
61+
return 'SUCCESS';
62+
} catch (err) {
63+
return err instanceof Error ? err.message : String(err);
64+
}
65+
}`,
66+
},
67+
},
68+
response,
69+
context,
70+
);
71+
72+
assert.strictEqual(
73+
JSON.parse(response.responseLines.at(2)!),
74+
'Failed to fetch',
75+
);
76+
},
77+
{
78+
blocklist: [server.getRoute('/blocked.html')],
79+
},
80+
);
81+
});
82+
83+
it('blocks URLs not in allowlist', async () => {
84+
server.addHtmlRoute('/allowed.html', '<html><body>Allowed</body></html>');
85+
server.addHtmlRoute('/blocked.html', '<html><body>Blocked</body></html>');
86+
87+
await withMcpContext(
88+
async (response, context) => {
89+
const allowedUrl = server.getRoute('/allowed.html');
90+
await navigatePage().handler(
91+
{
92+
params: {url: allowedUrl},
93+
page: context.getSelectedMcpPage(),
94+
},
95+
response,
96+
context,
97+
);
98+
assert.strictEqual(
99+
response.responseLines[0],
100+
`Successfully navigated to ${allowedUrl}.`,
101+
);
102+
103+
response.resetResponseLineForTesting();
104+
await evaluateScript().handler(
105+
{
106+
params: {function: String(() => document.body.textContent)},
107+
},
108+
response,
109+
context,
110+
);
111+
assert.strictEqual(
112+
JSON.parse(response.responseLines.at(2)!),
113+
'Allowed',
114+
);
115+
116+
const blockedUrl = server.getRoute('/blocked.html');
117+
response.resetResponseLineForTesting();
118+
await evaluateScript().handler(
119+
{
120+
params: {
121+
function: `async () => {
122+
try {
123+
await fetch("${blockedUrl}");
124+
return 'SUCCESS';
125+
} catch (err) {
126+
return err instanceof Error ? err.message : String(err);
127+
}
128+
}`,
129+
},
130+
},
131+
response,
132+
context,
133+
);
134+
135+
assert.strictEqual(
136+
JSON.parse(response.responseLines.at(2)!),
137+
'Failed to fetch',
138+
);
139+
},
140+
{
141+
allowlist: [server.getRoute('/allowed.html')],
142+
},
143+
);
144+
});
145+
146+
it('respects blocklist after Lighthouse audits', async () => {
147+
server.addHtmlRoute('/allowed.html', '<html><body>Allowed</body></html>');
148+
server.addHtmlRoute('/blocked.html', '<html><body>Blocked</body></html>');
149+
150+
await withMcpContext(
151+
async (response, context) => {
152+
const allowedUrl = server.getRoute('/allowed.html');
153+
await navigatePage().handler(
154+
{
155+
params: {url: allowedUrl},
156+
page: context.getSelectedMcpPage(),
157+
},
158+
response,
159+
context,
160+
);
161+
assert.strictEqual(
162+
response.responseLines[0],
163+
`Successfully navigated to ${allowedUrl}.`,
164+
);
165+
166+
const blockedUrl = server.getRoute('/blocked.html');
167+
168+
// Verifies fetch is blocked before Lighthouse audit
169+
response.resetResponseLineForTesting();
170+
await evaluateScript().handler(
171+
{
172+
params: {
173+
function: `async () => {
174+
try {
175+
await fetch("${blockedUrl}");
176+
return 'SUCCESS';
177+
} catch (err) {
178+
return err instanceof Error ? err.message : String(err);
179+
}
180+
}`,
181+
},
182+
},
183+
response,
184+
context,
185+
);
186+
assert.strictEqual(
187+
JSON.parse(response.responseLines.at(2)!),
188+
'Failed to fetch',
189+
'Fetch should be blocked before audit',
190+
);
191+
192+
await lighthouseAudit.handler(
193+
{
194+
params: {
195+
mode: 'navigation',
196+
device: 'desktop',
197+
},
198+
page: context.getSelectedMcpPage(),
199+
},
200+
response,
201+
context,
202+
);
203+
204+
assert.equal(
205+
response.attachedLighthouseResult?.summary.mode,
206+
'navigation',
207+
);
208+
209+
// 2. Verify fetch remains blocked AFTER Lighthouse audit
210+
response.resetResponseLineForTesting();
211+
await evaluateScript().handler(
212+
{
213+
params: {
214+
function: `async () => {
215+
try {
216+
await fetch("${blockedUrl}");
217+
return 'SUCCESS';
218+
} catch (err) {
219+
return err instanceof Error ? err.message : String(err);
220+
}
221+
}`,
222+
},
223+
},
224+
response,
225+
context,
226+
);
227+
assert.strictEqual(
228+
JSON.parse(response.responseLines.at(2)!),
229+
'Failed to fetch',
230+
'Fetch should still be blocked after audit',
231+
);
232+
},
233+
{
234+
blocklist: [server.getRoute('/blocked.html')],
235+
},
236+
);
237+
});
238+
});

tests/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ export async function withBrowser(
7474
autoOpenDevTools?: boolean;
7575
executablePath?: string;
7676
args?: string[];
77+
blocklist?: string[];
78+
allowlist?: string[];
7779
} = {},
7880
) {
7981
const launchOptions: LaunchOptions = {
@@ -86,6 +88,8 @@ export async function withBrowser(
8688
handleDevToolsAsPage: true,
8789
args: [...(options.args || []), '--screen-info={3840x2160}'],
8890
enableExtensions: true,
91+
blocklist: options.blocklist,
92+
allowlist: options.allowlist,
8993
};
9094
const key = JSON.stringify(launchOptions);
9195

@@ -115,6 +119,8 @@ export async function withMcpContext(
115119
performanceCrux?: boolean;
116120
executablePath?: string;
117121
args?: string[];
122+
blocklist?: string[];
123+
allowlist?: string[];
118124
} = {},
119125
args: ParsedArguments = {} as ParsedArguments,
120126
) {

0 commit comments

Comments
 (0)