test: generate debug controller channel (#30018)
This commit is contained in:
parent
c712b365ad
commit
dd0b6f7ec5
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
export type ProtocolRequest = {
|
export type ProtocolRequest = {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
@ -109,6 +110,7 @@ export class Backend extends EventEmitter {
|
||||||
private static _lastId = 0;
|
private static _lastId = 0;
|
||||||
private _callbacks = new Map<number, { fulfill: (a: any) => void, reject: (e: Error) => void }>();
|
private _callbacks = new Map<number, { fulfill: (a: any) => void, reject: (e: Error) => void }>();
|
||||||
private _transport!: WebSocketTransport;
|
private _transport!: WebSocketTransport;
|
||||||
|
channel: channels.DebugControllerChannel;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
@ -133,48 +135,23 @@ export class Backend extends EventEmitter {
|
||||||
pair.fulfill(message.result);
|
pair.fulfill(message.result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.channel = new Proxy(this, {
|
||||||
|
get: (target, propKey) => {
|
||||||
|
if (['on', 'once'].includes(String(propKey)))
|
||||||
|
return target[propKey].bind(target);
|
||||||
|
return (...args: any) => this._send(String(propKey), ...args);
|
||||||
|
}
|
||||||
|
}) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize() {
|
async initialize() {
|
||||||
await this._send('initialize', { codegenId: 'playwright-test', sdkLanguage: 'javascript' });
|
await this.channel.initialize({ codegenId: 'playwright-test', sdkLanguage: 'javascript' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async close() {
|
async close() {
|
||||||
await this._transport.closeAndWait();
|
await this._transport.closeAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
async resetForReuse() {
|
|
||||||
await this._send('resetForReuse');
|
|
||||||
}
|
|
||||||
|
|
||||||
async navigate(params: { url: string }) {
|
|
||||||
await this._send('navigate', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setMode(params: { mode: 'none' | 'inspecting' | 'recording', language?: string, file?: string, testIdAttributeName?: string }) {
|
|
||||||
await this._send('setRecorderMode', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
async setReportStateChanged(params: { enabled: boolean }) {
|
|
||||||
await this._send('setReportStateChanged', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
async highlight(params: { selector: string }) {
|
|
||||||
await this._send('highlight', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
async hideHighlight() {
|
|
||||||
await this._send('hideHighlight');
|
|
||||||
}
|
|
||||||
|
|
||||||
async resume() {
|
|
||||||
await this._send('resume');
|
|
||||||
}
|
|
||||||
|
|
||||||
async kill() {
|
|
||||||
await this._send('kill');
|
|
||||||
}
|
|
||||||
|
|
||||||
private _send(method: string, params: any = {}): Promise<any> {
|
private _send(method: string, params: any = {}): Promise<any> {
|
||||||
return new Promise((fulfill, reject) => {
|
return new Promise((fulfill, reject) => {
|
||||||
const id = ++Backend._lastId;
|
const id = ++Backend._lastId;
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,12 @@ import { PlaywrightServer } from '../../packages/playwright-core/lib/remote/play
|
||||||
import { createGuid } from '../../packages/playwright-core/lib/utils/crypto';
|
import { createGuid } from '../../packages/playwright-core/lib/utils/crypto';
|
||||||
import { Backend } from '../config/debugControllerBackend';
|
import { Backend } from '../config/debugControllerBackend';
|
||||||
import type { Browser, BrowserContext } from '@playwright/test';
|
import type { Browser, BrowserContext } from '@playwright/test';
|
||||||
|
import type * as channels from '@protocol/channels';
|
||||||
|
|
||||||
type BrowserWithReuse = Browser & { _newContextForReuse: () => Promise<BrowserContext> };
|
type BrowserWithReuse = Browser & { _newContextForReuse: () => Promise<BrowserContext> };
|
||||||
type Fixtures = {
|
type Fixtures = {
|
||||||
wsEndpoint: string;
|
wsEndpoint: string;
|
||||||
backend: Backend;
|
backend: channels.DebugControllerChannel;
|
||||||
connectedBrowserFactory: () => Promise<BrowserWithReuse>;
|
connectedBrowserFactory: () => Promise<BrowserWithReuse>;
|
||||||
connectedBrowser: BrowserWithReuse;
|
connectedBrowser: BrowserWithReuse;
|
||||||
};
|
};
|
||||||
|
|
@ -40,7 +41,7 @@ const test = baseTest.extend<Fixtures>({
|
||||||
const backend = new Backend();
|
const backend = new Backend();
|
||||||
await backend.connect(wsEndpoint);
|
await backend.connect(wsEndpoint);
|
||||||
await backend.initialize();
|
await backend.initialize();
|
||||||
await use(backend);
|
await use(backend.channel);
|
||||||
await backend.close();
|
await backend.close();
|
||||||
},
|
},
|
||||||
connectedBrowserFactory: async ({ wsEndpoint, browserType }, use) => {
|
connectedBrowserFactory: async ({ wsEndpoint, browserType }, use) => {
|
||||||
|
|
@ -70,7 +71,7 @@ test('should pick element', async ({ backend, connectedBrowser }) => {
|
||||||
const events = [];
|
const events = [];
|
||||||
backend.on('inspectRequested', event => events.push(event));
|
backend.on('inspectRequested', event => events.push(event));
|
||||||
|
|
||||||
await backend.setMode({ mode: 'inspecting' });
|
await backend.setRecorderMode({ mode: 'inspecting' });
|
||||||
|
|
||||||
const context = await connectedBrowser._newContextForReuse();
|
const context = await connectedBrowser._newContextForReuse();
|
||||||
const [page] = context.pages();
|
const [page] = context.pages();
|
||||||
|
|
@ -90,7 +91,7 @@ test('should pick element', async ({ backend, connectedBrowser }) => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// No events after mode disabled
|
// No events after mode disabled
|
||||||
await backend.setMode({ mode: 'none' });
|
await backend.setRecorderMode({ mode: 'none' });
|
||||||
await page.locator('body').click();
|
await page.locator('body').click();
|
||||||
expect(events).toHaveLength(2);
|
expect(events).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
@ -163,7 +164,7 @@ test('should record', async ({ backend, connectedBrowser }) => {
|
||||||
const events = [];
|
const events = [];
|
||||||
backend.on('sourceChanged', event => events.push(event));
|
backend.on('sourceChanged', event => events.push(event));
|
||||||
|
|
||||||
await backend.setMode({ mode: 'recording' });
|
await backend.setRecorderMode({ mode: 'recording' });
|
||||||
|
|
||||||
const context = await connectedBrowser._newContextForReuse();
|
const context = await connectedBrowser._newContextForReuse();
|
||||||
const [page] = context.pages();
|
const [page] = context.pages();
|
||||||
|
|
@ -189,7 +190,7 @@ test('test', async ({ page }) => {
|
||||||
});
|
});
|
||||||
const length = events.length;
|
const length = events.length;
|
||||||
// No events after mode disabled
|
// No events after mode disabled
|
||||||
await backend.setMode({ mode: 'none' });
|
await backend.setRecorderMode({ mode: 'none' });
|
||||||
await page.getByRole('button').click();
|
await page.getByRole('button').click();
|
||||||
expect(events).toHaveLength(length);
|
expect(events).toHaveLength(length);
|
||||||
});
|
});
|
||||||
|
|
@ -207,7 +208,7 @@ test('should record custom data-testid', async ({ backend, connectedBrowser }) =
|
||||||
await page.setContent(`<div data-custom-id='one'>One</div>`);
|
await page.setContent(`<div data-custom-id='one'>One</div>`);
|
||||||
|
|
||||||
// 2. "Record at cursor".
|
// 2. "Record at cursor".
|
||||||
await backend.setMode({ mode: 'recording', testIdAttributeName: 'data-custom-id' });
|
await backend.setRecorderMode({ mode: 'recording', testIdAttributeName: 'data-custom-id' });
|
||||||
|
|
||||||
// 3. Record a click action.
|
// 3. Record a click action.
|
||||||
await page.locator('div').click();
|
await page.locator('div').click();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue