puppeteer / puppeteer

JavaScript API for Chrome and Firefox
https://pptr.dev
Apache License 2.0
88.91k stars 9.09k forks source link

How do I change Puppeteer's focus to a second tab? 0 #6235

Closed sfelice777 closed 2 years ago

sfelice777 commented 4 years ago

I have a test that clicks a button that opens a second tab.

How do I get Puppeteer to latch on to the new tab to verify text, click buttons, etc?

vsemozhetbyt commented 4 years ago

You can listen to 'targetcreated' event and then use page.bringToFront().

sfelice777 commented 4 years ago

Could you post some example code? Thanks

vsemozhetbyt commented 4 years ago

Something like this:

const puppeteer = require('puppeteer');

(async function main() {
  try {
    const browser = await puppeteer.launch({ headless: false, defaultViewport: null });
    const [page] = await browser.pages();

    await page.goto('https://example.org/');

    const link = await page.$('a[href]');

    const [target] = await Promise.all([
      new Promise(resolve => browser.once('targetcreated', resolve)),
      link.click({ button: 'middle' }),
    ]);

    const newPage = await target.page();
    await newPage.bringToFront();
  } catch (err) {
    console.error(err);
  }
})();
sfelice777 commented 4 years ago

I'm very close to getting what I want with this code. This code works.

it('Click button get text', async () => { const ck = await func.expect_clickEnabledElement((await (await editTask()).task_configureBaseline_btn(0, 5, 0)))

    const [target] = await Promise.all([
        new Promise(resolve => browser.once('targetcreated', resolve)),
        ck,
    ]);

    const newPage = await target.page();
    await newPage.bringToFront();

    await page.waitFor(5000)
    const ele = await newPage.$$('#baselineSetup .tab-header [data-bind]')
    for (const item of ele) {
        const txt = await item.evaluate(e => e.innerText)
        console.log('TEXT: ' + txt)
    }

});

I want to use, "newPage" in my next, "it" block and several more, "it" blocks. How would I keep,"newPage" going after this, "it" block has completed?

The my framework passes the, "page" instance to each page object file at the top of the test file like this. const navbar2 = async () => new (require('../../../../../pageObjects/navbar2.po.js'))(page)

I'm not using Typescript. I am using Jest to handle, "page" for me. Jest make, "page" available throughout the entire project. I don't know how to do the same thing with, "newPage"?

Any ideas? Thanks!

sfelice777 commented 4 years ago

I got it working the way I need it to.

I declared, "newPage" on line 1 of my tests file. var newPage

Then I did this to my require line. const navbar2 = async () => new (require('../../../../../pageObjects/navbar2.po.js'))(newPage)

I changed the,"it" block where I click the link that opens the new tab. it('Click the button', async () => { await func.expect_clickEnabledElement((await (await cerHeaderbar()).sideBar_taskGroup_task_lbls(0))[5]) await func.expect_waitForElementToBeVisible('#Routine .groups-container > [id^=task-group]:nth-child(1) > [data-bind=template]:nth-child(6) .card:nth-child(1) [data-bind=navToMachineWorkspace]') const [target] = await Promise.all([ new Promise(resolve => browser.once('targetcreated', resolve)), await func.expect_clickEnabledElement((await (await editTask()).task_configureBaseline_btn(0, 5, 0))), ]) newPage = await target.page() await newPage.bringToFront() await page.waitFor(5000) });

All the following, "it" blocks that use elements in the require line I posted above work!

GiorgioRemindme commented 3 years ago

It would be nice if you added your code in a code block... Hard to read otherwise.

Sangamchoudhary commented 3 years ago

i have an issue actually when i clicked on a page it opens a diff tab now i wanna acces that tab and do some work there

`const puppeteer = require("puppeteer"); let page; console.log("before"); // launch browser

var browserOpenPromise = puppeteer.launch({ headless: false }); browserOpenPromise .then(function (browser) { const pagesArrpromise = browser.pages(); // get all tabs of browser return pagesArrpromise; }) .then(function (browserPages) { page = browserPages[0]; //select the 1st tab let gotoPromise = page.goto("https://www.google.com/"); //open this url return gotoPromise; }) .then(function () { let elementWaitPromise = page.waitForSelector("input[type='text']", { //waiting for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keysWillBeSendPromise = page.type("input[type='text']", "flipkart"); // it will type on input area return keysWillBeSendPromise; }) .then(function () { let enterWillBePressed = page.keyboard.press("Enter"); //after typing it will enter return enterWillBePressed; }) .then(function () { let elementWaitPromise = page.waitForSelector(".LC20lb.DKV0Md", { //again wait for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keyWillBeSend = page.click(".LC20lb.DKV0Md"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let elementWaitPromise = page.waitForSelector(".IiD88i._351hSN", { //again wait for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keyWillBeSend = page.type(".IiD88i._351hSN", "you can enter your email id here"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let elementWaitPromise = page.waitForSelector("._2IX_2-._3mctLh.VJZDxU", { //again wait for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keyWillBeSend = page.type("._2IX_2-._3mctLh.VJZDxU", "and your password too"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let keyWillBeSend = page.click("._2KpZ6l._2HKlqd._3AWRsL"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let keyWillBeSend = page.click("._3704LK"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let keyWillBeSend = page.type("._3704LK", "iphone 11"); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let elementWaitPromise = page.waitForSelector('[type="submit"]', { //again wait for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keyWillBeSend = page.click('[type="submit"]'); //click on the 1st link present on google page return keyWillBeSend; }) .then(function () { let elementWaitPromise = page.waitForSelector("._4rR01T", { //again wait for url to open visible: true, }); return elementWaitPromise; }) .then(function () { let keyWillBeSend = page.click("._4rR01T"); //click on the 1st link present on google page return keyWillBeSend; }).then(function(){ var pagesArrpromise = browserOpenPromise.pages(); page=pagesArrpromise[1]; return page; }) .then(function () { let elementWaitPromise = page.waitForSelector( "._2KpZ6l._2U9uOA.ihZ75k._3AWRsL", { //again wait for url to open visible: true, } ); return elementWaitPromise; }) .then(function () { //select the 1st tab let buyNow = page.click("._2KpZ6l._2U9uOA.ihZ75k._3AWRsL"); return buyNow; }) .catch(function (err) { console.log(err); //during all this if script faces any error that will be shown in terminal }); console.log("after"); `

sfeliceSNC commented 3 years ago

Here is what I ended up using. At the top of my test I declare - let newPage Then I call a method I have in another file - newPage = await SNC_confBase.clickConfigureBaselineButton(taskGroup, task, card) After I'm done with the new tab I close it like this - await newPage.close()

async clickConfigureBaselineButton(...args3) { try { const [target] = await Promise.all([ new Promise(resolve => browser.once('targetcreated', resolve)), await func.expect_clickEnabledElement((await (await editRunTask()).task_configureOrExecute_baseline_btn(...args3))), ]) newPage = await target.page() await newPage.bringToFront() await newPage.waitForNavigation({ waitUntil: 'networkidle0' }) await newPage.waitForTimeout(5000) return newPage } catch (error) { throw new Error('newPage' is undefined) } }

stale[bot] commented 2 years ago

We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

stale[bot] commented 2 years ago

We are closing this issue. If the issue still persists in the latest version of Puppeteer, please reopen the issue and update the description. We will try our best to accomodate it!