Webdriver Selenium click a <li> element inside an Iframe - python-3.x

[![enter image description here][1]][1]trying to click and select the marked
element.
https://i.stack.imgur.com/cIRn8.png
#The options - https://i.stack.imgur.com/e66m1.png
using
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Current attempt:
driver.switch_to.frame(driver.find_element_by_id("moduleManagement")) driver.find_element_by_class_name("ranges").find_element_by_tag_name("ul").find_element_by_tag_name("li").click()
I need help with how to select a
element . where i worng

I would advise you to use explicit wait to switch to frame and interact with them :
to click on second li tag, below code should work for you.
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "moduleManagement")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#colorbox+div[class^='daterangepicker']"))).click()
second_li_element = wait.until(EC.visibility_of_element_located((By.XPATH, "(//li[#data-range-key])[2]")))
second_li_element.click()
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Related

Cannot find element for a popup chart that opens in the same page after clicking a button using selenium package in python. NoSuchElementException

from selenium.webdriver import ActionChains
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://indexes.morningstar.com/our-indexes/fixed-income/F000011BSH")
searchfor = driver.find_element_by_xpath('//*[#id="sal-components-performance"]/div/div[2]/div/div[2]/div/section[1]/div/div[2]/div/div[2]/div/div/div[1]/div[2]/div/div[1]/div')
## This opens the popup chart. Works fine
searchfor.click()
## This is the xpath of the button in that popup chart called "MAX". This throws NoElementFound error
x=driver.find_element_by_xpath('/html/body/div/div[1]/div/div[2]/div[3]/section[1]/div/button[12]').click()
Error:
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div[1]/div/div[2]/div[3]/section[1]/div/button[12]"}
(Session info: chrome=88.0.4324.150)
How to click the buttons in that popup chart window that appears on the same page? I think the element of the popup chart window is not found because it uses the source code of the first page without the popup window code.
use webdriver wait and switch to iframe:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options=webdriver.ChromeOptions()
driver = webdriver.Chrome()
driver.get("https://indexes.morningstar.com/our-indexes/fixed-income/F000011BSH")
driver.find_element_by_xpath('//*[contains(text(),"Show Interactive Chart")]/..').click()
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,
'//iframe')))
## This is the xpath of the button in that popup chart called "MAX". This throws NoElementFound error
WebDriverWait(driver,20).until(EC.presence_of_element_located((By.XPATH,
'/html/body/div/div[1]/div/div[2]/div[3]/section[1]/div/button[12]'))).click()

Can't get this selenium web driver to wait. but I can get it to sleep why?

Been struggling on this for a little while now and I'm pulling my hairout. Why does the 1st code not work? But second one does?
'''from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
driver = webdriver.Chrome(executable_path='/Users/jackrossanderson/Desktop/chromedriver')
driver.get('https://www.url.Iwanttoscrape.com')
search = driver.find_element_by_name('searchbar')
search.send_keys("hometown")
search.send_keys(Keys.RETURN)
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.Class_Name, 'button i want to click'))
)
element.click()
driver.back()
except:
print(error)'''
'''from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome(executable_path='/Users/jackrossanderson/Desktop/chromedriver')
driver.get('https://www.urlIwanttoscrape')
search = driver.find_element_by_name('searchbar')
search.send_keys("home town")
search.send_keys(Keys.RETURN)
time.sleep(12)
element = driver.find_element_by_class_name('button I want to press')
element.click()
driver.back()'''
I know the second way is frowned upon but I cant see why the top one doesnt work?
You can try using
element = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CLASS_NAME, "button i want to click"))) to make the driver wait and click based on the class name
Use, element_to_be_clickable is recommended as mentioned here because, presence_of_element_located description defines that it does not necessarily mean the element is visible or clickable.
Also, check the casing for By.CLASS_NAME used.

Issue with login using selenium and python

I am getting following error
no such element: Unable to locate element: {"method":"xpath","selector":"//input[#placeholder='User ID']"}
(Session info: chrome=78.0.3904.70). Let me know how can i pass user id here
Without additional context, I can only recommend that you wait on the element before sending keys to it:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
input = WebDriverWait(driver, 30).until(
EC.visibility_of_element_located((By.XPATH, "//input[#placeholder='User ID']")))
input.send_keys("userId")
Full working sample as requested by asker:
from selenium import webdriver
from time import sleep
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.get("https://kite.zerodha.com/connect/login?api_key=b8w63qg9m4c3zubd&sess_id=bW3U1OwidO97o11scfeTbyfX4j5tViNp")
input = WebDriverWait(driver, 30).until(
EC.visibility_of_element_located((By.XPATH, "//input[#placeholder='User ID']")))
input.send_keys("userId")
sleep(10) # this sleep is here so you can visually verify the text was sent.
driver.close()
driver.quit()
The above code has succeeded every time I have run it.

How to locate and click "speed test" link on netflix using selenium in python?

I'm a complete beginner with selenium, sorry if the question is dumb (it is dumb):)
I need to find Speed test link on https://www.netflix.com/ and then click it.
i've tried searching by text and some other options. But nothing seems to work, I don't know why.
from selenium import webdriver
from selenium.webdriver.common.keys import Keysfrom selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.get("https://www.netflix.com/")
driver.implicitly_wait(10)
elem = driver.find_element_by_link_text("Speed test")
elem.click()
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"Sign in"}
(Session info: chrome=75.0.3770.142)
The element with text as Speed Test is out ofthe Viewport so you need to induce WebDriverWait for the desired element to be clickable() and you can use the following Locator Strategy:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='footer-link']/span[text()='Speed Test']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Use WebDriverWait and element_to_be_clickable with following xpath.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.netflix.com/")
elem = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[#data-uia='data-uia-footer-label'][contains(.,'Speed Test')]")))
elem.click()
Browser snapshot:
To added to this answer you need to use WebDriverWait and then click on the element Show more info
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.netflix.com/")
elem = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[#data-uia='data-uia-footer-label'][contains(.,'Speed Test')]")))
elem.click()
WebDriverWait(driver,60).until(EC.element_to_be_clickable((By.XPATH,"//a[contains(.,'Show more info' )]"))).click()

How to get rid of the hardcoded sleep()?

def textfield(boxid,textadded):
project = driver.find_element_by_id(boxid)
project.send_keys(textadded)
sleep(3)
def dropdown(dropdownid, dropdownvalue):
select = Select(driver.find_element_by_id(dropdownid))
select.select_by_visible_text(dropdownvalue)
sleep(5)
These 2 functions are functional however i'm using sleep() which is a bad practice since some my drop-downs and text fields will take longer than others to fill so i have to put the longest sleep value not to get errors, how can i fix these 2 functions using wait.
You can explicitly wait for the element. Read more about waits here. Please note that this is not the official documentation.
#.....
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#......
select=WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID ,dropdownid)))
#....
As you are invoking send_keys() on the WebElement project, ideally you should invoke WebDriverWait with EC as element_to_be_clickable, so you have to:
Replace:
def textfield(boxid,textadded):
project = driver.find_element_by_id(boxid)
project.send_keys(textadded)
sleep(3)
with:
def textfield(boxid,textadded):
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "boxid"))).send_keys(textadded)
As the drop-down take longer to fill so you should invoke WebDriverWait with EC as visibility_of_element_located, so you have to:
Replace:
def dropdown(dropdownid, dropdownvalue):
select = Select(driver.find_element_by_id(dropdownid))
select.select_by_visible_text(dropdownvalue)
sleep(5)
with:
def dropdown(dropdownid, dropdownvalue):
select = Select(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.ID, "dropdownid"))))
select.select_by_visible_text(dropdownvalue)
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You should use WebDriverWait!
You can use presence_of_all_elements_located on the list of select items...
An example:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 10).wait.until(EC.presence_of_all_elements_located((By.ID, dropdownid)))
Hope this helps!

Resources