Queries regarding page object model with Python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Queries regarding page object model with Python



I've tried implementing the page object model in Python. I have two questions:


verify_login_failure


verify_login_success


driver.get()


BasePage


driver.quit()



Here's my code:


# Basepage.py

from selenium import webdriver


class BasePage(object):

def __init__(self):
self.driver = webdriver.Chrome(
executable_path="chromedriver_mac")
self.driver.get("http://automationpractice.com/index.php?controller=authentication&back=my-account")
self.driver.implicitly_wait(5)


# LoginPage.py

from selenium.webdriver.common.by import By

from page_object.pages.BasePage import BasePage


class Login(BasePage):
email = (By.ID, "email")
password = (By.ID, "passwd")
sign_in_btn = (By.ID, "SubmitLogin")
failure_message = (By.XPATH, "//li[contains(text(),'Authentication failed.')]")

def set_email(self, email):
email_element = self.driver.find_element(*Login.email)
email_element.clear()
email_element.send_keys(email)

def set_password(self, password):
password_element = self.driver.find_element(*Login.password)
password_element.clear()
password_element.send_keys(password)

def click_sign_in_btn(self):
sign_in_element = self.driver.find_element(*Login.sign_in_btn)
sign_in_element.click()

def is_failure_message_displayed(self):
failure_message_element = self.driver.find_element(*Login.failure_message)
return failure_message_element.is_displayed()

def login(self, email, password):
self.set_email(email)
self.set_password(password)
self.click_sign_in_btn()


# MyAccountPage.py

from selenium.webdriver.common.by import By

from page_object.pages.BasePage import BasePage


class MyAccount(BasePage):
my_account_text = (By.XPATH, "LoginPage.py")

def is_my_account_text_displayed(self):
my_account_text_element = self.driver.find_element(*MyAccount.my_account_text)
return my_account_text_element.is_displayed()


# LoginTests.py

import lemoncheesecake.api as lcc
from lemoncheesecake.matching import check_that, is_true

from page_object.pages.LoginPage import Login
from page_object.pages.MyAccountPage import MyAccount


@lcc.suite("Login page tests")
class LoginTests:

def setup_suite(self):
lcc.log_info("Inside setup")

@lcc.test("check login failure")
def verify_login_failure(self):
login = Login()
login.login(email="myemail@gmail.com", password="incorrectpasswd")
check_that("Failure message is displayed", login.is_failure_message_displayed(), is_true())

@lcc.test("check login success")
def verify_login_success(self):
login = Login()
login.login(email="myemail@gmail.com", password="correctpasswd")
my_account = MyAccount()
check_that("My Account text is displayed", my_account.is_my_account_text_displayed(), is_true())

def teardown_suite(self):
lcc.log_info("Inside teardown")





Put a breakpoint at the very start of your test and run it. Step through each line of code and watch the flow of the execution. Now you'll know why the browser is created 3 times during your test.
– JeffC
Aug 7 at 13:42




2 Answers
2



Why does the browser launch thrice my test run? Is it because I'm making new page objects in each of the tests verify_login_failure and verify_login_success? This could be because my driver.get() is wrongly placed in my BasePage class. Please advise.



Every time then you initialise page, constructor of parent class BasePage also initialises. If you want to have one place for driver initialisation then i offer to extend BasePage (rename of course) from LoginTests



Where shall I call driver.quit() in order end my test suite execution gracefully after all the tests are completed?



It's best way to initialise browser session in setup_suite() and quit browser session in teardown_suite(). At least we doing it in Java and this format allows us to run tests in parallel.





Regarding #1, I didn't understand what exactly you meant by "extend BasePage (rename of course) from LoginTests". Shall I make LoginTests a child class of BasePage? Won't that violate the page object design pattern? Regarding #2, how do I access the driver object in setup and teardown methods in order to initialise and quit the browser sessions respectively?
– Akshay Maldhure
Aug 7 at 17:23



BasePage


LoginTests


LoginTests


BasePage


setup


teardown



Changing my test class to something like below helped.


import lemoncheesecake.api as lcc
from lemoncheesecake.matching import check_that, is_true
from selenium import webdriver

from core.common.constants import Global
from core.utils.fileutils import capture_screenshot
from pages.login_page import LoginPage
from pages.my_account_page import MyAccountPage


@lcc.suite("Login page tests")
class LoginTests(object):
login, my_account, driver = None, None, None

def setup_suite(self):
lcc.log_info("Inside setup")
self.driver = webdriver.Chrome(executable_path=Global.CHROME_DRIVER)
self.login = LoginPage(driver=self.driver)
self.my_account = MyAccountPage(driver=self.driver)

@lcc.test("check login failure")
def verify_login_failure(self):
self.login.login(email="myemail@gmail.com", password="incorrectpasswd")
check_that("Failure message is displayed", self.login.is_failure_message_displayed(), is_true())

@lcc.test("check login success")
def verify_login_success(self):
self.login.login(email="myemail@gmail.com", password="correctpasswd")
check_that("My Account text is displayed", self.my_account.is_my_account_text_displayed(), is_true())

def teardown_test(self, test_name):
lcc.log_info("Finished running test " + test_name)
capture_screenshot(self.driver)

def teardown_suite(self):
lcc.log_info("Inside teardown")
self.driver.quit()






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard