Skip to content

Instantly share code, notes, and snippets.

@DArmstrong87
Created May 9, 2025 15:38
Show Gist options
  • Select an option

  • Save DArmstrong87/83647b4f157089fb73c6cda2b854f73c to your computer and use it in GitHub Desktop.

Select an option

Save DArmstrong87/83647b4f157089fb73c6cda2b854f73c to your computer and use it in GitHub Desktop.
Django Test with Selenium
import time
from unittest import skipIf
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.conf import settings
from django.test.client import Client
# Selenium imports
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select, WebDriverWait
from authentication.group_permissions import AuthGroups
from .utils import create_user, IGNORED_BROWSER_ERRORS
class FormSeleniumTestCase(StaticLiveServerTestCase):
"""
In order for this test to work in github actions,
you must set up the workflow to add Chrome and the Chrome driver.
Once you do that, you can remove the skipIf decorator.
"""
# Time to wait for elements to change after an action
DELAY = 0
# Whether to show the browser
SHOW_BROWSER = False
def get_state(self) -> dict:
"""Return state from javascript"""
return self.driver.execute_script(""" return state; """)
def print_console_logs(self):
"""Print browser console logs"""
logs = self.driver.get_log("browser")
if logs:
print("\n=== Browser Console Logs ===")
for log in logs:
print(f"[{log['level']}] {log['message']}")
print("===========================\n")
# Always print current state
state = self.get_state()
print("\n=== Current State ===")
print(f"State: {state}")
@skipIf(not settings.IS_LOCAL_DEV, "Test does not work in github actions")
def setUp(self):
# Use a unique port for this test run
self.live_server_url = f"http://localhost:{self.server_thread.port}"
user = create_user(AuthGroups.ADMIN.value)
self.client = Client()
self.client.force_login(user)
chrome_options = webdriver.ChromeOptions()
if not self.SHOW_BROWSER:
chrome_options.add_argument("--headless")
chrome_options.set_capability(
"goog:loggingPrefs", {"browser": "ALL"}
) # Enable all browser logs
self.driver = webdriver.Chrome(options=chrome_options)
def print_available_elements(self):
"""Print all elements with IDs on the page"""
print("\n=== Available Elements ===")
elements = self.driver.find_elements(By.CSS_SELECTOR, "[id]")
for element in elements:
print(f"ID: {element.get_attribute('id')}")
print("=========================\n")
@skipIf(not settings.IS_LOCAL_DEV, "Test does not work in github actions")
def test_elements(self):
"""
Tests state changes when selecting an element
"""
self.driver.get(self.live_server_url)
cookie = self.client.cookies["sessionid"]
self.driver.add_cookie(
{"name": "sessionid", "value": cookie.value, "secure": False, "path": "/"}
)
self.driver.refresh()
self.driver.get(self.live_server_url + "/app/my-url")
# Wait for an element that indicates the JavaScript file has loaded
WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.ID, "submit-button")))
my_select_element = self.driver.find_element(By.ID, "mySelect")
self.assertIsNotNone(my_select_element)
my_select = Select(my_select_element)
my_select.select_by_visible_text("Text shown on the select element")
time.sleep(self.DELAY)
self.print_console_logs()
my_number_input= self.driver.find_element(By.ID, "myNumberInput")
my_number_input.send_keys(3)
time.sleep(self.DELAY)
self.print_console_logs()
# Check for uncaught errors in the logs
# Fail test if errors found
browser_log = self.driver.get_log("browser")
for entry in browser_log:
if entry.get("level") == "SEVERE":
if (
any([err for err in IGNORED_BROWSER_ERRORS if err in entry.get("message")])
or "cloudflare" in entry.get("message").lower()
):
print("Ignoring browser log:", entry.get("message"))
else:
self.fail(f"Console error: {entry.get('message')}")
def tearDown(self):
self.client.logout()
self.driver.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment