Implicitly_wait() missing 1 required positional argument - python

I'm studying selenium with python and in a tutorial I found the following code.
from selenium import webdriver
from time import gmtime, strftime
import unittest
#from builtins import classmethod
class RegisterNewUser(unittest.TestCase):
##classmethod
def setUp(self):
self.driver = webdriver.Firefox
self.driver.implicitly_wait(30)
self.driver.maximize_window()
# navigate to the application home page
self.driver.get("http://demo-store.seleniumacademy.com/")
def test_register_new_user(self):
driver = self.driver
pass
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main(verbosity=2)
It throw an error:
File "register_new_user.py", line 10, in setUp
self.driver.implicitly_wait(30)
TypeError: implicitly_wait() missing 1 required positional argument: 'time_to_wait'
I try to add the code commented out (classmethod) but doesn't change anything. Without the test_register_new_user doesn't give error.
I'm using python 3.6.4, selenium 3.141 (and geckodriver 0.23)

Your problem is one line above:
self.driver = webdriver.Firefox
This does not create a browser object. It just sets self.driver to the class webdriver.Firefox, which means that self.driver.implicitly_wait(30) is trying to use implicitly_wait in the static way, ie webdriver.Firefox.implicitly_wait(30), so it is missing the instance, ie webdriver.Firefox.implicitly_wait(an_actual_browser, 30).
You are missing ():
self.driver = webdriver.Firefox() # which will potentially ask for a path to
# firefox/geckodriver if it is not in PATH,
# but that is out of the scope of this question

Related

How to pass Selenium WebDriver instances between functions in Python?

I have a function that handles logging into a website. I then return the webdriver instance so that I can pass it into another fucnction that actually handles getting the information that I need.
For some reason I have been unable to call my second function using the returned driver instance.
Was wondering if anyone had any insight into how I can pass a webdriver instance to another function? Thanks.
how I can pass a webdriver instance to another function?
You would return the instance from the first function and call the second function with it.
In the example below, I define 2 functions. A webdriver is instantiaterd inside func1, which returns the instance. Then I call func2, which takes a driver instance as an argument.
from selenium import webdriver
def func1():
driver = webdriver.Chrome()
driver.get('https://example.com')
return driver
def func2(driver):
return driver.title
if __name__ == '__main__':
driver = func1()
title = func2(driver)
print(title)
driver.quit()
This code will launch a browser (Chrome), navigate to a site (https://example.com), print the page title ("Example Domain"), and then quit the browser.
Alternatively, extending Corey Goldberg's answer. It is perfectly fine to simply pass a reference of the driver to all functions that use it.
from selenium import webdriver
def func1(driver):
driver.get('https://example.com')
def func2(driver):
return driver.title
if __name__ == '__main__':
driver = webdriver.Chrome()
func1(driver)
title = func2(driver)
print(title)
driver.quit()

Django test using Selenium package error

I want to create some Django test using Selenium package.
Here below is the simple test :
import unittest
from selenium import webdriver
class TestSignup(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_signup_fire(self):
self.driver.get("http://localhost:8000/add/")
self.driver.find_element_by_id('id_title').send_keys("test title")
self.driver.find_element_by_id('id_body').send_keys("test body")
self.driver.find_element_by_id('submit').click()
self.assertIn("http://localhost:8000/", self.driver.current_url)
def tearDown(self):
self.driver.quit
if __name__ == '__main__':
unittest.main()
but I take this error :
TypeError: environment can only contain strings
in this line :
self.driver = webdriver.Firefox()
and I don't know why, any idea how to fix this error?
As you are seeing the error as :
TypeError: environment can only contain strings
In the line :
self.driver = webdriver.Firefox()
This essentially means there is some configuration error while updating the path within Environment Variables. To suppress that you can supply the argument with geckodriver binary location as follows :
self.driver = webdriver.Firefox(executable_path=r'C:\path\to\geckodriver.exe')

Error while switching window in python selenium

I want to work with multiple windows and tabs using selenium and python.
I am getting below error during script execution:-
( code is mentioned at last)
{f625f26d-cfcf-442c-b9fc-5e96a199cd43}
C:\Python34\lib\site-packages\selenium-2.47.1- py3.4.egg\selenium\webdriver\remot
e\webdriver.py:525: DeprecationWarning: use driver.switch_to.window instead
warnings.warn("use driver.switch_to.window instead", DeprecationWarning)
{cad6e3cf-9062-408e-a6f1-11e98813dc6c}
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
class GoogleTabs(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
def test_google_search_page(self):
driver = self.driver
driver.get("http://www.cdot.in")
window_before = driver.window_handles[0]
print (window_before)
driver.find_element_by_xpath("//a[#href='http://www.cdot.in/home.htm']").click()
window_after = driver.window_handles[1]
driver.switch_to_window(window_after)
print (window_after)
driver.find_element_by_link_text("ATM").click()
driver.switch_to_window(window_before)
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
As the warning says
DeprecationWarning: use driver.switch_to.window instead
you'll need to change your
driver.switch_to_window
with
driver.switch_to.window
But think about it: it is a warning, not an error! Your code should work, it is just telling you that that method is deprecated.
You're getting a warning message, for new versions of selenium the method has changed.
Instead of using: driver.switch_to_window(window)
Try with: driver.switch_to.window
Where window is your variable.
I propose a very simple way to switch between windows without any hassles of playing with the handles yourself. https://gist.github.com/ab9-er/08c3ce7d2d5cdfa94bc7
def change_window(browser):
"""
Simple window switcher without the need of playing with ids.
#param browser: Current browser instance
"""
curr = browser.current_window_handle
all_handles = browser.window_handles
for handle in list(set([curr]) - set(all_handles)):
return browser.switch_to_window(handle)

Python WebDriver AttributeError: LoginPage instance has no attribute 'driver'

I have read a few tutorials on Python Selenium Webdriver Page Object model as I have to automate the gui tests using Selenium with Python.
To start off with I am trying to write a Login Page class and a LoginMainTest class. I am getting the following error when i run the code.
AttributeError: LoginPage instance has no attribute 'driver'
I think i have to specify the selenium driver where i instantiate the LoginPage
e.g. on this line log_in = LoginPage.LoginPage()
I need some help please.
Full error:
Traceback (most recent call last):
File "E:\Python projects\unitTest_sample - Modifying into Page Object\LoginMainTest.py", line 11, in test_valid_login
log_in = LoginPage.LoginPage()
File "E:\unitTest_sample - Modifying into Page Object\LoginPage.py", line 20, in __init__
emailFieldElement = self.driver.find_element_by_id(self.emailFieldID)
AttributeError: LoginPage instance has no attribute 'driver'
My LoginMainTest.py class is as follows:
import LoginPage
import unittest
class GoogleTest(unittest.TestCase):
def test_valid_login(self):
log_in = LoginPage.LoginPage()
log_in.userLogin_valid()
if __name__ == '__main__':
unittest.main()
My Login.py class is as follows:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
class LoginPage():
Username = "test1"
password = "Test"
emailFieldID = "email"
passFieldID = "pass"
loginButtonXpath = "//input[#value='log in']"
logo_xpath = "//a[contains(#href, 'logo')])[1]"
def setup(self):
self.driver = webdriver.Firefox()
self.driver.get("http://www.testaaa.com")
def __init__(self):
emailFieldElement = self.driver.find_element_by_id(self.emailFieldID)
passFieldElement = self.driver. find_element_by_id(self.passFieldID)
loginFieldElement = self.driver.find_element_by_xpath(self.loginButtonXpath)
def userLogin_valid(self):
self.emailFieldElement.clear()
self.emailFieldElement.send_keys(self.Username)
self.passFieldElement.clear()
self.send_keys(self.password)
self.loginFieldElement.click()
def tearDown(self):
self.driver.quit()
Firstly, there is a flaw in your design.
The reason your script is failing because when you create the object of login page the init gets called but it fails to find the driver since it is defined in the setup fn (which is never called)
Ideally in the page object model you should initialize your browser(driver) in your test file and then while creating a object of any page file you should pass that driver.
Your setup should look something like this,
Page file:
# setup() fn not needed here
.
.
def __init__(self, driver):
self.driver = driver
emailFieldElement = self.driver.find_element_by_id(self.emailFieldID)
passFieldElement = self.driver. find_element_by_id(self.passFieldID)
loginFieldElement = self.driver.find_element_by_xpath(self.loginButtonXpath)
.
# teardown() not needed here, should be in test file
.
Test File:
.
.
class GoogleTest(unittest.TestCase):
def test_valid_login(self):
self.driver = webdriver.Firefox() # the first 2 stmts can be in a setupclass
self.driver.get("http://www.testaaa.com")
log_in = LoginPage.LoginPage(self.driver)
log_in.userLogin_valid()
.
.
I've had this issue a couple of times and every time I found it due to a mismatch between my Chrome browser version and the Chrome Webdriver version.
So, in your Chrome browser check Help>About Google Chrome before downloading a corresponding ChromeDriver from https://chromedriver.chromium.org/.
Good luck!

How to to run unitest and selenium from a django view?

I have a functional test 'y1.py' which I have exported from the selenium IDE. It looks like:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
class Y1(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.yahoo.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_y1(self):
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_link_text("Weather").click()
driver.save_screenshot('out11.png')
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
I am trying to call this directly from within a python/django function. while investigating this I came across: AttributeError 'module' object has no attribute 'runserver' in django, where Udi states:
Are you trying to run unitest and selenium from a view? You should
consider launching a second process for that.
How can I do this?
You can start django server as new process with subprocess module.

Categories