Skip to content

Commit

Permalink
modify and export recorder
Browse files Browse the repository at this point in the history
  • Loading branch information
kyungeunni committed Jul 28, 2022
1 parent 637a935 commit 84309bf
Show file tree
Hide file tree
Showing 10 changed files with 39 additions and 18 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ node_modules/
yarn.lock
/packages/playwright-core/src/generated/*
packages/*/lib/
# !packages/playwright-core/lib/
drivers/
.android-sdk/
.gradle/
Expand Down
1 change: 1 addition & 0 deletions packages/playwright-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"./lib/utils/timeoutRunner": "./lib/utils/timeoutRunner.js",
"./lib/remote/playwrightServer": "./lib/remote/playwrightServer.js",
"./lib/server": "./lib/server/index.js",
"./lib/server/recorder/javascript": "./lib/server/recorder/javascript.js",
"./lib/utilsBundle": "./lib/utilsBundle.js",
"./lib/zipBundle": "./lib/zipBundle.js",
"./types/protocol": "./types/protocol.d.ts",
Expand Down
1 change: 1 addition & 0 deletions packages/playwright-core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ async function codegen(options: Options, url: string | undefined, language: stri
device: options.device,
saveStorage: options.saveStorage,
startRecording: true,
showRecorder: true,
outputFile: outputFile ? path.resolve(outputFile) : undefined
});
await openPage(context, url);
Expand Down
12 changes: 2 additions & 10 deletions packages/playwright-core/src/client/browserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { Worker } from './worker';
import { Events } from './events';
import { TimeoutSettings } from '../common/timeoutSettings';
import { Waiter } from './waiter';
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState, LaunchOptions } from './types';
import type { URLMatch, Headers, WaitForEventOptions, BrowserContextOptions, StorageState } from './types';
import { headersObjectToArray, isRegExp, isString } from '../utils';
import { mkdirIfNeeded } from '../utils/fileUtils';
import { isSafeCloseError } from '../common/errors';
Expand Down Expand Up @@ -367,15 +367,7 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel>
}
}

async _enableRecorder(params: {
language: string,
launchOptions?: LaunchOptions,
contextOptions?: BrowserContextOptions,
device?: string,
saveStorage?: string,
startRecording?: boolean,
outputFile?: string
}) {
async _enableRecorder(params: channels.BrowserContextRecorderSupplementEnableParams) {
await this._channel.recorderSupplementEnable(params);
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/playwright-core/src/protocol/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,8 @@ export type BrowserContextRecorderSupplementEnableParams = {
device?: string,
saveStorage?: string,
outputFile?: string,
showRecorder?: boolean,
actionListener?: any,
};
export type BrowserContextRecorderSupplementEnableOptions = {
language?: string,
Expand All @@ -1433,6 +1435,8 @@ export type BrowserContextRecorderSupplementEnableOptions = {
device?: string,
saveStorage?: string,
outputFile?: string,
showRecorder?: boolean,
actionListener?: any,
};
export type BrowserContextRecorderSupplementEnableResult = void;
export type BrowserContextNewCDPSessionParams = {
Expand Down
2 changes: 2 additions & 0 deletions packages/playwright-core/src/protocol/protocol.yml
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,8 @@ BrowserContext:
device: string?
saveStorage: string?
outputFile: string?
showRecorder: boolean?
actionListener: json?

newCDPSession:
parameters:
Expand Down
2 changes: 2 additions & 0 deletions packages/playwright-core/src/protocol/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,8 @@ scheme.BrowserContextRecorderSupplementEnableParams = tObject({
device: tOptional(tString),
saveStorage: tOptional(tString),
outputFile: tOptional(tString),
showRecorder: tOptional(tBoolean),
actionListener: tOptional(tAny),
});
scheme.BrowserContextRecorderSupplementEnableResult = tOptional(tObject({}));
scheme.BrowserContextNewCDPSessionParams = tObject({
Expand Down
26 changes: 20 additions & 6 deletions packages/playwright-core/src/server/recorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ export class Recorder implements InstrumentationListener {
let recorderPromise = (context as any)[symbol] as Promise<Recorder>;
if (!recorderPromise) {
const recorder = new Recorder(context, params);
recorderPromise = recorder.install().then(() => recorder);
recorderPromise = recorder.install(Boolean(params.showRecorder)).then(() => recorder);

(context as any)[symbol] = recorderPromise;
}
return recorderPromise;
Expand All @@ -78,7 +79,7 @@ export class Recorder implements InstrumentationListener {
context.instrumentation.addListener(this, context);
}

async install() {
async installRecorder() {
const recorderApp = await RecorderApp.open(this._context._browser.options.sdkLanguage, !!this._context._browser.options.headful);
this._recorderApp = recorderApp;
recorderApp.once('close', () => {
Expand Down Expand Up @@ -119,11 +120,17 @@ export class Recorder implements InstrumentationListener {
recorderApp.setPaused(this._debugger.isPaused()),
this._pushAllSources()
]);

(this._context as any).recorderAppForTest = this._recorderApp;
}

async install(showRecorder: Boolean) {
if (showRecorder)
await this.installRecorder();
this._context.once(BrowserContext.Events.Close, () => {
this._contextRecorder.dispose();
this._context.instrumentation.removeListener(this);
recorderApp.close().catch(() => {});
this._recorderApp?.close().catch(() => {});
});
this._contextRecorder.on(ContextRecorder.Events.Change, (data: { sources: Source[], primaryFileName: string }) => {
this._recorderSources = data.sources;
Expand All @@ -150,9 +157,14 @@ export class Recorder implements InstrumentationListener {

await this._context.exposeBinding('__pw_recorderSetSelector', false, async (_, selector: string) => {
this._setMode('none');
this._contextRecorder.emitSelector(selector);
await this._recorderApp?.setSelector(selector, true);
await this._recorderApp?.bringToFront();
});
// added for synthetics
await this._context.exposeBinding('__pw_setMode', false, async (_, mode: Mode) => {
this._setMode(mode);
});

await this._context.exposeBinding('__pw_resume', false, () => {
this._debugger.resume(false);
Expand All @@ -164,8 +176,6 @@ export class Recorder implements InstrumentationListener {
if (this._debugger.isPaused())
this._pausedStateChanged();
this._debugger.on(Debugger.Events.PausedStateChanged, () => this._pausedStateChanged());

(this._context as any).recorderAppForTest = recorderApp;
}

_pausedStateChanged() {
Expand Down Expand Up @@ -320,7 +330,7 @@ class ContextRecorder extends EventEmitter {
const orderedLanguages = [primaryLanguage, ...languages];

this._recorderSources = [];
const generator = new CodeGenerator(context._browser.options.name, !!params.startRecording, params.launchOptions || {}, params.contextOptions || {}, params.device, params.saveStorage);
const generator = new CodeGenerator(context._browser.options.name, !!params.startRecording, params.launchOptions || {}, params.contextOptions || {}, params.device, params.saveStorage, params.actionListener);
const throttledOutputFile = params.outputFile ? new ThrottledFile(params.outputFile) : null;
generator.on('change', () => {
this._recorderSources = [];
Expand Down Expand Up @@ -380,6 +390,10 @@ class ContextRecorder extends EventEmitter {
this._timers.clear();
}

emitSelector(selector: string) {
this._params.actionListener?.emit('selector', selector);
}

private async _onPage(page: Page) {
// First page is called page, others are called popup1, popup2, etc.
const frame = page.mainFrame();
Expand Down
6 changes: 4 additions & 2 deletions packages/playwright-core/src/server/recorder/codeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ export class CodeGenerator extends EventEmitter {
private _enabled: boolean;
private _options: LanguageGeneratorOptions;

constructor(browserName: string, generateHeaders: boolean, launchOptions: LaunchOptions, contextOptions: BrowserContextOptions, deviceName: string | undefined, saveStorage: string | undefined) {
constructor(browserName: string, generateHeaders: boolean, launchOptions: LaunchOptions, contextOptions: BrowserContextOptions, deviceName: string | undefined, saveStorage: string | undefined, actionListener: EventEmitter | undefined) {
super();

// Make a copy of options to modify them later.
launchOptions = { headless: false, ...launchOptions };
contextOptions = { ...contextOptions };
this._enabled = generateHeaders;
this._options = { browserName, generateHeaders, launchOptions, contextOptions, deviceName, saveStorage };
this._options = { browserName, generateHeaders, launchOptions, contextOptions, deviceName, saveStorage, actionListener };
this.restart();
}

Expand Down Expand Up @@ -111,6 +111,7 @@ export class CodeGenerator extends EventEmitter {
this._actions.pop();
this._actions.push(actionInContext);
this.emit('change');
this._options.actionListener?.emit('actions', this._actions);
}

commitLastAction() {
Expand Down Expand Up @@ -138,6 +139,7 @@ export class CodeGenerator extends EventEmitter {
signals.length = signals.length - 1;
this._lastAction.action.signals.push(signal);
this.emit('change');
this._options.actionListener?.emit('actions', this._actions);
return;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/playwright-core/src/server/recorder/language.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* limitations under the License.
*/

import { EventEmitter } from 'stream';
import type { BrowserContextOptions, LaunchOptions } from '../../..';
import type { ActionInContext } from './codeGenerator';
import type { Action, DialogSignal, DownloadSignal, NavigationSignal, PopupSignal } from './recorderActions';
Expand All @@ -25,6 +26,7 @@ export type LanguageGeneratorOptions = {
contextOptions: BrowserContextOptions;
deviceName?: string;
saveStorage?: string;
actionListener?: EventEmitter;
};

export interface LanguageGenerator {
Expand Down

0 comments on commit 84309bf

Please sign in to comment.