Rayrun
← Back to Discord Forum

How to handle a popup log in page that might show something else after clicking log in

Hi all,

I would like some suggestions on how to handle the following scenario....

When we run our test suite, a page loads with a link that we click to authenticate. That click opens a popup page with the login username, password, and login button.

After entering the credentials and clicking 'Log in', the popup page will either close (in most cases) and the tests continue to execute, OR the popup will then ask the user to accept terms of service by clicking an 'Accept' button which becomes visible. After clicking 'Accept', the popup closes and the tests continue to execute.

I currently have no way of knowing when the popup will ask the user to 'Accept' before letting them continue.

I did try locator.or(locator) and check for either the Accept button being visible or something else on the main page before continue, but that only works with locators on the same page/frame.

Any thoughts appreciated.

This thread is trying to answer question "How to handle a popup login page that might show something else after clicking log in?"

8 replies

Hi you can use the or too something like this

await page.locator('yourloginbutton').or(page.locator('acceptterms)).click();

async function handleLoginPopup(page: Page) {
  // Wait for the login popup to appear.
  const loginPopup = await page.waitForEvent('popup');
  const acceptButton = await loginPopup.locator('');
  if (acceptButton) {
    await acceptButton.click();
    await loginPopup.waitForEvent('close');
  } else {
  }
}

await page.locator('').click();
await handleLoginPopup(page);

Hi @inf , thanks for your help. The .or wont work in this case. Well, it kind of will as it will certainly for the login button, but not for the Accept button because it can only be visible after login has been clicked.

The following appears to work, but I don't particularly like it....feels a bit hacky!

setup('authenticate', async ({ page, context }) => {
    await page.goto('../');

    const pagePromise = context.waitForEvent('page');
    await page.getByText('Authenticate').click();
    const newPage = await pagePromise;
    await newPage.waitForLoadState();

    await newPage.getByLabel(/Email address/).fill(process.env.USER_NAME as string);
    await newPage.getByText('Next').click();

    await newPage.getByLabel(/Password/).fill(process.env.USER_PASSWORD as string);
    await newPage.getByText('Sign In').click();

    // terms of service dialog might appear so try and handle it
    const acceptTermsOfService = newPage.getByRole('link', { name: 'Accept' });

    while (!newPage.isClosed()) {
        try {
            if (await acceptTermsOfService.isVisible()) {
                await acceptTermsOfService.click();
                await newPage.waitForEvent('close');
            }
        } catch (e) {
            if (!e.message.includes('Target closed')) {
                throw new Error(e);
            }
        }
    }
    await page.context().storageState({ path: authFile });
});

Maybe the terms of service checkbox shows after some API request you can check if some API request returns some value and use the value to click

Maybe you can check with page.waitForLoadState("networkidle"); for the request roundtrip without the while loop?

tphillips8117

"that only works with locators on the same page/frame." Does it?

tphillips8117

is the popup in a totally different page?

@tphillips8117 Yes.

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.