Skip to content

Commit 5463cdf

Browse files
committed
chore: update extension action trigger test to use snapshot testing
1 parent 41b9d3a commit 5463cdf

4 files changed

Lines changed: 36 additions & 32 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
exports[`extension > triggers an extension action 1`] = `
2+
# list_pages response
3+
## Pages
4+
1: about:blank [selected]
5+
## Extension Service Workers
6+
`;
7+
8+
exports[`extension > triggers an extension action 2`] = `
9+
# list_pages response
10+
## Pages
11+
1: about:blank [selected]
12+
sw-1: chrome-extension://<extension-id>/sw.js
13+
`;

tests/tools/extensions.test.ts

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {afterEach, describe, it} from 'node:test';
1111
import sinon from 'sinon';
1212

1313
import type {ParsedArguments} from '../../src/cli.js';
14-
import type {McpResponse} from '../../src/McpResponse.js';
1514
import {
1615
installExtension,
1716
uninstallExtension,
@@ -20,7 +19,7 @@ import {
2019
triggerExtensionAction,
2120
} from '../../src/tools/extensions.js';
2221
import {listPages} from '../../src/tools/pages.js';
23-
import {withMcpContext} from '../utils.js';
22+
import {extractId, withMcpContext} from '../utils.js';
2423

2524
const EXTENSION_WITH_SW_PATH = path.join(
2625
import.meta.dirname,
@@ -31,15 +30,6 @@ const EXTENSION_PATH = path.join(
3130
'../../../tests/tools/fixtures/extension',
3231
);
3332

34-
export function extractId(response: McpResponse) {
35-
const responseLine = response.responseLines[0];
36-
assert.ok(responseLine, 'Response should not be empty');
37-
const match = responseLine.match(/Extension installed\. Id: (.+)/);
38-
const extensionId = match ? match[1] : null;
39-
assert.ok(extensionId, 'Response should contain a valid key');
40-
return extensionId;
41-
}
42-
4333
describe('extension', () => {
4434
afterEach(() => {
4535
sinon.restore();
@@ -135,17 +125,13 @@ describe('extension', () => {
135125
assert.ok(reinstalled, 'Extension should be present after reload');
136126
});
137127
});
138-
it('triggers an extension action', async () => {
128+
it('triggers an extension action', async t => {
139129
await withMcpContext(
140130
async (response, context) => {
141-
await installExtension.handler(
142-
{params: {path: EXTENSION_WITH_SW_PATH}},
143-
response,
144-
context,
131+
const extensionId = await context.installExtension(
132+
EXTENSION_WITH_SW_PATH,
145133
);
146134

147-
const extensionId = extractId(response);
148-
149135
response.resetResponseLineForTesting();
150136
const listPageDef = listPages({
151137
categoryExtensions: true,
@@ -160,9 +146,8 @@ describe('extension', () => {
160146
type: 'text';
161147
text: string;
162148
};
163-
assert.ok(
164-
!textContent.text.includes(extensionId),
165-
'Response should not contain extension service worker id',
149+
t.assert.snapshot?.(
150+
textContent.text.replaceAll(extensionId, '<extension-id>'),
166151
);
167152

168153
await triggerExtensionAction.handler(
@@ -187,9 +172,11 @@ describe('extension', () => {
187172
type: 'text';
188173
text: string;
189174
};
190-
assert.ok(
191-
textContent.text.includes(swUrl),
192-
'Response should contain extension service worker url',
175+
t.assert.snapshot?.(
176+
textContent.text
177+
.replaceAll(extensionId, '<extension-id>')
178+
.replaceAll(swUrl, '<sw-url>')
179+
.replaceAll(/localhost:\d+/g, 'localhost:<port>'),
193180
);
194181
},
195182
{

tests/tools/script.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ import type {ParsedArguments} from '../../src/cli.js';
1212
import {installExtension} from '../../src/tools/extensions.js';
1313
import {evaluateScript} from '../../src/tools/script.js';
1414
import {serverHooks} from '../server.js';
15-
import {html, withMcpContext} from '../utils.js';
16-
17-
import {extractId} from './extensions.test.js';
15+
import {extractId, html, withMcpContext} from '../utils.js';
1816

1917
const EXTENSION_PATH = path.join(
2018
import.meta.dirname,

tests/utils.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
import assert from 'node:assert';
8+
79
import type {CallToolResult} from '@modelcontextprotocol/sdk/types.js';
810
import logger from 'debug';
911
import type {Browser} from 'puppeteer';
1012
import puppeteer, {Locator} from 'puppeteer';
1113
import type {
12-
ChromeReleaseChannel,
1314
Frame,
1415
HTTPRequest,
1516
HTTPResponse,
@@ -43,6 +44,15 @@ export function getImageContent(content: CallToolResult['content'][number]): {
4344
throw new Error(`Expected image content but got ${content.type}`);
4445
}
4546

47+
export function extractId(response: McpResponse) {
48+
const responseLine = response.responseLines[0];
49+
assert.ok(responseLine, 'Response should not be empty');
50+
const match = responseLine.match(/Extension installed\. Id: (.+)/);
51+
const extensionId = match ? match[1] : null;
52+
assert.ok(extensionId, 'Response should contain a valid key');
53+
return extensionId;
54+
}
55+
4656
const browsers = new Map<string, Browser>();
4757
let context: McpContext | undefined;
4858

@@ -51,16 +61,12 @@ export async function withBrowser(
5161
options: {
5262
debug?: boolean;
5363
autoOpenDevTools?: boolean;
54-
channel?: string;
5564
executablePath?: string;
5665
} = {},
5766
) {
5867
const launchOptions: LaunchOptions = {
5968
executablePath:
6069
options.executablePath ?? process.env.PUPPETEER_EXECUTABLE_PATH,
61-
channel: (options.executablePath
62-
? undefined
63-
: options.channel) as ChromeReleaseChannel,
6470
headless: !options.debug,
6571
defaultViewport: null,
6672
devtools: options.autoOpenDevTools ?? false,

0 commit comments

Comments
 (0)