Hey everyone, I’m working on automating a two-step process for registering a developer app. The first page is where I input app details and click a button to generate an App ID. This opens a new tab with the second page showing the App ID. I need to grab that ID, close the tab, go back to the first page, and paste the ID there before submitting the form.
I’ve got the basics down for opening the first page and clicking the button, but I’m stumped on how to handle the new tab that opens. Can anyone share some tips on managing multiple tabs in Puppeteer?
Here’s a simplified version of what I’m trying to do:
const puppeteer = require('puppeteer');
async function registerApp() {
const browser = await puppeteer.launch({headless: false});
const mainPage = await browser.newPage();
await mainPage.goto('https://dev.mysite.com/register');
// Fill out initial form
await mainPage.type('#appName', 'CoolApp');
await mainPage.type('#appDescription', 'A really cool app');
await mainPage.click('#generateAppId');
// How do I handle the new tab that opens here?
// Need to get the App ID, close the tab, and return to the main page
await mainPage.type('#appIdField', 'APP_ID_FROM_NEW_TAB');
await mainPage.click('#submitForm');
await browser.close();
}
registerApp();
Any help would be appreciated!
I’ve dealt with multi-tab scenarios in Puppeteer before, and here’s what worked for me:
Instead of relying on browser.pages(), I found it more reliable to use the ‘targetcreated’ event listener. This way, you can immediately capture the new tab as it’s created. Here’s a rough idea:
const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
await mainPage.click('#generateAppId');
const newPage = await newPagePromise;
await newPage.waitForSelector('#appIdElement');
const appId = await newPage.$eval('#appIdElement', el => el.textContent.trim());
await newPage.close();
await mainPage.type('#appIdField', appId);
This approach has been more consistent for me, especially when dealing with dynamic page loads. Just remember to add proper error handling and timeouts to make it robust.
hey, i solved this by using page.waitForTarget() to catch the new tab. its neat:
const nt = await page.waitForTarget(t => t.url().includes('app-id'));
const np = await nt.page();
const id = await np.$eval('#appIdElement', el => el.textContent);
await np.close();
hope it helps!
I encountered a similar situation and solved it by getting all open pages with browser.pages() after clicking the button. I determined the new tab by either filtering out the main page or simply taking the last element of the pages array. Once on the new tab, I waited for the App ID element to load, extracted its text content with $eval, closed the tab, and brought focus back to the main page with bringToFront. For example:
const pages = await browser.pages();
const newPage = pages[pages.length - 1];
await newPage.waitForSelector('#appIdElement');
const appId = await newPage.$eval('#appIdElement', el => el.textContent);
await newPage.close();
await mainPage.bringToFront();
This approach worked reliably for me, provided proper error handling and timeouts are in place.