From fc8aa99dca117c5a1db6b5a025e160063d1108c1 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 7 Nov 2024 12:19:03 -0800 Subject: [PATCH] fix: update codegen to generate correct actions (#971) --- .../__snapshots__/javascript.test.ts.snap | 12 +- __tests__/formatter/javascript.test.ts | 119 ++++++------------ src/formatter/javascript.ts | 64 ++-------- 3 files changed, 52 insertions(+), 143 deletions(-) diff --git a/__tests__/formatter/__snapshots__/javascript.test.ts.snap b/__tests__/formatter/__snapshots__/javascript.test.ts.snap index 57294cff..4fb0c4ae 100644 --- a/__tests__/formatter/__snapshots__/javascript.test.ts.snap +++ b/__tests__/formatter/__snapshots__/javascript.test.ts.snap @@ -52,9 +52,7 @@ step('Go to https://vigneshh.in/', async () => { const page1Promise = page.waitForEvent('popup'); await page.locator('text=Tailor').click(); page1 = await page1Promise; - await page1.frame({ - url: 'https://github.com/zalando/tailor' - }).locator('text=Packages 0').click(); + await page1.locator('text=Packages 0').click(); }); step('Close page', async () => { await page1.close(); @@ -63,9 +61,7 @@ step('Close page', async () => { page2 = await page2Promise; }); step('Close page', async () => { - await page2.frame({ - url: 'https://github.com/babel/minify' - }).close(); + await page2.close(); });" `; @@ -89,9 +85,7 @@ step('Click text=Babel Minify', async () => { await page2.locator(':nth-match(a:has-text("babel-minify"), 3)').click(); }); step('Close page', async () => { - await page2.frame({ - url: 'https://github.com/topics/babel-minify' - }).close(); + await page2.close(); });" `; diff --git a/__tests__/formatter/javascript.test.ts b/__tests__/formatter/javascript.test.ts index e8ca5d16..fdbdc9e5 100644 --- a/__tests__/formatter/javascript.test.ts +++ b/__tests__/formatter/javascript.test.ts @@ -31,7 +31,7 @@ import { const recorderStep: Step = { actions: [ { - frame: { pageAlias: 'page', isMainFrame: true, url: 'about:blank' }, + frame: { pageAlias: 'page', "framePath": [] }, committed: true, action: { name: 'openPage', @@ -42,8 +42,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + "framePath": [], }, committed: true, action: { @@ -55,8 +54,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'assert', @@ -69,8 +67,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'assert', @@ -83,8 +80,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'assert', @@ -98,8 +94,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -120,8 +115,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/babel/minify', + framePath: [], }, action: { name: 'click', @@ -154,8 +148,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/babel/minify', + framePath: [], }, committed: true, action: { @@ -166,8 +159,7 @@ const recorderStep: Step = { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, committed: true, action: { @@ -219,8 +211,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, committed: true, action: { @@ -233,8 +224,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -263,8 +253,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/zalando/tailor', + framePath: [], }, action: { name: 'click', @@ -297,8 +286,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/packages?repo_name=tailor', + framePath: [], }, action: { name: 'click', @@ -327,8 +315,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/repositories', + framePath: [], }, action: { name: 'click', @@ -344,8 +331,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/repositories', + framePath: [], }, action: { name: 'fill', @@ -364,8 +350,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/repositories?q=tailor&type=all&language=&sort=', + framePath: [], }, action: { name: 'click', @@ -398,8 +383,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -428,8 +412,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page2', - isMainFrame: true, - url: 'https://github.com/babel/minify', + framePath: [], }, action: { name: 'click', @@ -470,8 +453,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page2', - isMainFrame: true, - url: 'https://github.com/topics/babel-minify', + framePath: [], }, committed: true, action: { @@ -487,8 +469,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/zalando/tailor', + framePath: [], }, committed: true, action: { @@ -511,8 +492,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, committed: true, action: { @@ -525,8 +505,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -555,8 +534,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/zalando/tailor', + framePath: [], }, action: { name: 'click', @@ -585,8 +563,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/packages?repo_name=tailor', + framePath: [], }, action: { name: 'click', @@ -615,8 +592,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -645,8 +621,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page2', - isMainFrame: true, - url: 'https://github.com/babel/minify', + framePath: [], }, action: { name: 'click', @@ -683,8 +658,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page2', - isMainFrame: true, - url: 'https://github.com/topics/babel-minify', + framePath: [], }, committed: true, action: { @@ -696,8 +670,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/zalando', + framePath: [], }, committed: true, action: { @@ -720,8 +693,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'navigate', @@ -732,8 +704,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -748,7 +719,7 @@ describe('Synthetics JavaScript formatter', () => { }, { frame: { - url: 'https://github.com/zalando/tailor', + framePath: [], pageAlias: 'page1', }, action: { @@ -772,8 +743,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - url: 'https://github.com/orgs/zalando/packages?repo_name=tailor', - isMainFrame: true, + framePath: [], }, action: { name: 'closePage', signals: [] }, }, @@ -781,8 +751,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -801,7 +770,7 @@ describe('Synthetics JavaScript formatter', () => { actions: [ { frame: { - url: 'https://github.com/babel/minify', + framePath: [], pageAlias: 'page2', }, action: { name: 'closePage', signals: [] }, @@ -820,8 +789,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'navigate', @@ -832,8 +800,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -849,8 +816,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/zalando/tailor', + framePath: [], }, action: { name: 'click', @@ -873,8 +839,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page1', - isMainFrame: true, - url: 'https://github.com/orgs/zalando/packages?repo_name=tailor', + framePath: [], }, action: { name: 'closePage', signals: [] }, }, @@ -885,8 +850,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page', - isMainFrame: true, - url: 'https://vigneshh.in/', + framePath: [], }, action: { name: 'click', @@ -902,8 +866,7 @@ describe('Synthetics JavaScript formatter', () => { { frame: { pageAlias: 'page2', - isMainFrame: true, - url: 'https://github.com/babel/minify', + framePath: [], }, action: { name: 'click', @@ -925,7 +888,7 @@ describe('Synthetics JavaScript formatter', () => { actions: [ { frame: { - url: 'https://github.com/topics/babel-minify', + framePath: [], pageAlias: 'page2', }, action: { name: 'closePage', signals: [] }, diff --git a/src/formatter/javascript.ts b/src/formatter/javascript.ts index 6a9d8bf5..49962e86 100644 --- a/src/formatter/javascript.ts +++ b/src/formatter/javascript.ts @@ -37,14 +37,10 @@ export type Steps = Step[]; // from playwright-core export type FrameDescription = { pageAlias: string; - isMainFrame?: boolean; - url: string; - name?: string; - selectorsChain?: string[]; + framePath: string[]; }; export type ActionInContext = { - frameName?: string; action: Action; committed?: boolean; modified?: boolean; @@ -52,6 +48,9 @@ export type ActionInContext = { frame: FrameDescription; isOpen?: boolean; isSoftDeleted?: boolean; + description?: string; + startTime?: number; + endTime?: number; }; export type Action = { @@ -127,34 +126,6 @@ export function quote(text: string, char = "'"): string { throw new Error('Invalid escape char'); } -type Formattable = string | string[] | Record; - -function isFormattable(value: unknown): value is Formattable { - return ( - typeof value === 'string' || - (Array.isArray(value) && value.every(v => typeof v === 'string')) || - typeof value === 'object' - ); -} - -function formatObject(value: Formattable, indent = ' '): string { - if (typeof value === 'string') return quote(value); - if (Array.isArray(value)) - return `[${value.map(o => formatObject(o)).join(', ')}]`; - if (typeof value === 'object') { - const keys = Object.keys(value); - if (!keys.length) return '{}'; - const tokens: string[] = []; - for (const key of keys) { - const child = value[key]; - if (child === undefined || !isFormattable(child)) continue; - tokens.push(`${key}: ${formatObject(child)}`); - } - return `{\n${indent}${tokens.join(`,\n${indent}`)}\n}`; - } - return String(value); -} - /** * Generates an appropriate title string based on the action type/data. * @param action Playwright action IR @@ -228,27 +199,8 @@ export class SyntheticsGenerator extends JavaScriptLanguageGenerator { const offset = this.isProject ? 2 + stepIndent : 0 + stepIndent; const formatter = new JavaScriptFormatter(offset); - let subject: string; - if (actionInContext.frame.isMainFrame) { - subject = pageAlias; - } else if ( - actionInContext.frame.selectorsChain && - action.name !== 'navigate' - ) { - const locators = actionInContext.frame.selectorsChain.map( - selector => `.frameLocator(${quote(selector)})` - ); - subject = `${pageAlias}${locators.join('')}`; - } else if (actionInContext.frame.name) { - subject = `${pageAlias}.frame(${formatObject({ - name: actionInContext.frame.name, - })})`; - } else { - subject = `${pageAlias}.frame(${formatObject({ - url: actionInContext.frame.url, - })})`; - } - + const locators = actionInContext.frame.framePath.map(selector => `.${super._asLocator(selector)}.contentFrame()`); + const subject = `${pageAlias}${locators.join('')}`; const signals = toSignalMap(action); if (signals.dialog) { @@ -289,12 +241,12 @@ export class SyntheticsGenerator extends JavaScriptLanguageGenerator { } isNewStep(actioninContext: ActionInContext) { - const { action, frame } = actioninContext; + const { action } = actioninContext; if (action.name === 'navigate') { return true; } else if (action.name === 'click') { return ( - this.previousContext?.frame.url === frame.url && + this.previousContext?.action.url === action.url && action.signals.length > 0 ); }