Skip to content

Commit ac96c18

Browse files
committed
chore: introduce new extension test mode
1 parent c3c842c commit ac96c18

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed

tests/extension/extensionTest.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (c) Microsoft Corporation.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { baseTest } from '../config/baseTest';
18+
import { chromium } from 'playwright';
19+
import { expect, type PageTestFixtures, type PageWorkerFixtures } from '../page/pageTestApi';
20+
import type { TraceViewerFixtures } from '../config/traceViewerFixtures';
21+
import { traceViewerFixtures } from '../config/traceViewerFixtures';
22+
export { expect } from '@playwright/test';
23+
import http from 'node:http';
24+
import path from 'node:path';
25+
import { AddressInfo } from 'node:net';
26+
27+
export const extensionTest = baseTest.extend<TraceViewerFixtures>(traceViewerFixtures).extend<PageTestFixtures, PageWorkerFixtures>({
28+
browserVersion: [({ browser }) => browser.version(), { scope: 'worker' }],
29+
browserMajorVersion: [({ browserVersion }, use) => use(Number(browserVersion.split('.')[0])), { scope: 'worker' }],
30+
isAndroid: [false, { scope: 'worker' }],
31+
isElectron: [false, { scope: 'worker' }],
32+
electronMajorVersion: [0, { scope: 'worker' }],
33+
isWebView2: [false, { scope: 'worker' }],
34+
isHeadlessShell: [false, { scope: 'worker' }],
35+
36+
browser: [async ({ playwright }, use, testInfo) => {
37+
const httpServer = http.createServer();
38+
await new Promise<void>(resolve => httpServer.listen(0, resolve));
39+
const pathToExtension = path.join(__dirname, '../../../playwright-mcp/extension');
40+
const context = await chromium.launchPersistentContext('', {
41+
args: [
42+
`--disable-extensions-except=${pathToExtension}`,
43+
`--load-extension=${pathToExtension}`,
44+
'--enable-features=AllowContentInitiatedDataUrlNavigations',
45+
],
46+
channel: 'chromium',
47+
});
48+
const { CDPBridgeServer } = await import('../../../playwright-mcp/src/cdp-relay.ts');
49+
const server = new CDPBridgeServer(httpServer);
50+
const origin = `ws://localhost:${(httpServer.address() as AddressInfo).port}`;
51+
await expect.poll(() => context?.serviceWorkers()).toHaveLength(1);
52+
await context.pages()[0].goto(new URL('/popup.html', context.serviceWorkers()[0].url()).toString());
53+
await context.pages()[0].getByRole('textbox', { name: 'Bridge Server URL:' }).clear();
54+
await context.pages()[0].getByRole('textbox', { name: 'Bridge Server URL:' }).fill(`${origin}${server.EXTENSION_PATH}`);
55+
await context.pages()[0].getByRole('button', { name: 'Share This Tab' }).click();
56+
await context.pages()[0].goto('about:blank');
57+
const browser = await playwright.chromium.connectOverCDP(`${origin}${server.CDP_PATH}`);
58+
await use(browser);
59+
httpServer.close();
60+
}, { scope: 'worker' }],
61+
62+
context: async ({ browser }, use) => {
63+
await use(browser.contexts()[0]);
64+
},
65+
66+
page: async ({ browser }, use) => {
67+
await use(browser.contexts()[0].pages()[0]);
68+
}
69+
});

tests/extension/playwright.config.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* Copyright (c) Microsoft Corporation.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { config as loadEnv } from 'dotenv';
18+
loadEnv({ path: path.join(__dirname, '..', '..', '.env') });
19+
process.env.PWTEST_UNDER_TEST = '1';
20+
21+
import type { Config, PlaywrightTestOptions, PlaywrightWorkerOptions } from '@playwright/test';
22+
import * as path from 'path';
23+
24+
process.env.PWPAGE_IMPL = 'extension';
25+
26+
const outputDir = path.join(__dirname, '..', '..', 'test-results');
27+
const testDir = path.join(__dirname, '..');
28+
const config: Config<PlaywrightWorkerOptions & PlaywrightTestOptions> = {
29+
testDir,
30+
outputDir,
31+
timeout: 30000,
32+
globalTimeout: 5400000,
33+
workers: process.env.CI ? 1 : undefined,
34+
forbidOnly: !!process.env.CI,
35+
retries: process.env.CI ? 3 : 0,
36+
reporter: process.env.CI ? [
37+
['dot'],
38+
['json', { outputFile: path.join(outputDir, 'report.json') }],
39+
['blob', { fileName: `${process.env.PWTEST_BOT_NAME}.zip` }],
40+
] : 'line',
41+
projects: [],
42+
};
43+
44+
const metadata = {
45+
platform: process.platform,
46+
headless: true,
47+
browserName: 'extension',
48+
channel: undefined,
49+
mode: 'default',
50+
video: false,
51+
};
52+
53+
config.projects.push({
54+
name: 'extension',
55+
// Share screenshots with chromium.
56+
snapshotPathTemplate: '{testDir}/{testFileDir}/{testFileName}-snapshots/{arg}-chromium{ext}',
57+
use: {
58+
browserName: 'chromium',
59+
},
60+
testDir: path.join(testDir, 'page'),
61+
metadata,
62+
});
63+
64+
export default config;

tests/page/pageTest.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { androidTest } from '../android/androidTest';
2121
import { browserTest } from '../config/browserTest';
2222
import { electronTest } from '../electron/electronTest';
2323
import { webView2Test } from '../webview2/webView2Test';
24+
import { extensionTest } from '../extension/extensionTest';
2425
import type { PageTestFixtures, PageWorkerFixtures } from './pageTestApi';
2526
import type { ServerFixtures, ServerWorkerOptions } from '../config/serverFixtures';
2627
import { expect as baseExpect } from '@playwright/test';
@@ -34,6 +35,8 @@ if (process.env.PWPAGE_IMPL === 'electron')
3435
impl = electronTest;
3536
if (process.env.PWPAGE_IMPL === 'webview2')
3637
impl = webView2Test;
38+
if (process.env.PWPAGE_IMPL === 'extension')
39+
impl = extensionTest;
3740

3841
export const test = impl;
3942

0 commit comments

Comments
 (0)