Selenium will not click class id - selenium

I am trying to have selenium to do the following:
Open a website
Click on the search box
Type "Seattle" in the search box
Select the first result from the suggested results
My code fails at Step 2.
The class id for the search box is "class = input_search ng-pristine ng-valid ng-empty ng-touched"
Here's my code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
url = 'https://wego.here.com/'
driver.get(url)
driver.find_element_by_css_selector('.input_search.ng-pristine.ng-valid.ng-empty.ng-touched').click()
driver.find_element_by_css_selector('.input_search.ng-pristine.ng-valid.ng-empty.ng-touched').send_keys('Seattle')
driver.find_element_by_css_selector('.input_search.ng-pristine.ng-valid.ng-empty.ng-touched').send_keys(Keys.ENTER)
Any suggestions would be greatly appreciated!
ADDITIONAL QUESTION
Thanks to #Prophet I was able to get the first auto-click and auto-fill done, but when I try to do the same task with a different search box, it does not like it. Please refer to the following code that I added to the existing code:
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button.btn"))).send_keys(Keys.ENTER)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.itinerary_item_input_0"))).click()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.itinerary_item_input_0"))).send_keys('Chicago')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.itinerary_item_input_0"))).send_keys(Keys.ENTER)
button.btn did work, but not the input.itinerary_item_input_0. Here is the source screenshot:

You are using a wrong locator.
ng-empty and ng-touched may not be there all the times.
So instead of
driver.find_element_by_css_selector('.input_search.ng-pristine.ng-valid.ng-empty.ng-touched').click()
Try using this:
driver.find_element_by_css_selector('input.input_search').click()
input.input_search is an unique, stable locator for that element.
Also, you have to add a delay, preferably to use the expected conditions, as following:
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
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 20)
url = 'https://wego.here.com/'
driver.get(url)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "input.input_search"))).click()

wait=WebDriverWait(driver, 60)
driver.get('https://wego.here.com/')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"input.input_search"))).send_keys("Seattle")
wait.until(EC.element_to_be_clickable((By.XPATH,"//div[#class='dropdown_list']/div[1]"))).click()
This will select the first option after sending a string to input tag.
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Related

How to select subject from an auto complete option?

Website link- https://demoqa.com/automation-practice-form/
I am trying to find xpath for an auto suggested option for Subject field
This is one way of interacting with that dropdown:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
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.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument('disable-notifications')
chrome_options.add_argument("window-size=1280,720")
webdriver_service = Service("chromedriver/chromedriver") ## path to where you saved chromedriver binary
browser = webdriver.Chrome(service=webdriver_service, options=chrome_options)
actions = ActionChains(browser)
url = 'https://demoqa.com/automation-practice-form/'
browser.get(url)
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "subjectsInput"))).send_keys('m')
elusive_el = WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".subjects-auto-complete__menu")))
print(elusive_el.get_attribute('outerHTML'))
maths_option = elusive_el.find_element(By.XPATH, "//div[text()='Maths']")
maths_option.click()
print('selected maths')
This should select the Math option, and also print in terminal the html structure of that element, so you can inspect them, and eventually select other child elements as well - you will have to send another string into that input field, wait for the dropdown to initialize, select another option.
Selenium docs: https://www.selenium.dev/documentation/
HTML of required element is
<div class="subjects-auto-complete__option subjects-auto-complete__option--is-focused css-1n7v3ny-option" id="react-select-2-option-0" tabindex="-1">Maths</div>
Try this one
//div[contains(#class, "subjects-auto-complete__option")]
I am also trying to find xpath for the 'subject' field to select multiple options.
I am able to send the text, but not able to select it from the dropdown.
Here is my code:
driver.findElement(By.id("subjectsInput")).sendKeys("M"); driver.findElement(By.xpath("//div[text()='Maths']")).click();
`Thread.sleep(1000);
Suggest me where I went wrong.

Get text inside the href link inside the span marker using Selenium

How to extract the text which is displayed as part of the link inside the span marker.
<span class="pull-left w-100 font30 medium_blue_type mb10"><a href='/XLY'>XLY</a></span> <span class="w-100">Largest Allocation</span>
Output:
XLY
I've tried several approaches, among all, using
elems = driver.find_elements_by_class_name("span.pull-left.w-100.font30.medium_blue_type.mb10")
elems = driver.find_element_by_xpath('.//span[#class = "pull-left w-100 font30 medium_blue_type mb10"]')
but can't get it working. The website is https://www.etf.com/stock/TSLA.
EDIT:
Is it possible to do it without opening the window in the browser, e.g. using "headless" option?
op = webdriver.ChromeOptions()
op.add_argument('headless')
driver = webdriver.Chrome(CHROME_DRIVER_PATH, options=op)
If you prefer to have a text-based locators, you can use the below:
//span[text()='Largest Allocation']/../span
You should click on the cookies I understand button first.
Make use of explicit waits.
So your effective code would be:
driver = webdriver.Chrome(driver_path)
driver.maximize_window()
wait = WebDriverWait(driver, 30)
driver.get("https://www.etf.com/stock/TSLA")
try:
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "I Understand"))).click()
print("Clicked on I understand button")
except:
pass
txt = wait.until(EC.visibility_of_element_located((By.XPATH, "//span[text()='Largest Allocation']/../span"))).text
print(txt)
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Output:
Clicked on I understand button
XLY
Process finished with exit code 0
If you are looking for locators not based on text, use the below line of code:
txt = wait.until(EC.visibility_of_element_located((By.XPATH, "(//span[contains(#class,'medium_blue_type')]//a)[2]"))).text
There are several possible problems here:
Maybe you are missing a delay
The locator you are using may be not unique
I can see here you are extracting the attribute value from the returned web element
The web element can be inside iframe etc.
Based on currently shared information you can try adding a wait and extracting the web element value as following:
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
wait = WebDriverWait(driver, 20)
href = wait.until(EC.visibility_of_element_located((By.XPATH, "//span[#class = "pull-left w-100 font30 medium_blue_type mb10"]"))).get_attribute("href")
Use the following xpath to identify the href link.
//div[./span[text()='Largest Allocation']]//a
You need to induce some delay to get the element.
Use WebDriverWait() and wait for visibility of the element.
To get the text:
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH, "//div[./span[text()='Largest Allocation']]//a"))).text)
To get the href:
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH, "//div[./span[text()='Largest Allocation']]//a"))).get_attribute("href"))
you need to import below libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Selenium Firefox Webdriver - need help locating button and with code to click button

I'm using Selenium and need to click on a button called Income Statement at http://www.tradingview.com/screener. Could anyone help me to find the button name and let me know if the code where I'm trying to implement it is correct. Any help much appreciated. Thanks!!
url = 'http://www.tradingview.com/screener'
driver = webdriver.Firefox()
driver.get(url)
button_element = driver.find_element_by_xpath("//input[#name='Income Statement']")
button_element.click()
There are 2 problems here:
You have to add wait / delay before accessing that element.
This should preferably be done by expected conditions explicit waits.
You are using a wrong locator.
This should work better:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
url = 'http://www.tradingview.com/screener'
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 20)
driver.get(url)
wait.until(EC.visibility_of_element_located((By.XPATH, "//div[#data-set='income_statement']"))).click()
Your xpath does not locate the right element in the HTMLDOM.
so instead of this:
//input[#name='Income Statement']
use this:
//div[#data-set='income_statement']
or
a CSS like this:
div[data-set = 'income_statement']
explanation:
See this is a outerHTML:
<div class="tv-screener-toolbar__favorites-item js-favorite-item" data-set="income_statement">
Income Statement
</div>
As we can see it is a div tag, so we are using //div and also it has data-set attribute income_statement and when you write the XPath, it is able to locate the right node with 1/1 uniqueness.
Also It's a best practise to use ExplicitWait:
wait = WebDriverWait(driver, 30)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#data-set='income_statement']"))).click()
print('Clicked on the button')
except:
print('Could not click ')
pass
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Python Selenium can't find element by Class Name and xpath

I try to use Selenium to perform click Download button at Historical Data/Time and Sales Historical Data section in webpage: https://www.sgx.com/research-education/derivatives.
I tried the code below:
sgxMainPageUrl = "https://www.sgx.com/research-education/derivatives"
# downloadButtonClassName = "sgx-button--primary"
downloadButtonXpath = "//widget-reports-derivatives-tick-and-trade-cancellation//button[contains(#class,'sgx-button--primary')]"
driver = webdriver.Chrome(chromedriver_path)
driver.get(sgxMainPageUrl)
# search = driver.find_element_by_class_name(downloadButtonClassName)
search = driver.find_element_by_xpath(downloadButtonXpath)
But it returns:
File "...\\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//widget-reports-derivatives-tick-and-trade-cancellation//button[contains(#class,'sgx-button--primary')]"}
I read several post and they faced this problem because duplicate xpath but this xpath is unique. Please help me explain why, many thanks!
There's an Accept cookies button, you need to click first. after that you can use the below xpath to click on download button :
(//button[text()='Download'])[1]
Code :
driver.get(sgxMainPageUrl)
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[class*='banner-acceptance-button']"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "(//button[text()='Download'])[1]"))).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
You should add a wait to let the page loaded before accessing that element.
Try this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((By.XPATH, downloadButtonXpath))).click()

Select on complicated a tag with Selenium

I am trying to click on an "a-tag" n a web page using selenium.
Basically my objective is to click on that button which will redirect me on another webpage.
The a-tag looks as follows:
<a class="SheetInfoLink xl35" href="/ux/WebReport/tabbedsummarypage.aspx?itemId=118685&lType=modData&compId=1002&showTabs=" onclick="javascript:spSPGetModData('118685', '1002' ,'', 'modData');return false;" style="border:0px">Zolgensma</a>
I am using something likee this:
driver = webdriver.Chrome()
driver.get("https://app.evaluate.com/ux/WebReport/tabbedsummarypage.aspx?itemId=10&lType=modData&compId=1006&tabId=")
button = driver.find_element_by_xpath("//a[#data-trackable='sign-in']")
button.click()
but it does not work.
Any suggeestion?
Thank you all!
try with explicit wait :
code :
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#href, '/ux/WebReport/tabbedsummarypage.aspx') and text() ='Zolgensma']"))).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