mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-18 14:02:15 +00:00
Bunch of test refactoring
This commit is contained in:
@@ -7,6 +7,7 @@ import pytz
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import LiveServerTestCase
|
from django.test import LiveServerTestCase
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
|
|
||||||
from RIGS import models as rigsmodels
|
from RIGS import models as rigsmodels
|
||||||
from . import pages
|
from . import pages
|
||||||
@@ -31,6 +32,7 @@ class BaseTest(LiveServerTestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUpClass()
|
super().setUpClass()
|
||||||
self.driver = create_browser()
|
self.driver = create_browser()
|
||||||
|
self.wait = WebDriverWait(self.driver, 5)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
@@ -44,8 +46,8 @@ class AutoLoginTest(BaseTest):
|
|||||||
username="EventTest", first_name="Event", last_name="Test", initials="ETU", is_superuser=True)
|
username="EventTest", first_name="Event", last_name="Test", initials="ETU", is_superuser=True)
|
||||||
self.profile.set_password("EventTestPassword")
|
self.profile.set_password("EventTestPassword")
|
||||||
self.profile.save()
|
self.profile.save()
|
||||||
loginPage = pages.LoginPage(self.driver, self.live_server_url).open()
|
login_page = pages.LoginPage(self.driver, self.live_server_url).open()
|
||||||
loginPage.login("EventTest", "EventTestPassword")
|
login_page.login("EventTest", "EventTestPassword")
|
||||||
|
|
||||||
|
|
||||||
def screenshot_failure(func):
|
def screenshot_failure(func):
|
||||||
@@ -60,6 +62,7 @@ def screenshot_failure(func):
|
|||||||
self.driver.save_screenshot(screenshot_file)
|
self.driver.save_screenshot(screenshot_file)
|
||||||
print("Error in test {} is at path {}".format(screenshot_name, screenshot_file), file=sys.stderr)
|
print("Error in test {} is at path {}".format(screenshot_name, screenshot_file), file=sys.stderr)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return wrapper_func
|
return wrapper_func
|
||||||
|
|
||||||
|
|
||||||
@@ -70,12 +73,9 @@ def screenshot_failure_cls(cls):
|
|||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
# Checks if animation is done
|
def assert_times_equal(first_time, second_time):
|
||||||
class animation_is_finished():
|
assert first_time.replace(microsecond=0) == second_time.replace(microsecond=0)
|
||||||
def __call__(self, driver):
|
|
||||||
numberAnimating = driver.execute_script('return $(":animated").length')
|
|
||||||
finished = numberAnimating == 0
|
def response_contains(response, needle):
|
||||||
if finished:
|
return str(needle) in str(response.content)
|
||||||
import time
|
|
||||||
time.sleep(0.1)
|
|
||||||
return finished
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class FormPage(BasePage):
|
|||||||
submit = self.find_element(*self._submit_locator)
|
submit = self.find_element(*self._submit_locator)
|
||||||
ActionChains(self.driver).move_to_element(submit).perform()
|
ActionChains(self.driver).move_to_element(submit).perform()
|
||||||
submit.click()
|
submit.click()
|
||||||
|
self.wait.until(animation_is_finished())
|
||||||
self.wait.until(lambda x: self.errors != previous_errors or self.success)
|
self.wait.until(lambda x: self.errors != previous_errors or self.success)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -73,3 +74,13 @@ class LoginPage(BasePage):
|
|||||||
password_element.send_keys(password)
|
password_element.send_keys(password)
|
||||||
|
|
||||||
self.find_element(*self._submit_locator).click()
|
self.find_element(*self._submit_locator).click()
|
||||||
|
|
||||||
|
|
||||||
|
class animation_is_finished():
|
||||||
|
def __call__(self, driver):
|
||||||
|
number_animating = driver.execute_script('return $(":animated").length')
|
||||||
|
finished = number_animating == 0
|
||||||
|
if finished:
|
||||||
|
import time
|
||||||
|
time.sleep(0.1)
|
||||||
|
return finished
|
||||||
@@ -10,8 +10,8 @@ from selenium.webdriver.support.ui import WebDriverWait
|
|||||||
|
|
||||||
from PyRIGS.tests import base
|
from PyRIGS.tests import base
|
||||||
from PyRIGS.tests import regions as base_regions
|
from PyRIGS.tests import regions as base_regions
|
||||||
from PyRIGS.tests.base import (AutoLoginTest, animation_is_finished,
|
from PyRIGS.tests.base import (AutoLoginTest, screenshot_failure_cls)
|
||||||
screenshot_failure_cls)
|
from PyRIGS.tests.pages import animation_is_finished
|
||||||
from RIGS import models
|
from RIGS import models
|
||||||
from RIGS.tests import regions
|
from RIGS.tests import regions
|
||||||
from . import pages
|
from . import pages
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ from django.core.exceptions import ObjectDoesNotExist
|
|||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
from django.urls import reverse
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from pytest_django.asserts import assertRedirects
|
||||||
|
|
||||||
|
from PyRIGS.tests.base import assert_times_equal, response_contains
|
||||||
from RIGS import models
|
from RIGS import models
|
||||||
|
|
||||||
|
|
||||||
@@ -353,203 +355,105 @@ class TestSampleDataGenerator(TestCase):
|
|||||||
self.assertRaisesRegex(CommandError, ".*production", call_command, 'generateSampleRIGSData')
|
self.assertRaisesRegex(CommandError, ".*production", call_command, 'generateSampleRIGSData')
|
||||||
|
|
||||||
|
|
||||||
class TestSearchLogic(TestCase):
|
def search(client, url, found, notfound, arguments):
|
||||||
@classmethod
|
for argument in arguments:
|
||||||
def setUpTestData(cls):
|
query = getattr(found, argument)
|
||||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
|
request_url = "%s?q=%s" % (reverse_lazy(url), query)
|
||||||
is_active=True, is_staff=True)
|
response = client.get(request_url, follow=True)
|
||||||
|
assert response_contains(response, getattr(found, 'name'))
|
||||||
cls.persons = {
|
assert not response_contains(response, getattr(notfound, 'name'))
|
||||||
1: models.Person.objects.create(name="Right Person", phone="1234"),
|
|
||||||
2: models.Person.objects.create(name="Wrong Person", phone="5678"),
|
|
||||||
}
|
|
||||||
|
|
||||||
cls.organisations = {
|
|
||||||
1: models.Organisation.objects.create(name="Right Organisation", email="test@example.com"),
|
|
||||||
2: models.Organisation.objects.create(name="Wrong Organisation", email="check@fake.co.uk"),
|
|
||||||
}
|
|
||||||
|
|
||||||
cls.venues = {
|
|
||||||
1: models.Venue.objects.create(name="Right Venue", address="1 Test Street, EX1"),
|
|
||||||
2: models.Venue.objects.create(name="Wrong Venue", address="2 Check Way, TS2"),
|
|
||||||
}
|
|
||||||
|
|
||||||
cls.events = {
|
|
||||||
1: models.Event.objects.create(name="Right Event", start_date=date.today(), person=cls.persons[1],
|
|
||||||
organisation=cls.organisations[1], venue=cls.venues[1]),
|
|
||||||
2: models.Event.objects.create(name="Wrong Event", start_date=date.today(), person=cls.persons[2],
|
|
||||||
organisation=cls.organisations[2], venue=cls.venues[2]),
|
|
||||||
}
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.profile.set_password('testuser')
|
|
||||||
self.profile.save()
|
|
||||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
|
||||||
|
|
||||||
def test_event_search(self):
|
|
||||||
# Test search by name
|
|
||||||
request_url = "%s?q=%s" % (reverse('event_archive'), self.events[1].name)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.events[1].name)
|
|
||||||
self.assertNotContains(response, self.events[2].name)
|
|
||||||
|
|
||||||
# Test search by ID
|
|
||||||
request_url = "%s?q=%s" % (reverse('event_archive'), self.events[1].pk)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.events[1].name)
|
|
||||||
self.assertNotContains(response, self.events[2].name)
|
|
||||||
|
|
||||||
def test_people_search(self):
|
|
||||||
# Test search by name
|
|
||||||
request_url = "%s?q=%s" % (reverse('person_list'), self.persons[1].name)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.persons[1].name)
|
|
||||||
self.assertNotContains(response, self.persons[2].name)
|
|
||||||
|
|
||||||
# Test search by ID
|
|
||||||
request_url = "%s?q=%s" % (reverse('person_list'), self.persons[1].pk)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.persons[1].name)
|
|
||||||
self.assertNotContains(response, self.persons[2].name)
|
|
||||||
|
|
||||||
# Test search by phone
|
|
||||||
request_url = "%s?q=%s" % (reverse('person_list'), self.persons[1].phone)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.persons[1].name)
|
|
||||||
self.assertNotContains(response, self.persons[2].name)
|
|
||||||
|
|
||||||
def test_organisation_search(self):
|
|
||||||
# Test search by name
|
|
||||||
request_url = "%s?q=%s" % (reverse('organisation_list'), self.organisations[1].name)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.organisations[1].name)
|
|
||||||
self.assertNotContains(response, self.organisations[2].name)
|
|
||||||
|
|
||||||
# Test search by ID
|
|
||||||
request_url = "%s?q=%s" % (reverse('organisation_list'), self.organisations[1].pk)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.organisations[1].name)
|
|
||||||
self.assertNotContains(response, self.organisations[2].name)
|
|
||||||
|
|
||||||
# Test search by email
|
|
||||||
request_url = "%s?q=%s" % (reverse('organisation_list'), self.organisations[1].email)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.organisations[1].email)
|
|
||||||
self.assertNotContains(response, self.organisations[2].email)
|
|
||||||
|
|
||||||
def test_venue_search(self):
|
|
||||||
# Test search by name
|
|
||||||
request_url = "%s?q=%s" % (reverse('venue_list'), self.venues[1].name)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.venues[1].name)
|
|
||||||
self.assertNotContains(response, self.venues[2].name)
|
|
||||||
|
|
||||||
# Test search by ID
|
|
||||||
request_url = "%s?q=%s" % (reverse('venue_list'), self.venues[1].pk)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.venues[1].name)
|
|
||||||
self.assertNotContains(response, self.venues[2].name)
|
|
||||||
|
|
||||||
# Test search by address
|
|
||||||
request_url = "%s?q=%s" % (reverse('venue_list'), self.venues[1].address)
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, self.venues[1].address)
|
|
||||||
self.assertNotContains(response, self.venues[2].address)
|
|
||||||
|
|
||||||
|
|
||||||
class TestHSLogic(TestCase):
|
def test_search(admin_client):
|
||||||
@classmethod
|
persons = {
|
||||||
def setUpTestData(cls):
|
1: models.Person.objects.create(name="Right Person", phone="1234"),
|
||||||
cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True,
|
2: models.Person.objects.create(name="Wrong Person", phone="5678"),
|
||||||
is_active=True, is_staff=True)
|
}
|
||||||
|
organisations = {
|
||||||
|
1: models.Organisation.objects.create(name="Right Organisation", email="test@example.com"),
|
||||||
|
2: models.Organisation.objects.create(name="Wrong Organisation", email="check@fake.co.uk"),
|
||||||
|
}
|
||||||
|
venues = {
|
||||||
|
1: models.Venue.objects.create(name="Right Venue", address="1 Test Street, EX1"),
|
||||||
|
2: models.Venue.objects.create(name="Wrong Venue", address="2 Check Way, TS2"),
|
||||||
|
}
|
||||||
|
events = {
|
||||||
|
1: models.Event.objects.create(name="Right Event", start_date=date.today(), venue=venues[1], person=persons[1],
|
||||||
|
organisation=organisations[1]),
|
||||||
|
2: models.Event.objects.create(name="Wrong Event", start_date=date.today(), venue=venues[2], person=persons[2],
|
||||||
|
organisation=organisations[2]),
|
||||||
|
}
|
||||||
|
search(admin_client, 'event_archive', events[1], events[2], ['name', 'id'])
|
||||||
|
search(admin_client, 'person_list', persons[1], persons[2], ['name', 'id', 'phone'])
|
||||||
|
search(admin_client, 'organisation_list', organisations[1], organisations[2],
|
||||||
|
['name', 'id', 'email'])
|
||||||
|
search(admin_client, 'venue_list', venues[1], venues[2],
|
||||||
|
['name', 'id', 'address'])
|
||||||
|
|
||||||
cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
|
||||||
cls.venue = models.Venue.objects.create(name="Venue 1")
|
|
||||||
|
|
||||||
cls.events = {
|
def setup_for_hs():
|
||||||
1: models.Event.objects.create(name="TE E1", start_date=date.today(),
|
models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1')
|
||||||
description="This is an event description\nthat for a very specific reason spans two lines.",
|
venue = models.Venue.objects.create(name="Venue 1")
|
||||||
venue=cls.venue),
|
return venue, {
|
||||||
2: models.Event.objects.create(name="TE E2", start_date=date.today()),
|
1: models.Event.objects.create(name="TE E1", start_date=date.today(),
|
||||||
}
|
description="This is an event description\nthat for a very specific reason spans two lines.",
|
||||||
|
venue=venue),
|
||||||
|
2: models.Event.objects.create(name="TE E2", start_date=date.today()),
|
||||||
|
}
|
||||||
|
|
||||||
cls.ras = {
|
|
||||||
1: models.RiskAssessment.objects.create(event=cls.events[1],
|
|
||||||
nonstandard_equipment=False,
|
|
||||||
nonstandard_use=False,
|
|
||||||
contractors=False,
|
|
||||||
other_companies=False,
|
|
||||||
crew_fatigue=False,
|
|
||||||
big_power=False,
|
|
||||||
power_mic=cls.profile,
|
|
||||||
generators=False,
|
|
||||||
other_companies_power=False,
|
|
||||||
nonstandard_equipment_power=False,
|
|
||||||
multiple_electrical_environments=False,
|
|
||||||
noise_monitoring=False,
|
|
||||||
known_venue=True,
|
|
||||||
safe_loading=True,
|
|
||||||
safe_storage=True,
|
|
||||||
area_outside_of_control=True,
|
|
||||||
barrier_required=True,
|
|
||||||
nonstandard_emergency_procedure=True,
|
|
||||||
special_structures=False,
|
|
||||||
suspended_structures=False,
|
|
||||||
outside=False),
|
|
||||||
}
|
|
||||||
|
|
||||||
cls.checklists = {
|
def create_ra(usr):
|
||||||
1: models.EventChecklist.objects.create(event=cls.events[1],
|
venue, events = setup_for_hs()
|
||||||
power_mic=cls.profile,
|
return models.RiskAssessment.objects.create(event=events[1], nonstandard_equipment=False, nonstandard_use=False,
|
||||||
safe_parking=False,
|
contractors=False, other_companies=False, crew_fatigue=False,
|
||||||
safe_packing=False,
|
big_power=False, power_mic=usr, generators=False,
|
||||||
exits=False,
|
other_companies_power=False, nonstandard_equipment_power=False,
|
||||||
trip_hazard=False,
|
multiple_electrical_environments=False, noise_monitoring=False,
|
||||||
warning_signs=False,
|
known_venue=True, safe_loading=True, safe_storage=True,
|
||||||
ear_plugs=False,
|
area_outside_of_control=True, barrier_required=True,
|
||||||
hs_location="Locked away safely",
|
nonstandard_emergency_procedure=True, special_structures=False,
|
||||||
extinguishers_location="Somewhere, I forgot",
|
suspended_structures=False, outside=False)
|
||||||
earthing=False,
|
|
||||||
pat=False,
|
|
||||||
date=timezone.now(),
|
|
||||||
venue=cls.venue),
|
|
||||||
}
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.profile.set_password('testuser')
|
|
||||||
self.profile.save()
|
|
||||||
self.assertTrue(self.client.login(username=self.profile.username, password='testuser'))
|
|
||||||
|
|
||||||
def test_list(self):
|
def create_checklist(usr):
|
||||||
request_url = reverse('hs_list')
|
venue, events = setup_for_hs()
|
||||||
response = self.client.get(request_url, follow=True)
|
return models.EventChecklist.objects.create(event=events[1], power_mic=usr, safe_parking=False,
|
||||||
self.assertContains(response, self.events[1].name)
|
safe_packing=False, exits=False, trip_hazard=False, warning_signs=False,
|
||||||
self.assertContains(response, self.events[2].name)
|
ear_plugs=False, hs_location="Locked away safely",
|
||||||
self.assertContains(response, 'Create')
|
extinguishers_location="Somewhere, I forgot", earthing=False, pat=False,
|
||||||
|
date=timezone.now(), venue=venue)
|
||||||
|
|
||||||
def test_ra_review(self):
|
|
||||||
request_url = reverse('ra_review', kwargs={'pk': self.ras[1].pk})
|
|
||||||
response = self.client.get(request_url, follow=True)
|
|
||||||
self.assertContains(response, 'Reviewed by')
|
|
||||||
self.assertContains(response, self.profile.name)
|
|
||||||
ra = models.RiskAssessment.objects.get(event=self.events[1])
|
|
||||||
self.assertEqual(timezone.now().date(), ra.reviewed_at.date())
|
|
||||||
self.assertEqual(timezone.now().hour, ra.reviewed_at.hour)
|
|
||||||
self.assertEqual(timezone.now().minute, ra.reviewed_at.minute)
|
|
||||||
|
|
||||||
def test_checklist_review(self):
|
def test_list(admin_client):
|
||||||
request_url = reverse('ec_review', kwargs={'pk': self.checklists[1].pk})
|
venue, events = setup_for_hs()
|
||||||
response = self.client.get(request_url, follow=True)
|
request_url = reverse('hs_list')
|
||||||
self.assertContains(response, 'Reviewed by')
|
response = admin_client.get(request_url, follow=True)
|
||||||
self.assertContains(response, self.profile.name)
|
assert response_contains(response, events[1].name)
|
||||||
checklist = models.EventChecklist.objects.get(event=self.events[1])
|
assert response_contains(response, events[2].name)
|
||||||
self.assertEqual(timezone.now().date(), checklist.reviewed_at.date())
|
assert response_contains(response, 'Create')
|
||||||
self.assertEqual(timezone.now().hour, checklist.reviewed_at.hour)
|
|
||||||
self.assertEqual(timezone.now().minute, checklist.reviewed_at.minute)
|
|
||||||
|
|
||||||
def test_ra_redirect(self):
|
|
||||||
request_url = reverse('event_ra', kwargs={'pk': self.events[1].pk})
|
|
||||||
expected_url = reverse('ra_edit', kwargs={'pk': self.ras[1].pk})
|
|
||||||
|
|
||||||
response = self.client.get(request_url, follow=True)
|
def review(client, profile, obj, request_url):
|
||||||
self.assertRedirects(response, expected_url, status_code=302, target_status_code=200)
|
time = timezone.now()
|
||||||
|
response = client.get(reverse(request_url, kwargs={'pk': obj.pk}), follow=True)
|
||||||
|
obj.refresh_from_db()
|
||||||
|
assert response_contains(response, 'Reviewed by')
|
||||||
|
assert response_contains(response, profile.name)
|
||||||
|
assert_times_equal(time, obj.reviewed_at)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ra_review(admin_client, admin_user):
|
||||||
|
review(admin_client, admin_user, create_ra(admin_user), 'ra_review')
|
||||||
|
|
||||||
|
|
||||||
|
def test_checklist_review(admin_client, admin_user):
|
||||||
|
review(admin_client, admin_user, create_checklist(admin_user), 'ec_review')
|
||||||
|
|
||||||
|
|
||||||
|
def test_ra_redirect(admin_client, admin_user):
|
||||||
|
ra = create_ra(admin_user)
|
||||||
|
request_url = reverse('event_ra', kwargs={'pk': ra.event.pk})
|
||||||
|
expected_url = reverse('ra_edit', kwargs={'pk': ra.pk})
|
||||||
|
|
||||||
|
response = admin_client.get(request_url, follow=True)
|
||||||
|
assertRedirects(response, expected_url, status_code=302, target_status_code=200)
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ from django.urls import reverse
|
|||||||
from pypom import Region
|
from pypom import Region
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support import expected_conditions
|
||||||
|
|
||||||
from PyRIGS.tests import regions
|
from PyRIGS.tests import regions
|
||||||
from PyRIGS.tests.pages import BasePage, FormPage
|
from PyRIGS.tests.pages import BasePage, FormPage, animation_is_finished
|
||||||
|
|
||||||
|
|
||||||
class AssetList(BasePage):
|
class AssetList(BasePage):
|
||||||
@@ -196,6 +197,7 @@ class AssetAuditList(AssetList):
|
|||||||
|
|
||||||
def search(self):
|
def search(self):
|
||||||
self.find_element(*self._go_button_locator).click()
|
self.find_element(*self._go_button_locator).click()
|
||||||
|
self.wait.until(animation_is_finished())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def error(self):
|
def error(self):
|
||||||
@@ -237,13 +239,13 @@ class AssetAuditList(AssetList):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def submit(self):
|
def submit(self):
|
||||||
previous_errors = self.errors
|
|
||||||
self.root.find_element(*self._submit_locator).click()
|
self.root.find_element(*self._submit_locator).click()
|
||||||
# self.wait.until(lambda x: not self.is_displayed) TODO
|
# self.wait.until(lambda x: not self.is_displayed) TODO
|
||||||
|
self.wait.until(expected_conditions.invisibility_of_element_located((By.ID, 'modal')))
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
previous_errors = self.errors
|
|
||||||
self.page.find_element(*self._close_selector).click()
|
self.page.find_element(*self._close_selector).click()
|
||||||
|
self.wait.until(expected_conditions.invisibility_of_element_located((By.ID, 'modal')))
|
||||||
|
|
||||||
def remove_all_required(self):
|
def remove_all_required(self):
|
||||||
self.driver.execute_script("Array.from(document.getElementsByTagName(\"input\")).forEach(function (el, ind, arr) { el.removeAttribute(\"required\")});")
|
self.driver.execute_script("Array.from(document.getElementsByTagName(\"input\")).forEach(function (el, ind, arr) { el.removeAttribute(\"required\")});")
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import datetime
|
|||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as ec
|
||||||
from selenium.webdriver.support.ui import WebDriverWait
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
|
||||||
from PyRIGS.tests.base import AutoLoginTest, screenshot_failure_cls
|
from PyRIGS.tests.base import AutoLoginTest, screenshot_failure_cls, assert_times_equal
|
||||||
from PyRIGS.tests.base import animation_is_finished
|
from PyRIGS.tests.pages import animation_is_finished
|
||||||
from assets import models
|
from assets import models
|
||||||
from . import pages
|
from . import pages
|
||||||
|
|
||||||
@@ -29,10 +29,10 @@ class TestAssetList(AutoLoginTest):
|
|||||||
|
|
||||||
def test_default_statuses_applied(self):
|
def test_default_statuses_applied(self):
|
||||||
# Only the working stuff should be shown initially
|
# Only the working stuff should be shown initially
|
||||||
assetDescriptions = list(map(lambda x: x.description, self.page.assets))
|
asset_descriptions = list(map(lambda x: x.description, self.page.assets))
|
||||||
self.assertEqual(2, len(assetDescriptions))
|
self.assertEqual(2, len(asset_descriptions))
|
||||||
self.assertIn("A light", assetDescriptions)
|
self.assertIn("A light", asset_descriptions)
|
||||||
self.assertIn("Working Mic", assetDescriptions)
|
self.assertIn("Working Mic", asset_descriptions)
|
||||||
|
|
||||||
def test_asset_order(self):
|
def test_asset_order(self):
|
||||||
# Only the working stuff should be shown initially
|
# Only the working stuff should be shown initially
|
||||||
@@ -42,11 +42,11 @@ class TestAssetList(AutoLoginTest):
|
|||||||
|
|
||||||
self.page.search()
|
self.page.search()
|
||||||
|
|
||||||
assetIDs = list(map(lambda x: x.id, self.page.assets))
|
asset_ids = list(map(lambda x: x.id, self.page.assets))
|
||||||
self.assertEqual("1", assetIDs[0])
|
self.assertEqual("1", asset_ids[0])
|
||||||
self.assertEqual("2", assetIDs[1])
|
self.assertEqual("2", asset_ids[1])
|
||||||
self.assertEqual("10", assetIDs[2])
|
self.assertEqual("10", asset_ids[2])
|
||||||
self.assertEqual("C1", assetIDs[3])
|
self.assertEqual("C1", asset_ids[3])
|
||||||
|
|
||||||
def test_search(self):
|
def test_search(self):
|
||||||
self.page.set_query("10")
|
self.page.set_query("10")
|
||||||
@@ -84,9 +84,9 @@ class TestAssetList(AutoLoginTest):
|
|||||||
self.assertFalse(self.page.category_selector.is_open)
|
self.assertFalse(self.page.category_selector.is_open)
|
||||||
self.page.search()
|
self.page.search()
|
||||||
self.assertTrue(len(self.page.assets) == 2)
|
self.assertTrue(len(self.page.assets) == 2)
|
||||||
assetIDs = list(map(lambda x: x.id, self.page.assets))
|
asset_ids = list(map(lambda x: x.id, self.page.assets))
|
||||||
self.assertEqual("1", assetIDs[0])
|
self.assertEqual("1", asset_ids[0])
|
||||||
self.assertEqual("10", assetIDs[1])
|
self.assertEqual("10", asset_ids[1])
|
||||||
|
|
||||||
|
|
||||||
@screenshot_failure_cls
|
@screenshot_failure_cls
|
||||||
@@ -99,7 +99,6 @@ class TestAssetForm(AutoLoginTest):
|
|||||||
self.parent = models.Asset.objects.create(asset_id="9000", description="Shelf", status=self.status, category=self.category, date_acquired=datetime.date(2000, 1, 1))
|
self.parent = models.Asset.objects.create(asset_id="9000", description="Shelf", status=self.status, category=self.category, date_acquired=datetime.date(2000, 1, 1))
|
||||||
self.connector = models.Connector.objects.create(description="IEC", current_rating=10, voltage_rating=240, num_pins=3)
|
self.connector = models.Connector.objects.create(description="IEC", current_rating=10, voltage_rating=240, num_pins=3)
|
||||||
self.cable_type = models.CableType.objects.create(plug=self.connector, socket=self.connector, circuits=1, cores=3)
|
self.cable_type = models.CableType.objects.create(plug=self.connector, socket=self.connector, circuits=1, cores=3)
|
||||||
self.wait = WebDriverWait(self.driver, 5)
|
|
||||||
self.page = pages.AssetCreate(self.driver, self.live_server_url).open()
|
self.page = pages.AssetCreate(self.driver, self.live_server_url).open()
|
||||||
|
|
||||||
def test_asset_create(self):
|
def test_asset_create(self):
|
||||||
@@ -141,7 +140,6 @@ class TestAssetForm(AutoLoginTest):
|
|||||||
self.assertFalse(self.driver.find_element_by_id('cable-table').is_displayed())
|
self.assertFalse(self.driver.find_element_by_id('cable-table').is_displayed())
|
||||||
|
|
||||||
self.page.submit()
|
self.page.submit()
|
||||||
self.wait.until(animation_is_finished())
|
|
||||||
self.assertTrue(self.page.success)
|
self.assertTrue(self.page.success)
|
||||||
# Check that data is right
|
# Check that data is right
|
||||||
asset = models.Asset.objects.get(asset_id="9001")
|
asset = models.Asset.objects.get(asset_id="9001")
|
||||||
@@ -285,48 +283,41 @@ class TestAssetAudit(AutoLoginTest):
|
|||||||
asset_id = "1111"
|
asset_id = "1111"
|
||||||
self.page.set_query(asset_id)
|
self.page.set_query(asset_id)
|
||||||
self.page.search()
|
self.page.search()
|
||||||
self.wait.until(EC.visibility_of_element_located((By.ID, 'modal')))
|
self.wait.until(ec.visibility_of_element_located((By.ID, 'modal')))
|
||||||
# Do it wrong on purpose to check error display
|
# Do it wrong on purpose to check error display
|
||||||
self.page.modal.remove_all_required()
|
self.page.modal.remove_all_required()
|
||||||
self.page.modal.description = ""
|
self.page.modal.description = ""
|
||||||
self.page.modal.submit()
|
self.page.modal.submit()
|
||||||
self.wait.until(animation_is_finished())
|
|
||||||
self.wait.until(EC.visibility_of_element_located((By.ID, 'modal')))
|
|
||||||
self.assertIn("This field is required.", self.page.modal.errors["Description"])
|
self.assertIn("This field is required.", self.page.modal.errors["Description"])
|
||||||
# Now do it properly
|
# Now do it properly
|
||||||
self.page.modal.description = new_desc = "A BIG hammer"
|
self.page.modal.description = new_desc = "A BIG hammer"
|
||||||
self.page.modal.submit()
|
self.page.modal.submit()
|
||||||
submit_time = timezone.now()
|
submit_time = timezone.now()
|
||||||
self.wait.until(EC.invisibility_of_element_located((By.ID, 'modal')))
|
|
||||||
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
||||||
|
|
||||||
# Check data is correct
|
# Check data is correct
|
||||||
audited = models.Asset.objects.get(asset_id=asset_id)
|
audited = models.Asset.objects.get(asset_id=asset_id)
|
||||||
self.assertEqual(audited.description, new_desc)
|
self.assertEqual(audited.description, new_desc)
|
||||||
# Make sure audit 'log' was filled out
|
# Make sure audit 'log' was filled out
|
||||||
self.assertEqual(self.profile.initials, audited.last_audited_by.initials)
|
self.assertEqual(self.profile.initials, audited.last_audited_by.initials)
|
||||||
self.assertEqual(submit_time.replace(microsecond=0), audited.last_audited_at.replace(microsecond=0))
|
assert_times_equal(submit_time, audited.last_audited_at)
|
||||||
# Check we've removed it from the 'needing audit' list
|
# Check we've removed it from the 'needing audit' list
|
||||||
self.assertNotIn(asset_id, self.page.assets)
|
self.assertNotIn(asset_id, self.page.assets)
|
||||||
|
|
||||||
def test_audit_list(self):
|
def test_audit_list(self):
|
||||||
self.assertEqual(len(models.Asset.objects.filter(last_audited_at=None)), len(self.page.assets))
|
self.assertEqual(len(models.Asset.objects.filter(last_audited_at=None)), len(self.page.assets))
|
||||||
|
|
||||||
asset_row = self.page.assets[0]
|
asset_row = self.page.assets[0]
|
||||||
self.driver.find_element(By.XPATH, "//a[contains(@class,'btn') and contains(., 'Audit')]").click()
|
self.driver.find_element(By.XPATH, "//a[contains(@class,'btn') and contains(., 'Audit')]").click()
|
||||||
self.wait.until(EC.visibility_of_element_located((By.ID, 'modal')))
|
self.wait.until(ec.visibility_of_element_located((By.ID, 'modal')))
|
||||||
self.assertEqual(self.page.modal.asset_id, asset_row.id)
|
self.assertEqual(self.page.modal.asset_id, asset_row.id)
|
||||||
self.page.modal.close()
|
self.page.modal.close()
|
||||||
self.wait.until(EC.invisibility_of_element_located((By.ID, 'modal')))
|
|
||||||
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
||||||
# Make sure audit log was NOT filled out
|
# Make sure audit log was NOT filled out
|
||||||
audited = models.Asset.objects.get(asset_id=asset_row.id)
|
audited = models.Asset.objects.get(asset_id=asset_row.id)
|
||||||
self.assertEqual(None, audited.last_audited_by)
|
assert audited.last_audited_by is None
|
||||||
|
|
||||||
def test_audit_search(self):
|
def test_audit_search(self):
|
||||||
# Check that a failed search works
|
# Check that a failed search works
|
||||||
self.page.set_query("NOTFOUND")
|
self.page.set_query("NOTFOUND")
|
||||||
self.page.search()
|
self.page.search()
|
||||||
self.wait.until(animation_is_finished())
|
|
||||||
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
||||||
self.assertIn("Asset with that ID does not exist!", self.page.error.text)
|
self.assertIn("Asset with that ID does not exist!", self.page.error.text)
|
||||||
@@ -6,19 +6,16 @@ from django.test.utils import override_settings
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from pytest_django.asserts import assertFormError, assertRedirects
|
from pytest_django.asserts import assertFormError, assertRedirects
|
||||||
|
|
||||||
|
from PyRIGS.tests.base import response_contains
|
||||||
from assets import models, urls
|
from assets import models, urls
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db # TODO
|
pytestmark = pytest.mark.django_db # TODO
|
||||||
|
|
||||||
|
|
||||||
def response_contains(response, needle):
|
|
||||||
return needle in str(response.content)
|
|
||||||
|
|
||||||
|
|
||||||
def login(client, django_user_model):
|
def login(client, django_user_model):
|
||||||
pwd = 'testuser'
|
pwd = 'testuser'
|
||||||
usr = "TestUser"
|
usr = "TestUser"
|
||||||
profile = django_user_model.objects.create_user(username=usr, email="TestUser@test.com", password=pwd, is_superuser=True, is_active=True, is_staff=True)
|
django_user_model.objects.create_user(username=usr, email="TestUser@test.com", password=pwd, is_superuser=True, is_active=True, is_staff=True)
|
||||||
assert client.login(username=usr, password=pwd)
|
assert client.login(username=usr, password=pwd)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user