mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: extract polling recorder (#32749)
We are reusing recorder in a snapshot tab, no need for the polling harness to be there.
This commit is contained in:
parent
99895005e2
commit
0cdc7ee1a3
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Mode, OverlayState, UIState } from '@recorder/recorderTypes';
|
||||
import type * as actions from '../../recorder/recorderActions';
|
||||
import type { InjectedScript } from '../injectedScript';
|
||||
import { Recorder } from './recorder';
|
||||
import type { RecorderDelegate } from './recorder';
|
||||
|
||||
interface Embedder {
|
||||
__pw_recorderPerformAction(action: actions.PerformOnRecordAction): Promise<void>;
|
||||
__pw_recorderRecordAction(action: actions.Action): Promise<void>;
|
||||
__pw_recorderState(): Promise<UIState>;
|
||||
__pw_recorderSetSelector(selector: string): Promise<void>;
|
||||
__pw_recorderSetMode(mode: Mode): Promise<void>;
|
||||
__pw_recorderSetOverlayState(state: OverlayState): Promise<void>;
|
||||
__pw_refreshOverlay(): void;
|
||||
}
|
||||
|
||||
export class PollingRecorder implements RecorderDelegate {
|
||||
private _recorder: Recorder;
|
||||
private _embedder: Embedder;
|
||||
private _pollRecorderModeTimer: number | undefined;
|
||||
|
||||
constructor(injectedScript: InjectedScript) {
|
||||
this._recorder = new Recorder(injectedScript);
|
||||
this._embedder = injectedScript.window as any;
|
||||
|
||||
injectedScript.onGlobalListenersRemoved.add(() => this._recorder.installListeners());
|
||||
|
||||
const refreshOverlay = () => {
|
||||
this._pollRecorderMode().catch(e => console.log(e)); // eslint-disable-line no-console
|
||||
};
|
||||
this._embedder.__pw_refreshOverlay = refreshOverlay;
|
||||
refreshOverlay();
|
||||
}
|
||||
|
||||
private async _pollRecorderMode() {
|
||||
const pollPeriod = 1000;
|
||||
if (this._pollRecorderModeTimer)
|
||||
clearTimeout(this._pollRecorderModeTimer);
|
||||
const state = await this._embedder.__pw_recorderState().catch(() => {});
|
||||
if (!state) {
|
||||
this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);
|
||||
return;
|
||||
}
|
||||
const win = this._recorder.document.defaultView!;
|
||||
if (win.top !== win) {
|
||||
// Only show action point in the main frame, since it is relative to the page's viewport.
|
||||
// Otherwise we'll see multiple action points at different locations.
|
||||
state.actionPoint = undefined;
|
||||
}
|
||||
this._recorder.setUIState(state, this);
|
||||
this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);
|
||||
}
|
||||
|
||||
async performAction(action: actions.PerformOnRecordAction) {
|
||||
await this._embedder.__pw_recorderPerformAction(action);
|
||||
}
|
||||
|
||||
async recordAction(action: actions.Action): Promise<void> {
|
||||
await this._embedder.__pw_recorderRecordAction(action);
|
||||
}
|
||||
|
||||
async setSelector(selector: string): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetSelector(selector);
|
||||
}
|
||||
|
||||
async setMode(mode: Mode): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetMode(mode);
|
||||
}
|
||||
|
||||
async setOverlayState(state: OverlayState): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetOverlayState(state);
|
||||
}
|
||||
}
|
||||
|
||||
export default PollingRecorder;
|
||||
@ -21,9 +21,8 @@ import type { Mode, OverlayState, UIState } from '@recorder/recorderTypes';
|
||||
import type { ElementText } from '../selectorUtils';
|
||||
import type { Highlight, HighlightOptions } from '../highlight';
|
||||
import clipPaths from './clipPaths';
|
||||
import type { SimpleDomNode } from '../simpleDom';
|
||||
|
||||
interface RecorderDelegate {
|
||||
export interface RecorderDelegate {
|
||||
performAction?(action: actions.PerformOnRecordAction): Promise<void>;
|
||||
recordAction?(action: actions.Action): Promise<void>;
|
||||
setSelector?(selector: string): Promise<void>;
|
||||
@ -1457,73 +1456,3 @@ function createSvgElement(doc: Document, { tagName, attrs, children }: SvgJson):
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
interface Embedder {
|
||||
__pw_recorderPerformAction(action: actions.PerformOnRecordAction, simpleDomNode?: SimpleDomNode): Promise<void>;
|
||||
__pw_recorderRecordAction(action: actions.Action, simpleDomNode?: SimpleDomNode): Promise<void>;
|
||||
__pw_recorderState(): Promise<UIState>;
|
||||
__pw_recorderSetSelector(selector: string): Promise<void>;
|
||||
__pw_recorderSetMode(mode: Mode): Promise<void>;
|
||||
__pw_recorderSetOverlayState(state: OverlayState): Promise<void>;
|
||||
__pw_refreshOverlay(): void;
|
||||
}
|
||||
|
||||
export class PollingRecorder implements RecorderDelegate {
|
||||
private _recorder: Recorder;
|
||||
private _embedder: Embedder;
|
||||
private _pollRecorderModeTimer: number | undefined;
|
||||
|
||||
constructor(injectedScript: InjectedScript) {
|
||||
this._recorder = new Recorder(injectedScript);
|
||||
this._embedder = injectedScript.window as any;
|
||||
|
||||
injectedScript.onGlobalListenersRemoved.add(() => this._recorder.installListeners());
|
||||
|
||||
const refreshOverlay = () => {
|
||||
this._pollRecorderMode().catch(e => console.log(e)); // eslint-disable-line no-console
|
||||
};
|
||||
this._embedder.__pw_refreshOverlay = refreshOverlay;
|
||||
refreshOverlay();
|
||||
}
|
||||
|
||||
private async _pollRecorderMode() {
|
||||
const pollPeriod = 1000;
|
||||
if (this._pollRecorderModeTimer)
|
||||
clearTimeout(this._pollRecorderModeTimer);
|
||||
const state = await this._embedder.__pw_recorderState().catch(() => {});
|
||||
if (!state) {
|
||||
this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);
|
||||
return;
|
||||
}
|
||||
const win = this._recorder.document.defaultView!;
|
||||
if (win.top !== win) {
|
||||
// Only show action point in the main frame, since it is relative to the page's viewport.
|
||||
// Otherwise we'll see multiple action points at different locations.
|
||||
state.actionPoint = undefined;
|
||||
}
|
||||
this._recorder.setUIState(state, this);
|
||||
this._pollRecorderModeTimer = this._recorder.injectedScript.builtinSetTimeout(() => this._pollRecorderMode(), pollPeriod);
|
||||
}
|
||||
|
||||
async performAction(action: actions.PerformOnRecordAction, simpleDomNode?: SimpleDomNode) {
|
||||
await this._embedder.__pw_recorderPerformAction(action, simpleDomNode);
|
||||
}
|
||||
|
||||
async recordAction(action: actions.Action, simpleDomNode?: SimpleDomNode): Promise<void> {
|
||||
await this._embedder.__pw_recorderRecordAction(action, simpleDomNode);
|
||||
}
|
||||
|
||||
async setSelector(selector: string): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetSelector(selector);
|
||||
}
|
||||
|
||||
async setMode(mode: Mode): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetMode(mode);
|
||||
}
|
||||
|
||||
async setOverlayState(state: OverlayState): Promise<void> {
|
||||
await this._embedder.__pw_recorderSetOverlayState(state);
|
||||
}
|
||||
}
|
||||
|
||||
export default PollingRecorder;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
../isomorphic/**
|
||||
../registry/**
|
||||
../../common/
|
||||
../../generated/recorderSource.ts
|
||||
../../generated/pollingRecorderSource.ts
|
||||
../../protocol/
|
||||
../../utils/**
|
||||
../../utilsBundle.ts
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
import type * as channels from '@protocol/channels';
|
||||
import type { Source } from '@recorder/recorderTypes';
|
||||
import { EventEmitter } from 'events';
|
||||
import * as recorderSource from '../../generated/recorderSource';
|
||||
import * as recorderSource from '../../generated/pollingRecorderSource';
|
||||
import { eventsHelper, monotonicTime, quoteCSSAttributeValue, type RegisteredListener } from '../../utils';
|
||||
import { raceAgainstDeadline } from '../../utils/timeoutRunner';
|
||||
import { BrowserContext } from '../browserContext';
|
||||
|
||||
@ -45,7 +45,7 @@ const injectedScripts = [
|
||||
true,
|
||||
],
|
||||
[
|
||||
path.join(ROOT, 'packages', 'playwright-core', 'src', 'server', 'injected', 'recorder', 'recorder.ts'),
|
||||
path.join(ROOT, 'packages', 'playwright-core', 'src', 'server', 'injected', 'recorder', 'pollingRecorder.ts'),
|
||||
path.join(ROOT, 'packages', 'playwright-core', 'lib', 'server', 'injected', 'packed'),
|
||||
path.join(ROOT, 'packages', 'playwright-core', 'src', 'generated'),
|
||||
true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user