switch tabs in playwright test

35.5k Views Asked by At

I'm trying to switch between tabs using playwright tests but it's not taking control of windows element. Do we have any method similar to selenium driver.switchto().window() in playwright?

const { chromium } = require('playwright');
(async () => {
    const browser = await chromium.launch({ headless: false, args: ['--start-maximized'] });
    const context = await browser.newContext({ viewport: null });
    context.on("page", async newPage => {
        console.log("***newPage***", await newPage.title())
    })
    const page = await context.newPage()
    const navigationPromise = page.waitForNavigation()

    // dummy url
    await page.goto('https://www.myapp.com/')
    await navigationPromise

    // User login
    await page.waitForSelector('#username-in')
    await page.fill('#username-in', 'username')
    await page.fill('#password-in', 'password')
    await page.click('//button[contains(text(),"Sign In")]')
    await navigationPromise

    // User lands in application home page and clicks on link in dashboard 
    // link will open another application in new tab 
    await page.click('(//span[text()="launch-app-from-dashboard"])[2]')

    await navigationPromise
    await page.context()
    // Waiting for element to appear in new tab and click on ok button
    await page.waitForTimeout(6000)
    await page.waitForSelector('//bdi[text()="OK"]')
    await page.click('//bdi[text()="OK"]')

})()
4

There are 4 best solutions below

3
On BEST ANSWER

Assuming "launch-app-from-dashboard" is creating a new page tag, you can use the following pattern to run the subsequent lines of code on the new page. See multi-page scenarios doc for more examples.

// Get page after a specific action (e.g. clicking a link)
const [newPage] = await Promise.all([
  context.waitForEvent('page'),
  page.click('a[target="_blank"]') // Opens a new tab
])
await newPage.waitForLoadState();
console.log(await newPage.title());

Since you run headless, it might also be useful to switch the visible tab in the browser with page.bringToFront (docs).

0
On
it('Open a new tab and check the title', async function () {
  await page.click(button, { button: "middle" }); //to open an another tab
  await page.waitForTimeout(); // wait for page loading 
  let pages = await context.pages();
  expect(await pages[1].title()).equal('Title'); /to compare the title of the second page
})
1
On

The browserContext?.pages() is an array that contains the tabs opened by your application, from there you can use a temporal page to make a switch, once completed your validations you can switch back.

playwright.pageMain: Page = await playwright.Context.newPage();
playwright.pageTemp: Page; 

// Save your current page to Temp 
playwright.pageTemp = playwright.pageMain;

// Make the new tab launched your main page
playwright.pageMain = playwright.browserContext?.pages()[1];
expect(await playwright.pageMain.title()).toBe('Tab Title');
0
On

Assume you only created one page (via browser context), but for some reason, new pages/tabs open. You can have a list of all the pages by : context.pages, Now each element of that list represents a <class 'playwright.async_api._generated.Page'> object. So, now you can assign each page to any variable and access it. (For eg. page2 = context.pages[1])