How to handle another tab and/or popups
subiron opened this issue · comments
Hi!
Is it possible to switch page context to the newly opened tab or popup window?
can't find it in the API.
For example:
await browser.open("https://ch.viivexchange.com/login/");
let selector="img[title=saml-swissrx]";
await browser.waitFor(selector);
const swissrxButton = await browser.query(selector);
await browser.click(swissrxButton);
...
new popup window is shown after a click and it looks it is impossible to interact with it.
or another question is it possible to directly access underlying puppeter api?
Regards
Hi @subiron
It is possible to access the puppeteer page directly through browser.page
, would this be enough or you need access to other parts of the puppeteer API?
If you feel there should be an easier way of doing this, please feel free to propose an interface for this case or an example (using wendigo or puppeteer) of what you plan to achieve.
thanks for a quick response.
I was missing puppeteer's browser object but I can see now that page object has browser() method that returns original puppeteer-browser object.
nevertheless, I wanted to switch context to the popup page but also to keep the possibility to use wendigo API.
I endup with following solution:
let originalPage = browser.page; //temp copy for later use (switch back context)
let puppeteerBrowser = browser.page.browser(); // this part I was missing
const popUpPagePromise = new Promise(x => puppeteerBrowser.once('targetcreated', target => x(target.page())));
await browser.click(swissrxButton); //button that will triger openning up of a popup (as a seperate window)
browser.page = await popUpPagePromise;// replace page object inside wendigo browser to use wendigo api for popUp scope
await browser.type("#Password", "blblblb"); //works in context of popup !
console.log(await browser.title() + " " + await browser.url()); //title and url of a popup window !
// ok lets get back to out main page(/tab/window)
browser.page = originalPage;
console.log(await browser.title()) //back on original page
I'm worried if there are any consequences of replacing page object inside wendigo's browser object but for now, it looks that everything is working fine.
See here how it's done in puppeteer:
https://pocketadmin.tech/en/puppeteer-popup-window/
Well, there may be some unwanted side effects (some methods may not work as expected due to code injection made by wendigo), but it may be a reasonable workaround for now, I'll try and come up with a better solution for handling popups/tabs without having to rely on hacks.
Maybe a way to create a new WendigoBrowser with a custom context (a.k.a. page) or a "Popup handler" that contains reference to the targets created by the page
After some checks, to solve this there are two main issues that need to be addressed:
- Provide an interface to get a browser tabs (and popups) through
browser.pages()
method. - On each
targetcreated
event, the whole wendigo setup (_afterPageLoad
) must be called for the new page, this could substitute the current "on load" event used for normal links.
Proposed API:
browser.page
return the current active page (a.k.a. tab) of the browser (works as before).browser.pages
return all pages.browser.selectPage(index)
to change active pagebrowser.close()
should close all pages (works as before)browser.closePage(index)
should close the page with given index
Due to how puppeteer handles tabs, popups would be handled the same way as tabs
Things to discuss:
browser.browser
returns the native Puppeteer browser -> naming may be confused, check alternatives to browser- Consider using
browser.tab
andbrowser.tabs
instead of page/pages browser.pageIndex
should return the current page index (?)
Possible changes for v3.0 (breaking changes):
browser.page
->browser.currentPage
orbrowser.activePage
(maybebrowser.currentTab
?)browser.page
andbrowser.pages
should be methods instead of getters
If I may suggest 'browser' as the main object is confusing. I you say about renameing it to just 'wendigo'?
and then
wendigo.pages //[page1, page2...]
wendigo.browser// (puppeter browser)
wendigo.page /(current page)
wendigo.switchContext(pageIndex / page object/ promise)
Well, I agree in the possible confusion of the main name for wendigo's browser, however a few things:
- Wendigo is already the main exported name
- I consider
Browser
to be an intuitive name for common usage (browser.open()
orbrowser.click()
are quite self-explanatory)
In the end, this naming is mostly for docs, because it is a local variable you could easily use whatever you want e.g. const wendigo = Wendigo.createBrowser()
I'm actually thinking on using context
as name for the Puppeteer native variable, as it will probably be a Context exported intead of a browser. (Due to how incognito works in Puppeteer, the internal variable used in wendigo is context insteadof browser)
The following methods will be added on Wendigo 2.5.0:
browser.pages()
will return all the pages of the browser (tabs and popups)browser.selectPage(index)
changes the active page to the page with given index and reloads itbrowser.closePage(index)
closes the page with given index
These methods are still under revision and may change or behave unpredictably, but should be enough to gracefully solve your problem @subiron
In future issues I will address some improvements for these problems