From 3abbe0d8502ce7373d9b02cc888bc95036e5305c Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 20 Sep 2022 14:32:21 -0700 Subject: [PATCH] chore: migrate codegen to controller events (#17450) --- packages/playwright-core/src/cli/driver.ts | 2 +- .../playwright-core/src/protocol/channels.ts | 19 +++++ .../playwright-core/src/protocol/protocol.yml | 24 ++++++ .../playwright-core/src/protocol/validator.ts | 16 ++++ .../dispatchers/reuseControllerDispatcher.ts | 3 + .../src/server/injected/recorder.ts | 2 +- .../playwright-core/src/server/recorder.ts | 2 +- .../src/server/recorder/recorderApp.ts | 2 +- .../src/server/recorder/recorderTypes.ts | 64 ---------------- .../src/server/recorder/recorderUtils.ts | 4 +- .../src/server/reuseController.ts | 13 +++- packages/recorder/src/callLog.tsx | 4 +- packages/recorder/src/main.tsx | 12 +-- packages/recorder/src/recorder.tsx | 2 +- packages/recorder/src/recorderTypes.ts | 76 +++++++++++++++++++ packages/recorder/tsconfig.json | 1 - packages/trace-viewer/tsconfig.json | 1 + tests/library/inspector/inspectorTest.ts | 2 +- tsconfig.json | 1 + 19 files changed, 160 insertions(+), 90 deletions(-) delete mode 100644 packages/playwright-core/src/server/recorder/recorderTypes.ts create mode 100644 packages/recorder/src/recorderTypes.ts diff --git a/packages/playwright-core/src/cli/driver.ts b/packages/playwright-core/src/cli/driver.ts index 67e4c2d08f..0607fcd9c6 100644 --- a/packages/playwright-core/src/cli/driver.ts +++ b/packages/playwright-core/src/cli/driver.ts @@ -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() { diff --git a/packages/playwright-core/src/protocol/channels.ts b/packages/playwright-core/src/protocol/channels.ts index 463e0a56e2..e0cc073532 100644 --- a/packages/playwright-core/src/protocol/channels.ts +++ b/packages/playwright-core/src/protocol/channels.ts @@ -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 ----------- diff --git a/packages/playwright-core/src/protocol/protocol.yml b/packages/playwright-core/src/protocol/protocol.yml index 285653c25a..73facbebed 100644 --- a/packages/playwright-core/src/protocol/protocol.yml +++ b/packages/playwright-core/src/protocol/protocol.yml @@ -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 diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 7ed51dca8e..bd657821bb 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -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, }); diff --git a/packages/playwright-core/src/server/dispatchers/reuseControllerDispatcher.ts b/packages/playwright-core/src/server/dispatchers/reuseControllerDispatcher.ts index 38ab0acb30..138e9d8353 100644 --- a/packages/playwright-core/src/server/dispatchers/reuseControllerDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/reuseControllerDispatcher.ts @@ -31,6 +31,9 @@ export class ReuseControllerDispatcher extends Dispatcher { this._dispatchEvent('inspectRequested', { selector }); }); + this._object.on(ReuseController.Events.SourcesChanged, sources => { + this._dispatchEvent('sourcesChanged', { sources }); + }); } async setTrackHierarchy(params: channels.ReuseControllerSetTrackHierarchyParams) { diff --git a/packages/playwright-core/src/server/injected/recorder.ts b/packages/playwright-core/src/server/injected/recorder.ts index 4f1774cf47..64427f8f0a 100644 --- a/packages/playwright-core/src/server/injected/recorder.ts +++ b/packages/playwright-core/src/server/injected/recorder.ts @@ -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'; diff --git a/packages/playwright-core/src/server/recorder.ts b/packages/playwright-core/src/server/recorder.ts index b1174b63f5..9b0e45980f 100644 --- a/packages/playwright-core/src/server/recorder.ts +++ b/packages/playwright-core/src/server/recorder.ts @@ -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'; diff --git a/packages/playwright-core/src/server/recorder/recorderApp.ts b/packages/playwright-core/src/server/recorder/recorderApp.ts index 045e025776..9add17d1c2 100644 --- a/packages/playwright-core/src/server/recorder/recorderApp.ts +++ b/packages/playwright-core/src/server/recorder/recorderApp.ts @@ -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'; diff --git a/packages/playwright-core/src/server/recorder/recorderTypes.ts b/packages/playwright-core/src/server/recorder/recorderTypes.ts deleted file mode 100644 index 7fa30477d7..0000000000 --- a/packages/playwright-core/src/server/recorder/recorderTypes.ts +++ /dev/null @@ -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; -}; diff --git a/packages/playwright-core/src/server/recorder/recorderUtils.ts b/packages/playwright-core/src/server/recorder/recorderUtils.ts index 219ea50fc3..d6237b4899 100644 --- a/packages/playwright-core/src/server/recorder/recorderUtils.ts +++ b/packages/playwright-core/src/server/recorder/recorderUtils.ts @@ -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, }; diff --git a/packages/playwright-core/src/server/reuseController.ts b/packages/playwright-core/src/server/reuseController.ts index ef8e2bce83..12fcbc93cd 100644 --- a/packages/playwright-core/src/server/reuseController.ts +++ b/packages/playwright-core/src/server/reuseController.ts @@ -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 { this._reuseController.emit(ReuseController.Events.InspectRequested, selector); } + + override async setSources(sources: Source[]): Promise { + this._reuseController.emit(ReuseController.Events.SourcesChanged, sources); + } } diff --git a/packages/recorder/src/callLog.tsx b/packages/recorder/src/callLog.tsx index 88efa2d69e..553232afba 100644 --- a/packages/recorder/src/callLog.tsx +++ b/packages/recorder/src/callLog.tsx @@ -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 = ({ { message.trim() } ; })} - { !!callLog.error && } + { !!callLog.error && } ; })}
diff --git a/packages/recorder/src/main.tsx b/packages/recorder/src/main.tsx index 8b57e9ccd0..ddd9d90acd 100644 --- a/packages/recorder/src/main.tsx +++ b/packages/recorder/src/main.tsx @@ -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([]); diff --git a/packages/recorder/src/recorder.tsx b/packages/recorder/src/recorder.tsx index 0d23de2639..70c0717a42 100644 --- a/packages/recorder/src/recorder.tsx +++ b/packages/recorder/src/recorder.tsx @@ -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'; diff --git a/packages/recorder/src/recorderTypes.ts b/packages/recorder/src/recorderTypes.ts new file mode 100644 index 0000000000..c41b750b50 --- /dev/null +++ b/packages/recorder/src/recorderTypes.ts @@ -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; + } +} diff --git a/packages/recorder/tsconfig.json b/packages/recorder/tsconfig.json index fd28152728..53bc039f94 100644 --- a/packages/recorder/tsconfig.json +++ b/packages/recorder/tsconfig.json @@ -18,7 +18,6 @@ "useUnknownInCatchVariables": false, "paths": { "@web/*": ["../web/src/*"], - "@playwright-core/*": ["../playwright-core/src/*"], } }, "include": ["src"], diff --git a/packages/trace-viewer/tsconfig.json b/packages/trace-viewer/tsconfig.json index 69193c83c8..fe902f3205 100644 --- a/packages/trace-viewer/tsconfig.json +++ b/packages/trace-viewer/tsconfig.json @@ -16,6 +16,7 @@ "jsx": "react-jsx", "baseUrl": ".", "paths": { + "@recorder/*": ["../recorder/src/*"], "@web/*": ["../web/src/*"], "@playwright-core/*": ["../playwright-core/src/*"], }, diff --git a/tests/library/inspector/inspectorTest.ts b/tests/library/inspector/inspectorTest.ts index 6e68337230..d3c08c3465 100644 --- a/tests/library/inspector/inspectorTest.ts +++ b/tests/library/inspector/inspectorTest.ts @@ -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'; diff --git a/tsconfig.json b/tsconfig.json index 767795f069..3cd48faba8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -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,