How to handle multiple windows in Python selenium with Firefox driver - python-3.x

I want to learn WINDOW handling in Python Selenium.
My Task is:
First open 'Google.com'.
Second open 'Yahoo.com' in New Window.
Third switch back to First Window and click on Gmail Link.
Fourth switch to Second Window and click on Finance Link.
Following Code works for me:
browser.get("http://www.google.co.in")
browser.execute_script("window.open('https://www.yahoo.com')")
browser.switch_to_window(browser.window_handles[0])
print(browser.title)
gmail=browser.find_element_by_class_name("gb_P")
gmail.click()
browser.switch_to_window(browser.window_handles[1])
print(browser.title)
fin=browser.find_element_by_link_text("Finance")
fin.click()
But when I try to change sequence to task as:
First open 'Google.com'.
Second open 'Yahoo.com' in New Window.
Third remaining in same window and click on Finance Link.
Fourth switch to First Window and click on Gmail Link.
The below altered code for the task in which after opening yahoo.com in new window and then clicking on finance link and then switching to main window containing Google.com then clicking on Gmail link doesn't work:
browser.get("http://www.google.co.in")
browser.execute_script("window.open('https://www.yahoo.com')")
browser.switch_to_window(browser.window_handles[1])
print(browser.title)
fin=browser.find_element_by_link_text("Finance")
fin.click()
browser.switch_to_window(browser.window_handles[0])
print(browser.title)
gmail=browser.find_element_by_class_name("gb_P")
gmail.click()
But if I refresh the page after switching to the Yahoo tab this works only in Chrome Driver and not in Firefox Driver.
browser.get("http://www.google.co.in")
print(browser.current_window_handle)
browser.execute_script("window.open('https://www.yahoo.com')")
print(browser.current_window_handle)
WebDriverWait(browser, 10).until(EC.number_of_windows_to_be(2))
browser.switch_to_window(browser.window_handles[1])
print(browser.current_window_handle)
print(browser.title)
browser.refresh()
fin=browser.find_element_by_link_text("Finance")
fin.click()
print(browser.window_handles)
WebDriverWait(browser,10000)
browser.switch_to_window(browser.window_handles[0])
print(browser.title)
print(browser.current_window_handle)
gmail=browser.find_element_by_class_name("gb_P")
gmail.click()

As per your updated question a few words about Tab/Window switching/handling:
Always keep track of the Parent Window handle so you can traverse back for the rest of your usecases.
Always use WebDriverWait with expected-conditions as number_of_windows_to_be(num_windows)
Always keep track of the Child Window handles so you can traverse back if required.
Here is your own code with some minor tweaks mentioned above:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#other lines of code
browser.get("http://www.google.co.in")
print("Initial Page Title is : %s" %browser.title)
windows_before = browser.current_window_handle
print("First Window Handle is : %s" %windows_before)
browser.execute_script("window.open('https://www.yahoo.com')")
WebDriverWait(browser, 10).until(EC.number_of_windows_to_be(2))
windows_after = browser.window_handles
new_window = [x for x in windows_after if x != windows_before][0]
# browser.switch_to_window(new_window) <!---deprecated>
browser.switch_to.window(new_window)
print("Page Title after Tab Switching is : %s" %browser.title)
print("Second Window Handle is : %s" %new_window)
Console Output:
Initial Page Title is : Google
First Window Handle is : CDwindow-34D74AB1BB2F0A1A8B7426BF25B86F52
Page Title after Tab Switching is : Yahoo
Second Window Handle is : CDwindow-F3ABFEBE4907CFBB3CD09CEB75ED570E
Browser Snapshot:
Now you have got both the Window Handles so you can easily switch to any of the TABs to perform any action.

Related

How to check if Open File dialog has been open after pressing a button in a Chrome Browser tab on Python?

I'm trying to automate a process within the OpenSea Create page after having logged in with Metamask, and so far, I have managed to develop a simple program that chooses a particular image file using a path which passes to the Open File dialog "implicitly", here's the code:
import pyautogui
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
def wait_xpath(code): #function to wait for the xpath of an element to be located
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, code)))
opt = Options() #the variable that will store the selenium options
opt.add_experimental_option("debuggerAddress", "localhost:9222") #this allows bulk-dozer to take control of your Chrome Browser in DevTools mode.
s = Service(r'C:\Users\ResetStoreX\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe') #Use the chrome driver located at the corresponding path
driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions
nft_folder_path = r'C:\Users\ResetStoreX\Pictures\Cryptobote\Cryptobote NFTs\Crypto Cangrejos\SANDwich\Crabs'
start_number = 3
if driver.current_url == 'https://opensea.io/asset/create':
print('all right')
print('')
print(driver.current_window_handle)
print(driver.window_handles)
print(driver.title)
print('')
nft_to_be_selected = nft_folder_path+"\\"+str(start_number)+".png"
wait_xpath('//*[#id="main"]/div/div/section/div/form/div[1]/div/div[2]')
imageUpload = driver.find_element(By.XPATH, '//*[#id="main"]/div/div/section/div/form/div[1]/div/div[2]').click() #click on the upload image button
print(driver.current_window_handle)
print(driver.window_handles)
time.sleep(2)
pyautogui.write(nft_to_be_selected)
pyautogui.press('enter', presses = 2)
Output:
After checking the URL, the program clicks on the corresponding button to upload a file
Then it waits 2 seconds before pasting the image path into the Name textbox, for then pressing Enter
So the file ends up being correctly uploaded to this page.
The thing is, the program above works because the following conditions are met before execution:
The current window open is the Chrome Browser tab (instead of the Python program itself, i.e. Spyder environment in my case)
After clicking the button to upload a file, the Name textbox is selected by default, regardless the current path it opens with.
So, I'm kind of perfectionist, and I would like to know if there's a method (using Selenium or other Python module) to check if there's an Open File dialog open before doing the rest of the work.
I tried print(driver.window_handles) right after clicking that button, but Selenium did not recognize the Open File dialog as another Chrome Window, it just printed the tab ID of this page, so it seems to me that Selenium can't do what I want, but I'm not sure, so I would like to hear what other methods could be used in this case.
PS: I had to do this process this way because send_keys() method did not work in this page
The dialog you are trying to interact with is a native OS dialog, it's not a kind of browser handler / dialog / tab etc. So Selenium can not indicate it and can not handle it. There are several approaches to work with such OS native dialogs. I do not want to copy - paste existing solutions. You can try for example this solution. It is highly detailed and looks good.

Avoid download pop up in python3 using serelinum Download pdf

Object:
automate following process.
1. Open particular web page, fill the information in search box, submit.
2. from search results click on first result and download the PDF
Work done:
To reach to this object I have written a code as first step. The code works fine but opens up download pop up. Till the time I can't get rid of it, I can not automate the process further. Searched for very many solutions. But none has worked.
For instance, This solution is hard for me to understand and I think its more to do with Java then Python. I changed fire fox profile as suggested by many. This dose matches though not exactly same. I haven't tried as there is no much difference. Even this speaks about changing fire fox profile but that doesn't work.
My code is as below
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui
from time import sleep
import time
import wget
from wget import download
import os
#set firefox Profile
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2)
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference("browser.download.manager.showAlertOnComplete", False)
profile.set_preference('browser.download.dir', os.getcwd())
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/pdf')
#set variable driver to open firefox
driver = webdriver.Firefox(profile)
#set variable webpage to open the expected URL
webpage = r"https://documents.un.org/prod/ods.nsf/home.xsp" # edit me
#set variable to enter in search box
searchterm = "A/HRC/41/23" # edit me
#open the webpage with get command
driver.get(webpage)
#find the element "symbol", insert data and click submit.
symbolBox = driver.find_element_by_id("view:_id1:_id2:txtSymbol")
symbolBox.send_keys(searchterm)
submit = driver.find_element_by_id("view:_id1:_id2:btnRefine")
submit.click()
#list of search results open up and 1st occarance is clicked by coppying its id element
downloadPage = driver.find_element_by_id("view:_id1:_id2:cbMain:_id135:rptResults:0:linkURL")
downloadPage.click()
#change windiows. with sleep time
window_before = driver.window_handles[0]
window_after = driver.window_handles[1]
time.sleep(10)
driver.switch_to.window(window_after)
#the actual download of the pdf page
theDownload = driver.find_element_by_id("download")
theDownload.click()
Please guide.
The "Selections" popup is not a different window/tab, it's just an HTML popup. You can tell this because if you right click on the dialog, you will see the normal context menu. You just need to make your "Language" and "File type(s)" selections and click the "Download selected" button.

Open a link from a list of links in new tab

I have a bunch of links in a list and I want to open each link in a different tab (only one window). I know how to open a new tab in Selenium but for some reason, when I iterate over the list, all links get open in the same tab and I don't know what I am missing. Could anyone explain me what the error is and how I can fix it? I would really appreciate it.
from selenium import webdriver as wd
from selenium.webdriver.common.keys import Keys
url_list = ["https://www.kdnuggets.com/2017/06/text-clustering-unstructured-data.html", "https://github.com/vivekkalyanarangan30/Text-Clustering-API/", "https://machinelearningblogs.com/2017/01/26/text-clustering-get-quick-insights-from-unstructured-data/", "https://machinelearningblogs.com/2017/06/23/text-clustering-get-quick-insights-unstructured-data-2/", "https://machinelearningblogs.com/2017/06/23/text-clustering-get-quick-insights-unstructured-data-2/"]
driver = wd.Firefox(executable_path="/usr/local/bin/geckodriver")
for url in url_list:
body = driver.find_element_by_tag_name("body")
body.send_keys(Keys.COMMAND + "t")
driver.get(url)
Currently using python3.7, Firefox 65.0.1 and Selenium 3.141 on a Mac
When you open a new tab it is a new window for webdriver which will have its unique handle. driver.window_handles holds the list of active windows, you can use this to switch to newly created window and perform tasks on it.
for url in url_list:
body = driver.find_element_by_tag_name("body")
body.send_keys(Keys.COMMAND + "t")
driver.switch_to_window(driver.window_handles[-1])
driver.get(url)
Note that you will be using the same variable driver to refer to the newly switched window, so if you close that window then you need to switch to an active window again to perform further tasks.
UPDATE:
If new tab is not opening with your code then you can also try this.
for url in url_list:
driver.execute_script("window.open()")
driver.switch_to_window(driver.window_handles[-1])
driver.get(url)
use window switching with commands
one=driver.window_handles[0] - set the name of the first window
two=driver.window_handles[1] - the name of the second window (after opening it)
driver.switch_to.window(two) - switch to the desired window

I want to right click and open link in new tab using selenium with python

from selenium.webdriver import ActionChains
action = ActionChains(driver)
action.context_click(driver.find_element_by_id('id')).perform()
it's doing a right click for me but unable to perform further action.like open link in new tab using python
First off, we import our packages:
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.keys import Keys
from time import sleep
Let's do it:
browser = webdriver.Firefox()
browser.get('https://www.google.com?q=python#q=python')
first_result = ui.WebDriverWait(browser, 15).until(lambda browser: browser.find_element_by_class_name('rc'))
first_link = first_result.find_element_by_tag_name('a')
# Save the window opener (current window, do not mistaken with tab... not the same)
main_window = browser.current_window_handle
# Open the link in a new tab by sending key strokes on the element
# Use: Keys.CONTROL + Keys.SHIFT + Keys.RETURN to open tab on top of the stack
first_link.send_keys(Keys.CONTROL + Keys.RETURN)
# Switch tab to the new tab, which we will assume is the next one on the right
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)
# Put focus on current window which will, in fact, put focus on the current visible tab
browser.switch_to_window(main_window)
# do whatever you have to do on this page, we will just got to sleep for now
sleep(2)
# Close current tab
browser.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 'w')
# Put focus on current window which will be the window opener
browser.switch_to_window(main_window)
As discussed with you.I have tried to open a create page on Facebook as a new window using right click options.Here is the code.Hope this help you.
driver = webdriver.Chrome('D:/Java/TestChrome/lib/chromedriver.exe')
driver.get("https://www.facebook.com/")
element=driver.find_element_by_xpath("//a[text()[contains(.,'Create a Page')]]")
#Open in new window to click on Create page using right click
ActionChains(driver).context_click(element).key_down(Keys.CONTROL).click(element).perform()
Let me know if it works.

Selenium Python does not close the child window

I have webpage which open new browser window on click. I am able to get 2 handles however driver.close() always closes the first/main window.
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("file:///D:/blackhole/print.html")
han = driver.window_handles
print("handles:", han) # gets 1 handle
time.sleep(2)
click_btn = driver.find_element_by_link_text('Print')
click_btn.click()
han = driver.window_handles
print("handles:", han) # gets 2 handles
driver.switch_to_window = han[1] # first element is always first window handle
driver.close() # main window close
Below webpage code which invokes new window
<a href="print.html"
onclick="window.open('popprint.html',
'newwindow',
'width=300,height=250');
return false;"
>Print</a>
Same behaviour for Firefox as well.
Python 3.6.7
Selenium is unable to close the active window i.e the newly opened window because practically you havn't switched to the newly opened window in a clean way.
Solution
A few words about Tab/Window switching/handling:
switch_to_window(window_name) is deprecated for quite some time now and you need to use driver.switch_to.window
Always keep track of the Parent Window handle so you can traverse back later if required as per your usecase.
Always use WebDriverWait with expected_conditions as number_of_windows_to_be(num_windows) before switching between Tabs/Windows.
Always keep track of the Child Window handles so you can traverse whenever required.
Always use WebDriverWait with expected_conditions as title_contains("partial_page_title") before extracting the Page Title.
Here is your own code with some minor tweaks mentioned above:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox(executable_path=r'C:\WebDrivers\geckodriver.exe')
driver.get("file:///D:/blackhole/print.html")
parent_han = driver.window_handles
driver.find_element_by_link_text('Print').click()
WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
all_han = driver.window_handles
new_han = [x for x in all_han if x != parent_han][0]
driver.switch_to.window(new_han)
driver.close()
You can find a detailed discussion in Selenium Switch Tabs
driver.close() only closes the current window.
To close all Windows and quit the webdriver, call driver.quit() instead.

Resources