3

I have a beforeAll function that performs the login in the application I am testing in every test.describe. When I am in headless: false mode, everything works perfectly. This is the beforeAll and the login function:

//before alll function
test.beforeAll(async ({ browser }) => {
    page = await browser.newPage();
    await performAutomaticLogin(page);
});

//login function (necessary code for this question)
export const performAutomaticLogin = async (page: Page) => {
    await page.goto('/login');
    await page.click('text=Log in with Google account');
    await page.fill('id=identifierId', process.env.NEXT_PUBLIC_TEST_USER!);
    ...
};

However, when I swich to headless mode, I begin to have failures in this line:

await page.fill('id=identifierId', process.env.NEXT_PUBLIC_TEST_USER!);

page.fill: Target closed
=========================== logs ===========================
waiting for selector "id=identifierId"
============================================================

I have no idea why. I followed this GitHub thread but the configuration recommended there did not work for me. This is my configuration:

const config: PlaywrightTestConfig = {
    workers: 1,
    testDir: '../',
    use: {
        baseURL: 'http://localhost:3000',
    },
    timeout: 60000,
    projects: [
        {
            name: 'Chrome / Edge - FullHD',
            use: {
                browserName: 'chromium',
                headless: true,
                viewport: { width: 1920, height: 1080 },
                //these launch options came from github. I tried with and without them
                launchOptions: {
                    args: ['--no-sandbox', '--headless', '--disable-gpu'],
                },
            },
        },
    ],
    reporter: [['junit', { outputFile: 'test-results.xml' }]],
};
export default config;

Versions:

  • playwright/ @playwright/test: ^1.25.0
  • chromium version: 105.0.5195.19
Pelicer
  • 1,348
  • 4
  • 23
  • 54

3 Answers3

2

Just add 'headless=chrome' in launchOptions

use:{launchOptions: {args: ['--headless=chrome']}}
  • 2
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 26 '22 at 12:08
1

Google OAuth page is different when accessing it in headless mode. You can notice it by taking a screenshot of the page with page.screenshot() or by checking the page URL with page.url().

This is how I do it in my project:

async signIn(emailAddress, password) {
    // Make sure we are prompted to sign in with Google
    expect(this.page.url()).toMatch(new RegExp('https://accounts.google.com/(signin|o/oauth2|ServiceLogin)'))

    if (this.page.url().match(new RegExp('https://accounts.google.com/(signin|o/oauth2)'))) {
        // Email address
        await this.page.fill('input[type="email"]', emailAddress)
        await this.page.click('#identifierNext')

        // Password
        await this.page.fill('input[type="password"]', password)
        await this.page.click('#passwordNext')
    } else {
        /* Google uses legacy OAuth page when browser is in headless mode */

        // Fill email address
        await this.page.fill('//html/body/div/div[2]/div[2]/div[1]/form/div/div/div/div/div/input[1]', emailAddress)
        await this.page.click('//html/body/div/div[2]/div[2]/div[1]/form/div/div/input')

        // Fill password
        await this.page.fill('//html/body/div[1]/div[2]/div/div[2]/form/span/div/div[2]/input', password)
        await this.page.click('//html/body/div[1]/div[2]/div/div[2]/form/span/div/input[2]')
    }
}

It's not an efficient solution, but works for several months now.

neosploit
  • 26
  • 2
0

Use this:

await page.waitForSelector('id=yourId');
await page.fill('id=yourId', process.env.NEXT_PUBLIC_TEST_USER!);
rdx
  • 87
  • 3
  • 10