test: generate debug controller channel (#30018)

This commit is contained in:
Max Schmitt 2024-03-20 16:56:29 +01:00 committed by GitHub
parent c712b365ad
commit dd0b6f7ec5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 40 deletions

View file

@ -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;

View file

@ -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();