selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable after switching the frame - python

I want to automate filling google forms with the images in google drive so I am using python with selenium.
The first image I can automate, but I got the error when I repeated the same process for the second image.
I created a sample google form to test.
https://forms.gle/fZ439KckkbpNU68v5
time.sleep(5)
driver.find_element_by_xpath('x path to first add file button').click()
frame= driver.find_element_by_class_name('picker-frame')
driver.switch_to.frame(frame)
*the first time it is working time*
driver.switch_to_default_content()
time.sleep(5)
driver.find_element_by_xpath('xpath to secondadd file button').click()
frame= driver.find_element_by_class_name('picker-frame')
driver.switch_to.frame(frame)
*after this, it causes an error*
I could not use the send_keys() method because this is button type.
Full code:
from selenium import webdriver
import random,time
option=webdriver.ChromeOptions()
driver = webdriver.Chrome("path to chrome driver")
driver.get("https://forms.gle/RvBYTZG5xuWoD8QA7")
driver.find_element_by_xpath('//*[#id="identifierId"]').send_keys("gmail")
driver.find_element_by_xpath('//*[#id="identifierNext"]/div/button').click()
time.sleep(3)
driver.find_element_by_xpath('//*[#id="password"]/div[1]/div/div[1]/input').send_keys("password")
driver.find_element_by_xpath('//*[#id="passwordNext"]/div/button').click()
time.sleep(5)
driver.find_element_by_xpath('//*[#id="mG61Hd"]/div[2]/div/div[2]/div[1]/div/div/div[2]/div/div[2]/span').click()
frame1 = driver.find_element_by_class_name('picker-frame')
driver.switch_to.frame(frame1)
driver.find_element_by_xpath('//*[#id=":6"]').click()
time.sleep(5)
driver.find_element_by_xpath('//*[#id=":1a.docs.0.1oe7tESa9uNnUC75FdYuqzPtPbLYz7QFi"]/div[2]').click()
driver.find_element_by_xpath('//*[#id="picker:ap:2"]').click()
driver.switch_to_default_content()
driver.find_element_by_xpath('//*[#id="mG61Hd"]/div[2]/div/div[2]/div[2]/div/div/div[2]/div/div[2]').click()
frame2 = driver.find_element_by_class_name('picker-frame')
driver.switch_to.frame(frame2)
driver.find_element_by_xpath('//*[#id=":6"]').click()
time.sleep(3)

This is a guess since no HTML was provided but maybe the location in the iframe of the element isnt correct since if you give it the global iframe path it want work i suggest to check if the button has a specifique i frame and switch to that iframe and give it the path in that one.
Or the element path isn't unique that makes problems too.

I think you are typing it wrongly. You should try this code.
driver.switch_to.default_content()

The solution is to put the refresh after switching the frame. Without having to use the switch_to_default_content() at all.
driver.refresh()
driver.switch_to.alert.accept()
It works.

Related

Right click save link as then save

hello guys i want to right click save link as then save on the save pop up that windows shows.
this is an example:
https://www.who.int/data/gho/data/indicators/indicator-details/GHO/proportion-of-population-below-the-international-poverty-line-of-us$1-90-per-day-(-)
go on this page in the data tab u can see EXPORT DATA in CSV format:Right-click here & Save link
so if u right click and save link as it will let u save the data as csv.
i want to automate that can it be done using selenium python if so how?
i tried using actionchains but im not sure thats gona work
I think you would be better off using the Data API (json) offered on the same page, but I have managed to download the file using the code below and Google Chrome.
There is a lot going on which I didn't want to go into (hence the lazy usage of an occasional sleep), but the basic principle is that the Export link is inside a frame inside a frame (and there are many iframes on the page). Once the correct iframe has been found and the link located, a right click brings up the system menu.
This menu cannot be accessed via Selenium (because it is inside an iframe?), so pyautogui is used to move down to "Save link as..." and also to click the "Save" button on the Save As dialog.:
url = "https://www.who.int/data/gho/data/indicators/indicator-details/GHO/proportion-of-population-below-the-international-poverty-line-of-us$1-90-per-day-(-)"
driver.get(url)
driver.execute_script("window.scrollBy(0, 220);")
button = driver.find_element(By.CSS_SELECTOR, "button#dataButton")
button.click()
WebDriverWait(driver, 5).until(EC.text_to_be_present_in_element_attribute((By.CSS_SELECTOR, "button#dataButton"), "class", "active"))
time.sleep(10)
iframes = driver.find_elements(By.CSS_SELECTOR, "iframe[src*='https://app.powerbi.com/reportEmbed'")
for i in iframes:
try:
driver.switch_to.frame(i)
iframes2 = driver.find_elements(By.CSS_SELECTOR, "iframe[src*='cvSandboxPack.html']")
for i2 in iframes2:
try:
driver.switch_to.frame(i2)
downloads = driver.find_elements(By.CSS_SELECTOR, "a[download='data.csv']")
if len(downloads) > 0:
ActionChains(driver).context_click(downloads[0]).perform()
# Selenium cannot communicate with system dialogs
time.sleep(1)
pyautogui.typewrite(['down','down','down','down','enter'])
time.sleep(1)
pyautogui.press('enter')
time.sleep(2)
return
except StaleElementReferenceException as e:
continue
finally:
driver.switch_to.frame(i)
iframes2 = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.TAG_NAME, "iframe")))
except StaleElementReferenceException as e:
continue
finally:
driver.switch_to.default_content()
iframes = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "iframe[src*='https://app.powerbi.com/reportEmbed']")))

Python Selenium Iframe issue on Bing

I am using selenium driver with python 3.6 and am looking to search for images of coffee cups and download the first image. However, I want the bigger image and the site url so I have selenium driver click on the image and open up the frame. When I try to download the image I get an error that no such element exists. I've tried the two scenarios below
driver.switch_to_frame('#OverlayIFrame')
driver.switch_to_frame(driver.find_element_by_selector('#OverlayIFrame'))
also tried pulling the first element in the frame to see whats there and nothing comes back. I am not sure what I am doing wrong but any help would be great.
bing_url = 'https://www.bing.com/'
driver = webdriver.Chrome()
driver.get(bing_url)
time.sleep(4)
# select the search box and enter a search condition
search_box = driver.find_element_by_xpath('//*[#id="sb_form_q"]')
search_box.send_keys('coffee cups', Keys.ENTER)
# click on the images tab
images_tab = driver.find_element_by_xpath('//*
[#id="b_header"]/nav/ul/li[2]/a')
images_tab.click()
select_first_image = driver.find_element_by_xpath('//*[#id="mmComponent_images_1"]/ul[1]/li[1]/div/div/a/div/img')
select_first_image.click()
# gives error that no such element exists
image_url = driver.find_element_by_xpath('//*[#id="mainImageWindow"]/div[1]/div/div/div/img')
Try this.If it works for you.
select_first_image = driver.find_element_by_xpath("//div[#class='cico br-pdMainImg']")
select_first_image.click()
image_url = driver.find_element_by_xpath("//div[#class='br-pdItemName br-standardText']").text
print(image_url)
driver.execute_script("window.open('{},_blank');".format(image_url))
Found the solution
driver.switch_to_active_element()

How to click the icon using selenium

I am trying to automate my certain activities using selenium. I was launching a webpage and a security windows popup appears for the login credentials.
I have automated that using Autoit. Now after login I need to click on the option and I have tried it based on the find_element_by_text and find_element_by_id.
I was getting an error as Unable to find the element with CSS selector and I have seen some other post in the StackOverflow with the same issue but I could not able to fix it by myself.
Here is how my HTML looks like. Could you please guide me on this and also please share any document for further checking. Thanks.
driver = webdriver.Ie(r"C:\\IEDriverServer\\IEDriverServer.exe")
driver.get('URL of the page')
#driver.implicitly_wait(10) # seconds
autoit.win_wait("Windows Security")
# now make that crap active so we can do stuff to it
autoit.win_activate("Windows Security")
# type in the username
autoit.send('username')
# tab to the password field
autoit.send("{TAB}")
# type in the password
autoit.send('password')
# kill!
autoit.send("{ENTER}")
driver.maximize_window()
driver.implicitly_wait(120) # seconds
#submit_button_incidents = driver.find_element_by_link_text("3-Normal Incidents")
submit_button_incidents= driver.find_element_by_id("nodeImgs13pm")
submit_button_incidents.click()
driver.implicitly_wait(10)
++ updating the info
I have tried to copy the whole HTML but the page was restricted so I cant able to view the full HTML page other than the basic templates. Adding some more screenshots of the developer tools.
Here how my webpage looks like.
try with this code :
submit_button_incidents = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//span[contains(text(),'My Group'])")))
submit_button_incidents.click()
and do not use implicit wait too many times in code.
Implicit wait is set for life time of web driver instance.
Reference :
Selenium official document for wiats
Xpath tutorial
cssSelector tutorial
UPDATE :
As OP has shared the HTML code. As per the requirement you can go ahead with this code.
As there are two elements with text as My Groups's queue.
For first one you can write XPATH as :
//a[#class='scbdtext']/span[contains(text(),'My Group')]
Code:
submit_button_incidents = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='scbdtext']/span[contains(text(),'My Group')]")))
submit_button_incidents.click()
For second one you can write XPATH as :
//a[#class='scbdtextfoc']/span[contains(text(),'My Group')]
Code :
submit_button_incidents = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//a[#class='scbdtextfoc']/span[contains(text(),'My Group')]")))
submit_button_incidents.click()
Hope this will help.
Use ActionChains with double click for this to work in Python.
from selenium.webdriver import ActionChains
# Get the element however you want
element = driver.find_element_by_xpath("//a[#class='scbdtextfoc']/span[contains(text(),'My Group')]")
ActionChains(driver).double_click(settings_icon).perform()

How do I interact with this iframe in selenium

textbox = driver.find_element_by_id('applicant.name')
doesn't work.
Unfortunately and I've tried every variation of inspect element, copy xpath , trying to identify the class name of the text boxes etc.
I want to be able to send some text to the input fields in the indeed-apply-widget seen here.
If you click 'apply now' (unfortunately I can't link it) you'll see the inputs are contained within 2 iframes.
Is there an easy way to access them?
Here's what I have so far:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://ca.indeed.com/cmp/Clearview-Plumbing-&-Heating/jobs/HVAC-Installer-Opening-6183dce44a9bfe10?sjdu=vQIlM60yK_PwYat7ToXhk42rccfWGklJDtD_zDpWBzDCfUEiSP2Zk-zLpFc6GNuF8wyV4_UaMyNFtpjETvX0fCpQXc3PxTbrGkwAMNkR5vGMtAfe9wNpTncItNgAIJHx' )
driver.find_element_by_class_name("indeed-apply-widget").click()
# move into the iframe
iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to_frame(iframe)
Updated Code (still unable to interact with the iframe)
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://ca.indeed.com/cmp/Clearview-Plumbing-&-Heating/jobs/HVAC-Installer-Opening-6183dce44a9bfe10?sjdu=vQIlM60yK_PwYat7ToXhk42rccfWGklJDtD_zDpWBzDCfUEiSP2Zk-zLpFc6GNuF8wyV4_UaMyNFtpjETvX0fCpQXc3PxTbrGkwAMNkR5vGMtAfe9wNpTncItNgAIJHx' )
driver.find_element_by_class_name("indeed-apply-widget").click()
# move into the iframe
path = driver.find_element_by_xpath("/html/body/div[5]/div/div[2]/iframe")
driver.switch_to_frame(path)
driver.find_element_by_xpath('//*[#id="applicant.name"]').sendKeys("TEST_NAME")
The element that you want is inside two nested IFRAMEs. The below code should work. You need to go into the first frame... and then the first nested frame. The rest should work at that point.
driver = webdriver.Firefox()
driver.get('http://ca.indeed.com/cmp/Clearview-Plumbing-&-Heating/jobs/HVAC-Installer-Opening-6183dce44a9bfe10?sjdu=vQIlM60yK_PwYat7ToXhk42rccfWGklJDtD_zDpWBzDCfUEiSP2Zk-zLpFc6GNuF8wyV4_UaMyNFtpjETvX0fCpQXc3PxTbrGkwAMNkR5vGMtAfe9wNpTncItNgAIJHx')
driver.find_element_by_css_selector("span.indeed-apply-button-label")).click()
driver.switch_to_frame(0)
driver.switch_to_frame(0)
driver.find_element_by_id("applicant.name")).send_keys(username)
driver.find_element_by_id("applicant.email")).send_keys(email)
driver.find_element_by_id("resume")).send_keys(resumePath)
driver.find_element_by_css_selector("a.button_content.form-page-next")).click()
driver.find_element_by_id("apply")).click()

How to use find_element_by_link_text() properly to not raise NoSuchElementException?

I have a HTML code like this:
<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span> • <span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span> • </span><span><a
title="Sign Out" class="csiAction csiActionLink">Sign Out</a></span></div>
I would like to click on the link that has the text Home. As this Home link appears after login, I have a code like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The part till login works great. However the last but one line is problematic
elem = browser.find_element_by_link_text("Home")
It raises this NoSuchElementException where the Home link is there as you can see from the HTML code.
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: u'Unable to locate element: {"method":"link text","selector":"Home"}'
Any guidance as to what I am doing wrong, please?
Have you tried adding an implicit wait to this so that it waits instead of running to quickly.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.implicitly_wait(10) #wait 10 seconds when doing a find_element before carrying on
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The implicitly_wait call makes the browser poll until the item is on the page and visible to be interacted with.
The most common issues with NoSuchElementException while the element is there are:
the element is in different window/frame, so you've to switch to it first,
your page is not loaded or your method of page load is not reliable.
Solution could include:
check if you're using the right frame/window by: driver.window_handles,
write a wait wrapper to wait for an element to appear,
try XPath instead, like: driver.find_element_by_xpath(u'//a[text()="Foo"]').click(),
use pdb to diagnose your problem more efficiently.
See also: How to find_element_by_link_text while having: NoSuchElement Exception?
Maybe the element you are looking for doesn't exactly match that text string?
I know it can be tricky if it looks like it does on-screen, but sometimes there are oddities embedded like this simple markup "Home" or "Home" which makes the first char italic:
"<i>H</i>ome" is visually identical to "<em>H</em>ome" but does not match text.
Edit: after writing the above answer, I studied the question closer and discovered the HTML sample does show "Home" in plain text, but was not visible due to long lines not wrapping. So I edited the OP to wrap the line for readability.
New observation: I noticed that the Logout element has a "title" attribute, but the Home link element lacks such--try giving it one and using that.
Try adding an implicit wait to this in order to wait, instead of running too quickly.
Or
else you can import time and use time.sleep(25)

Categories

Resources