I am trying to open a new tab and scrape information from the new tab using puppeteer. I am doing
pages = browser.pages();
new_tab = pages[pages.length - 1]
new_tab.screenshot({path: "sample.png"});
to switch to the new tab and take a screenshot. However, puppeteer doesn't switch to the new tab and takes a screenshot of the old tab instead. After some debugging I realized that the new tab isn't added to pages for some reason. Specifically, I used pages.length() which returned 2, pages[0] manipulates the pre-existing blank page and pages[1] = pages[pages.length()-1] manipulates the previous page.How do I fix this?
Thank you
Related
I am using Puppeteer to gather a list of companies that hire remotely. The page I am trying to collect the data from has a call to action that is not an <a href="" blank"_tab", but a <button></button>. The button doesn't have any data attribute either, that gives a hint as to what the URL of the page that gets opened in a new tab, when I click the button, is. I am now trying to find a way to catch the opening of the new tab, by clicking the said button, to then fetch the URL of the newly opened tab. Is this possible with puppeteer?
The solution is to extract all pages of the browser via the browser.pages() method call.
In your puppeteer project you always start by initialising the browser. The puppeteer virtual browser does contain the method pages(). Usage of pages().
What you have to do now: At first get the current url of the current page you are on. Then stream the result of the browser.pages() method. While streaming the array you can just get the index of your current tab. The tab you just opened using the button is the page with that index + 1 (the next element in the array)...
How to handle multiple tabs
Puppeteer Documentation about pages()
I am currently unable to open a new tab in the same browser window. Please refer scenario.
After login, the application opens the page in the same browser
window. I need to click on the card and after it will open in a new
tab and where I need to test everything. Currently, I need to
simulate a direct URL for a new tab but I want to open a new tab with
test case code.
Please let me know is it possible in the test cafe?
Thanks.
Yes, you can pass --disableNewWindow in testcafe/runner argument to open url in same tab.
Also, refer to https://testcafe.io/documentation/402841/guides/advanced-guides/multiple-browser-windows#disable-support-for-multiple-windows
--disable-multiple-windows
In order to automate my test application, I need to open few links in a new window instead of tab. Keep this in mind that I am not opening the links in new tab explicitly, it is my web application which automatically lands user in the new tab after clicking on the link.
Why do I want to do this?
Because running the tests on chrome browser closes the main tab and keeps open the newly opened tab. Which ultimately fails the tests.So ultimate intention is to open the new window instead of tab and handle it properly using driver.getWindowHandles().
What have I done so far?
I tried to find some kind of capability setting or profile in Chrome which automatically opens the links in a new window which are supposed to be open in a tab.But did not find any convincing solution most of the suggestions are CTRL+CLICK ON THE LINK.
I'm not a guru of web-design, but I can suggest following scenario:
// Get required page
// Excecute below JavaScript with JavaScriptExecutor
var reference = document.querySelector('a#someID').getAttribute('href'); // You can use your specific CSS Selector instead of "a#someID"
document.querySelector('a#someID').setAttribute("onclick", "window.open('" + reference + "', '', 'width=800,height=600')")
document.querySelector('a#someID').removeAttribute('href')
// Find target link
// Click on it
This code should allow you to make changes in HTML source code of target web-element to force its opening in new browser window.
Note that with this code element's appearance on page will be changed until page refresh
P.S. You didn't mentioned your programming language, so there is no complete implementation... However, this is Python implementation example:
from selenium import webdriver as web
dr = web.Chrome()
dr.get('https://login.live.com/login.srf?&wreply=https%3a%2f%2foutlook.live.com%2fowa%2f%3fnlp%3d1%26realm%3dlogin.live.com')
dr.execute_script("""
var reference = document.querySelector('a#ftrTerms').getAttribute('href');
document.querySelector('a#ftrTerms').setAttribute("onclick", "window.open('" + reference + "', '', 'width=800,height=600')")
document.querySelector('a#ftrTerms').removeAttribute('href')
""")
link = dr.find_element_by_id('ftrTerms')
link.click()
Well, in the absence of any flag/setting/capability in Chrome browser which opens the links in a new window instead of the new tab I used a Chrome Extension for that via WebDriver.
Why did I do that?
Because my tests are running fine on Firefox and I have no idea how many WebElements are there in the suite which gets open in new tab in Chrome browser. The suite is also very huge so doing any changes in its core page class may break the all the tests.In addition to that, changing code at an element level will be very time-consuming and most importantly not a generic solution.
What did I do?
I used a chrome extension New Tab New Window, which opens all the new tabs into a new window.
Downloaded the CRX file of this extension using an extension Get CRX.
Set the CRX file as a capability of Chrome.
ChromeOptions options = new ChromeOptions();
options.addExtensions(new File("pathOfCRXFile"));
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(capabilities);
So above will convert all the new tabs into a new window.So whenever the driver clicks on any link which further opens in a new tab will get opened into the new window.
Short version: new tabs in Chrome prevent old tabs from being used, fixing that means that opened tabs with PDFs in them get reused before a human can examine the PDFs.
Long version:
Originally it worked like this:
open new Chrome window to main page of the app (tab #1)
2.[do process A and then] click the button and a new tab (tab #2) opens with PDF A in it.
Go back to tab #1 [do process B and then] click the button and a new tab (tab #3) opens with PDF B in it.
Go back to tab #1 [do process C and then] click the button and a new tab (tab #4) opens and Word document C document gets downloaded.
Go back to tab #1 [do process D and then] click the button and a new tab (tab #5) opens and Word document D document gets downloaded.
All tabs stay open and PDFs can be viewed. Not perfect, but workable.
But then things changed. I pulled frequently used stuff out, put them in methods in another file so all of the various tests could use them, which seemed like a good idea. But that seems to have caused problems with losing focus on the original window. (I may be wrong) now I'm stuck with:
open new Chrome window to main page of the app (tab #1)
[do process A and then] click the button and a new tab (tab #2) opens with PDF A in it.
Stay in tab #2 [do process B and then] click the button and a new tab (tab #3) opens with PDF B in it. PDF A is now lost
Stay in tab #3 [do process C and then] click the button and a new tab (tab #4) opens and Word document C document gets downloaded. PDF B is now lost
Stay in tab #4 [do process D and then] click the button and a new tab (tab #5) opens and Word document D document gets downloaded.
This was caused by using "b.windows.last.use"
So I tried using "b.windows.first.use"
But that fails, because focus isn't going back to tab #1, and watir can't find the object in the modal that it needs to click.
(in `assert_ok': Element is not clickable at point (737.5, -373) (Selenium::WebDriver::Error::UnknownError))
So far as I can tell, I would be fine if I could do any one of the following
get PDFs to download. I cannot. This page seemed promising, but the code didn't work and I couldn't fix it.
get watir to go back to the first page, "for realsies", and find the buttons it needs
perhaps open a new tab for every section of the test (I'm going to look into this one, but I'm not overly hopeful)
Any ideas?
I updated Watir and Ruby both within the last two months. I'm using Chrome on OSX. Moving to Windows or IE are not viable options.
Here is a section of the code. No, I'm not a programmer first and foremost.
Thanks.
currenturl = "stackoverflow.placeholder.com/works"
# print Inventory Report .PDF (document 1)
b.goto currenturl
b.div(:id, 'page').a(:text, 'Inventory Report').click
sleep 1
b.div(:id, 'printInventoryReportModal').a(:text, 'A4').click
b.link(:id => "submitBTNprint-inventory-report").fire_event "onclick"
# print General List .PDF (document 2)
b.goto [main page URL]
b.div(:id, 'page').a(:text, 'General List').click
sleep 1
b.div(:id, 'printGeneralInventoryListModal').a(:text, 'A4').click
b.link(:id => "submitBTNprint-general-list").fire_event "onclick"
# print General List .DOC (document 3)
b.goto [main page URL]
b.div(:id, 'page').a(:text, 'General List').click
sleep 1
b.div(:id, 'printGeneralInventoryListModal').a(:text, '.DOC').click
b.div(:id, 'printGeneralInventoryListModal').a(:text, 'A4').click
b.link(:id => "submitBTNprint-general-list").fire_event "onclick"
It seems mostly that the browser.window function is not working the way you expect, or you are not using it properly. Since your question currently contains very little in terms of examples of how you are trying to change windows (tabs) it's very difficult to tell what you might be doing wrong.
To start with I would use IRB to do some exploring and troubleshooting
Get into IRB, then use
require 'watir-webdriver'
b = Watir::Browser.new :chrome
Now manually navigate the browser window that opens and get it into the state where you have multiple tabs open
Now try something like this in IRB to see if you can get it to spit out window titles
b.windows.each {|window| puts window.title}
If the titles are different, then you should be able to use that to set which window you want to use. If they are not different you will need to look at other attributes to see if there is an easy way to identify which window you want. (or maybe just use :index)
Try below code,
sleep (2)
#browser.driver.switch_to.window(#browser.driver.window_handles[put_your_index])
#browser.window(:title,"Please put your title here").use do
end
#browser.button.when_present.click
when you want to want to switch back to your actual window, use the
same code as above and change the window index accordingly.
For an example, if parent window index is 0 and then child window index would be 1
I want to know the ID which the original new tab page of chrome would take when I open a new tab?
to inject a javascript code into it.
** note that the new tab I'm talking about here is the original chrome new tab page.
This is not possible, JavaScript injection into Chrome's original New Tab Page is not allowed for security reasons.