From dacd060a2a350ef113047dfc5731930e7d141de0 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 10 Jul 2026 13:45:42 +0100 Subject: [PATCH] chore(recorder): mint page aliases in the language generators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recorder was naming the pages of the generated source code (page, page1, ...) and stamping the name onto every action. Drop it: actions and signals now carry only `pageGuid`, and each language generator lazily mints its own aliases into a pageGuid -> alias map, cleared by a new `reset()` that `generateCode()` calls. `PopupSignal.popupAlias` was the popup page's own alias, so it becomes `popupPageGuid` and resolves through the same map. `FrameDescription` held nothing else, so `pageGuid` moves onto `ActionInContext`/`SignalInContext` directly, and `mainFrameForAction()` goes away — the caller already has the frame the action came from. --- packages/isomorphic/codegen/actions.d.ts | 11 ++---- packages/isomorphic/codegen/csharp.ts | 34 ++++++++++------- packages/isomorphic/codegen/java.ts | 20 +++++++++- packages/isomorphic/codegen/javascript.ts | 26 ++++++++++--- packages/isomorphic/codegen/jsonl.ts | 5 ++- packages/isomorphic/codegen/language.ts | 3 +- packages/isomorphic/codegen/python.ts | 22 +++++++++-- packages/isomorphic/codegen/types.ts | 1 + .../src/server/debugController.ts | 2 +- .../playwright-core/src/server/recorder.ts | 37 +++++-------------- .../src/server/recorder/recorderApp.ts | 12 +++--- .../src/server/recorder/recorderRunner.ts | 9 +---- .../recorder/recorderSignalProcessor.ts | 12 ++---- .../src/server/recorder/recorderUtils.ts | 11 +----- tests/library/inspector/cli-codegen-3.spec.ts | 4 -- 15 files changed, 110 insertions(+), 99 deletions(-) diff --git a/packages/isomorphic/codegen/actions.d.ts b/packages/isomorphic/codegen/actions.d.ts index 9fa7203a23975..f6dbc6b51a115 100644 --- a/packages/isomorphic/codegen/actions.d.ts +++ b/packages/isomorphic/codegen/actions.d.ts @@ -142,7 +142,7 @@ export type NavigationSignal = BaseSignal & { export type PopupSignal = BaseSignal & { name: 'popup', - popupAlias: string, + popupPageGuid: string, }; export type DownloadSignal = BaseSignal & { @@ -163,20 +163,15 @@ export type ExpectSignal = BaseSignal & { export type Signal = NavigationSignal | PopupSignal | DownloadSignal | DialogSignal | ExpectSignal; -export type FrameDescription = { - pageGuid: string; - pageAlias: string; -}; - export type ActionInContext = { - frame: FrameDescription; + pageGuid: string; action: Action; startTime: number; endTime?: number; }; export type SignalInContext = { - frame: FrameDescription; + pageGuid: string; signal: Signal; timestamp: number; }; diff --git a/packages/isomorphic/codegen/csharp.ts b/packages/isomorphic/codegen/csharp.ts index 5df1321f6089f..a3a57ba93d10c 100644 --- a/packages/isomorphic/codegen/csharp.ts +++ b/packages/isomorphic/codegen/csharp.ts @@ -31,6 +31,7 @@ export class CSharpLanguageGenerator implements LanguageGenerator { name: string; highlighter = 'csharp' as Language; _mode: CSharpLanguageMode; + private _pageAliases = new Map(); constructor(mode: CSharpLanguageMode) { if (mode === 'library') { @@ -51,6 +52,22 @@ export class CSharpLanguageGenerator implements LanguageGenerator { this._mode = mode; } + reset() { + this._pageAliases.clear(); + } + + private _pageAlias(pageGuid: string): string { + let alias = this._pageAliases.get(pageGuid); + if (!alias) { + alias = 'page' + (this._pageAliases.size || ''); + // Outside of the library mode, the first page is a class member, the rest are local variables. + if (this._mode !== 'library' && alias === 'page') + alias = 'Page'; + this._pageAliases.set(pageGuid, alias); + } + return alias; + } + generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const action = this._generateActionInner(actionInContext, options); if (action) @@ -60,9 +77,10 @@ export class CSharpLanguageGenerator implements LanguageGenerator { _generateActionInner(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const action = actionInContext.action; + // Resolve before the early return, so that pages are named in the order they are opened. + const pageAlias = this._pageAlias(actionInContext.pageGuid); if (this._mode !== 'library' && (action.name === 'openPage' || action.name === 'closePage')) return ''; - const pageAlias = this._formatPageAlias(actionInContext.frame.pageAlias); const formatter = new CSharpFormatter(this._mode === 'library' ? 0 : 8); if (action.name === 'openPage') { @@ -94,7 +112,8 @@ export class CSharpLanguageGenerator implements LanguageGenerator { } if (signals.popup) { - lines.unshift(`var ${this._formatPageAlias(signals.popup.popupAlias)} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>\n{`); + const popupAlias = this._pageAlias(signals.popup.popupPageGuid); + lines.unshift(`var ${popupAlias} = await ${pageAlias}.RunAndWaitForPopupAsync(async () =>\n{`); lines.push(`});`); } @@ -107,17 +126,6 @@ export class CSharpLanguageGenerator implements LanguageGenerator { return formatter.format(); } - private _formatPageAlias(pageAlias: string): string { - if (this._mode === 'library') - return pageAlias; - - if (pageAlias === 'page') - return 'Page'; // first page is class member - - // other pages are local variables - return pageAlias; - } - private _generateActionCall(subject: string, actionInContext: actions.ActionInContext): string { const action = actionInContext.action; switch (action.name) { diff --git a/packages/isomorphic/codegen/java.ts b/packages/isomorphic/codegen/java.ts index bbb119b6e2bb2..3e318114e2681 100644 --- a/packages/isomorphic/codegen/java.ts +++ b/packages/isomorphic/codegen/java.ts @@ -33,6 +33,7 @@ export class JavaLanguageGenerator implements LanguageGenerator { name: string; highlighter = 'java' as Language; _mode: JavaLanguageMode; + private _pageAliases = new Map(); constructor(mode: JavaLanguageMode) { if (mode === 'library') { @@ -47,9 +48,23 @@ export class JavaLanguageGenerator implements LanguageGenerator { this._mode = mode; } + reset() { + this._pageAliases.clear(); + } + + private _pageAlias(pageGuid: string): string { + let alias = this._pageAliases.get(pageGuid); + if (!alias) { + alias = 'page' + (this._pageAliases.size || ''); + this._pageAliases.set(pageGuid, alias); + } + return alias; + } + generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const action = actionInContext.action; - const pageAlias = actionInContext.frame.pageAlias; + // Resolve before the early return, so that pages are named in the order they are opened. + const pageAlias = this._pageAlias(actionInContext.pageGuid); const offset = this._mode === 'junit' ? 4 : 6; const formatter = new JavaScriptFormatter(offset); @@ -76,7 +91,8 @@ export class JavaLanguageGenerator implements LanguageGenerator { let code = this._generateActionCall(subject, actionInContext); if (signals.popup) { - code = `Page ${signals.popup.popupAlias} = ${pageAlias}.waitForPopup(() -> { + const popupAlias = this._pageAlias(signals.popup.popupPageGuid); + code = `Page ${popupAlias} = ${pageAlias}.waitForPopup(() -> { ${code} });`; } diff --git a/packages/isomorphic/codegen/javascript.ts b/packages/isomorphic/codegen/javascript.ts index 9237df55711b2..01002d3f5901a 100644 --- a/packages/isomorphic/codegen/javascript.ts +++ b/packages/isomorphic/codegen/javascript.ts @@ -29,6 +29,7 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator { name: string; highlighter = 'javascript' as Language; private _isTest: boolean; + private _pageAliases = new Map(); constructor(isTest: boolean) { this.id = isTest ? 'playwright-test' : 'javascript'; @@ -36,12 +37,26 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator { this._isTest = isTest; } + reset() { + this._pageAliases.clear(); + } + + private _pageAlias(pageGuid: string): string { + let alias = this._pageAliases.get(pageGuid); + if (!alias) { + alias = 'page' + (this._pageAliases.size || ''); + this._pageAliases.set(pageGuid, alias); + } + return alias; + } + generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const action = actionInContext.action; + // Resolve before the early return, so that pages are named in the order they are opened. + const pageAlias = this._pageAlias(actionInContext.pageGuid); if (this._isTest && (action.name === 'openPage' || action.name === 'closePage')) return ''; - const pageAlias = actionInContext.frame.pageAlias; const formatter = new JavaScriptFormatter(2); if (action.name === 'openPage') { @@ -61,15 +76,16 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator { });`); } - if (signals.popup) - formatter.add(`const ${signals.popup.popupAlias}Promise = ${pageAlias}.waitForEvent('popup');`); + const popupAlias = signals.popup ? this._pageAlias(signals.popup.popupPageGuid) : undefined; + if (popupAlias) + formatter.add(`const ${popupAlias}Promise = ${pageAlias}.waitForEvent('popup');`); if (signals.download) formatter.add(`const download${signals.download.downloadAlias}Promise = ${pageAlias}.waitForEvent('download');`); formatter.add(this._generateActionCall(subject, actionInContext)); - if (signals.popup) - formatter.add(`const ${signals.popup.popupAlias} = await ${signals.popup.popupAlias}Promise;`); + if (popupAlias) + formatter.add(`const ${popupAlias} = await ${popupAlias}Promise;`); if (signals.download) formatter.add(`const download${signals.download.downloadAlias} = await download${signals.download.downloadAlias}Promise;`); if (options.generateExpectSignal && signals.expect) diff --git a/packages/isomorphic/codegen/jsonl.ts b/packages/isomorphic/codegen/jsonl.ts index 2f6aecd81c391..d31858594e5ed 100644 --- a/packages/isomorphic/codegen/jsonl.ts +++ b/packages/isomorphic/codegen/jsonl.ts @@ -26,11 +26,14 @@ export class JsonlLanguageGenerator implements LanguageGenerator { name = 'JSONL'; highlighter = 'javascript' as Language; + reset() { + } + generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const locator = (actionInContext.action as any).selector ? JSON.parse(asLocator('jsonl', (actionInContext.action as any).selector)) : undefined; const entry = { ...actionInContext.action, - ...actionInContext.frame, + pageGuid: actionInContext.pageGuid, locator, ariaSnapshot: undefined, }; diff --git a/packages/isomorphic/codegen/language.ts b/packages/isomorphic/codegen/language.ts index 8ea2c5fa97c6b..eb3df508efd3d 100644 --- a/packages/isomorphic/codegen/language.ts +++ b/packages/isomorphic/codegen/language.ts @@ -20,6 +20,7 @@ import type { LanguageGenerator, LanguageGeneratorOptions } from './types'; import type * as actions from './actions'; export function generateCode(actions: actions.ActionInContext[], languageGenerator: LanguageGenerator, options: LanguageGeneratorOptions) { + languageGenerator.reset(); const header = languageGenerator.generateHeader(options); const footer = languageGenerator.generateFooter(options.saveStorage); const actionTexts = actions.map(a => languageGenerator.generateAction(a, options)).filter(Boolean); @@ -29,7 +30,7 @@ export function generateCode(actions: actions.ActionInContext[], languageGenerat export function expectSignalAction(actionInContext: actions.ActionInContext, signal: actions.ExpectSignal): actions.ActionInContext { return { - frame: actionInContext.frame, + pageGuid: actionInContext.pageGuid, startTime: actionInContext.startTime, endTime: actionInContext.startTime, action: { diff --git a/packages/isomorphic/codegen/python.ts b/packages/isomorphic/codegen/python.ts index c80039d7fc1c8..2640b52c17e3a 100644 --- a/packages/isomorphic/codegen/python.ts +++ b/packages/isomorphic/codegen/python.ts @@ -33,6 +33,7 @@ export class PythonLanguageGenerator implements LanguageGenerator { private _asyncPrefix: '' | 'async '; private _isAsync: boolean; private _isPyTest: boolean; + private _pageAliases = new Map(); constructor(isAsync: boolean, isPyTest: boolean) { this.id = isPyTest ? 'python-pytest' : (isAsync ? 'python-async' : 'python'); @@ -43,12 +44,26 @@ export class PythonLanguageGenerator implements LanguageGenerator { this._asyncPrefix = isAsync ? 'async ' : ''; } + reset() { + this._pageAliases.clear(); + } + + private _pageAlias(pageGuid: string): string { + let alias = this._pageAliases.get(pageGuid); + if (!alias) { + alias = 'page' + (this._pageAliases.size || ''); + this._pageAliases.set(pageGuid, alias); + } + return alias; + } + generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string { const action = actionInContext.action; + // Resolve before the early return, so that pages are named in the order they are opened. + const pageAlias = this._pageAlias(actionInContext.pageGuid); if (this._isPyTest && (action.name === 'openPage' || action.name === 'closePage')) return ''; - const pageAlias = actionInContext.frame.pageAlias; const formatter = new PythonFormatter(4); if (action.name === 'openPage') { @@ -67,10 +82,11 @@ export class PythonLanguageGenerator implements LanguageGenerator { let code = `${this._awaitPrefix}${this._generateActionCall(subject, actionInContext)}`; if (signals.popup) { - code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as ${signals.popup.popupAlias}_info { + const popupAlias = this._pageAlias(signals.popup.popupPageGuid); + code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as ${popupAlias}_info { ${code} } - ${signals.popup.popupAlias} = ${this._awaitPrefix}${signals.popup.popupAlias}_info.value`; + ${popupAlias} = ${this._awaitPrefix}${popupAlias}_info.value`; } if (signals.download) { diff --git a/packages/isomorphic/codegen/types.ts b/packages/isomorphic/codegen/types.ts index 000f1e49cce5c..85bea0e8f2369 100644 --- a/packages/isomorphic/codegen/types.ts +++ b/packages/isomorphic/codegen/types.ts @@ -44,6 +44,7 @@ export interface LanguageGenerator { groupName: string; name: string; highlighter: Language; + reset(): void; generateHeader(options: LanguageGeneratorOptions): string; generateAction(actionInContext: actions.ActionInContext, options: LanguageGeneratorOptions): string; generateFooter(saveStorage: string | undefined): string; diff --git a/packages/playwright-core/src/server/debugController.ts b/packages/playwright-core/src/server/debugController.ts index 3706ddb4ee6e9..d09d972131923 100644 --- a/packages/playwright-core/src/server/debugController.ts +++ b/packages/playwright-core/src/server/debugController.ts @@ -213,7 +213,7 @@ function wireListeners(recorder: Recorder, debugController: DebugController) { actionsChanged(); }); recorder.on(RecorderEvent.SignalAdded, (signal: actions.SignalInContext) => { - const lastAction = actions.findLast(a => a.frame.pageGuid === signal.frame.pageGuid); + const lastAction = actions.findLast(a => a.pageGuid === signal.pageGuid); if (lastAction) lastAction.action.signals.push(signal.signal); actionsChanged(); diff --git a/packages/playwright-core/src/server/recorder.ts b/packages/playwright-core/src/server/recorder.ts index 81eecfbfadd3f..5ef7ffc08f1e3 100644 --- a/packages/playwright-core/src/server/recorder.ts +++ b/packages/playwright-core/src/server/recorder.ts @@ -89,8 +89,6 @@ export class Recorder extends EventEmitter implements Instrume private _recorderMode: 'default' | 'api'; private _signalProcessor: RecorderSignalProcessor; - private _pageAliases = new Map(); - private _lastPopupOrdinal = 0; private _lastDialogOrdinal = -1; private _lastDownloadOrdinal = -1; private _listeners: RegisteredListener[] = []; @@ -495,18 +493,16 @@ export class Recorder extends EventEmitter implements Instrume } private async _onPage(page: Page) { - // First page is called page, others are called popup1, popup2, etc. const frame = page.mainFrame(); page.on(Page.Events.Close, () => { this._signalProcessor.addAction({ - frame: this._describeMainFrame(page), + pageGuid: page.guid, action: { name: 'closePage', signals: [], }, startTime: monotonicTime() }); - this._pageAliases.delete(page); this._filePrimaryURLChanged(); }); frame.on(Frame.Events.InternalNavigation, event => { @@ -516,15 +512,12 @@ export class Recorder extends EventEmitter implements Instrume } }); page.on(Page.Events.Download, () => this._onDownload(page)); - const suffix = this._pageAliases.size ? String(++this._lastPopupOrdinal) : ''; - const pageAlias = 'page' + suffix; - this._pageAliases.set(page, pageAlias); if (page.opener()) { this._onPopup(page.opener()!, page); } else { this._signalProcessor.addAction({ - frame: this._describeMainFrame(page), + pageGuid: page.guid, action: { name: 'openPage', url: page.mainFrame().url(), @@ -548,13 +541,6 @@ export class Recorder extends EventEmitter implements Instrume } } - private _describeMainFrame(page: Page): actions.FrameDescription { - return { - pageGuid: page.guid, - pageAlias: this._pageAliases.get(page)!, - }; - } - private _testIdAttributeName(): string { return this._params.testIdAttributeName || this._context.selectors().testIdAttributeName() || 'data-testid'; } @@ -563,7 +549,7 @@ export class Recorder extends EventEmitter implements Instrume if (framePath.length && 'selector' in action) action.selector = buildFullSelector(framePath, action.selector); const actionInContext: actions.ActionInContext = { - frame: this._describeMainFrame(frame._page), + pageGuid: frame._page.guid, action, startTime: monotonicTime(), }; @@ -573,12 +559,12 @@ export class Recorder extends EventEmitter implements Instrume private async _performAction(progress: Progress, frame: Frame, action: actions.PerformOnRecordAction, preconditionSelector?: string) { const framePath = await generateFrameSelector(progress, frame); if (preconditionSelector) - this._signalProcessor.signal(this._pageAliases.get(frame._page)!, frame, { name: 'expect', selector: buildFullSelector(framePath, preconditionSelector) }); + this._signalProcessor.signal(frame, { name: 'expect', selector: buildFullSelector(framePath, preconditionSelector) }); const actionInContext = this._appendContextToAction(frame, action, framePath); this._signalProcessor.addAction(actionInContext); try { if (actionInContext.action.name !== 'openPage' && actionInContext.action.name !== 'closePage') - await performAction(progress, this._pageAliases, actionInContext); + await performAction(progress, frame._page.mainFrame(), actionInContext); } finally { actionInContext.endTime = monotonicTime(); } @@ -591,26 +577,21 @@ export class Recorder extends EventEmitter implements Instrume } private _onFrameNavigated(frame: Frame, page: Page) { - const pageAlias = this._pageAliases.get(page); - this._signalProcessor.signal(pageAlias!, frame, { name: 'navigation', url: frame.url() }); + this._signalProcessor.signal(frame, { name: 'navigation', url: frame.url() }); } private _onPopup(page: Page, popup: Page) { - const pageAlias = this._pageAliases.get(page)!; - const popupAlias = this._pageAliases.get(popup)!; - this._signalProcessor.signal(pageAlias, page.mainFrame(), { name: 'popup', popupAlias }); + this._signalProcessor.signal(page.mainFrame(), { name: 'popup', popupPageGuid: popup.guid }); } private _onDownload(page: Page) { - const pageAlias = this._pageAliases.get(page)!; ++this._lastDownloadOrdinal; - this._signalProcessor.signal(pageAlias, page.mainFrame(), { name: 'download', downloadAlias: this._lastDownloadOrdinal ? String(this._lastDownloadOrdinal) : '' }); + this._signalProcessor.signal(page.mainFrame(), { name: 'download', downloadAlias: this._lastDownloadOrdinal ? String(this._lastDownloadOrdinal) : '' }); } private _onDialog(page: Page) { - const pageAlias = this._pageAliases.get(page)!; ++this._lastDialogOrdinal; - this._signalProcessor.signal(pageAlias, page.mainFrame(), { name: 'dialog', dialogAlias: this._lastDialogOrdinal ? String(this._lastDialogOrdinal) : '' }); + this._signalProcessor.signal(page.mainFrame(), { name: 'dialog', dialogAlias: this._lastDialogOrdinal ? String(this._lastDialogOrdinal) : '' }); } } diff --git a/packages/playwright-core/src/server/recorder/recorderApp.ts b/packages/playwright-core/src/server/recorder/recorderApp.ts index 09d5619478854..e61603a964c64 100644 --- a/packages/playwright-core/src/server/recorder/recorderApp.ts +++ b/packages/playwright-core/src/server/recorder/recorderApp.ts @@ -288,7 +288,7 @@ export class RecorderApp { } private _onSignalAdded(signal: actions.SignalInContext) { - const lastAction = this._actions.findLast(a => a.frame.pageGuid === signal.frame.pageGuid); + const lastAction = this._actions.findLast(a => a.pageGuid === signal.pageGuid); if (lastAction) lastAction.action.signals.push(signal.signal); this._updateActions(); @@ -370,18 +370,18 @@ export class ProgrammaticRecorderApp { const languageGenerator = languages.find(l => l.id === params.language) ?? languages.find(l => l.id === 'playwright-test')!; recorder.on(RecorderEvent.ActionAdded, action => { - const page = findPageByGuid(inspectedContext, action.frame.pageGuid); + const page = findPageByGuid(inspectedContext, action.pageGuid); if (!page) return; - const { actionTexts } = generateCode([action], languageGenerator, languageGeneratorOptions); + const code = languageGenerator.generateAction(action, languageGeneratorOptions); if (!lastAction || !shouldMergeAction(action, lastAction)) - inspectedContext.emit(BrowserContext.Events.RecorderEvent, { event: 'actionAdded', data: action, page, code: actionTexts.join('\n') }); + inspectedContext.emit(BrowserContext.Events.RecorderEvent, { event: 'actionAdded', data: action, page, code }); else - inspectedContext.emit(BrowserContext.Events.RecorderEvent, { event: 'actionUpdated', data: action, page, code: actionTexts.join('\n') }); + inspectedContext.emit(BrowserContext.Events.RecorderEvent, { event: 'actionUpdated', data: action, page, code }); lastAction = action; }); recorder.on(RecorderEvent.SignalAdded, signal => { - const page = findPageByGuid(inspectedContext, signal.frame.pageGuid); + const page = findPageByGuid(inspectedContext, signal.pageGuid); if (!page) return; inspectedContext.emit(BrowserContext.Events.RecorderEvent, { event: 'signalAdded', data: signal, page, code: '' }); diff --git a/packages/playwright-core/src/server/recorder/recorderRunner.ts b/packages/playwright-core/src/server/recorder/recorderRunner.ts index aef46f7b3b344..6b2e92dee9e4f 100644 --- a/packages/playwright-core/src/server/recorder/recorderRunner.ts +++ b/packages/playwright-core/src/server/recorder/recorderRunner.ts @@ -15,20 +15,13 @@ */ import { toKeyboardModifiers } from '@isomorphic/codegen/language'; -import { mainFrameForAction } from './recorderUtils'; import { Progress } from '../progress'; -import type { Page } from '../page'; import type * as types from '../types'; import type * as actions from '@isomorphic/codegen/actions'; import type { Frame } from '../frames'; -export async function performAction(progress: Progress, pageAliases: Map, actionInContext: actions.ActionInContext) { - const mainFrame = mainFrameForAction(pageAliases, actionInContext); - return await performActionImpl(progress, mainFrame, actionInContext); -} - -async function performActionImpl(progress: Progress, mainFrame: Frame, actionInContext: actions.ActionInContext) { +export async function performAction(progress: Progress, mainFrame: Frame, actionInContext: actions.ActionInContext) { const { action } = actionInContext; if (action.name === 'navigate') { diff --git a/packages/playwright-core/src/server/recorder/recorderSignalProcessor.ts b/packages/playwright-core/src/server/recorder/recorderSignalProcessor.ts index 7a0f714a84cdb..fb510fe657f26 100644 --- a/packages/playwright-core/src/server/recorder/recorderSignalProcessor.ts +++ b/packages/playwright-core/src/server/recorder/recorderSignalProcessor.ts @@ -39,7 +39,7 @@ export class RecorderSignalProcessor { this._delegate.addAction(actionInContext); } - signal(pageAlias: string, frame: Frame, signal: Signal) { + signal(frame: Frame, signal: Signal) { const timestamp = monotonicTime(); if (signal.name === 'navigation' && frame._page.mainFrame() === frame) { const lastAction = this._lastAction; @@ -55,10 +55,7 @@ export class RecorderSignalProcessor { if (generateGoto) { this.addAction({ - frame: { - pageGuid: frame._page.guid, - pageAlias, - }, + pageGuid: frame._page.guid, action: { name: 'navigate', url: frame.url(), @@ -72,10 +69,7 @@ export class RecorderSignalProcessor { } this._delegate.addSignal({ - frame: { - pageGuid: frame._page.guid, - pageAlias, - }, + pageGuid: frame._page.guid, signal, timestamp, }); diff --git a/packages/playwright-core/src/server/recorder/recorderUtils.ts b/packages/playwright-core/src/server/recorder/recorderUtils.ts index 99f4959662215..fd66b37da8c9e 100644 --- a/packages/playwright-core/src/server/recorder/recorderUtils.ts +++ b/packages/playwright-core/src/server/recorder/recorderUtils.ts @@ -21,7 +21,6 @@ import { quoteCSSAttributeValue } from '@isomorphic/stringUtils'; import { Frame } from '../frames'; import type { CallMetadata } from '../instrumentation'; -import type { Page } from '../page'; import type * as actions from '@isomorphic/codegen/actions'; import type { CallLog, CallLogStatus } from '@recorder/recorderTypes'; import type { Progress } from '../progress'; @@ -55,16 +54,8 @@ export function metadataToCallLog(metadata: CallMetadata, status: CallLogStatus) return callLog; } -export function mainFrameForAction(pageAliases: Map, actionInContext: actions.ActionInContext): Frame { - const pageAlias = actionInContext.frame.pageAlias; - const page = [...pageAliases.entries()].find(([, alias]) => pageAlias === alias)?.[0]; - if (!page) - throw new Error(`Internal error: page ${pageAlias} not found in [${[...pageAliases.values()]}]`); - return page.mainFrame(); -} - function isSameAction(a: actions.ActionInContext, b: actions.ActionInContext): boolean { - return a.action.name === b.action.name && a.frame.pageAlias === b.frame.pageAlias; + return a.action.name === b.action.name && a.pageGuid === b.pageGuid; } function isSameSelector(action: actions.ActionInContext, lastAction: actions.ActionInContext): boolean { diff --git a/tests/library/inspector/cli-codegen-3.spec.ts b/tests/library/inspector/cli-codegen-3.spec.ts index 342a895417cba..e6851934698e0 100644 --- a/tests/library/inspector/cli-codegen-3.spec.ts +++ b/tests/library/inspector/cli-codegen-3.spec.ts @@ -61,7 +61,6 @@ await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).First.ClickAsyn locator: { body: 'button', kind: 'role', options: { exact: false, attrs: [], name: 'Submit' }, next: { body: '', kind: 'first', options: {} } }, modifiers: 0, signals: [], - pageAlias: 'page', pageGuid: expect.any(String), }); @@ -142,7 +141,6 @@ await page.Locator("#frame1").ContentFrame.GetByText("Hello1").ClickAsync();`); }, modifiers: 0, signals: [], - pageAlias: 'page', pageGuid: expect.any(String), }); }); @@ -192,7 +190,6 @@ await page.Locator("#frame1").ContentFrame.Locator("iframe").ContentFrame.GetByT }, modifiers: 0, signals: [], - pageAlias: 'page', pageGuid: expect.any(String), }); }); @@ -251,7 +248,6 @@ await page.Locator("#frame1").ContentFrame.Locator("iframe").ContentFrame.Locato }, modifiers: 0, signals: [], - pageAlias: 'page', pageGuid: expect.any(String), }); });