diff --git a/src/build-code/buildStepLines.ts b/src/build-code/buildStepLines.ts index f2a131147..11884b27a 100644 --- a/src/build-code/buildStepLines.ts +++ b/src/build-code/buildStepLines.ts @@ -4,6 +4,7 @@ import { isUndefined } from 'util'; export type StepLineBuildContext = { initializedFrames: Map; initializedPages: Set; + visiblePage: number; }; /** @@ -59,7 +60,8 @@ export const buildStepLines = ( step: Step, buildContext: StepLineBuildContext = { initializedFrames: new Map(), - initializedPages: new Set(), + initializedPages: new Set([0]), + visiblePage: 0, }, ): string[] => { const lines: string[] = []; @@ -67,14 +69,27 @@ export const buildStepLines = ( const { frameIndex, frameSelector, page } = step.event; const { initializedFrames, initializedPages } = buildContext; + // The page variable is the word "page" followed by 1-based index, but just "page" for first page. const pageVariableName = getStepPageVariableName(step); - if (page > 0 && !initializedPages.has(page)) { + + // If we haven't done anything on this page yet, add a `qawolf.waitForPage` call. + // Otherwise, if we were doing steps on a different page and have now switched back + // to this one, add a `bringToFront` call. Otherwise no extra page-waiting line is needed. + if (!initializedPages.has(page)) { lines.push( `const ${pageVariableName} = await qawolf.waitForPage(page.context(), ${page});`, ); initializedPages.add(page); + buildContext.visiblePage = page; + } else if (buildContext.visiblePage !== page) { + lines.push( + `await ${pageVariableName}.bringToFront();`, + ); + buildContext.visiblePage = page; } + // If the step occurred within an iframe on the page, use the frame variable as the + // context for the step. If this is the first use of this frame variable, create it first. let frameVariableName: string; if (frameSelector) { frameVariableName = initializedFrames.get(frameIndex + frameSelector); @@ -91,6 +106,7 @@ export const buildStepLines = ( } } + // Now add the line for what the user actually did (click, scroll, fill, etc.) lines.push(buildExpressionLine(step, frameVariableName)); return lines; diff --git a/src/build-code/buildVirtualCode.ts b/src/build-code/buildVirtualCode.ts index b66b62d32..97d5e0a3d 100644 --- a/src/build-code/buildVirtualCode.ts +++ b/src/build-code/buildVirtualCode.ts @@ -7,7 +7,9 @@ export const buildVirtualCode = (steps: Step[]): VirtualCode => { const buildContext: StepLineBuildContext = { initializedFrames: new Map(), - initializedPages: new Set(), + // page 0 is initialized and brought to front in "before" + initializedPages: new Set([0]), + visiblePage: 0, }; steps.forEach((step) => { diff --git a/test/build-code/buildStepLines.test.ts b/test/build-code/buildStepLines.test.ts index 9408138cf..4227e79bd 100644 --- a/test/build-code/buildStepLines.test.ts +++ b/test/build-code/buildStepLines.test.ts @@ -25,7 +25,7 @@ describe('escapeSelector', () => { }); describe('buildStepLines', () => { - test('consecutive steps on different pages', () => { + test('step on new page, after step on a different page', () => { const lines = buildStepLines({ ...baseStep, event: { @@ -43,6 +43,31 @@ describe('buildStepLines', () => { `); }); + test('step on existing page, after step on a different page', () => { + const lines = buildStepLines( + { + ...baseStep, + event: { + ...baseStep.event, + page: 1, + }, + index: 1, + }, + { + initializedFrames: new Map(), + initializedPages: new Set([0, 1]), + visiblePage: 0, + }, + ); + + expect(lines).toMatchInlineSnapshot(` + Array [ + "await page2.bringToFront();", + "await page2.click('[data-qa=\\"test-input\\"]');", + ] + `); + }); + test('iframe step', () => { const lines = buildStepLines({ ...baseStep, @@ -78,7 +103,8 @@ describe('buildStepLines', () => { }, { initializedFrames, - initializedPages: new Set(), + initializedPages: new Set([0]), + visiblePage: 0, }, ); @@ -105,7 +131,8 @@ describe('buildStepLines', () => { }, { initializedFrames, - initializedPages: new Set(), + initializedPages: new Set([0]), + visiblePage: 0, }, );