Skip to content

Commit

Permalink
Support live server tests with Selenium and add first test
Browse files Browse the repository at this point in the history
  • Loading branch information
hansegucker committed Nov 20, 2023
1 parent 431077a commit d1316bf
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
23 changes: 22 additions & 1 deletion deployment/provision_vagrant_vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export DEBIAN_FRONTEND=noninteractive
apt-get -q update

# system utilities that docker containers don't have
apt-get -q install -y sudo wget git bash-completion
apt-get -q install -y sudo wget git bash-completion software-properties-common
# docker weirdly needs this -- see https://stackoverflow.com/questions/46247032/how-to-solve-invoke-rc-d-policy-rc-d-denied-execution-of-start-when-building
printf '#!/bin/sh\nexit 0' > /usr/sbin/policy-rc.d

Expand Down Expand Up @@ -93,6 +93,27 @@ cp $REPO_FOLDER/deployment/manage_autocompletion.sh /etc/bash_completion.d/
# install chrome, see: https://github.com/puppeteer/puppeteer/issues/7740
apt-get -q install -y chromium-browser

# install firefox and geckodriver
cat <<EOT >> /etc/apt/preferences.d/mozillateam
Package: *
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 100
Package: firefox*
Pin: release o=LP-PPA-mozillateam
Pin-Priority: 1001
Package: firefox*
Pin: release o=Ubuntu
Pin-Priority: -1
EOT
add-apt-repository -y ppa:mozillateam/ppa
apt-get -q install -y firefox

wget https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz -O geckodriver.tar.gz
tar xzf geckodriver.tar.gz -C /usr/local/bin/
chmod +x /usr/local/bin/geckodriver

# install libraries for puppeteer
apt-get -q install -y libasound2 libgconf-2-4 libgbm1 libgtk-3-0 libnss3 libx11-xcb1 libxss1 libxshmfence-dev

Expand Down
35 changes: 35 additions & 0 deletions evap/evaluation/tests/test_live.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from django.core import mail
from django.urls import reverse
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from evap.evaluation.tests.tools import LiveServerTest


class ContactModalTests(LiveServerTest):
def test_contact_modal(self):
self._login()
self.selenium.get(self.live_server_url + reverse("evaluation:index"))
self.selenium.find_element(By.ID, "feedbackModalShowButton").click()
self._screenshot("feedback_modal_")

WebDriverWait(self.selenium, 10).until(
expected_conditions.visibility_of_element_located((By.ID, "feedbackModalMessageText"))
)
self._screenshot("feedback_modal_2")
self.selenium.find_element(By.ID, "feedbackModalMessageText").send_keys("Testmessage")
self._screenshot("feedback_modal_typed")
self.selenium.find_element(By.ID, "feedbackModalActionButton").click()

WebDriverWait(self.selenium, 10).until(
expected_conditions.text_to_be_present_in_element(
(By.CSS_SELECTOR, "#successMessageModal_feedbackModal .modal-body"),
"Your message was successfully sent.",
)
)
self._screenshot("feedback_modal_success")

self.assertEqual(len(mail.outbox), 1)

self.assertEqual(mail.outbox[0].subject, f"[EvaP] Message from {self.test_user.email}")
54 changes: 54 additions & 0 deletions evap/evaluation/tests/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
from django.contrib.auth.models import Group
from django.db import DEFAULT_DB_ALIAS, connections
from django.http.request import QueryDict
from django.test.selenium import SeleniumTestCase, SeleniumTestCaseBase
from django.test.utils import CaptureQueriesContext
from django.utils import timezone
from django_webtest import WebTest
from model_bakery import baker
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from evap.evaluation.models import (
CHOICES,
Expand Down Expand Up @@ -245,3 +249,53 @@ def assert_no_database_modifications(*args, **kwargs):
lower_sql = query["sql"].lower()
if not any(lower_sql.startswith(prefix) for prefix in allowed_prefixes):
raise AssertionError("Unexpected modifying query found: " + query["sql"])


class CustomSeleniumTestCaseBase(SeleniumTestCaseBase):
external_host = os.environ.get("TEST_HOST", "") or None
browsers = ["firefox"]
selenium_hub = os.environ.get("TEST_SELENIUM_HUB", "") or None
headless = True

def create_options(self): # pylint: disable=bad-mcs-method-argument
options = super().create_options()

if self.browser == "chrome":
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--disable-gpu")
elif self.browser == "firefox":
options.add_argument("--headless")

return options


class LiveServerTest(SeleniumTestCase, metaclass=CustomSeleniumTestCaseBase):
def _screenshot(self, name):
self.selenium.save_screenshot(os.path.join(settings.BASE_DIR, f"{name}.png"))

def _create_test_user(self):
self.test_user = baker.make( # pylint: disable=attribute-defined-outside-init
UserProfile, email="[email protected]", groups=[Group.objects.get(name="Manager")]
)
self.test_user_password = "evap" # pylint: disable=attribute-defined-outside-init
self.test_user.set_password(self.test_user_password)
self.test_user.save()
return self.test_user

def _login(self):
self._create_test_user()
self.selenium.get(self.live_server_url)
self.selenium.find_element(By.ID, "id_email").click()
self.selenium.find_element(By.ID, "id_email").send_keys(self.test_user.email)
self.selenium.find_element(By.ID, "id_email").click()
self.selenium.find_element(By.ID, "id_password").send_keys(self.test_user_password)
self.selenium.find_element(By.CSS_SELECTOR, ".login-button").click()
self.selenium.save_screenshot(os.path.join(settings.BASE_DIR, "login_success.png"))

WebDriverWait(self.selenium, 10).until(expected_conditions.presence_of_element_located((By.ID, "logout-form")))

@classmethod
def tearDownClass(cls):
cls.selenium.quit()
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ pylint-django~=2.5.4
pylint~=3.0.1
tblib~=3.0.0
xlrd~=2.0.1
selenium~=4.15.2

0 comments on commit d1316bf

Please sign in to comment.