Selenium Python : pick element from drop down in a span - python

i am relatively new to Selenium , I am working on a web browser automation project and one of the action is to pick a element from an drop down menu please find below the html code.
<span id="export_menu" class="ui-button drop-down export-menu" tabindex="0" role="application">
<span class="menu_text">Export</span>
<span class="drop-down-menu ui-icon ui-icon-triangle-1-s"></span>
<ul class="export-actions"><li><header>Export Report</header>
<ul><li class="menu-action"><input type="button" value="CSV" class="button ui-button ui-widget ui-state-default ui-corner-all" id="export_csv" data-format="csv" role="button" aria-disabled="false"></li></ul>
<ul><li class="menu-action"><input type="button" value="PDF" class="button ui-button ui-widget ui-state-default ui-corner-all" id="export_pdf" data-format="pdf" role="button" aria-disabled="false"></li></ul>
<ul><li class="menu-action"><input type="button" value="Schedule Export" class="button ui-button ui-widget ui-state-default ui-corner-all" id="schedule" role="button" aria-disabled="false"></li></ul></li></ul>
</ul>
</span>
I tried following on Python, which give out error as below
driver.find_element_by_id("export_menu").click()
driver.find_element_by_id("export_csv").click()
selenium.common.exceptions.ElementNotInteractableException: Message: Element could not be scrolled into view
after some research I also tried following, which simply timeouts
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="export_csv"]'))).click()
requesting help!

To pick the element with value as CSV from an drop-down-menu you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.ui-button.drop-down.export-menu#export_menu"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul.export-actions li.menu-action > input.button.ui-button.ui-widget.ui-state-default.ui-corner-all#export_csv"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#class='ui-button drop-down export-menu' and #id='export_menu']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='export-actions']//li[#class='menu-action']/input[#class='button ui-button ui-widget ui-state-default ui-corner-all' and #id='export_csv']"))).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
You can find a relevant discussion in How to select an option from a dropdown of non select tag?

Try first clicking the <ul>:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, '//*[#class="export-actions"]'))).click()
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="export_csv"]'))).click()

Related

Selenium click button with <a> tag - intercepted exception

I am trying to click a button on a website in Python using Selenium. The html for the button I want looks like this:
<a onclick="exportGridExcel()"><span class="accordion-download"><i class="fa fa-file-excel-o" title="Download Excel" aria-hidden="true"></i></span></a>
A more expanded version of the html is:
<div class="lang-switch-wrapper lang-switch-inverse-wrapper">
<div class="lang-switch">
<ul>
<li class="dropdown">
<a href="#" class="dropdown-toggle lang-lable" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class=" hidden-xs">English</span>
<span class="hidden-lg hidden-md hidden-sm">EN</span>
<img src="/etc/designs/wbrrdesign/clientlibs-wbrredsign/img/angle-down-gray.svg" alt="dropdown"></a>
<ul class="dropdown-menu dropdown-item">
<li>Español</li>
</ul>
</li>
</ul>
</div>
</div>
Then some other stuff before going to the button group and button I want:
<div class="button-group">
<button onclick="onModifyQuery()" type="button" class="btn">Modify Query</button>
<a onclick="exportGridExcel()"><span class="accordion-download"><i class="fa fa-file-excel-o" title="Download Excel" aria-hidden="true"></i></span></a>
<a title="Undo to column removal" onclick="restoreColumn()" class="toggle-btn primary-light-blue-btn"><i class="fa fa-circle-o-notch" aria-hidden="true"></i></a>
</div>
Part of my confusion is inexperience with this html with multiple classes and "i class".
EDIT:
If I try something like:
WebDriverWait(driver,300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick='exportGridExcel()']"))).click()
Then I get the error:
ElementClickInterceptedException: element click intercepted: Element <a onclick="exportGridExcel()">...</a> is not clickable at point (772, 11). Other element would receive the click: <div class="lang-switch-wrapper lang-switch-inverse-wrapper">...</div>
The problem is that your page is automatically scrolled up and the excel download button is probably hidden by the top banner that contains the language selector. When Selenium tries to click on the excel download button, it finds the language selector instead.
I would suggest you to scroll the page up till the whole data table is visible
You can use something like this. Press HOME key to go to top of the page
from selenium.webdriver.common.keys import Keys
...
...
element = WebDriverWait(driver,300).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick='exportGridExcel()']")))
element.send_keys(Keys.CONTROL + Keys.HOME)
element.click()
Ideally clicking on the element <a onclick="exportGridExcel()"> as per your code trials inducing WebDriverWait for the elementToBeClickable() should have worked.
However, there seems to be a decendant <span>. So you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick^='exportGridExcel'] > span.accordion-download"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[starts-with(#onclick, 'exportGridExcel')]/span[#class='accordion-download']"))).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
In another approach you can also use JavascriptExecutor as follows:
Using CSS_SELECTOR:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a[onclick^='exportGridExcel'] > span.accordion-download")))
driver.execute_script("arguments[0].click();", element)
Using XPATH:
element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[starts-with(#onclick, 'exportGridExcel')]/span[#class='accordion-download']")))
driver.execute_script("arguments[0].click();", element)

Python Selenium input date in ng datepicker

I am trying to input a date into the text portion of a datepicker and send_keys is not working.
Here is the html:
<date-picker _ngcontent-bdp-c11="" _nghost-bdp-c3="">
<div _ngcontent-bdp-c3="" class="datePicker formDiv-header datePickerContainer">
<div _ngcontent-bdp-c3="" class="formLabel-header">
<!---->
<label _ngcontent-bdp-c3="" for="dateInput1">Search Date:</label>
<!---->
</div>
<div _ngcontent-bdp-c3="" class="formField-header" style="padding:0;">
<div _ngcontent-bdp-c3="" class="input-group date" id="dateTimePicker1">
<input _ngcontent-bdp-c3="" class="form-control formField-header" maxlength="10" type="text">
<span _ngcontent-bdp-c3="" class="input-group-addon"><span _ngcontent-bdp-c3="" class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
</date-picker>
<search-button _ngcontent-bdp-c11="" _nghost-bdp-c4="">
<button _ngcontent-bdp-c4="" class="selectionButton" type="button"> Search
</button></search-button>
Here is my code:
dateInputfield = driver.find_element_by_xpath('// *[ # id = "dateTimePicker1"] / input')
# the dateInputfield: <selenium.webdriver.remote.webelement.WebElement (session="6911b2bc422dac02d926b3b36429e8de", element="0.8362094047920967-3")>
dateInputfield.send_keys('01/15/2021')
searchbt = driver.find_element_by_xpath('//*[#id="filters"]/search-button/button')
searchbt.click()
Alternatively, I have tried to click the calendar icon, which actually opens the calendar for selection, but I don't know how to navigate to a given date in order to select it.
calicon = driver.find_element_by_xpath('//*[#id="dateTimePicker1"]/span/span')
calicon.click()
Any help would be appreciated.
To send the date characters to the element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "div.input-group.date#dateTimePicker1 > input.form-control.formField-header").send_keys('01/15/2021')
Using xpath:
driver.find_element(By.XPATH, "//div[#class='input-group date' and #id='dateTimePicker1']/input[#class='form-control formField-header']").send_keys('01/15/2021')
Ideally, to send the date characters to the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.input-group.date#dateTimePicker1 > input.form-control.formField-header"))).send_keys('01/15/2021')
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='input-group date' and #id='dateTimePicker1']/input[#class='form-control formField-header']"))).send_keys('01/15/2021')
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

How to click available button which refuses the click?

I'm working on automation of one website. My problem is that the button which is visible in my selenium (simply prints out) stopped working after recent update. Eventho I can see it, I cannot click it. I've noticed that it has started to have dynamic id selector, but class stays stable. What that can be ? Is there any other way to click it ?
<div>
<div>
<div class="pull-left middle-col-4">
<!---->
</div>
<div class="pull-left middle-col-4">
<!---->
</div>
</div>
<button tabindex="-1" id="exit-button-ZpyYaHCdmZ5jnmaamGhjaJjFcsVrmJOUcZWVaZlsaGlolpOaZg" class="btn btn-inverse btn-large pull-right">Wyjście</button>
</div>
To Click on the button induce WebDriverWait and element_to_be_clickable() And following locator strategy.
By Css Selector:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.btn.btn-inverse.btn-large.pull-right"))).click()
By Xpath:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//button[#class='btn btn-inverse btn-large pull-right' and starts-with(#id,'exit-button-')][text()='Wyjście']"))).click()
You need to import followings to execute above code.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Please find below solution to click exit button if id is dynamic
1. Xpath and contains method
button=driver.find_element_by_xpath("//button[contains(text(), 'Wyjście')]")
button.click()
2. Class name
element = driver.find_element_by_class_name("btn btn-inverse btn-large pull-right")
element.click()

How to click on item in navigation bar on top of page using selenium python?

I am trying to test a web page using selenium python. All is working well but issue is encountering when clicking on navbar item
I have used:
driver.find_element_by_xpath('./li/a[. = "Log in"]')
Also have used:
driver.find_element_by_link_text('Log in')
Nothing got luck !!
The code snippet:
<div class='container'>
<div class='navigationbar__header'>
<a class='navigationbar__header__logo tracking-link' data-link-name='logo' href='/' target='_self'>
<div id='hired-brand'>HIRED</div>
</a>
</div>
<div class='navigationbar__toggle'>
<div class='navigationbar__toggle__element'>
<img alt='Menu' class='icon icon--sandwich' src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'>
</div>
<input class='navigationbar__toggle__helper' type='checkbox'>
<ul class='navigationbar__navigation'>
<li class="navigationbar__item "><a class="sm-ml0 tracking-link" data-link-name="employers_page" target="_self" href="/employers">For Employers</a></li>
<li class="navigationbar__item "><a class="sm-ml0 tracking-link" data-link-name="success_stories" target="_self" href="/success-stories">Success Stories</a></li>
<li class="navigationbar__item "><a class="sm-ml0 tracking-link" data-link-name="employers_resources" target="_self" href="/employers/resources">Resources</a></li>
<li class="navigationbar__item "><a class="text-medium sm-ml0 tracking-link" data-link-name="login" target="_self" href="/login">Log in</a></li>
<div class='xs-ptb1 xs-prl1 md-ptb0 md-inline-block'><li class="navigationbar__item "><a class="button button--primary tracking-link" data-link-name="signup" target="_self" href="/signup">Sign Up</a></li></div>
</ul>
</div>
</div>
</nav>
This code is visible on page inspect easily. Anyone know the better way to interact with it?
To click() on the link with text as Log in within the website you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "li.navigationbar__item a[data-link-name='login'][href='/login']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='navigationbar__item ']/a[#data-link-name='login' and #href='/login']"))).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
Browser Snapshot:
Update
As an alternative you can use execute_script() as follows:
Using CSS_SELECTOR:
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "li.navigationbar__item a[data-link-name='login'][href='/login']"))))
Using XPATH:
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='navigationbar__item ']/a[#data-link-name='login' and #href='/login']"))))
Ok so I checked the site.
The problem is that when the window size is small there is toggle for navigation that you need to click first.
try this
from selenium.common.exceptions import NoSuchElementException
try:
login_button = driver.find_element_by_link_text('Log in')
login_button.click()
except NoSuchElementException:
nav_bar_toggle = driver.find_element_by_class_name(
'navigationbar__toggle__helper'
)
nav_bar_toggle.click()
login_button = driver.find_element_by_link_text('Log in')
login_button.click()

How to click on a Radio Button as per the HTML using Selenium and Python

I am trying to click on element with following html code:
<div class="delivery-pseudo-table">
<div class=" i-popup-lk user-address" id="userAddress">
<div class="address-container">
<div class="titlebar">
<h1 class="title"></h1>
</div>
<div id="userAddressContent"></div>
</div>
<div class="hide j-map map" id="addressMap"></div>
<div class="hide j-map-pickpoint postamat-map" id="pickpointMap"></div>
<div class="added-addres-loader"></div>
</div>
<ul class="delivery-method" data-jsv-df=""><li class="selfDelivery selectDeliveryWay active" data-jsv="#34_#35_" title="">
<script type="jsv#37_"></script>
<label><input autocomplete="off" checked="checked" data-id="2" name="orderDetails.DeliveryWay_q" type="radio" value="Self"/>Самовывоз</label>
<script type="jsv/37_"></script>
</li><li class="courierDelivery selectDeliveryWay" data-jsv="/35_#38_" title="">
<script type="jsv#39_"></script>
<label><input autocomplete="off" data-id="1" name="orderDetails.DeliveryWay_q" type="radio" value="Courier"/>Доставка курьером</label>
<script type="jsv/39_"></script>
</li><li class="wbpostamatDelivery selectDeliveryWay" data-jsv="/38_#40_" title="">
<script type="jsv#41_"></script>
<label><input autocomplete="off" data-id="16" name="orderDetails.DeliveryWay_q" type="radio" value="WbPostamat"/>Постамат</label>
<script type="jsv/41_"></script>
</li></ul>
I need to click on button with value "Courier"
And I am trying to do it with following Python code:
elem = browser.find_element_by_css_selector("input[type='radio'][#value='Courier']")
elem.click()
(I've also tried to find by xpath)
But it says that the element is invisible. Are the any ways to click on such element?
Try to use this xPath:
//input[#type='radio' and #value='Courier']
also try to use WebDriverWait:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#type='radio' and #value='Courier']"))).click()
Note: you have to add some imports:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
WebDriverWait statement is for waiting at least 10 seconds until element will be clickable and only then clicks on it.
PS: more information about WebDriverWait can be found here.
EDIT: try to execute JavaScript:
radio_btn = driver.find_element_by_xpath("//input[#type='radio' and #value='Courier']")
driver.execute_script("arguments[0].click();", radio_btn)
As per the HTML you have shared the <ul> tag contains a lot of JavaScripts so to invoke click() on the desired element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul.delivery-method li.courierDelivery.selectDeliveryWay input[value='Courier']"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='delivery-method']//li[#class='courierDelivery selectDeliveryWay']//input[#value='Courier']"))).click()

Categories