chore(recorder): standby mode, expose setModeRequested in DebugController (#28117)

This commit is contained in:
Dmitry Gozman 2023-11-13 16:39:14 -08:00 committed by GitHub
parent 2c3955a28c
commit 36b99c3437
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 38 additions and 11 deletions

View File

@ -367,6 +367,9 @@ scheme.DebugControllerInspectRequestedEvent = tObject({
selector: tString,
locator: tString,
});
scheme.DebugControllerSetModeRequestedEvent = tObject({
mode: tString,
});
scheme.DebugControllerStateChangedEvent = tObject({
pageCount: tNumber,
});

View File

@ -35,6 +35,7 @@ export class DebugController extends SdkObject {
InspectRequested: 'inspectRequested',
SourceChanged: 'sourceChanged',
Paused: 'paused',
SetModeRequested: 'setModeRequested',
};
private _autoCloseTimer: NodeJS.Timeout | undefined;
@ -240,4 +241,8 @@ class InspectingRecorderApp extends EmptyRecorderApp {
override async setPaused(paused: boolean) {
this._debugController.emit(DebugController.Events.Paused, { paused });
}
override async setMode(mode: Mode) {
this._debugController.emit(DebugController.Events.SetModeRequested, { mode });
}
}

View File

@ -40,7 +40,10 @@ export class DebugControllerDispatcher extends Dispatcher<DebugController, chann
}),
eventsHelper.addEventListener(this._object, DebugController.Events.Paused, ({ paused }) => {
this._dispatchEvent('paused', ({ paused }));
})
}),
eventsHelper.addEventListener(this._object, DebugController.Events.SetModeRequested, ({ mode }) => {
this._dispatchEvent('setModeRequested', ({ mode }));
}),
];
}

View File

@ -740,7 +740,7 @@ class Overlay {
this._recordToggle.classList.add('record');
this._recordToggle.appendChild(this._recorder.injectedScript.document.createElement('x-div'));
this._recordToggle.addEventListener('click', () => {
this._recorder.delegate.setMode?.(this._recorder.state.mode === 'none' || this._recorder.state.mode === 'inspecting' ? 'recording' : 'none');
this._recorder.delegate.setMode?.(this._recorder.state.mode === 'none' || this._recorder.state.mode === 'standby' || this._recorder.state.mode === 'inspecting' ? 'recording' : 'standby');
});
toolsListElement.appendChild(this._recordToggle);
@ -750,8 +750,9 @@ class Overlay {
this._pickLocatorToggle.appendChild(this._recorder.injectedScript.document.createElement('x-div'));
this._pickLocatorToggle.addEventListener('click', () => {
const newMode: Record<Mode, Mode> = {
'inspecting': 'none',
'inspecting': 'standby',
'none': 'inspecting',
'standby': 'inspecting',
'recording': 'recording-inspecting',
'recording-inspecting': 'recording',
'assertingText': 'recording-inspecting',
@ -786,11 +787,15 @@ class Overlay {
this._recordToggle.classList.toggle('active', state.mode === 'recording' || state.mode === 'assertingText' || state.mode === 'recording-inspecting');
this._pickLocatorToggle.classList.toggle('active', state.mode === 'inspecting' || state.mode === 'recording-inspecting');
this._assertToggle.classList.toggle('active', state.mode === 'assertingText');
this._assertToggle.classList.toggle('disabled', state.mode === 'none' || state.mode === 'inspecting');
this._assertToggle.classList.toggle('disabled', state.mode === 'none' || state.mode === 'standby' || state.mode === 'inspecting');
if (this._offsetX !== state.overlay.offsetX) {
this._offsetX = state.overlay.offsetX;
this._updateVisualPosition();
}
if (state.mode === 'none')
this._overlayElement.setAttribute('hidden', 'true');
else
this._overlayElement.removeAttribute('hidden');
}
private _updateVisualPosition() {
@ -851,6 +856,7 @@ export class Recorder {
this.highlight = new Highlight(injectedScript);
this._tools = {
'none': new NoneTool(),
'standby': new NoneTool(),
'inspecting': new InspectTool(this),
'recording': new RecordActionTool(this),
'recording-inspecting': new InspectTool(this),
@ -929,7 +935,7 @@ export class Recorder {
this._actionSelectorModel = null;
if (state.actionSelector !== this._actionSelectorModel?.selector)
this._actionSelectorModel = state.actionSelector ? querySelector(this.injectedScript, state.actionSelector, this.document) : null;
if (this.state.mode === 'none')
if (this.state.mode === 'none' || this.state.mode === 'standby')
this.updateHighlight(this._actionSelectorModel, false);
}

View File

@ -248,7 +248,7 @@ export class Recorder implements InstrumentationListener {
this._recorderApp?.setMode(this._mode);
this._contextRecorder.setEnabled(this._mode === 'recording' || this._mode === 'assertingText');
this._debugger.setMuted(this._mode === 'recording' || this._mode === 'assertingText');
if (this._mode !== 'none' && this._context.pages().length === 1)
if (this._mode !== 'none' && this._mode !== 'standby' && this._context.pages().length === 1)
this._context.pages()[0].bringToFront().catch(() => {});
this._refreshOverlay();
}

View File

@ -170,7 +170,7 @@ export class RecorderApp extends EventEmitter implements IRecorderApp {
async setSelector(selector: string, userGesture?: boolean): Promise<void> {
if (userGesture) {
if (this._recorder.mode() === 'inspecting') {
this._recorder.setMode('none');
this._recorder.setMode('standby');
this._page.bringToFront();
} else {
this._recorder.setMode('recording');

View File

@ -636,6 +636,7 @@ export type RecorderSource = {
export type DebugControllerInitializer = {};
export interface DebugControllerEventTarget {
on(event: 'inspectRequested', callback: (params: DebugControllerInspectRequestedEvent) => void): this;
on(event: 'setModeRequested', callback: (params: DebugControllerSetModeRequestedEvent) => void): this;
on(event: 'stateChanged', callback: (params: DebugControllerStateChangedEvent) => void): this;
on(event: 'sourceChanged', callback: (params: DebugControllerSourceChangedEvent) => void): this;
on(event: 'paused', callback: (params: DebugControllerPausedEvent) => void): this;
@ -658,6 +659,9 @@ export type DebugControllerInspectRequestedEvent = {
selector: string,
locator: string,
};
export type DebugControllerSetModeRequestedEvent = {
mode: string,
};
export type DebugControllerStateChangedEvent = {
pageCount: number,
};
@ -732,6 +736,7 @@ export type DebugControllerCloseAllBrowsersResult = void;
export interface DebugControllerEvents {
'inspectRequested': DebugControllerInspectRequestedEvent;
'setModeRequested': DebugControllerSetModeRequestedEvent;
'stateChanged': DebugControllerStateChangedEvent;
'sourceChanged': DebugControllerSourceChangedEvent;
'paused': DebugControllerPausedEvent;

View File

@ -763,6 +763,10 @@ DebugController:
selector: string
locator: string
setModeRequested:
parameters:
mode: string
stateChanged:
parameters:
pageCount: number

View File

@ -116,20 +116,21 @@ export const Recorder: React.FC<RecorderProps> = ({
return <div className='recorder'>
<Toolbar>
<ToolbarButton icon='circle-large-filled' title='Record' toggled={mode === 'recording' || mode === 'recording-inspecting' || mode === 'assertingText'} onClick={() => {
window.dispatch({ event: 'setMode', params: { mode: mode === 'none' || mode === 'inspecting' ? 'recording' : 'none' } });
window.dispatch({ event: 'setMode', params: { mode: mode === 'none' || mode === 'standby' || mode === 'inspecting' ? 'recording' : 'none' } });
}}>Record</ToolbarButton>
<ToolbarSeparator />
<ToolbarButton icon='inspect' title='Pick locator' toggled={mode === 'inspecting' || mode === 'recording-inspecting'} onClick={() => {
const newMode = {
'inspecting': 'none',
'inspecting': 'standby',
'none': 'inspecting',
'standby': 'inspecting',
'recording': 'recording-inspecting',
'recording-inspecting': 'recording',
'assertingText': 'recording-inspecting',
}[mode];
window.dispatch({ event: 'setMode', params: { mode: newMode } }).catch(() => { });
}}>Pick locator</ToolbarButton>
<ToolbarButton icon='check-all' title='Assert text and values' toggled={mode === 'assertingText'} disabled={mode === 'none' || mode === 'inspecting'} onClick={() => {
<ToolbarButton icon='check-all' title='Assert text and values' toggled={mode === 'assertingText'} disabled={mode === 'none' || mode === 'standby' || mode === 'inspecting'} onClick={() => {
window.dispatch({ event: 'setMode', params: { mode: mode === 'assertingText' ? 'recording' : 'assertingText' } });
}}>Assert</ToolbarButton>
<ToolbarSeparator />

View File

@ -18,7 +18,7 @@ import type { Language } from '../../playwright-core/src/utils/isomorphic/locato
export type Point = { x: number, y: number };
export type Mode = 'inspecting' | 'recording' | 'none' | 'assertingText' | 'recording-inspecting';
export type Mode = 'inspecting' | 'recording' | 'none' | 'assertingText' | 'recording-inspecting' | 'standby';
export type EventData = {
event: 'clear' | 'resume' | 'step' | 'pause' | 'setMode' | 'selectorUpdated' | 'fileChanged';