mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-05 19:04:43 +03:00
chore: migrate codegen to controller events (#17450)
This commit is contained in:
parent
4dccba72ed
commit
3abbe0d850
@ -25,7 +25,7 @@ import type { Playwright } from '../server/playwright';
|
||||
import { IpcTransport, PipeTransport } from '../protocol/transport';
|
||||
import { PlaywrightServer } from '../remote/playwrightServer';
|
||||
import { gracefullyCloseAll } from '../utils/processLauncher';
|
||||
import type { Mode } from '../server/recorder/recorderTypes';
|
||||
import type { Mode } from '@recorder/recorderTypes';
|
||||
import { ReuseController } from '../server/reuseController';
|
||||
|
||||
export function printApiJson() {
|
||||
|
@ -558,11 +558,26 @@ export type PlaywrightHideHighlightResult = void;
|
||||
export interface PlaywrightEvents {
|
||||
}
|
||||
|
||||
export type RecorderSource = {
|
||||
isRecorded: boolean,
|
||||
id: string,
|
||||
label: string,
|
||||
text: string,
|
||||
language: string,
|
||||
highlight: {
|
||||
line: number,
|
||||
type: string,
|
||||
}[],
|
||||
revealLine?: number,
|
||||
group?: string,
|
||||
};
|
||||
|
||||
// ----------- ReuseController -----------
|
||||
export type ReuseControllerInitializer = {};
|
||||
export interface ReuseControllerEventTarget {
|
||||
on(event: 'inspectRequested', callback: (params: ReuseControllerInspectRequestedEvent) => void): this;
|
||||
on(event: 'browsersChanged', callback: (params: ReuseControllerBrowsersChangedEvent) => void): this;
|
||||
on(event: 'sourcesChanged', callback: (params: ReuseControllerSourcesChangedEvent) => void): this;
|
||||
}
|
||||
export interface ReuseControllerChannel extends ReuseControllerEventTarget, Channel {
|
||||
_type_ReuseController: boolean;
|
||||
@ -587,6 +602,9 @@ export type ReuseControllerBrowsersChangedEvent = {
|
||||
}[],
|
||||
}[],
|
||||
};
|
||||
export type ReuseControllerSourcesChangedEvent = {
|
||||
sources: RecorderSource[],
|
||||
};
|
||||
export type ReuseControllerSetTrackHierarchyParams = {
|
||||
enabled: boolean,
|
||||
};
|
||||
@ -648,6 +666,7 @@ export type ReuseControllerCloseAllBrowsersResult = void;
|
||||
export interface ReuseControllerEvents {
|
||||
'inspectRequested': ReuseControllerInspectRequestedEvent;
|
||||
'browsersChanged': ReuseControllerBrowsersChangedEvent;
|
||||
'sourcesChanged': ReuseControllerSourcesChangedEvent;
|
||||
}
|
||||
|
||||
// ----------- SocksSupport -----------
|
||||
|
@ -622,6 +622,24 @@ Playwright:
|
||||
|
||||
hideHighlight:
|
||||
|
||||
RecorderSource:
|
||||
type: object
|
||||
properties:
|
||||
isRecorded: boolean
|
||||
id: string
|
||||
label: string
|
||||
text: string
|
||||
language: string
|
||||
highlight:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
line: number
|
||||
type: string
|
||||
revealLine: number?
|
||||
group: string?
|
||||
|
||||
ReuseController:
|
||||
type: interface
|
||||
|
||||
@ -686,6 +704,12 @@ ReuseController:
|
||||
type: array
|
||||
items: string
|
||||
|
||||
sourcesChanged:
|
||||
parameters:
|
||||
sources:
|
||||
type: array
|
||||
items: RecorderSource
|
||||
|
||||
SocksSupport:
|
||||
type: interface
|
||||
|
||||
|
@ -308,6 +308,19 @@ scheme.PlaywrightNewRequestResult = tObject({
|
||||
});
|
||||
scheme.PlaywrightHideHighlightParams = tOptional(tObject({}));
|
||||
scheme.PlaywrightHideHighlightResult = tOptional(tObject({}));
|
||||
scheme.RecorderSource = tObject({
|
||||
isRecorded: tBoolean,
|
||||
id: tString,
|
||||
label: tString,
|
||||
text: tString,
|
||||
language: tString,
|
||||
highlight: tArray(tObject({
|
||||
line: tNumber,
|
||||
type: tString,
|
||||
})),
|
||||
revealLine: tOptional(tNumber),
|
||||
group: tOptional(tString),
|
||||
});
|
||||
scheme.ReuseControllerInitializer = tOptional(tObject({}));
|
||||
scheme.ReuseControllerInspectRequestedEvent = tObject({
|
||||
selector: tString,
|
||||
@ -319,6 +332,9 @@ scheme.ReuseControllerBrowsersChangedEvent = tObject({
|
||||
})),
|
||||
})),
|
||||
});
|
||||
scheme.ReuseControllerSourcesChangedEvent = tObject({
|
||||
sources: tArray(tType('RecorderSource')),
|
||||
});
|
||||
scheme.ReuseControllerSetTrackHierarchyParams = tObject({
|
||||
enabled: tBoolean,
|
||||
});
|
||||
|
@ -31,6 +31,9 @@ export class ReuseControllerDispatcher extends Dispatcher<ReuseController, chann
|
||||
this._object.on(ReuseController.Events.InspectRequested, selector => {
|
||||
this._dispatchEvent('inspectRequested', { selector });
|
||||
});
|
||||
this._object.on(ReuseController.Events.SourcesChanged, sources => {
|
||||
this._dispatchEvent('sourcesChanged', { sources });
|
||||
});
|
||||
}
|
||||
|
||||
async setTrackHierarchy(params: channels.ReuseControllerSetTrackHierarchyParams) {
|
||||
|
@ -18,7 +18,7 @@ import type * as actions from '../recorder/recorderActions';
|
||||
import { type InjectedScript } from '../injected/injectedScript';
|
||||
import { generateSelector, querySelector } from '../injected/selectorGenerator';
|
||||
import type { Point } from '../../common/types';
|
||||
import type { UIState } from '../recorder/recorderTypes';
|
||||
import type { UIState } from '@recorder/recorderTypes';
|
||||
import { Highlight } from '../injected/highlight';
|
||||
|
||||
|
||||
|
@ -34,7 +34,7 @@ import type { IRecorderApp } from './recorder/recorderApp';
|
||||
import { RecorderApp } from './recorder/recorderApp';
|
||||
import type { CallMetadata, InstrumentationListener, SdkObject } from './instrumentation';
|
||||
import type { Point } from '../common/types';
|
||||
import type { CallLog, CallLogStatus, EventData, Mode, Source, UIState } from './recorder/recorderTypes';
|
||||
import type { CallLog, CallLogStatus, EventData, Mode, Source, UIState } from '@recorder/recorderTypes';
|
||||
import { createGuid, monotonicTime } from '../utils';
|
||||
import { metadataToCallLog } from './recorder/recorderUtils';
|
||||
import { Debugger } from './debugger';
|
||||
|
@ -20,7 +20,7 @@ import type { Page } from '../page';
|
||||
import { ProgressController } from '../progress';
|
||||
import { EventEmitter } from 'events';
|
||||
import { serverSideCallMetadata } from '../instrumentation';
|
||||
import type { CallLog, EventData, Mode, Source } from './recorderTypes';
|
||||
import type { CallLog, EventData, Mode, Source } from '@recorder/recorderTypes';
|
||||
import { isUnderTest } from '../../utils';
|
||||
import { mime } from '../../utilsBundle';
|
||||
import { installAppIcon } from '../chromium/crApp';
|
||||
|
@ -1,64 +0,0 @@
|
||||
/**
|
||||
* 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 { Point } from '../../common/types';
|
||||
import type { SerializedError } from '../../protocol/channels';
|
||||
|
||||
export type Mode = 'inspecting' | 'recording' | 'none';
|
||||
|
||||
export type EventData = {
|
||||
event: 'clear' | 'resume' | 'step' | 'pause' | 'setMode' | 'selectorUpdated';
|
||||
params: any;
|
||||
};
|
||||
|
||||
export type UIState = {
|
||||
mode: Mode;
|
||||
actionPoint?: Point;
|
||||
actionSelector?: string;
|
||||
};
|
||||
|
||||
export type CallLogStatus = 'in-progress' | 'done' | 'error' | 'paused';
|
||||
|
||||
export type CallLog = {
|
||||
id: string;
|
||||
title: string;
|
||||
messages: string[];
|
||||
status: CallLogStatus;
|
||||
error?: SerializedError;
|
||||
reveal?: boolean;
|
||||
duration?: number;
|
||||
params: {
|
||||
url?: string,
|
||||
selector?: string,
|
||||
};
|
||||
};
|
||||
|
||||
export type SourceHighlight = {
|
||||
line: number;
|
||||
type: 'running' | 'paused' | 'error';
|
||||
};
|
||||
|
||||
export type Source = {
|
||||
isRecorded: boolean;
|
||||
id: string;
|
||||
label: string;
|
||||
text: string;
|
||||
language: string;
|
||||
highlight: SourceHighlight[];
|
||||
revealLine?: number;
|
||||
// used to group the language generators
|
||||
group?: string;
|
||||
};
|
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import type { CallMetadata } from '../instrumentation';
|
||||
import type { CallLog, CallLogStatus } from './recorderTypes';
|
||||
import type { CallLog, CallLogStatus } from '@recorder/recorderTypes';
|
||||
|
||||
export function metadataToCallLog(metadata: CallMetadata, status: CallLogStatus): CallLog {
|
||||
let title = metadata.apiName || metadata.method;
|
||||
@ -38,7 +38,7 @@ export function metadataToCallLog(metadata: CallMetadata, status: CallLogStatus)
|
||||
messages: metadata.log,
|
||||
title,
|
||||
status,
|
||||
error: metadata.error,
|
||||
error: metadata.error?.error?.message,
|
||||
params,
|
||||
duration,
|
||||
};
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Mode } from '../server/recorder/recorderTypes';
|
||||
import type { Mode, Source } from '@recorder/recorderTypes';
|
||||
import { gracefullyCloseAll } from '../utils/processLauncher';
|
||||
import type { Browser } from './browser';
|
||||
import type { BrowserContext } from './browserContext';
|
||||
@ -29,7 +29,8 @@ const internalMetadata = serverSideCallMetadata();
|
||||
export class ReuseController extends SdkObject {
|
||||
static Events = {
|
||||
BrowsersChanged: 'browsersChanged',
|
||||
InspectRequested: 'inspectRequested'
|
||||
InspectRequested: 'inspectRequested',
|
||||
SourcesChanged: 'sourcesChanged',
|
||||
};
|
||||
|
||||
private _autoCloseTimer: NodeJS.Timeout | undefined;
|
||||
@ -61,9 +62,9 @@ export class ReuseController extends SdkObject {
|
||||
onPageNavigated: () => this._emitSnapshot(),
|
||||
onPageClose: () => this._emitSnapshot(),
|
||||
};
|
||||
this.instrumentation.addListener(this._trackHierarchyListener, null);
|
||||
this._playwright.instrumentation.addListener(this._trackHierarchyListener, null);
|
||||
} else if (!enabled && this._trackHierarchyListener) {
|
||||
this.instrumentation.removeListener(this._trackHierarchyListener);
|
||||
this._playwright.instrumentation.removeListener(this._trackHierarchyListener);
|
||||
this._trackHierarchyListener = undefined;
|
||||
}
|
||||
}
|
||||
@ -216,4 +217,8 @@ class InspectingRecorderApp extends EmptyRecorderApp {
|
||||
override async setSelector(selector: string): Promise<void> {
|
||||
this._reuseController.emit(ReuseController.Events.InspectRequested, selector);
|
||||
}
|
||||
|
||||
override async setSources(sources: Source[]): Promise<void> {
|
||||
this._reuseController.emit(ReuseController.Events.SourcesChanged, sources);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import './callLog.css';
|
||||
import * as React from 'react';
|
||||
import type { CallLog } from '@playwright-core/server/recorder/recorderTypes';
|
||||
import type { CallLog } from './recorderTypes';
|
||||
import { msToString } from '@web/uiUtils';
|
||||
|
||||
export interface CallLogProps {
|
||||
@ -54,7 +54,7 @@ export const CallLogView: React.FC<CallLogProps> = ({
|
||||
{ message.trim() }
|
||||
</div>;
|
||||
})}
|
||||
{ !!callLog.error && <div className='call-log-message error' hidden={!isExpanded}>{ callLog.error.error?.message }</div> }
|
||||
{ !!callLog.error && <div className='call-log-message error' hidden={!isExpanded}>{ callLog.error }</div> }
|
||||
</div>;
|
||||
})}
|
||||
<div ref={messagesEndRef}></div>
|
||||
|
@ -14,21 +14,11 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type { CallLog, Mode, Source } from '@playwright-core/server/recorder/recorderTypes';
|
||||
import type { CallLog, Mode, Source } from './recorderTypes';
|
||||
import * as React from 'react';
|
||||
import { Recorder } from './recorder';
|
||||
import './recorder.css';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
playwrightSetMode: (mode: Mode) => void;
|
||||
playwrightSetPaused: (paused: boolean) => void;
|
||||
playwrightSetSources: (sources: Source[]) => void;
|
||||
playwrightUpdateLogs: (callLogs: CallLog[]) => void;
|
||||
playwrightSourcesEchoForTest: Source[];
|
||||
}
|
||||
}
|
||||
|
||||
export const Main: React.FC = ({
|
||||
}) => {
|
||||
const [sources, setSources] = React.useState<Source[]>([]);
|
||||
|
@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import type { CallLog, Mode, Source } from '@playwright-core/server/recorder/recorderTypes';
|
||||
import type { CallLog, Mode, Source } from './recorderTypes';
|
||||
import { Source as SourceView } from '@web/components/source';
|
||||
import { SplitView } from '@web/components/splitView';
|
||||
import { Toolbar } from '@web/components/toolbar';
|
||||
|
76
packages/recorder/src/recorderTypes.ts
Normal file
76
packages/recorder/src/recorderTypes.ts
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
export type Point = { x: number, y: number };
|
||||
|
||||
export type Mode = 'inspecting' | 'recording' | 'none';
|
||||
|
||||
export type EventData = {
|
||||
event: 'clear' | 'resume' | 'step' | 'pause' | 'setMode' | 'selectorUpdated';
|
||||
params: any;
|
||||
};
|
||||
|
||||
export type UIState = {
|
||||
mode: Mode;
|
||||
actionPoint?: Point;
|
||||
actionSelector?: string;
|
||||
};
|
||||
|
||||
export type CallLogStatus = 'in-progress' | 'done' | 'error' | 'paused';
|
||||
|
||||
export type CallLog = {
|
||||
id: string;
|
||||
title: string;
|
||||
messages: string[];
|
||||
status: CallLogStatus;
|
||||
error?: string;
|
||||
reveal?: boolean;
|
||||
duration?: number;
|
||||
params: {
|
||||
url?: string,
|
||||
selector?: string,
|
||||
};
|
||||
};
|
||||
|
||||
export type SourceHighlight = {
|
||||
line: number;
|
||||
type: 'running' | 'paused' | 'error';
|
||||
};
|
||||
|
||||
export type Source = {
|
||||
isRecorded: boolean;
|
||||
id: string;
|
||||
label: string;
|
||||
text: string;
|
||||
language: string;
|
||||
highlight: SourceHighlight[];
|
||||
revealLine?: number;
|
||||
// used to group the language generators
|
||||
group?: string;
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
playwrightSetMode: (mode: Mode) => void;
|
||||
playwrightSetPaused: (paused: boolean) => void;
|
||||
playwrightSetSources: (sources: Source[]) => void;
|
||||
playwrightUpdateLogs: (callLogs: CallLog[]) => void;
|
||||
playwrightSetFileIfNeeded: (file: string) => void;
|
||||
playwrightSetSelector: (selector: string, focus?: boolean) => void;
|
||||
playwrightSourcesEchoForTest: Source[];
|
||||
dispatch(data: any): Promise<void>;
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@
|
||||
"useUnknownInCatchVariables": false,
|
||||
"paths": {
|
||||
"@web/*": ["../web/src/*"],
|
||||
"@playwright-core/*": ["../playwright-core/src/*"],
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
|
@ -16,6 +16,7 @@
|
||||
"jsx": "react-jsx",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@recorder/*": ["../recorder/src/*"],
|
||||
"@web/*": ["../web/src/*"],
|
||||
"@playwright-core/*": ["../playwright-core/src/*"],
|
||||
},
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { contextTest } from '../../config/browserTest';
|
||||
import type { ConsoleMessage, Page } from 'playwright-core';
|
||||
import * as path from 'path';
|
||||
import type { Source } from '../../../packages/playwright-core/src/server/recorder/recorderTypes';
|
||||
import type { Source } from '../../../packages/recorder/src/recorderTypes';
|
||||
import type { CommonFixtures, TestChildProcess } from '../../config/commonFixtures';
|
||||
export { expect } from '@playwright/test';
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
- playwright-core/lib means require dependency
|
||||
*/
|
||||
"@playwright-core/*": ["./packages/playwright-core/src/*"],
|
||||
"@recorder/*": ["./packages/recorder/src/*"],
|
||||
"playwright-core/lib/*": ["./packages/playwright-core/src/*"]
|
||||
},
|
||||
"esModuleInterop": true,
|
||||
|
Loading…
Reference in New Issue
Block a user