Mikhah
Mikhah

Reputation: 139

Selenium can't access web-element by it's id (python)

I've wrote a simple selenium script to login to our system but selenium webdriver can't find any elements that are mentioned in the script.Elemnts have thew id of "username" and "password".There is one strange thing - this script works sometimes without any mistakes and sometimes i get the same error(while script isn't changing) .I'm running this script on windows 7 script was written with python 3.4 (maybe that's important) Here is the code:

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class SodexoLogin(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_log_to_system(self):
        driver = self.driver
        driver.get("http://dev.itsoft.co.il:8080/dev/sodexo-backoffice-components")
        username = driver.find_element_by_id("username")
        password = driver.find_element_by_id("password")
        username.send_keys("*********")
        password.send_keys("*********")
        username.send_keys(Keys.RETURN)
        password.send_keys(Keys.RETURN)

    def tearDown(self):
        self.driver.close()

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

HTML code for the elements looks like this:

<input type="password" class="form-control ng-untouched ng-valid ng-dirty ng-valid-parse" id="password" ng-model="password" placeholder="Password">

And here is the error message I get:

======================================================================
ERROR: test_log_to_system (__main__.SodexoLogin)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\AT\test1.py", line 13, in test_log_to_system
    username = driver.find_element_by_id("username")
  File "C:\Python34\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 234, in find_element_by_id
    return self.find_element(by=By.ID, value=id_)
  File "C:\Python34\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 712, in find_element
    {'using': by, 'value': value})['value']
  File "C:\Python34\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "C:\Python34\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 181, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"id","selector":"username"}
Stacktrace:
    at FirefoxDriver.prototype.findElementInternal_ (file:///C:/TEMP/tmp_p25io7i/extensions/[email protected]/components/driver-component.js:10659)
    at FirefoxDriver.prototype.findElement (file:///C:/TEMP/tmp_p25io7i/extensions/[email protected]/components/driver-component.js:10668)
    at DelayedCommand.prototype.executeInternal_/h (file:///C:/TEMP/tmp_p25io7i/extensions/[email protected]/components/command-processor.js:12534)
    at DelayedCommand.prototype.executeInternal_ (file:///C:/TEMP/tmp_p25io7i/extensions/[email protected]/components/command-processor.js:12539)
    at DelayedCommand.prototype.execute/< (file:///C:/TEMP/tmp_p25io7i/extensions/[email protected]/components/command-processor.js:12481)

----------------------------------------------------------------------
Ran 1 test in 9.957s

FAILED (errors=1)

Upvotes: 1

Views: 1956

Answers (3)

Ben Dellarocco
Ben Dellarocco

Reputation: 121

This should fix it

driver.implicitly_wait(10)

Upvotes: -1

drkthng
drkthng

Reputation: 6909

You might wanna explicitly wait for the elements themselves:

import selenium.webdriver.support.ui as ui    

...

def test_log_to_system(self):
        driver = self.driver
        driver.get("http://dev.itsoft.co.il:8080/dev/sodexo-backoffice-components")
        wait = ui.WebDriverWait(driver,10)
        wait.until(lambda driver: driver.find_element_by_id('username'))
        username = driver.find_element_by_id("username")
        wait.until(lambda driver: driver.find_element_by_id('password'))
        password = driver.find_element_by_id("password")

In my personal opinion this is a better approach to the implicit wait, because the latter will slow you down the whole time, while the specific waiting for certain elements only adds time to the script running at this specific point.

Upvotes: 1

Kit Fung
Kit Fung

Reputation: 491

It seem to be the website haven't fully loaded.

Maybe you can add the implicit wait to it.

Just add driver.implicitly_wait(10) after driver = self.driver

Upvotes: 1

Related Questions