Another Selenium Project: Prague Tourism Website

Magnus Rydberg
Magnus Rydberg
Published in
4 min readFeb 26, 2020

Testing some basic functionality of prague.eu.

prague.eu

This time I wanted to make improvements on three areas.

  • More deliberate use of pytest fixtures
  • Moving away from implicit waits to explicit waits
  • Wiser use of web element locators

Conftest

Again setup and teardown.

import pytest
from selenium.webdriver import Chrome

# from selenium.webdriver.support.ui import WebDriverWait

# https://www.guru99.com/pytest-tutorial.html
# Fixture to initialize and quit for all tests
# conftest.py spcefifically allows a pytest fixture to be shared among multiple files
@pytest.fixture
def browser(scope="session"):
print("initiating chrome driver")
driver = Chrome()
yield driver
driver.close()
print("quitting chrome driver")

Test daytrips

Selenium clicks the “Day Trips” button in the navbar and asserts that two tabs are now open: the homepage and the daytrips tab. Not that the test does not assert which tab is visible, only which ones are open.

Selenium at work

The code:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException


def test_daytrips_tab_functionality(browser):
# GIVEN the user is on The Official Tourist website for Prague

base_url = "https://www.prague.eu/en"

browser.maximize_window()
browser.get(base_url)
try:
assert "Prague" in browser.title
print(browser.current_url)
except AssertionError as e:
print(e)
raise e

# WHEN the user clicks on 'Day Trips' in the navigation bar

day_trip_nav = "//nav/a[contains(@href, 'trips' )]"

wait = WebDriverWait(browser, 20)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, day_trip_nav)))
except TimeoutException as e:
print(e)
print("------------")
print(str(e))
print("------------")
print(e.args)
print("============")
except Exception:
print("FALLBACK EXCEPTION")

try:
day_trip_menu_item = browser.find_element(By.XPATH, day_trip_nav)
day_trip_menu_item.click()
except NoSuchElementException as e:
print(e)
print("------------")
print(str(e))
print("------------")
print(e.args)
print("============")
# THEN the user is on a new tab with information on day trips around Prague

browser_tabs = browser.window_handles
size = len(browser_tabs)
try:
assert size == 2
except AssertionError as e:
print(e)
raise e

browser.switch_to.window(browser_tabs[0])
print(browser.title)

# Assert that this is the main page
try:
assert "Prague" in browser.title
except AssertionError as e:
print(e)
raise e
browser.switch_to.window(browser_tabs[1])
print(browser.title)

# Assert the next tab is the Day Trip page
try:
assert "DayTrips" in browser.title
except AssertionError as e:
print(e)
raise e

Test search bar

This test script enters “Brewery” — a search term that would make much sense to any Prague visitor — in the search bar. The search results are displayed, and the script asserts that the search results contain the search term.

Search for “Brewery” in Prague should give us plenty search hits

The code:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException, NoSuchElementException


def test_search_bar_functionality(browser):
# GIVEN the user is on the officiaL tourist websire for Prague

base_url = "https://www.prague.eu/en"

browser.maximize_window()
browser.get(base_url)

# WHEN the user searches for 'Brewery' in the search window

search_toggle_xpath = "//div[contains(@class, 'search-toggle')]"

wait = WebDriverWait(browser, 20)
try:
wait.until(EC.element_to_be_clickable((By.XPATH, search_toggle_xpath)))
except TimeoutException as e:
print(e)
raise (e)
except Exception as e:
print(e)
raise e

try:
search_toggle = browser.find_element(By.XPATH, search_toggle_xpath)
search_toggle.click()
except NoSuchElementException as e:
print(e)
raise e
except Exception as e:
print(e)
raise e

# search_window clickable
try:
wait.until(EC.element_to_be_clickable((By.ID, "query")))
except TimeoutException as e:
print(e)
raise e
except Exception as e:
print(e)
raise e

search_window = browser.find_element(By.ID, "query")
search_term = "Brewery"
search_window.send_keys(search_term)
search_window.send_keys(Keys.ENTER)

# THEN the user is on a page that displays
# the search results related to breweries

query_results_url = "https://www.prague.eu/qf/en/ramjet/fulltextSearch"

# Assert correct url

try:
assert browser.current_url == query_results_url
except AssertionError as e:
print(e)
raise e
except Exception as e:
print(e)
raise e

# Assert that the list for results is visible
full_text_list_xpath = "//ul[@id='fulltextListing']"
try:
wait.until(EC.visibility_of_element_located((By.XPATH, full_text_list_xpath)))
except TimeoutException as e:
print(e)
raise e
except Exception as e:
print(e)
raise e

results_xpath = (
f"//ul[@id='fulltextListing']/li//*[contains(text(), '{search_term}')]"
)
# Assert both that a results list exists
# and that the search term is found in the result list
try:
results = browser.find_elements(By.XPATH, results_xpath)
assert len(results) > 0
except AssertionError as e:
print(e)
raise e

Lessons learned

If earlier I used implicit waits where it seemed appropriate, with explicit waits I am much more deliberate about what change in the website I am waiting for.

After learning more about xpath I have improved the locators compared with the first project.

All examples I have seen so far of how to use Chrome driver’s scope parameter are from within a class. Since I am not using classes in this project I am still not sure if so far it made much difference wether I choose “session” or “module”. So in this case I will chosen “session” as the parameter. I have also noticed how I get no printout of “quitting chrome driver” from the last line of code. In the future I will use classes and also build test projects with better understanding of the fixture .

--

--

Magnus Rydberg
Magnus Rydberg

Forging a career in Mars-terraforming. Prior to my off-world transition I am open to Earth-based projects in software testing.