diff --git a/packages/playwright-core/src/server/recorder.ts b/packages/playwright-core/src/server/recorder.ts index 136df7a946..b854ae3c38 100644 --- a/packages/playwright-core/src/server/recorder.ts +++ b/packages/playwright-core/src/server/recorder.ts @@ -340,8 +340,8 @@ class ContextRecorder extends EventEmitter { private _generator: CodeGenerator; private _pageAliases = new Map(); private _lastPopupOrdinal = 0; - private _lastDialogOrdinal = 0; - private _lastDownloadOrdinal = 0; + private _lastDialogOrdinal = -1; + private _lastDownloadOrdinal = -1; private _timers = new Set(); private _context: BrowserContext; private _params: channels.BrowserContextRecorderSupplementEnableParams; @@ -647,12 +647,14 @@ class ContextRecorder extends EventEmitter { private _onDownload(page: Page) { const pageAlias = this._pageAliases.get(page)!; - this._generator.signal(pageAlias, page.mainFrame(), { name: 'download', downloadAlias: String(++this._lastDownloadOrdinal) }); + ++this._lastDownloadOrdinal; + this._generator.signal(pageAlias, page.mainFrame(), { name: 'download', downloadAlias: this._lastDownloadOrdinal ? String(this._lastDownloadOrdinal) : '' }); } private _onDialog(page: Page) { const pageAlias = this._pageAliases.get(page)!; - this._generator.signal(pageAlias, page.mainFrame(), { name: 'dialog', dialogAlias: String(++this._lastDialogOrdinal) }); + ++this._lastDialogOrdinal; + this._generator.signal(pageAlias, page.mainFrame(), { name: 'dialog', dialogAlias: this._lastDialogOrdinal ? String(this._lastDialogOrdinal) : '' }); } } diff --git a/packages/playwright-core/src/server/recorder/java.ts b/packages/playwright-core/src/server/recorder/java.ts index a935b1fa58..c6394611f1 100644 --- a/packages/playwright-core/src/server/recorder/java.ts +++ b/packages/playwright-core/src/server/recorder/java.ts @@ -77,7 +77,7 @@ export class JavaLanguageGenerator implements LanguageGenerator { } if (signals.download) { - code = `Download download = ${pageAlias}.waitForDownload(() -> { + code = `Download download${signals.download.downloadAlias} = ${pageAlias}.waitForDownload(() -> { ${code} });`; } diff --git a/packages/playwright-core/src/server/recorder/javascript.ts b/packages/playwright-core/src/server/recorder/javascript.ts index 31d21c86ce..719f6a17bd 100644 --- a/packages/playwright-core/src/server/recorder/javascript.ts +++ b/packages/playwright-core/src/server/recorder/javascript.ts @@ -74,33 +74,18 @@ export class JavaScriptLanguageGenerator implements LanguageGenerator { });`); } - const emitPromiseAll = signals.popup || signals.download; - if (emitPromiseAll) { - // Generate either await Promise.all([]) or - // const [popup1] = await Promise.all([]). - let leftHandSide = ''; - if (signals.popup) - leftHandSide = `const [${signals.popup.popupAlias}] = `; - else if (signals.download) - leftHandSide = `const [download] = `; - formatter.add(`${leftHandSide}await Promise.all([`); - } - - // Popup signals. if (signals.popup) - formatter.add(`${pageAlias}.waitForEvent('popup'),`); - - // Download signals. + formatter.add(`const ${signals.popup.popupAlias}Promise = ${pageAlias}.waitForEvent('popup');`); if (signals.download) - formatter.add(`${pageAlias}.waitForEvent('download'),`); + formatter.add(`const download${signals.download.downloadAlias}Promise = ${pageAlias}.waitForEvent('download');`); - const prefix = (signals.popup || signals.download) ? '' : 'await '; const actionCall = this._generateActionCall(action); - const suffix = emitPromiseAll ? '' : ';'; - formatter.add(`${prefix}${subject}.${actionCall}${suffix}`); + formatter.add(`await ${subject}.${actionCall};`); - if (emitPromiseAll) - formatter.add(`]);`); + if (signals.popup) + formatter.add(`const ${signals.popup.popupAlias} = await ${signals.popup.popupAlias}Promise;`); + if (signals.download) + formatter.add(`const download${signals.download.downloadAlias} = await download${signals.download.downloadAlias}Promise;`); return formatter.format(); } diff --git a/packages/playwright-core/src/server/recorder/python.ts b/packages/playwright-core/src/server/recorder/python.ts index 302c7acec7..a0cb10702c 100644 --- a/packages/playwright-core/src/server/recorder/python.ts +++ b/packages/playwright-core/src/server/recorder/python.ts @@ -81,17 +81,17 @@ export class PythonLanguageGenerator implements LanguageGenerator { let code = `${this._awaitPrefix}${subject}.${actionCall}`; if (signals.popup) { - code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as popup_info { + code = `${this._asyncPrefix}with ${pageAlias}.expect_popup() as ${signals.popup.popupAlias}_info { ${code} } - ${signals.popup.popupAlias} = ${this._awaitPrefix}popup_info.value`; + ${signals.popup.popupAlias} = ${this._awaitPrefix}${signals.popup.popupAlias}_info.value`; } if (signals.download) { - code = `${this._asyncPrefix}with ${pageAlias}.expect_download() as download_info { + code = `${this._asyncPrefix}with ${pageAlias}.expect_download() as download${signals.download.downloadAlias}_info { ${code} } - download = ${this._awaitPrefix}download_info.value`; + download${signals.download.downloadAlias} = ${this._awaitPrefix}download${signals.download.downloadAlias}_info.value`; } formatter.add(code); diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts index 596f6108da..2c7a7d7668 100644 --- a/tests/library/inspector/cli-codegen-1.spec.ts +++ b/tests/library/inspector/cli-codegen-1.spec.ts @@ -624,10 +624,9 @@ test.describe('cli codegen', () => { ]); expect.soft(sources.get('JavaScript').text).toContain(` - const [page1] = await Promise.all([ - page.waitForEvent('popup'), - page.getByRole('link', { name: 'link' }).click() - ]);`); + const page1Promise = page.waitForEvent('popup'); + await page.getByRole('link', { name: 'link' }).click(); + const page1 = await page1Promise;`); expect.soft(sources.get('Java').text).toContain(` Page page1 = page.waitForPopup(() -> { @@ -635,14 +634,14 @@ test.describe('cli codegen', () => { });`); expect.soft(sources.get('Python').text).toContain(` - with page.expect_popup() as popup_info: + with page.expect_popup() as page1_info: page.get_by_role("link", name="link").click() - page1 = popup_info.value`); + page1 = page1_info.value`); expect.soft(sources.get('Python Async').text).toContain(` - async with page.expect_popup() as popup_info: + async with page.expect_popup() as page1_info: await page.get_by_role("link", name="link").click() - page1 = await popup_info.value`); + page1 = await page1_info.value`); expect.soft(sources.get('C#').text).toContain(` var page1 = await page.RunAndWaitForPopupAsync(async () => diff --git a/tests/library/inspector/cli-codegen-2.spec.ts b/tests/library/inspector/cli-codegen-2.spec.ts index 7bc69317da..6af03e2750 100644 --- a/tests/library/inspector/cli-codegen-2.spec.ts +++ b/tests/library/inspector/cli-codegen-2.spec.ts @@ -222,39 +222,53 @@ test.describe('cli codegen', () => { page.waitForEvent('download'), page.click('a') ]); - const sources = await recorder.waitForOutput('JavaScript', 'waitForEvent'); + await Promise.all([ + page.waitForEvent('download'), + page.click('a') + ]); + const sources = await recorder.waitForOutput('JavaScript', 'download1Promise'); expect.soft(sources.get('JavaScript').text).toContain(` - const context = await browser.newContext();`); + const downloadPromise = page.waitForEvent('download'); + await page.getByRole('link', { name: 'Download' }).click(); + const download = await downloadPromise;`); expect.soft(sources.get('JavaScript').text).toContain(` - const [download] = await Promise.all([ - page.waitForEvent('download'), - page.getByRole('link', { name: 'Download' }).click() - ]);`); + const download1Promise = page.waitForEvent('download'); + await page.getByRole('link', { name: 'Download' }).click(); + const download1 = await download1Promise;`); - expect.soft(sources.get('Java').text).toContain(` - BrowserContext context = browser.newContext();`); expect.soft(sources.get('Java').text).toContain(` Download download = page.waitForDownload(() -> { page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("Download")).click(); });`); + expect.soft(sources.get('Java').text).toContain(` + Download download1 = page.waitForDownload(() -> { + page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("Download")).click(); + });`); - expect.soft(sources.get('Python').text).toContain(` - context = browser.new_context()`); expect.soft(sources.get('Python').text).toContain(` with page.expect_download() as download_info: page.get_by_role("link", name="Download").click() download = download_info.value`); + expect.soft(sources.get('Python').text).toContain(` + with page.expect_download() as download1_info: + page.get_by_role("link", name="Download").click() + download1 = download1_info.value`); - expect.soft(sources.get('Python Async').text).toContain(` - context = await browser.new_context()`); expect.soft(sources.get('Python Async').text).toContain(` async with page.expect_download() as download_info: await page.get_by_role("link", name="Download").click() download = await download_info.value`); + expect.soft(sources.get('Python Async').text).toContain(` + async with page.expect_download() as download1_info: + await page.get_by_role("link", name="Download").click() + download1 = await download1_info.value`); expect.soft(sources.get('C#').text).toContain(` - var context = await browser.NewContextAsync();`); + var download = await page.RunAndWaitForDownloadAsync(async () => + { + await page.GetByRole(AriaRole.Link, new() { Name = "Download" }).ClickAsync(); + });`); expect.soft(sources.get('C#').text).toContain(` var download1 = await page.RunAndWaitForDownloadAsync(async () => { @@ -299,13 +313,13 @@ test.describe('cli codegen', () => { await page.get_by_role("button", name="click me").click()`); expect.soft(sources.get('C#').text).toContain(` - void page_Dialog1_EventHandler(object sender, IDialog dialog) + void page_Dialog_EventHandler(object sender, IDialog dialog) { Console.WriteLine($\"Dialog message: {dialog.Message}\"); dialog.DismissAsync(); - page.Dialog -= page_Dialog1_EventHandler; + page.Dialog -= page_Dialog_EventHandler; } - page.Dialog += page_Dialog1_EventHandler; + page.Dialog += page_Dialog_EventHandler; await page.GetByRole(AriaRole.Button, new() { Name = "click me" }).ClickAsync();`); }); @@ -348,12 +362,11 @@ test.describe('cli codegen', () => { await page1.GotoAsync("about:blank?foo");`); } else { expect(sources.get('JavaScript').text).toContain(` - const [page1] = await Promise.all([ - page.waitForEvent('popup'), - page.getByRole('link', { name: 'link' }).click({ - modifiers: ['${platform === 'darwin' ? 'Meta' : 'Control'}'] - }) - ]);`); + const page1Promise = page.waitForEvent('popup'); + await page.getByRole('link', { name: 'link' }).click({ + modifiers: ['${platform === 'darwin' ? 'Meta' : 'Control'}'] + }); + const page1 = await page1Promise;`); } });