Using Python bindings, Selenium WebDriver click() is not working sometimes.
Asked Answered
K

9

31

I am trying to submit an input(type= button).But I am unable to update the value. Any help is appreciated. I have attached the testcase below for your reference.

search for CLICK FAILS HERE

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re,datetime,os,sys

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains


def is_element_present(inst,selector,value):
    try:
        inst.find_element(by=selector, value=value)
        return True
    except:
        return False



class Testing(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(5)
        self.base_url = "http://new.ossmoketest.appspot.com/"
        self.verificationErrors = []

    def test_ing(self):
        try:

            driver = self.driver
            driver.get(self.base_url + "/Apab4b39d4_09d7_11e1_8df9_139372201eeb/1/signin?forward=/%3F")
            now = datetime.datetime.now()
            start = time.clock()

            for i in range(5000000):
                try:
                    if is_element_present(driver,By.ID,"userid"): break
                except: pass
            else: self.fail("time out")
            end = time.clock()
            diff = end - start
            print diff
            driver.find_element_by_id("userid").clear()
            driver.find_element_by_id("userid").send_keys("[email protected]")
            driver.find_element_by_xpath("//input[@src='/static/images/signup.png']").click()
            print 'finished'
            start = time.clock()

            for i in range(5000000):
                try:
                    if is_element_present(driver,By.LINK_TEXT,"Logout"): break
                except: pass
            else: self.fail("time out")
            end = time.clock()
            diff = end - start
            print diff
            time.sleep(5)

            start = time.clock()
            name = "smoketest"+ str(now.minute) +str(now.second)
            for i in range(5000000):
                try:
                    if is_element_present(driver,By.LINK_TEXT,"PurchaseOrder"): break
                except: pass
            else: self.fail("time out")
            end = time.clock()
            diff = end - start
            driver.find_element_by_link_text('PurchaseOrder').click()
            name = "smoketest"+ str(now.minute) +str(now.second)
            start = time.clock()
            for i in range(5000000):
                try:
                    if is_element_present(driver,By.ID,"Customer_Name"): break
                except: pass
            else: self.fail("time out")
            end = time.clock()
            diff = end - start

            newproduct = "rexona"+ str(now.minute) +str(now.second)
            newprice = str(now.minute) +str(now.second)
            newprice = float(newprice)
            print newprice
            driver.find_element_by_xpath("//input[starts-with(@id,'New_Product')]").send_keys(newproduct)
            driver.find_element_by_xpath("//input[starts-with(@id,'Price')]").clear()
            time.sleep(3)

            driver.find_element_by_xpath("//input[starts-with(@id,'Price')]").send_keys(Keys.CONTROL+'a'+Keys.NULL, str(newprice))
            Mouse_cntrl = ActionChains(driver)
            Mouse_cntrl.release(driver.find_element_by_xpath("//input[starts-with(@id,'Price')]"))
            value = newprice
            print value
            time.sleep(2)
            print 'start'
            print driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]").get_attribute('data-id')
            # ------------------------CLICK FAILS HERE ------------------------------
#            driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]").click()
#            driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]").submit()
            driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]").send_keys(keys.ENTER)
#            Mouse_cntrl.double_click(driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]"))
            for i in range(10):
                try:
                    print driver.switch_to_alert().text
                    if driver.switch_to_alert():
                        driver.switch_to_alert().accept()
                        break
                except: pass
                time.sleep(1)
            else:
                print "alert not found"
            print 'finished  -- '
            time.sleep(8)
            driver.find_element_by_xpath("//input[starts-with(@id,'Product')]").click()
            arg = newproduct
            print 'end'
            for i in range(60):
                try:
                    if is_element_present(driver,By.LINK_TEXT,arg): break
                except: pass
                time.sleep(1)
            else: self.fail("time out")
    #        sel.mouse_over("//html/body/ul/li/a[.=\""+arg+"\"]")
            driver.find_element_by_link_text(arg).click()
            start = time.clock()
            time.sleep(25)
            for i in range(1000000):
                try:

                    if newprice == float(driver.find_element_by_id('Unit_Price').text):
                        end = time.clock()
                        diff = end - start
                        log.log(module='Smoke',testcase='Action New', result='Pass',time_taken= diff)
                        break
                except: pass
            else:
                log.log(module='Smoke',testcase='Action New', result='Fail')
                self.fail('New Failure')
            log.log(module='Smoke',testcase='On Submit', result='Pass',time_taken= diff)
            driver.find_element_by_id('Quantity').send_keys(Keys.CONTROL+'a'+Keys.NULL,"1")
            time.sleep(5)
            start = time.clock()
            for i in range(1000000):
                try:
                    if value == float(driver.find_element_by_id('Unit_Price').text):
                        end = time.clock()
                        diff = end - start
                        log.log(module='Smoke',testcase='Multiply', result='Pass',time_taken= diff)
                        break
                except: pass
            else: self.fail("time out")
            for i in range(1000000):
                try:
                    if value == float(driver.find_element_by_id('Amount').text):
                        end = time.clock()
                        diff = end - start
                        log.log(module='Smoke',testcase='DSUM with Parent', result='Pass',time_taken= diff)
                        break
                except: pass
            else:
                end = time.clock()
                diff = end - start
                log.log(module='Smoke',testcase='DSUM with Parent', result='Fail',time_taken= diff)
                self.fail("time out")

        except:
            self.driver.quit()
            e = sys.exc_info()[1]
            print str(e)

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
     unittest.main()

It has been a showstopper for my work. Any help is appreciated.Thanks

Kukri answered 12/1, 2012 at 9:40 Comment(3)
what line is the code failing at?Integrant
what about the css selector: driver.find_element_by_css_selector("input[id*=NewItem_NewItem]").click() Also, does this line give you the attribute? print driver.find_element_by_xpath("//input[starts-with(@id,'NewItem_NewItem')]").get_attribute('data-id') If so, is there javascript running after page load that may be affecting this element?Sparse
The element is probably not 'ready' for the click in some way as a result of page rewriting. Determine why, then loop while that condition pervails or until a time out occurs.Tolerable
S
30

You could try substituting .click() with .send_keys("\n"), which is equivalent to "Pressing enter while focusing on an element".

So this:

driver.find_element_by_link_text('PurchaseOrder').click()

would become this:

driver.find_element_by_link_text('PurchaseOrder').send_keys("\n")
Sandon answered 13/3, 2012 at 3:42 Comment(2)
Just ran into this issue today, and send_keys("\n") didn't work. However send_keys(Keys.ENTER) did.Flair
I just ran into this issue and none of the solutions worked. .submit() worked instead of .click()Marmion
K
9

In case this is still a recurring problem for anyone else, if you have confirmed your code is correct (you've reviewed it for errors etc.) and you still find the find_element_by_...('text').click() function not working properly it is often due to your code continuing to run before the JavaScript can update the page.

A simple solution is to import time then insert the below code immediately after any click() methods:

time.sleep(2) 

The duration of the sleep timer can be whatever you choose. In my case I used 2 seconds. Hopefully that helps.

Kamal answered 15/10, 2014 at 2:16 Comment(7)
don't do this. there are better ways than polluting your testcases with static sleepsExtremadura
I realize that this is not recommended, but it did work for me and, if nothing else, provided a reason for why my code wasn't working.Cuthburt
Static sleeps are awful. Learn how to wait the proper way.Luckey
@Luckey 'Learn how to wait the proper way' & 'There are better ways' such as...?Everest
@Luckey And what is the proper way? Can you post the answer?Federalist
@RafaelMoreno, @Blaszard, you can refer to the following for wait ways: selenium.dev/docs/site/en/webdriver/waitsSignifics
they improved the waits over time. at the time the static sleep method was very effective.Kamal
A
4

I had this problem as well. Sometimes, for whatever reason webdriver didn't click the button. It was able to find the button (it didn't throw a NoSuchElementException and a WebDriverWait didn't help).

The problem with clicking the button twice was that if the first click succeed, the second one would fail (or click the submit button on the next page if it found a match!). My first attempt was to put the second click in a try/except block - this is how I found out about it clicking submit on the next page. XD And it also really slowed down my test when it couldn't find the second button.

I found some good insights at Selenium 2.0b3 IE WebDriver, Click not firing. Basically, I click on a parent element first, which seemingly does nothing. Then I click on the submit button.

Aundreaaunson answered 21/3, 2012 at 19:58 Comment(0)
H
2

If the element you click() is an url. I found that taking the href properties and using driver.get(elem.get_attribute('href')) being the cleanest.

Himelman answered 12/9, 2017 at 9:15 Comment(0)
C
0

I would try other element finders like className, cssSelector or something. xPath sometimes doesnt provide errors if the element isn't found. So first start by finding out if the element is really found by webdriver.

You can also try to click or use the other commands two times in a row. This already solved some of such issues.

Creasy answered 6/3, 2012 at 14:17 Comment(0)
T
0

I had the same issue where a two-part drop down menu selection would not generate what it's supposed to generate with proper selections. It worked when I did imported time and use time.sleep(2) between the two "click"s. (For reference I used find_element_by_xpath to find an modify the options.)

Tenaille answered 3/5, 2018 at 20:3 Comment(0)
M
0

I ran into the above issue where the same .click() is working in all browsers(IE, Chrome and Firefox) but not working for Safari. So I tried all the possible solutions from this post and none of them worked and it doesn't even throw error.

I tried below by substituting .click() with .submit(), which is an equivalent method and it worked not only for Safari but also for all other browsers.

So this:

driver.find_element_by_id('login_btn').click()

Replaced as:

driver.find_element_by_id('login_btn').submit()

If above fails to work on other browsers due to any reason keep .submit() in try and except. If it fails .click() will be triggered and executed.

Hope this helps if none of the other solutions works.

Marmion answered 18/6, 2020 at 9:50 Comment(0)
N
0

For those, click() doesn't work, use submit() if that button element(clickable element) is in a form element. Basically, in order to submit a form, we need to use submit(), click() will not work in some cases.

Nearsighted answered 17/5, 2021 at 9:23 Comment(0)
W
0

I foolishly did elem.click with the parentheses: elem.click().

Wilen answered 29/5, 2022 at 16:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.