Selenium Python does not close the child window - python-3.x

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.

Related

Selenium driver - not able to close the popup, element not found is the main issue

Using selenium find element (using xpath) method to close the popup but it is not able to detect it.
time.sleep(10)
driver.fin_element(By.XPATH,"XPATH").close()
I have also use time.sleep and webdriver wait methods but it not working
Website: www.multcloud.com
time.sleep(10)
webdriver wait
ec. Element traceable method
Also try Find elements but it is showing empty list.
Tried find element using class_name,xpath, full xpath,cs locator,link text
Try the below code
driver.get("https://www.multcloud.com/")
sleep(4)
driver.switch_to.frame("layui-layer-iframe1")
You could use explicit wait in the place of sleep
sleep(3)
button = driver.find_element(By.XPATH,"((//div[#class='sale-close-img'])[2])")
button.click()
Imports
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

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.

Why does firefox keep getting hungup after the fourth run through

I am trying to create a bot that clicks on a link on my site, opens a tab, closes, and then continues the cycle.
This keeps getting hungup after the 4-5 cycle however.
I also cannot figure out how to simply close both of the tabs, and get the url again as to not have to quit.
Sorry if this is very basic, I am new to this. :)
I am using selenium, firefox webdriver
from time import sleep
from selenium import webdriver
from keyboard import press
while True:
browser = webdriver.Firefox()
browser.implicitly_wait(10)
browser.get('https://pridedogecoin.com/')
sleep(15)
login_link = browser.find_element_by_xpath('//*[#id="slider-6-slide-6-layer-13"]')
login_link.click()
sleep(5)
browser.quit()
sleep(15)
okay, you need to switch to first tab like below, also you should use close not quit, since close is meant to kill current window instance, where as quit will kill all of the browser instance :
import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox(executable_path = "D:\geckodriver.exe")
driver.maximize_window()
while True:
driver.refresh()
time.sleep(10)
driver.get("https://pridedogecoin.com/")
driver.implicitly_wait(60)
wait = WebDriverWait(driver, 30)
current_windows_handle = driver.current_window_handle
wait.until(EC.element_to_be_clickable((By.ID, "slider-6-slide-6-layer-13"))).click()
driver.switch_to.window(driver.window_handles[1])
time.sleep(5)
driver.close()
driver.switch_to.window(current_windows_handle)

Can not pick up the element using python selenium binding from a website for unknown reasons

This is the website "https://agta.org/directory/", no matter what i tried i was not able to click the search button, i gave a delay clicked the button manually hoping for the script to pick up elements at the next stage, but it did not worked as well, "find_element_by_xpath" is returning empty objects. I can't understand why is it happening that way when the x path is 100% accurate. I have used similar script for other site but never had any problem.
For clicking the search button i used java script, action chains as well, still failed.
#using selenium
#search=driver.find_element_by_xpath("//input[#class='DLGButton']").click()
#using js
#driver.execute_script("document.getElementsByClassName('DLGButton')[0].click()")
Here is my detailed code:
options = Options()
options.add_argument("--start-maximized")
driver = webdriver.Chrome(options=options, executable_path=r'D:\chromedriver.exe')
url='https://agta.org/directory/'
driver.get(url)
time.sleep(10)
search=driver.find_element_by_xpath("//input[#class='DLGButton']").click()
time.sleep(10)
listings=driver.find_elements_by_xpath("//div[#class='col-md-3']//a")
print(listings)
check=1
while(check==1):
index=1
for l in listings:
l=driver.find_element_by_xpath("(//div[#class='col-md-3']//a)[{}]".format(index)).get_attribute('href').strip()
print(l)
index=index+1
try:
clickNext=find_element_by_xpath("(//*[contains(text(), 'Next')])[1]").click()
time.sleep()
except Exception as e:
print(e)
check=0
Search button is in the frame. So you should switch the frame first.
I modify your code and click Search Button successfully.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.maximize_window()
url='https://agta.org/directory/'
driver.get(url)
time.sleep(5)
# find the frame
frame = driver.find_element_by_xpath("//iframe[#class='directory_iframe']")
driver.switch_to.frame(frame)
# wait element to be clickable
search = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='DLGButton']")))
# check button can be found
print(search.get_attribute("value"))
# Scroll the page to show this button (or it will fail to click)
driver.execute_script("arguments[0].scrollIntoView();", search)
search.click()
And you can use Explicit Waits instead of time.sleep()
Ex: To confirm the presence of the element within the DOM Tree.
frame = WebDriverWait(driver, 10).until(EC.presence_of_element_located
((By.XPATH, "//iframe[#class='directory_iframe']")))
Reference: https://selenium-python.readthedocs.io/waits.html

ElementNotVisibleException Python/Selenium error for next page button click

I am trying to figure out how to use selenium to perform a next page click on a news release page. Here is my code that will go to the correct website and perform a search to obtain the correct news release articles topic page. This site is configured so that to see every news release on page 1 after the search has executed you must also select the More News Results button at the bottom of the page. I am able to get to the full page 1 news section without problem. Here is my code that performs the search and page clicks.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('http://www.businesswire.com/portal/site/home/')
search_box_element = browser.find_element_by_id('bw-search-input')
search_box_element.clear()
search_box_element.send_keys('biotechnology')
search_box_element.send_keys(Keys.ENTER)
search_box_element_two = browser.find_element_by_id('more-news-results')
search_box_element_two.click()
That part of the code works fine but I want to be able to click on the next button to move to page 2 and then page 3 and so on. Here is the code that I thought would work but it doesn't:
next_page_click_element = browser.find_element_by_class_name("bw-paging-next")
next_page_click_element.click()
This portion of the code throws an error:
selenium.common.exceptions.ElementNotVisibleException: Message:
element not visible
I have also tried using
next_page_click_element = browser.find_element_by_xpath('//*[#id="more-news-pagination"]/div/div[1]/div/a')
but got the same error message. I have also tried using a wait by adding these lines of codes just before the next_page_click_element section.
element_present = EC.presence_of_element_located((By.ID, "bw-paging-next"))
WebDriverWait(browser, 10).until(element_present)
While this does cause the program to wait it returns this error message:
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Any suggestions on how to resolve this issue would be greatly appreciated.
Here is the Answer to your Question:
A few words about the solution-
As the Page 2,Page 3,Next etc elements are at the bottom of the page, you have to scroll down to bring those elements within the Viewport.
Once you scroll down you may consider to induce some ExplicitWait for the elements to be located properly on the HTML DOM.
Here is your own code with some simple tweaks which will finally scroll to the bottom of the page and click on Next link:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
browser=webdriver.Chrome("C:\\Utility\\BrowserDrivers\\chromedriver.exe")
browser.get('http://www.businesswire.com/portal/site/home/')
search_box_element = browser.find_element_by_id('bw-search-input')
search_box_element.clear()
search_box_element.send_keys('biotechnology')
search_box_element.send_keys(Keys.ENTER)
search_box_element_two = browser.find_element_by_id('more-news-results')
search_box_element_two.click()
last_height = browser.execute_script("return document.body.scrollHeight")
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
next_page_click_element = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.XPATH, "//div[#id='more-news-pagination']/div/div/div/a[text()='Next']"))
)
next_page_click_element.click()
Let me know if this Answers your Question.

Resources