chore: plumb terminal size and port language (#5149)

This commit is contained in:
Pavel Feldman 2021-01-25 19:01:04 -08:00 committed by GitHub
parent 5033261d27
commit 45f7d73470
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 36 deletions

View File

@ -327,7 +327,15 @@ async function codegen(options: Options, url: string | undefined, language: stri
const { context, launchOptions, contextOptions } = await launchContext(options, false);
if (process.env.PWTRACE)
contextOptions._traceDir = path.join(process.cwd(), '.trace');
await context._enableRecorder(language, launchOptions, contextOptions, options.device, options.saveStorage, !!process.stdout.columns, outputFile ? path.resolve(outputFile) : undefined);
await context._enableRecorder({
language,
launchOptions,
contextOptions,
device: options.device,
saveStorage: options.saveStorage,
terminal: !!process.stdout.columns,
outputFile: outputFile ? path.resolve(outputFile) : undefined
});
await openPage(context, url);
if (process.env.PWCLI_EXIT_FOR_TEST)
await Promise.all(context.pages().map(p => p.close()));

View File

@ -270,23 +270,16 @@ export class BrowserContext extends ChannelOwner<channels.BrowserContextChannel,
await this._channel.consoleSupplementExpose();
}
async _enableRecorder(
language: string,
launchOptions?: LaunchOptions,
contextOptions?: BrowserContextOptions,
device?: string,
saveStorage?: string,
terminal?: boolean,
outputFile?: string) {
await this._channel.recorderSupplementEnable({
language,
launchOptions,
contextOptions,
device,
saveStorage,
terminal,
outputFile,
});
async _enableRecorder(params: {
language: string,
launchOptions?: LaunchOptions,
contextOptions?: BrowserContextOptions,
device?: string,
saveStorage?: string,
terminal?: boolean,
outputFile?: string
}) {
await this._channel.recorderSupplementEnable(params);
}
}

View File

@ -24,7 +24,7 @@ declare global {
playwrightRecorderPerformAction: (action: actions.Action) => Promise<void>;
playwrightRecorderRecordAction: (action: actions.Action) => Promise<void>;
playwrightRecorderCommitAction: () => Promise<void>;
playwrightRecorderState: () => Promise<{ state: any, paused: boolean, tool: 'codegen' | 'pause' }>;
playwrightRecorderState: () => Promise<{ state: any, paused: boolean, app: 'codegen' | 'debug' | 'pause' }>;
playwrightRecorderSetState: (state: any) => Promise<void>;
playwrightRecorderResume: () => Promise<boolean>;
}
@ -51,7 +51,7 @@ export class Recorder {
private _recordElement: HTMLElement;
private _resumeElement: HTMLElement;
private _mode: 'inspecting' | 'recording' | 'none' = 'none';
private _tool: 'codegen' | 'pause' = 'pause';
private _app: 'codegen' | 'debug' | 'pause' = 'debug';
private _paused = false;
constructor(injectedScript: InjectedScript) {
@ -130,7 +130,7 @@ export class Recorder {
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M24 24H0V0h24v24z" fill="none"/><circle cx="12" cy="12" r="8"/></svg>
</x-pw-button>`;
this._resumeElement = html`
<x-pw-button tabIndex=0 class="playwright-resume">
<x-pw-button tabIndex=0 class="playwright-resume hidden">
<svg xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M8 5v14l11-7z"/></svg>
</x-pw-button>`;
@ -180,6 +180,9 @@ export class Recorder {
x-pw-button.hidden {
display: none;
}
x-pw-button svg {
pointer-events: none;
}
</style>`);
const iconElement = html`<x-pw-button class="logo" tabIndex=0 style="background-size: 32px 32px;"></x-pw-button>`;
@ -244,7 +247,7 @@ export class Recorder {
clearTimeout(this._pollRecorderModeTimer);
const result = await window.playwrightRecorderState().catch(e => null);
if (result) {
const { state, paused, tool } = result;
const { state, paused, app } = result;
if (state && state.mode !== this._mode) {
this._mode = state.mode as any;
this._inspectElement.classList.toggle('toggled', this._mode === 'inspecting');
@ -255,11 +258,12 @@ export class Recorder {
}
if (paused !== this._paused) {
this._paused = paused;
this._resumeElement.classList.toggle('hidden', false);
this._resumeElement.classList.toggle('disabled', !this._paused);
}
if (tool !== this._tool) {
this._tool = tool;
this._resumeElement.classList.toggle('hidden', this._tool !== 'pause');
if (app !== this._app) {
this._app = app;
this._resumeElement.classList.toggle('hidden', this._app !== 'pause');
}
}
this._pollRecorderModeTimer = setTimeout(() => this._pollRecorderMode(), 250);
@ -295,6 +299,8 @@ export class Recorder {
}
private _onClick(event: MouseEvent) {
if (this._mode === 'inspecting' && !this._isInToolbar(event.target as HTMLElement))
console.log(this._hoveredModel ? this._hoveredModel.selector : ''); // eslint-disable-line no-console
if (this._shouldIgnoreMouseEvent(event))
return;
if (this._actionInProgress(event))

View File

@ -17,6 +17,9 @@
import { BrowserContext, ContextListener, contextListeners } from '../browserContext';
import { isDebugMode } from '../../utils/utils';
import { ConsoleApiSupplement } from './consoleApiSupplement';
import { RecorderSupplement } from './recorderSupplement';
import { Page } from '../page';
import { ConsoleMessage } from '../console';
export function installInspectorController() {
contextListeners.add(new InspectorController());
@ -27,6 +30,13 @@ class InspectorController implements ContextListener {
if (isDebugMode()) {
const consoleApi = new ConsoleApiSupplement(context);
await consoleApi.install();
RecorderSupplement.getOrCreate(context, 'debug', {
language: 'javascript',
terminal: true,
});
context.on(BrowserContext.Events.Page, (page: Page) => {
page.on(Page.Events.Console, (message: ConsoleMessage) => context.emit(BrowserContext.Events.StdOut, message.text() + '\n'));
});
}
}
async onContextWillDestroy(context: BrowserContext): Promise<void> {}

View File

@ -31,7 +31,7 @@ import * as consoleApiSource from '../../generated/consoleApiSource';
import { FileOutput, FlushingTerminalOutput, OutputMultiplexer, RecorderOutput, TerminalOutput, Writable } from './recorder/outputs';
type BindingSource = { frame: Frame, page: Page };
type Tool = 'codegen' | 'pause';
type App = 'codegen' | 'debug' | 'pause';
type Mode = 'inspecting' | 'recording' | 'none';
const symbol = Symbol('RecorderSupplement');
@ -47,23 +47,23 @@ export class RecorderSupplement {
private _resumeCallback: (() => void) | null = null;
private _recorderState: { mode: Mode };
private _paused = false;
private _tool: Tool;
private _app: App;
private _output: OutputMultiplexer;
static getOrCreate(context: BrowserContext, tool: Tool, params: channels.BrowserContextRecorderSupplementEnableParams): Promise<RecorderSupplement> {
static getOrCreate(context: BrowserContext, app: App, params: channels.BrowserContextRecorderSupplementEnableParams): Promise<RecorderSupplement> {
let recorderPromise = (context as any)[symbol] as Promise<RecorderSupplement>;
if (!recorderPromise) {
const recorder = new RecorderSupplement(context, tool, params);
const recorder = new RecorderSupplement(context, app, params);
recorderPromise = recorder.install().then(() => recorder);
(context as any)[symbol] = recorderPromise;
}
return recorderPromise;
}
constructor(context: BrowserContext, tool: Tool, params: channels.BrowserContextRecorderSupplementEnableParams) {
constructor(context: BrowserContext, app: App, params: channels.BrowserContextRecorderSupplementEnableParams) {
this._context = context;
this._tool = tool;
this._recorderState = { mode: tool === 'codegen' ? 'recording' : 'none' };
this._app = app;
this._recorderState = { mode: app === 'codegen' ? 'recording' : 'none' };
let languageGenerator: LanguageGenerator;
switch (params.language) {
case 'javascript': languageGenerator = new JavaScriptLanguageGenerator(); break;
@ -83,10 +83,10 @@ export class RecorderSupplement {
if (params.outputFile)
outputs.push(new FileOutput(params.outputFile));
this._output = new OutputMultiplexer(outputs);
this._output.setEnabled(tool === 'codegen');
this._output.setEnabled(app === 'codegen');
context.on(BrowserContext.Events.BeforeClose, () => this._output.flush());
const generator = new CodeGenerator(context._browser._options.name, tool === 'codegen', params.launchOptions || {}, params.contextOptions || {}, this._output, languageGenerator, params.device, params.saveStorage);
const generator = new CodeGenerator(context._browser._options.name, app === 'codegen', params.launchOptions || {}, params.contextOptions || {}, this._output, languageGenerator, params.device, params.saveStorage);
this._generator = generator;
}
@ -117,7 +117,7 @@ export class RecorderSupplement {
await this._context.exposeBinding('playwrightRecorderState', false, () => {
return {
state: this._recorderState,
tool: this._tool,
app: this._app,
paused: this._paused
};
});

View File

@ -39,7 +39,7 @@ fixtures.contextWrapper.init(async ({ browser }, runTest) => {
const context = await browser.newContext() as BrowserContext;
const outputBuffer = new WritableBuffer();
(context as any)._stdout = outputBuffer;
await (context as any)._enableRecorder('javascript');
await (context as any)._enableRecorder({ language: 'javascript' });
await runTest({ context, output: outputBuffer });
await context.close();
});