Here is the page object file: login.py
from pages.base import BasePage
from config import secrets
from selenium.webdriver.common.keys import Keys
class LoginPage(BasePage):
def __init__(self):
self.webdriver = BasePage.webdriver
port = raw_input("Enter port number: ")
self.url = "http://localhost:" + port
#property
def retrieve_username_field(self):
self.webdriver.find_element_by_name("username")
#property
def retrieve_password_field(self):
self.webdriver.find_element_by_name("password")
def login(self, username=None, password=None):
username = username or secrets.username
password = password or secrets.password
self.retrieve_username_field.send_keys(username)
self.retrieve_password_field.send_keys(password)
self.retrieve_password_field.send_keys(Keys.RETURN)
Here is the base page file: base.py
from selenium import webdriver
class BasePage(object):
webdriver = webdriver.Firefox()
def go(self):
self.webdriver.get(self.url)
Here is the test file: test_login.py
import unittest
from pages.login import LoginPage
login_page = LoginPage()
def setUpModule():
login_page.go()
def tearUpModule():
login_page.logout()
class TestLogin(unittest.TestCase):
def test_login_succeeds_with_valid_credentials(self):
login_page.login()
xpath = "//th[text() = 'Spool Name']"
self.assertIsNotNone(login_page.webdriver.find_element_by_xpath(xpath))
if __name__ == "__main__":
unittest.main()
The problem is that I get this error: http://puu.sh/9JgRd/e61f5acec3.png and I'm not sure why I cannot call login method. I have reference to LoginPage object but failure happens exactly here.
Your problem is not that you can't call login(), but that self.retrieve_username_field returns None and thus does not have a send_keys method.
That's exactly what the error you get is telling you.
Related
While running the below code getting error " NoneType' object has no attribute 'get'
"
TestProductRecogic.py:
import unittest
from PageObject.ProductRcognic import ProductPage
import pytest
class TestProductRecognic(unittest.TestCase):
#pytest.fixture(autouse=True)
def classSetup(self, setup):
self.driver = setup
def test_Product(self):
self.driver.get("https://www.recognic.ai/")
self.ep = ProductPage(self.driver)
self.ep.clickOnProduct()
def tearDown(self):
self.driver.close()
Ensure that your setup is returning the driver instance.
You would need to have a setup fixture which looks somewhat like this:
#pytest.fixture()
def setup():
driver = webdriver.Chrome(path) #example
return driver
class TestProductRecognic(unittest.TestCase):
#pytest.fixture(autouse=True)
def classSetup(self, setup):
self.driver = setup
def test_Product(self):
self.driver.get("https://www.recognic.ai/")
self.ep = ProductPage(self.driver)
self.ep.clickOnProduct()
def tearDown(self):
self.driver.close()
So I'm trying to build a bot with python and selenium
this is my code
from selenium import webdriver
import os
import time
class InstagramBot:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = webdriver.Chrome(executable_path='./chromedriver.exe')
self.driver.get('https://www.Instagram.com/')
The problem is nothing will happen when I try the python bot.py
I've tried py bot.py too
it didin't throw any errors but the commands really do nothing
please can someone help me findout what the problem is???
I've tried driver = webdriver.chrome ... outside the class and it works but when i put it in the InstagramBot class it wont work
im using python3.6.5
and ive tried other python versions too
it didint help
You were close enough. As you have defined the Class, now you simply need to create an instance so the constructor gets executed calling it from the main as follows:
from selenium import webdriver
import os
import time
class InstagramBot:
def __init__(self, username, password):
self.username = username
self.password = password
self.driver = webdriver.Chrome(executable_path='./chromedriver.exe')
self.driver.get('https://www.Instagram.com/')
InstagramBot("naa-G", "naa-G")
I have feature file from where I am trying to get the email :
Scenario: Login to website
Given I navigate to Login page
When I click on login button
Then I redirected to login page
Then I enter valid "<Email>"
| Email |
| test |
When I click on Submit
I have below code in LoginPage.py :
from Base.BasePage import BasePage
from Base.WebDriverActions import Seleniumdriver
class LoginPage():
instance = None
#classmethod
def get_instance(cls):
if cls.instance is None:
cls.instance = LoginPage()
return cls.instance
def __init__(self):
self.driver = BasePage.get_driver()
def enterEmail(self, email):
self.driver.implicitly_wait(20)
self.driver.find_element_by_id("login").send_keys(email)
When I call the above method into steps :
from Base.BasePage import BasePage
from behave import step, Given, When, Then
from Pages.LoginPage import loginpage
#Given('I navigate to Login page')
def step_impl(Context):
BasePage.load_BaseURL();
#When('I click on login button')
def step_impl(Context):
loginpage.clickLoginLink()
#Then('I redirected to login page')
def step_impl(self):
print('Verifying user logged in..')
#Then('I enter valid "{Email}"')
def step_impl(Email):
loginpage.enterEmail(Email);
I have below error :
File "..\steps\Steps_Login.py", line 27, in step_impl
loginpage.enterEmail(context, Email);
TypeError: enterEmail() takes 1 positional argument but 3 were given
I tried by adding ** with an argument but no luck.
You are calling enterEmail as loginpage.enterEmail(context, Email) here you are passing arguments to the method as follows
context
Email
Self for class loginpage
Try removing loginpage or context if it works.
I have a parent test class named as basetestcase()
This is inherited by all the test classes
class BaseTestCase(unittest.TestCase):
driver = None
browser = read from command line
operatingSystem = read from command line
url = read from command line
#classmethod
def setUpClass(cls):
"""
SetUp to initialize webdriver session, pages and other needed objects
Returns:
None
"""
# Get webdriver instance
# Browser should be read from the arguments
if browser == "iexplorer":
cls.driver = webdriver.Ie()
elif browser == "firefox":
cls.driver = webdriver.Firefox()
elif browser == "chrome":
cls.driver = webdriver.Chrome()
else:
cls.driver = webdriver.PhantomJS()
# Similarly I want to get operating system and url also from command line
driver.get(url)
print("Tests are running on: " + operatingSystem)
Then I have two separate test classes:
class TestClass1(BaseTestCase):
#classmethod
def setUpClass(cls):
super(TestClass1, cls).setUpClass()
# Create object of another class to use in the test class
# cls.abc = ABC()
def test_methodA(self):
# self.abc.methodFromABC() # This does not work
# Not sure if I can use self.driver as it was defined as cls.driver in the setUpClass()
self.driver.find_element(By.ID, "test_id").click()
if __name__ == '__main__':
unittest.main(verbosity=2)
This is the 2nd class, both the classes are in separate .py files
class TestClass2(GUIBaseTestCase):
#classmethod
def setUpClass(self):
super(TestClass2, self).setUpClass()
def test_methodA(self):
self.driver.find_element(By.ID, "test_id").click()
if __name__ == '__main__':
unittest.main(verbosity=2)
Then I have a test suite script, a separate .py file which clubs them together to run in a suite
import unittest
from tests.TestClass1 import TestClass1
from tests.TestClass2 import TestClass2
# Get all tests from TestClass1 and TestClass2
tc1 = unittest.TestLoader().loadTestsFromTestCase(TestClass1)
tc2 = unittest.TestLoader().loadTestsFromTestCase(TestClass2)
# Create a test suite combining TestClass1 and TestClass2
smokeTest = unittest.TestSuite([tc1, tc2])
unittest.TextTestRunner(verbosity=2).run(smokeTest)
I want to run the test suite and want to provide browser, operating system and url to the basetestcase from the command line and these arguments are directly used by basetestcase.py.
Actual test classes inherit the basetestcase.
Could you please help me with how to get these values from the command line in the best way and provide to the basetestcase?
I also struggled to run the same test cases on multiple browsers. After a lot of iterations, trial and error and input from friends I implemented the following solutions to my projects:
Here TestCase is the class that has all the tests and the browser driver is None. SafariTestCase inherits the TestCase and overrides setUpClass and sets the browser driver to be safari driver and same with the ChromeTestCase and you can add more class for other browsers. Command Line input can be taken in the TestSuite file and conditionally load tests based on the arguments:
class TestCase(unittest.TestCase):
#classmethod
def setUpClass(cls):
cls.browser = None
def test_1(self):
self.assert(self.browser.find_element_by_id('test1')
def test_2(self):
self.assert(self.browser.find_element_by_id('test2')
def test_3(self):
self.assert(self.browser.find_element_by_id('test3')
#classmethod
def tearDownClass(cls):
cls.browser.quit()
class SafariTestCase(TestCase):
#classmethod:
def setUpClass(cls):
cls.browser = webdriver.Safari(executable_path='/usr/bin/safaridriver')
class ChromeTestCase(TestCase):
#classmethod:
def setUpClass(cls):
cls.browser = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver')
In the runner file TestSuite.py:
import TestCase as tc
if len(sys.argv) == 1:
print("Missing arguments, tell a couple of browsers to test against.")
sys.exit(1)
if sys.argv[1] == 'safari':
test = unittest.TestLoader().loadTestsFromTestCase(tc.SafariTestCase)
if sys.argv[1] == 'chrome':
test = unittest.TestLoader().loadTestsFromTestCase(lt.ChromeTestCase)
unittest.TextTestRunner().run(test)
I'm creating a sample test using Selenium and the python bindings and running it with nose. I know I'm doing something wrong because the test opens two browsers (when setup is run, a Firefox window opens up and closes immediately, and then when the test runs driver.get, another window opens). I have the following project:
/test_project
/config
config.ini
/pages
__init__.py
test_page.py
/test_scripts
script.py
__init__.py
base.py
config_parser.py
config.ini:
[Selenium]
browser: firefox
base_url: http://www.google.com/
chromedriver_path:
base.py
from selenium import webdriver
from config_parser import Config
class TestCase(object):
def setup(self):
self.config = Config()
if self.config.read_config('Selenium', 'browser').lower() == 'firefox':
self.driver = webdriver.Firefox()
elif self.config.read_config('Selenium', 'browser').lower() == 'chrome':
self.driver = webdriver.Chrome(self.config.read_config('Selenium', 'chromedriver_path'))
def teardown(self):
self.driver.quit()
test_page.py
from config_parser import Config
class TestPage(object):
def __init__(self, driver):
self.driver = driver
self.config = Config()
def open(self):
self.driver.get(self.config.read_config('Selenium', 'base_url'))
import time
time.sleep(3)
script.py
from pages import test
from base import TestCase
class RandomTest(TestCase):
def test_foo(self):
x = test.TestPage(self.driver)
x.open()
assert 1 == 1
Can someone help me understand why two browser windows are opening and what I can do to correct this issue?
Thank you in advance.
This is because your base TestCase class is being recognized by nose test runner as a test too.
Mark it with #nottest decorator:
from selenium import webdriver
from config_parser import Config
from nose.tools import nottest
#nottest
class TestCase(object):
...