diff --git a/PyRIGS/tests/regions.py b/PyRIGS/tests/regions.py index a4ac9253..919190c8 100644 --- a/PyRIGS/tests/regions.py +++ b/PyRIGS/tests/regions.py @@ -126,6 +126,22 @@ class CheckBox(Region): self.toggle() +class RadioSelect(Region): # Currently only works for yes/no radio selects + def set_value(self, value): + if value: + value = "0" + else: + value = "1" + self.find_element(By.XPATH, "//label[@for='{}_{}']".format(self.root.get_attribute("id"), value)).click() + + @property + def value(self): + try: + return parse_bool_from_string(self.find_element(By.CSS_SELECTOR, '.custom-control-input:checked').get_attribute("value").lower()) + except: + return None + + class DatePicker(Region): @property def value(self): diff --git a/RIGS/templates/partials/yes_no_radio.html b/RIGS/templates/partials/yes_no_radio.html index 1bcd838b..05ef6458 100644 --- a/RIGS/templates/partials/yes_no_radio.html +++ b/RIGS/templates/partials/yes_no_radio.html @@ -1,7 +1,7 @@
-
+
{% for radio in formitem %}
{{ radio.tag }} diff --git a/RIGS/tests/pages.py b/RIGS/tests/pages.py index 9060f277..1d6ee34b 100644 --- a/RIGS/tests/pages.py +++ b/RIGS/tests/pages.py @@ -162,6 +162,47 @@ class CreateEvent(FormPage): return '/create' not in self.driver.current_url +class CreateRiskAssessment(FormPage): + URL_TEMPLATE = 'event/{event_id}/ra/' + + _submit_locator = (By.XPATH, "//button[@type='submit' and contains(., 'Save')]") + _power_mic_selector = (By.CSS_SELECTOR, ".bootstrap-select") + + form_items = { + 'nonstandard_equipment': (regions.RadioSelect, (By.ID, 'id_nonstandard_equipment')), + 'nonstandard_use': (regions.RadioSelect, (By.ID, 'id_nonstandard_use')), + 'contractors': (regions.RadioSelect, (By.ID, 'id_contractors')), + 'other_companies': (regions.RadioSelect, (By.ID, 'id_other_companies')), + 'crew_fatigue': (regions.RadioSelect, (By.ID, 'id_crew_fatigue')), + 'general_notes': (regions.TextBox, (By.ID, 'id_general_notes')), + 'big_power': (regions.RadioSelect, (By.ID, 'id_big_power')), + #'power_mic': (regions.RadioSelect, (By.ID, 'id_power_mic')), + 'generators': (regions.RadioSelect, (By.ID, 'id_generators')), + 'other_companies_power': (regions.RadioSelect, (By.ID, 'id_other_companies_power')), + 'nonstandard_equipment_power': (regions.RadioSelect, (By.ID, 'id_nonstandard_equipment_power')), + 'multiple_electrical_environments': (regions.RadioSelect, (By.ID, 'id_multiple_electrical_environments')), + 'power_notes': (regions.TextBox, (By.ID, 'id_power_notes')), + 'noise_monitoring': (regions.RadioSelect, (By.ID, 'id_noise_monitoring')), + 'sound_notes': (regions.TextBox, (By.ID, 'id_sound_notes')), + 'known_venue': (regions.RadioSelect, (By.ID, 'id_known_venue')), + 'safe_loading': (regions.RadioSelect, (By.ID, 'id_safe_loading')), + 'safe_storage': (regions.RadioSelect, (By.ID, 'id_safe_storage')), + 'area_outside_of_control': (regions.RadioSelect, (By.ID, 'id_area_outside_of_control')), + 'barrier_required': (regions.RadioSelect, (By.ID, 'id_barrier_required')), + 'nonstandard_emergency_procedure': (regions.RadioSelect, (By.ID, 'id_nonstandard_emergency_procedure')), + 'special_structures': (regions.RadioSelect, (By.ID, 'id_special_structures')), + 'persons_responsible_structures': (regions.TextBox, (By.ID, 'id_persons_responsible_structures')), + 'suspended_structures': (regions.RadioSelect, (By.ID, 'id_suspended_structures')), + } + + @property + def power_mic(self): + return regions.BootstrapSelectElement(self, self.find_element(*self._power_mic_selector)) + + @property + def success(self): + return '/event/ra' in self.driver.current_url + class DuplicateEvent(CreateEvent): URL_TEMPLATE = 'event/{event_id}/duplicate' _submit_locator = (By.XPATH, '/html/body/div[1]/form/div/div[5]/div/button') diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py index a6e1a837..610d15f7 100644 --- a/RIGS/tests/test_functional.py +++ b/RIGS/tests/test_functional.py @@ -23,6 +23,7 @@ from django.test.client import Client from django.core import mail, signing from django.http import HttpResponseBadRequest from django.conf import settings +from selenium.common.exceptions import NoSuchElementException @screenshot_failure_cls @@ -809,7 +810,6 @@ class ClientEventAuthorisationTest(TestCase): self.assertEqual(mail.outbox[1].to, [settings.AUTHORISATION_NOTIFICATION_ADDRESS]) -@screenshot_failure_cls class TECEventAuthorisationTest(TestCase): @classmethod def setUpTestData(cls): @@ -866,3 +866,82 @@ class TECEventAuthorisationTest(TestCase): self.assertEqual(self.event.auth_request_by, self.profile) self.assertEqual(self.event.auth_request_to, 'client@functional.test') self.assertIsNotNone(self.event.auth_request_at) + + + +@screenshot_failure_cls +class TestHealthAndSafety(BaseRigboardTest): + def setUp(self): + super().setUp() + self.profile = models.Profile.objects.get_or_create( + first_name='Test', + last_name='TEC User', + username='eventauthtest', + email='teccie@functional.test', + is_superuser=True # lazily grant all permissions + )[0] + self.testEvent = models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL, + start_date=date.today() + timedelta(days=6), + description="start future no end", + purchase_order='TESTPO', + person=self.client, + auth_request_by=self.profile, + auth_request_at=base.create_datetime(2015, 0o6, 0o4, 10, 00), + auth_request_to="some@email.address") + + item1 = models.EventItem( + event=self.testEvent, + name="Test Item 1", + cost="10.00", + quantity="1", + order=1 + ).save() + item2 = models.EventItem( + event=self.testEvent, + name="Test Item 2", + description="Foo", + cost="9.72", + quantity="3", + order=2, + ).save() + self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + def test_ra_creation(self): + self.page = pages.CreateRiskAssessment(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + # Check there are no defaults + self.assertIsNone(self.page.nonstandard_equipment) + + # No database side validation, only HTML5. + + self.page.nonstandard_equipment = False + self.page.nonstandard_use = False + self.page.contractors = False + self.page.other_companies = False + self.page.crew_fatigue = False + self.page.general_notes = "There are no notes." + self.page.big_power = False + self.page.power_mic.search(self.profile.name) + self.page.power_mic.set_option(self.profile.name, True) + # TODO This should not be necessary, normally closes automatically + self.page.power_mic.toggle() + self.assertFalse(self.page.power_mic.is_open) + self.page.generators = False + self.page.other_companies_power = False + self.page.nonstandard_equipment_power = False + self.page.multiple_electrical_environments = False + self.page.power_notes = "Remember to bring some power" + self.page.noise_monitoring = False + self.page.sound_notes = "Loud, but not too loud" + self.page.known_venue = True + self.page.safe_loading = True + self.page.safe_storage = True + self.page.area_outside_of_control = False + self.page.barrier_required = False + self.page.nonstandard_emergency_procedure = False + self.page.special_structures = False + self.page.persons_responsible_structures = "Nobody and her cat, She" + self.page.suspended_structures = False + + self.page.submit() + self.assertTrue(self.page.success)