Using Selenium and Pytest on Helsinki Central Library website
This is my first experiment in using Selenium and Pytest in a project of my own creation. The website I decided to test is Helsinki city library’s homepage.
I have no connection to the library organization, so the test case is basically me imagining how I would black-box test the website. I am not using cucumber but I have a BDD approach in mind, and the code comments follow a Given-When-Then pattern.
Much of the basic structure of my test is based on what I learned from the tutorial Create A Python Test Automation Project Using Pytest from AutomationPanda.
conftest.py
This is where the test starts. Conftest handles the setup and teardown of the tests.
# Thanks to PyBites
# https://pybit.es/pytest-fixtures.html
# setup and teardown in own file. I did need to sope to module... .
import pytest
from selenium.webdriver import Chrome
# Initialize and quit handled by a pytest fixture
@pytest.fixture
def browser(scope="module"):
driver = Chrome()
driver.implicitly_wait(15)
yield driver
driver.quit()
Testing Oodi FAQ page
The first test. The intention is to scroll to the FAQ link, click the link and assert that the user is indeed at the FAQ page. The test relies on a while loop for the scrolling.
The code:
# import pytest
# https://medium.com/testcult/intro-to-test-framework-pytest-5b1ce4d011ae
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementClickInterceptedException
from selenium.common.exceptions import NoSuchElementException
def test_oodi_faq_interaction(browser):
# GIVEN The Oodi homepage is displayed
URL = "https://www.oodihelsinki.fi/en/"
browser.get(URL)
browser.implicitly_wait(20)
# WHEN the user clicks on FAQ
faq_search_window = browser.find_element(By.LINK_TEXT, "Questions and answers")
browser.implicitly_wait(20)
while True:
try:
faq_search_window.click()
break
except ElementClickInterceptedException:
browser.execute_script("window.scrollBy(0,-100);")
# THEN the FAQ page is displayed
assert browser.current_url == "https://www.oodihelsinki.fi/en/faq/"
browser.implicitly_wait(20)
# AND the fact about dogs in the library is displayed
xpath = "/html/body/div[1]/div[1]/div/div/section[2]/div[16]/div/div[1]/h3"
def element_present_check():
try:
browser.find_element(By.XPATH, xpath)
return True
except NoSuchElementException:
return False
assert element_present_check() is True
Testing Oodi Facilities page
This test has Selenium click on a button in the nav bar, then click on another link that opens up below and finally asserts the user is on the Facilities page.
The code:
from selenium.webdriver.common.by import By
# from selenium.common.exceptions import ElementClickInterceptedException
def test_oodi_facilities_interaction(browser):
# Given The Oodi homepage is displayed
URL = "https://www.oodihelsinki.fi/en/"
browser.get(URL)
browser.implicitly_wait(20)
# WHEN the user clicks the plus buttton to expand 'Services and facilities'
# AND the user clicks on 'facilities'
plus_button_xpath = (
"/html/body/section/div[1]/div[1]/nav/ul/li[2]/button/div/div[2]"
)
facilities_xpath = "/html/body/section/div[1]/div[1]/nav/ul/li[2]/ul/li/ul/li[2]/a"
browser.implicitly_wait(20)
plus_button = browser.find_element(By.XPATH, plus_button_xpath)
plus_button.click()
browser.implicitly_wait(20)
facilities = browser.find_element(By.XPATH, facilities_xpath)
facilities.click()
browser.implicitly_wait(20)
# THEN the user is on the facilities page
assert (
browser.current_url
== "https://www.oodihelsinki.fi/en/services-and-facilities/facilities/"
)
Lessons Learned
I am glad I completed the project even though in retrospect I can spot some dodgy xpaths, redundant implicit waits and some questionable page scrolling using a while loop.
I realize I have to get clear on what user behaviour I am simulating with Selenium and what I intend to assert with pytest.
I had problems with some of the locators, and at I times ended up using inspector to find absolute xpaths such as the one below.
xpath = "/html/body/div[1]/div[1]/div/div/section[2]/div[16]/div/div[1]/h3"
That xpath is not too readable and very likely to be wrong once another part of the webpage is updated.
Admittedly the tests in this project turned out somewhat flaky and non-transparent but personally the important thing was to get started with a project.