How to Select Element Based on Parameters Passed in Button Onclick Method - python

I want to be able to select the button that has the timestamp i am targeting. Here is the HTML:
<a class="mdc-button mdc-button--unelevated mdc-ripple-upgraded" href="#" onclick="selectTime(7160, null, "2021-08-23T08:15:00-04:00", '8b96beed5b0b8f7b34e51853f14ef6eb'); return false;" style="--mdc-ripple-fg-size:55px; --mdc-ripple-fg-scale:1.97805; --mdc-ripple-fg-translate-start:17px, -19.5px; --mdc-ripple-fg-translate-end:18.5px, -9.5px;">
<div class="mdc-button__ripple"></div>
<span class="mdc-button__label">8:15 AM</span>
</a>
I do not know how to target the timestamp parameter it is calling in onclick that can be used to select the button. I have tried to find element by targeting the label's text, but I cannot click on the label, with it giving me this error :
Message: element click intercepted: Element <span class="mdc-button__label">...</span> is not clickable at point (132, 380). Other element would receive the click: <div class="mdc-button__ripple"></div>
Any help would be greatly appreciated.

You can use the below css_selector :
a[class$='mdc-ripple-upgraded'] span[class='mdc-button__label']
use it like this :
wait = WebDriverWait(driver, 10)
ActionChains(driver).move_to_element(wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "a[class$='mdc-ripple-upgraded'] span[class='mdc-button__label']")))).click().perform()
Imports :
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

Related

Not able to target 2nd matching element by XPATH

I have a html content like this
<div class="ng-star-inserted">
<span class="ng-star-inserted">
Seismic interpreter
</span>
<span class="ng-star-inserted">
Geophysicist
</span>
</div>
I have a selenium script where I am trying to get the first role name and second role name.
I tried this, but it's not giving me the 1st and 2nd elements as expected. Any idea what am I missing? thanks!
'//div[#class="ng-star-inserted"]//span//a[1]'
'//div[#class="ng-star-inserted"]//span//a[2]'
You can xpath indexing in this case :
so instead of this :
'//div[#class="ng-star-inserted"]//span//a[1]'
'//div[#class="ng-star-inserted"]//span//a[2]'
use this :
"(//div[#class='ng-star-inserted']//span//a)[1]"
"(//div[#class='ng-star-inserted']//span//a)[2]"
or if you think the text won't change, you can make use of LINK_TEXT as well or PARTIAL_LINK_TEXT
Sample code :-
wait = WebDriverWait(driver, 10)
button1 = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Seismic interpreter")))
button1.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
So you can use the below way
((//a[contains(text(),'Seismic interpreter')])[2])
((//a[contains(text(),'Geophysicist')])[2])
clickLink=WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"((//a[contains(text(),'Seismic interpreter')])[2])")))
checkbox.click()

Python Finding element by XPath

For reference visit https://rabirius.me/2020/02/14/bird-watching/ (not my website)
You may see a Like button there near a reblog button
I want python to click that but I get an error stating
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/div[2]/a"}
The code i wrote was
for posts in open_links:
bot.get(posts)
sleep(4)
bot.find_element_by_xpath('/html/body/div/div/div[2]/a').click()
sleep(2)
The HTML of the like button is
<div class="wpl-button like">
<a href="#" title="177 bloggers like this." class="like sd-button" rel="nofollow">
<span>Like</span>
</a>
</div>
Any Help would be Appreciated
An iframe is present on the page, so you need to first switch to that iframe and then operate on the element and its recommended to use explicit wait to wait for the element to be present on the page.
You can do it like:
for posts in open_links:
bot.get(posts)
driver.switch_to.frame(bot.find_element_by_tag_name('iframe'))
like_element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class,'wpl-likebox')]//span[text()='Like']")))
like_element.click()
You need 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

UnexpectedTagNameException while clicking dropdown menu item

I'm trying to get Python / Selenium to properly click on a dropdown menu and select "IT" but the best I could do was find the element and get an error stating I couldn't input text on what I have found.
Basically, the user would click on that menu and select IT or type IT and press enter.
HTML code:
<div class="form-group">
<label class="col-md-3 control-label" for="id_tenant_group">Tenant group</label>
<div class="col-md-9">
<select name="tenant_group" nullable="true" class="netbox-select2-api form-control" data-url="/api/tenancy/tenant-groups/" data-filter-for-tenant="group_id" placeholder="None" id="id_tenant_group">
<option value="" selected>---------</option>
<option value="2">IT</option>
<option value="1">OT</option>
</select>
</div>
When I inspect the element, I can see there is a span element that triggers an event showing another span where finally my option can be seen.
I cannot select via visible text, because other menus also contain the same "---------" visible text.
I've captured a couple screenshots to illustrate the issue, hope that helps.
html code browser inspect
To be honest I am really lost, any suggestions will be much appreciated.
EDIT:
I've attempted the following:
tenant_g_element = Select(browser.find_element(By.XPATH, '//span[#id="select2-id_tenant_group-container"]'))
tenant_g_element.selectByVisibleText("IT")
But I've got the following error:
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on <select> elements, not on span
Your first line is wrong. It should be something like this:
tenant_g_element = Select(browser.find_element(By.ID, 'id_tenant_group'))
because your has the attribute id="id_tenant_group". There is no need to use By.XPATH...if you have some reason to need that, then you'll need to look up how to specify an XPATH (note that //span is going to find a <span>, not a <select> for example).
This error message...
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on elements, not on span
...implies that the element which you are passing to Select class is not a <select> node but a <span> element which isn't supported.
Seems your locator was identifying a <span> element instead of the <select> element. Hence you see the error. Additionally, selectByVisibleText() is not a valid Python method, instead you need to use select_by_visible_text().
Solution
To click on the option with text as IT, you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and select_by_value():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.netbox-select2-api.form-control#id_tenant_group[name='tenant_group']"))))
tenant_g_element.select_by_value("2")
Using XPATH and select_by_visible_text():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#class='netbox-select2-api form-control' and #id='id_tenant_group'][#name='tenant_group']"))))
tenant_g_element.select_by_visible_text("IT")
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
from selenium.webdriver.support.ui import Select
Your Xpath seems wrong. You are trying to locate a span tag but you should locate select element. Additionally you should apply webdriver wait for of select element
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.support.ui import Select
select = Select(WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.ID, "id_tenant_group"))))
WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.XPATH, "//select[#id='id_tenant_group']/option[2]")))
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='id_tenant_group']//options[contains(.,'IT')]")))
select.select_by_visible_text('IT')

how to find button to click in Selenium using python?

</div>
<fieldset class="pi-search-form__footer">
<div class="pi-search-form__footer-cta" data-ng-show="stay.isStandardBooking()">
<button class="btn btn--primary" data-ng-click="submitSearch()">
<span data-ng-switch="ctaText">
<span data-ng-switch-when="checkavailability">Check availability</span>
<span data-ng-switch-when="searchnow">Search now</span>
<span data-ng-switch-default data-pi-track-click="SEARCH_AGAIN">Search</span>
</span>
</button>
</div>
This is my button code and I want to click "Check availability" button.
I use that code but it not works.
browser.find_elements_by_xpath(".//span[contains(text(), 'Check availability')]")
Here is the Answer to your Question:
As you want to click on a button so your xpath should be unique and should identify a single element. Hence instead of find_elements_by_xpath you should consider using find_element_by_xpath. To click on the Check availability button you can use the following line of code:
//ensure the imports
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
//other code
//click on Check availability button
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn--primary']//span[#data-ng-switch-when='checkavailability']")))
browser.find_element_by_xpath("//button[#class='btn btn--primary']//span[#data-ng-switch-when='checkavailability']").click()
Let me know if this Answers your Question.
it should be
browser.find_elements_by_xpath(".//span[contains(text(), 'Check availability')]")
and if it's not working use explicit wait.
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 30)
checkAvailability = wait.until(EC.presence_of_element_located((By.XPATH, ".//span[contains(text(), 'Check availability')]")))

Selenium Web-driver Click Button

[Python 2.7, Selenium Web-driver]
So there's this Website:
<div class="flex-module-header">
<h3><span class="trend-location js-trend-location">Greece Trends</span></h3>
<span class="middot">ยท</span> <a role="button" href="#" data-modal="change-trends" class="change-trends js-trend-toggle">Change</a>
And I want to click the button:
<a role="button" href="#" data-modal="change-trends" class="change-trends js-trend-toggle">Change</a>
And I've tried everything (trying to locate by xpath, class etc.), and I can't seem to be able to do what I'm looking for.
I basically want to click the button, that's all.
As you didn't provide error stack trace and tried code, Assuming you didn't use WebDriverWait yet to wait until element visible and clickable. So I'm giving the example with this as below :-
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, 10)
link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Change")))
link.click()
Note :- Before using this, make sure element is not present inside a frame or iframe. If element is present inside a frame or iframe you need to switch that frame before finding the button as driver.switch_to_frame("frame name or id").
Hope it helps...:)

Categories

Resources