Putting the page object model to good use on Nationalmuseum website
The Swedish institution Nationalmuseum website says the following about their mission;
Nationalmuseum is Sweden’s museum of art and design. Nationalmuseum is also a government authority with a mandate to preserve cultural heritage and promote art, interest in art and knowledge of art.
At the time of writing the museum is closed to the public due to Covid19 and a s such we can only experience the museum on the web. For example Superintendent Susanna Petterson gives an online tour of a current exhibition. The organization has also made their collections available om Wikimedia.
This test project is a good candidate for getting started with the page object model (with a base page object) as the test is for identical user behavior on two quite similar pages. Without page object model there would be plenty of repeated code. Below is the project structure.
nationalmuseum_testing
│ conftest.py
│
├───pages
│ basepage.py
│ free_images.py
│ homepage.py
│ __init__.py
│
└───tests
test_free_images_to_wikimedia.py
test_homepage_to_free_images.py
__init__.py
basepage.py
The base page object contains all interaction methods used for the tests. I will write more about get_title(self, title) later.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, browser):
self.browser = browser
self.wait = WebDriverWait(self.browser, 10)
def load(self, url):
return self.browser.get(url)
def scroll_to(self, locator):
try:
self.wait.until(
EC.presence_of_element_located(self.browser.find_element(*locator))
)
except Exception as e:
print(type(e))
print(e.args)
self.locator = self.browser.find_element(*locator)
return self.browser.execute_script(
"arguments[0].scrollIntoView({block: 'center'})", self.locator
)
def click_tile(self):
return self.browser.execute_script("arguments[0].click()", self.locator)
def get_title(self, title):
try:
self.wait.until(EC.title_is(title))
except Exception as e:
print(type(e))
print(e.args)
return self.browser.title
homepage.py
As homepage.py inherits all its methods from base page all it contains are variables for the url and a locator for the image tile.
from selenium.webdriver.common.by import By
from pages.basepage import BasePage
class HomePage(BasePage):
# URL
URL = "https://www.nationalmuseum.se/"
# Locators
FREE_IMAGES_TILE = (
By.XPATH,
"//div[@class='blurb-link']/a[@href='https://www.nationalmuseum.se/samlingarna/fria-bilder' and @tabindex='0']",
)
free_images.py
apart from the variable values this page object is identical to homepage.py. The URL is the link that is clicked in homepage. https://www.nationalmuseum.se/samlingarna/fria-bilder and the image tile on free images page here links to an exernal wikimedia page https://commons.wikimedia.org/wiki/Category:Media_contributed_by_Nationalmuseum_Stockholm:_2016-10
Each page has a test and similarly each test also echo one another. I will only display code from one test below.
test_homepage_to_free_images.py
"""
This test covers starting at the Nationalmuseum homepage
scrolling down and clicking in the Free Images tile
"""
from pages.homepage import HomePage
def test_homepage_to_free_images(browser):
homepage = HomePage(browser)
# free_images = FreeImages(browser)
# GIVEN Nationalmuseum homepage is displayed
homepage.load(HomePage.URL)
# WHEN whe user scrolls down to the Free Images tile
homepage.scroll_to(HomePage.FREE_IMAGES_TILE)
# AND clicks on the Freeimages tile
homepage.click_tile()
# THEN the user is at Nattionalmuseum Free Images page
title = "Fria bilder | Nationalmuseum"
assert homepage.get_title(title) == title
# NOTE # The test asserts only what the browser is doing at the moment,
# and does not actually test a property of the Free images page itself.
The assertion at the end of the test may look peculiar. The test passes the title of the page linked . The get_title() method on the home page object already uses a try except statement to check that the title of the current page is identical to the value that was passed. But the assertion occurs here still.
The home page has an opening hours announcement banner at the top as well as a cookie agreement banner at the bottom. As both take up quite some space my first attempts at locating the elements failed so I decided to center the element and use JavaScript execution to run user interaction methods.
test_free_images_to_wikimedia.py
As mentioned earlier this test is nearly identical; scroll to an image tile , click the tile and assert that the link in the take leads to the expected page, in this case Wikimedia commons.
Link to GitHub repository here.