Reputation: 139
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
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
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