How to open the new tab using Playwright (ex. click the button to open the new section in a new tab)
Asked Answered
H

6

14

I am looking for a simpler solution to a current situation. For example, you open the google (any another website) and you want BY CLICK on the button (ex. Gmail) - open this page in the new tab using Playwright.

let browser, page, context;
describe('Check the main page view', function () {
    before(async () => {
        for (const browserType of ['chromium']) {
            browser = await playwright[browserType].launch({headless: false});
            context = await browser.newContext();
            page = await context.newPage();
            await page.goto(baseUrl);
        }
    });
    after(async function () {
        browser.close();
    });
    
        await page.click(tax);
        const taxPage = await page.getAttribute(taxAccount, 'href');

        const [newPage] = await Promise.all([
        context.waitForEvent('page'),
        page.evaluate((taxPage) => window.open(taxPage, '_blank'), taxPage)]);

        await newPage.waitForLoadState();
        console.log(await newPage.title());
Haim answered 9/10, 2020 at 9:19 Comment(0)
H
13
it('Open a new tab', async function () {
     await page.click(button, { button: "middle" });
     await page.waitForTimeout(2000); //waitForNavigation and waitForLoadState do not work in this case
     let pages = await context.pages();
     expect(await pages[1].title()).equal('Title');
Haim answered 11/10, 2020 at 17:44 Comment(4)
This is a useful solution; I added an arbitrary 2000 ms to the waitForTimeoutCall so as to avoid confusion when that method is not passed any parameterThirtieth
where does context come from?Paulsen
There is some limitations in using this solution. For example, it relies on a fixed timeout to wait for the new tab to be created, which may not be reliable in all situations. Additionally, it does not verify that the new tab was actually opened by clicking the button, so it may not always be reliable.Shrivel
let context = await page.context();Objectivity
H
5

You could pass a modifier to the click function. In macos it would be Meta because you'd open in a new tab with cmd+click. In windows it would be Control.

const browser = await playwright["chromium"].launch({headless : false});
const page = await browser.newPage();
await page.goto('https://www.facebook.com/');
var pagePromise = page.context().waitForEvent('page', p => p.url() =='https://www.messenger.com/');
await page.click('text=Messenger', { modifiers: ['Meta']});
const newPage = await pagePromise;
await newPage.bringToFront();
await browser.close();
Humperdinck answered 9/10, 2020 at 11:42 Comment(0)
H
3

Waiting for new pages is mentioned in the playwright docs now, copied below:

// Start waiting for new page before clicking. Note no await.
const pagePromise = context.waitForEvent('page');
await page.getByText('open new tab').click();
const newPage = await pagePromise;
await newPage.waitForLoadState();
console.log(await newPage.title());
Hatfield answered 1/2, 2023 at 13:39 Comment(0)
C
1

In my case i am clicking on link in a pop up like (ctrl + click on link) then it opens new tab and work on that new tab

await page.click('#open')
const [newTab] = await Promise.all([
    page.waitForEvent('popup'),
    await page.keyboard.down('Control'),
    await page.frameLocator('//iframe[@title="New tab."]').locator('a').click(), // in popup
    await page.keyboard.up('Control'),
    console.log("clicked on link")
]);
await newTab.waitForFunction(()=>document.title === 'new tab title')
await newTab.fill('#firstname')
await newTab.close() // close the current tab
await page.click('#exitbutton') //back to parent tab and work on it
....
....
await page.close() // close the parent tab
Choral answered 16/11, 2022 at 5:8 Comment(0)
V
1
const pages = await this.page.context().pages();
return pages[1]; // Return an opened tab

If you want to switch to the old tab, you don't need to do anything, proceed to work with that old page object. However, if you want to switch to that tab to see what's going on there:

await oldTabPageObject.page.bringToFront();
Vivianaviviane answered 4/3, 2024 at 9:48 Comment(0)
V
1
  • Do not use await page.waitForTimeout(2000); this will cause tests to flaky over time.

You can use waitForEvent(page), from your BrowserContext instance right after triggering a click for a link or opening a page.

async loadNewPage() {
    const pagePromise = this.context.waitForEvent('page');
    const newPage = await pagePromise;
    await newPage.waitForLoadState();
    return newPage
  }
Vibrio answered 13/6, 2024 at 19:2 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.