Selenium: Can't find element by class name in any way - python

I have this problem where I can't access a button trough it's class name in any way I could think of.
This is the HTML:
<button class="expand-button">
<faceplate-number pretty="" number="18591"><!---->18.591</faceplate-number> weitere Kommentare anzeigen
</button>
I tried to access it using:
driver.find_element(By.CLASS_NAME, "expand-button")
But the error tells me that there was no such element.
I also tried X-Path and Css-Selector which both didn't appear to work.
I would be glad for any help!
Kind Regards and Thanks in advance
Eirik

Possible issue 1
It could be because you check before the element is created in the DOM.
One way to solve this problem is by using the waites option like below
driver.implicitly_wait(10)
driver.get("http://somedomain/url_that_delays_loading")
my_dynamic_element = driver.find_element(By.ID, "myDynamicElement")
You can read more about it here: https://www.selenium.dev/documentation/webdriver/waits/#implicit-wait
Another way is by using the Fluent Wait whhich marks the maximum amount of time for Selenium WebDriver to wait for a certain condition (web element) becomes visible. It also defines how frequently WebDriver will check if the condition appears before throwing the “ElementNotVisibleException”.
#Declare and initialise a fluent wait
FluentWait wait = new FluentWait(driver);
#Specify the timout of the wait
wait.withTimeout(5000, TimeUnit.MILLISECONDS);
#Sepcify polling time
wait.pollingEvery(250, TimeUnit.MILLISECONDS);
#Specify what exceptions to ignore
wait.ignoring(NoSuchElementException.class)
#specify the condition to wait on.
wait.until(ExpectedConditions.element_to_be_selected(your_element_here));
you can also read more about that from the official documentation
https://www.selenium.dev/documentation/webdriver/waits/#fluentwait
Possible issue 2
it is also possible that the element might be partially or completely blocked by an element overlaying it. If that is the case, then you will have to dismiss the overlaying element before you will be able to perform any action on your target

Related

Finding XPath without using inspecting element?

I am making an automation for download data from a weather institution.
The issue is that in my effort to make it more independent I am trying to make Selenium to Tab keys to a certain spot, so the Browser focus can "Walk" to the download button. When I call the click() function it doesn't do anything. So I tried to Extract the XPath with the function get_attribute("xpath") but it returns None. How I can extract the XPath?
I am going to paste the issue down here:
Bandera=driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input')
Bandera.click()
Bandera.click()
## So Here i just select and dis-select a checkbox just to be near the Download button.
actions = ActionChains(driver)
actions.send_keys(Keys.TAB * 1 )
actions.perform()
#Here i just tabed to the button
Accion=driver.switch_to.active_element
#Maybe, here is when i lost the focus of the button?
Descarga_Actual=Accion.get_attribute("xpath")
Thank you and sorry to borrow your time.
To make a click on hover I would use the following sequence:
your_dropdown_locator.click()
dropdown_option = driver.find_element_by_xpath("dropdown option locator")
actions = ActionChains(driver)
actions.move_to_element(dropdown_option)
actions.click().perform()
But, this is the approach that is usually used for dropdowns.
You use: driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div/div/div/div[1]/div/div/div[2]/div/table/tbody/tr[1]/td[1]/div/input') This is the main problem of your code.
If you pasted html code of this dropdown (or button you need to click), people would help you to find a better locator. XPath/CSS must be unique. In your case the locator is very bad.
Also, I see no sense making Bandera.click() two times.
In your case, as I understand, you just need to click the button. So the locator is your main problem.
You need to find the correct locator, to wait till the button is clickable and then to click it.
Another problem in what you are trying to do:
get_attribute("xpath") looks like incorrect expectation of how get_attribute function works. Check at least here what this function means Python Selenium: Find object attributes using xpath

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page

driver.get("https://www.zacks.com/")
driver.find_element_by_xpath("//*[#id='search-q']")
i am trying to find search box on zacks website with selenium but I am getting StaleElementReferenceException
The reason why you're getting this error is simply, the element has been removed from the DOM. There are several reasons for this:
The page itself is destroying/recreating the element on the fly, maybe even rapidly.
Parts of the page have been updated (replaced), but you're still having and old reference.
You navigate to a new page but holding an old reference.
To avoid this, try to keep the element reference as short as possible. If the content is rapidly changing, make the operation directly without the round trip to the client, via javascript:
driver.executeScript("document.getElementById('serach-q').click();");
Maybe you're trying to find while the page and this exact search box are loading. Try to implement wait mechanism for this element, smth like that:
WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(locator));

Explicit wait not working for a checkbox selenium

I'm trying to implement an explicit wait before giving a click on a checkbox:
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.XPATH, "pay_type_list_item_id_salary"]")))
self.driver.find_element_by_xpath('//input[#id="pay_type_list_item_id_salary"]').click()
My problem is that my explicit wait keeps sending the error:
not clickable at point (663, 478). Other element would receive the click.
I'm trying to use different kind of explicit waits like visibility_of_element_located or invisibility_of_element_located (using an element from the previous step on my script), but no luck with those options.
If I add a time.sleep(1) between the 2 lines my scripts works but I know it's not the most efficient thing to use time.sleep.
The previous step before this one opens a calendar and I'm not sure if it tries to give the click when the calendar is closing and that's the reason to receive this error.
The error you are getting is indicating that another element is covering the element you are trying to click. If you look at the error message (you really should post the full error message in your question), it will tell you the HTML of the element that is in the way. That will give you a good idea of what element is blocking the click so you can find it and figure out what part of the page it is. Then you can wait for it to get out of the way. From your description, it sounds like you need to add a wait for the calendar to close.

Rewrite click() method in Selenium 2 (python)

I'm using Seleniun 2 webdriver (python) to run auto tests on IE browser.
One of major bugs in IE webdriver is that click() method does not work in 100% of cases. It happens sometimes when IE browser cannot set/looses focus on element. So, there's a workaround i googled to solve the problem- first the parent element must be clicked/selected. After that click() on the current element always works.
I would like to add my own method, named for ex. ieclick() that would do something like:
element = driver.find_element_by_id('id')
parentElement = element.find_element_by_xpath('..')
parentElement.click()
element.click()
Instead of writing all this code i would like to make:
driver.find_element_by_id('id').ieclick()
But i don't know how to implement this. I'm lost in Selenium modules code. I know that selenium class has click() method but i can't understand how can i rewrite it/add my own and make it useble for all this find_element_by_id, find_element_by_xpath etc.
Can someone help me to understand this implementation or maybe paste a link to some sort of explanation/example/lesson ?
The only reason that an element would not receive a click is because :
The element is disabled.
The element is invisible (therefore, cannot interact with it)
The element is not listening for any clicks (not binded)
My guess is that your "inconsistency issue" is coming form the third reason.
Consider the following:
<a href="dosomething">
<span id="spanclick">Click me</span>
</a>
Doing driver.find_element_by_id("spanclick").click() would not work, because it's the <a> element that is receiving the click, not the <span>.
It's your responsibility as the test writer to determine which element is receiving the click. My suggestion would be use debugging anytime you are in doubt. I've actually had a scenario where an <li> was receiving the actions of the mouse, not the <a>. By using Watch Expressions you are able to find what element is receiving the actions.
Seems i was exaggerating the difficulty.
selenium\webdriver\remote\webelement.py
Added code right after native click() method:
def ieclick(self):
"""2013-12-27. Surely clicks the element in IE."""
parent = self.find_element(by=By.XPATH, value='..')
parent._execute(Command.CLICK_ELEMENT)
try:
self._execute(Command.CLICK_ELEMENT)
except:
pass

Selenium Webdriver - NoSuchElementExceptions

I am using the python unit testing library (unittest) with selenium webdriver. I am trying to find an element by it's name. About half of the time, the tests throw a NoSuchElementException and the other time it does not throw the exception.
I was wondering if it had to do with the selenium webdriver not waiting long enough for the page to load.
driver = webdriver.WhatEverBrowser()
driver.implicitly_wait(60) # This line will cause it to search for 60 seconds
it only needs to be inserted in your code once ( i usually do it right after creating webdriver object)
for example if your page for some reason takes 30 seconds to load ( buy a new server), and the element is one of the last things to show up on the page, it pretty much just keeps checking over and over and over again if the element is there for 60 seconds, THEN if it doesnt find it, it throws the exception.
also make sure your scope is correct, ie: if you are focused on a frame, and the element you are looking for is NOT in that frame, it will NOT find it.
I see that too. What I do is just wait it out...
you could try:
while True:
try:
x = driver.find_by_name('some_name')
break
except NoSuchElementException:
time.sleep(1)
# possibly use driver.get() again if needed
Also, try updating your selenium to the newest version with pip install --update selenium
I put my money on frame as I had similar issue before :)
Check your html again and check if you are dealing with frame. If it is then switching to correct frame will be able to locate the element.
Python
driver.switch_to_frame("frameName")
Then search for element.
If not, try put wait time as others suggested.
One way to handle waiting for an element to appear is like this:
import selenium.webdriver.support.ui as ui
wait = ui.WebDriverWait(driver,10)
wait.until(lambda driver: driver.find_by_name('some_name') )
elem = driver.find_by_name('some_name')
You are correct that the webdriver is not waiting for the page to load, there is no built-in default wait for driver.get().
To resolve this query you have to define explicit wait. so that till the time when page is loading it will not search any WebElement.
below url help on this.
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
You need to have a waitUntil (your element loads). If you are sure that your element will eventually appear on the page, this will ensure that what ever validations will only occur after your expected element is loaded.
I feel it might be synchronisation issue (i.e webdriver speed and application speed is mismatch )
Use Implicit wait:
driver.manage.timeouts.implicitlyWait(9000 TIMEUNITS.miliseconds)
Reference

Categories