From df385981ca52956293e98cea095977978ae204c6 Mon Sep 17 00:00:00 2001 From: Restioson Date: Wed, 6 Nov 2024 13:47:21 +0200 Subject: [PATCH] test(selenium): run tests across multiple {browser, js} combinations By passing the browser type and whether JS is enabled via environment variables, we can run the Selenium frontend tests on all combinations of targetted browsers and JS/no-JS in the CI pipeline. For now, we are not targetting Safari for this, as the GitHub Actions MacOS workers don't suppose `services`, which we use to run the postgres database. This will be left for a follow-up PR. --- .github/workflows/testing.yml | 10 ++++++-- Makefile | 2 +- app/general/tests/test_frontend.py | 41 +++++++++++++++++++++++++----- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 12dd25b..aa54b99 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -69,7 +69,13 @@ jobs: cd app/ python manage.py check selenium: - runs-on: ubuntu-latest + strategy: + matrix: + browser-and-os: + - [firefox, ubuntu-latest] + - [chrome, ubuntu-latest] + js: [js-enabled, js-disabled] + runs-on: ${{ matrix.browser-and-os[1] }} services: postgres: image: postgres:16 @@ -101,7 +107,7 @@ jobs: cp .env.testing app/.env cd app/ mkdir -p static_files - python manage.py test --tag=selenium + BROWSER=${{ matrix.browser-and-os[0] }} ENABLE_JS=${{ matrix.js }} python manage.py test --tag=selenium env: DJANGO_SETTINGS_MODULE: app.settings DATABASE_URL: postgres://sadilar:sadilar@localhost:5432/test_db diff --git a/Makefile b/Makefile index b4aa8e6..c0551aa 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ create-schema: @docker compose run --rm web python manage.py graph_models -a -o schema/schema.png test: - @docker compose run --rm web python manage.py test $(module) + @docker compose run --rm -e BROWSER -e JS_ENABLED web python manage.py test $(module) ruff-check: @docker compose run --rm web ruff check . diff --git a/app/general/tests/test_frontend.py b/app/general/tests/test_frontend.py index adf1eac..528de9b 100644 --- a/app/general/tests/test_frontend.py +++ b/app/general/tests/test_frontend.py @@ -1,8 +1,21 @@ +import os + from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.test import tag from selenium.common import TimeoutException -from selenium.webdriver.chrome.webdriver import Options, WebDriver +from selenium.webdriver.chrome.webdriver import ( + Options as ChromeOptions, +) +from selenium.webdriver.chrome.webdriver import ( + WebDriver as ChromeWebDriver, +) from selenium.webdriver.common.by import By +from selenium.webdriver.firefox.webdriver import ( + Options as FirefoxOptions, +) +from selenium.webdriver.firefox.webdriver import ( + WebDriver as FirefoxWebDriver, +) from selenium.webdriver.support.wait import WebDriverWait # Wait timeout in seconds @@ -13,13 +26,27 @@ class TestFrontend(StaticLiveServerTestCase): @classmethod def setUpClass(cls): - opts = Options() - opts.add_argument("--headless") - opts.add_argument("--no-sandbox") - opts.add_argument("--disable-dev-shm-usage") - opts.add_argument("--window-size=1920,1080") - cls.driver = WebDriver(opts) + browser = os.environ.get("BROWSER", "chrome").lower() + js_enabled = os.environ.get("JS_ENABLED", "js-enabled") == "js-enabled" + + print( + f"Running Selenium tests on {browser}. JS is {'enabled' if js_enabled else 'disabled'}." + ) + + if browser == "chrome": + opts = ChromeOptions() + opts.add_argument("--headless") + opts.add_argument("--no-sandbox") + opts.add_argument("--disable-dev-shm-usage") + opts.add_argument("--window-size=1920,1080") + cls.driver = ChromeWebDriver(opts) + elif browser == "firefox": + options = FirefoxOptions() + options.add_argument("-headless") + cls.driver = FirefoxWebDriver(options=options) + cls.driver.implicitly_wait(WAIT_TIMEOUT) + super().setUpClass() @classmethod