Skip to content

Commit 2d7a8dc

Browse files
author
Natallia Harshunova
committed
Fix extension tests
1 parent aa08758 commit 2d7a8dc

2 files changed

Lines changed: 40 additions & 109 deletions

File tree

tests/tools/extension.test.ts

Lines changed: 0 additions & 68 deletions
This file was deleted.

tests/tools/extensions.test.ts

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,65 +5,64 @@
55
*/
66

77
import assert from 'node:assert';
8-
import {describe, it} from 'node:test';
8+
import fs from 'node:fs';
9+
import os from 'node:os';
10+
import path from 'node:path';
11+
import { describe, it, after } from 'node:test';
912

1013
import {installExtension} from '../../src/tools/extensions.js';
1114
import {withMcpContext} from '../utils.js';
1215

13-
const EXTENSION_PATH = '/usr/local/google/home/nharshunova/test/extensions';
14-
const EXTENSION_ID = 'emhhlofcjnaambdnpppkpbcimdeaccnn';
15-
1616
describe('extension', () => {
17+
let tmpDir: string;
18+
1719
it('installs an extension and verifies it is listed in chrome://extensions', async () => {
20+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'extension-test-'));
21+
fs.writeFileSync(
22+
path.join(tmpDir, 'manifest.json'),
23+
JSON.stringify({
24+
manifest_version: 3,
25+
name: 'Test Extension',
26+
version: '1.0',
27+
action: {
28+
default_popup: 'popup.html',
29+
},
30+
}),
31+
);
32+
fs.writeFileSync(
33+
path.join(tmpDir, 'popup.html'),
34+
'<!DOCTYPE html><html><body><h1>Test Popup</h1></body></html>',
35+
);
36+
1837
await withMcpContext(async (response, context) => {
19-
// 1. Install the extension
2038
await installExtension.handler(
21-
{params: {path: EXTENSION_PATH}},
39+
{ params: { path: tmpDir } },
2240
response,
2341
context,
2442
);
2543

26-
// 2. Verify response
27-
assert.ok(
28-
response.responseLines[0]?.includes(EXTENSION_ID),
29-
`Response should include extension ID ${EXTENSION_ID}`,
30-
);
44+
const responseLine = response.responseLines[0];
45+
assert.ok(responseLine, 'Response should not be empty');
46+
const match = responseLine.match(/Extension installed\. Id: (.+)/);
47+
const extensionId = match ? match[1] : null;
48+
assert.ok(extensionId, 'Response should contain a valid key');
3149

32-
// 3. Verify extension is accessible by navigating to its popup
3350
const page = context.getSelectedPage();
34-
await page.goto(`chrome-extension://${EXTENSION_ID}/popup.html`);
35-
const popupContent = await page.content();
36-
assert.ok(
37-
popupContent.includes('Popup Action'),
38-
'Extension popup should be accessible',
39-
);
40-
41-
// 4. Verify extension presence in chrome://extensions UI
42-
// 4. Verify extension presence in chrome://extensions UI
4351
await page.goto('chrome://extensions');
4452

45-
// Wait for usage to ensure page is loaded
46-
await new Promise(r => setTimeout(r, 2000));
47-
48-
const EXTENSION_NAME = 'Simple Popup Action';
49-
const found = await page.evaluate(extName => {
50-
function deepSearch(root: Element | ShadowRoot): boolean {
51-
if (root.textContent?.includes(extName)) return true;
52-
if ('shadowRoot' in root && root.shadowRoot) {
53-
if (deepSearch(root.shadowRoot)) return true;
54-
}
55-
for (const child of Array.from(root.children)) {
56-
if (deepSearch(child)) return true;
57-
}
58-
return false;
59-
}
60-
return deepSearch(document.body);
61-
}, EXTENSION_NAME);
62-
53+
const element = await page.waitForSelector(
54+
`extensions-manager >>> extensions-item[id="${extensionId}"]`,
55+
);
6356
assert.ok(
64-
found,
65-
`Extension "${EXTENSION_NAME}" should be visible on chrome://extensions`,
57+
element,
58+
`Extension with ID "${extensionId}" should be visible on chrome://extensions`,
6659
);
6760
});
6861
});
62+
63+
after(() => {
64+
if (tmpDir) {
65+
fs.rmSync(tmpDir, { recursive: true, force: true });
66+
}
67+
});
6968
});

0 commit comments

Comments
 (0)