From 6426880708684b27bdf832436a38a4e01c743556 Mon Sep 17 00:00:00 2001 From: FreneticScribbler Date: Mon, 14 Sep 2020 16:26:02 +0100 Subject: [PATCH] Pages/start of tests for EventChecklists --- PyRIGS/tests/regions.py | 5 +- RIGS/models.py | 4 ++ RIGS/templates/hs_object_list.html | 8 +-- RIGS/tests/pages.py | 67 ++++++++++++++++++++----- RIGS/tests/test_functional.py | 80 ++++++++++++++++++++++-------- RIGS/urls.py | 18 +++---- 6 files changed, 134 insertions(+), 48 deletions(-) diff --git a/PyRIGS/tests/regions.py b/PyRIGS/tests/regions.py index 919190c8..06e21cda 100644 --- a/PyRIGS/tests/regions.py +++ b/PyRIGS/tests/regions.py @@ -6,6 +6,7 @@ from selenium.webdriver.remote.webelement import WebElement from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.select import Select from selenium.webdriver.common.keys import Keys +from selenium.common.exceptions import NoSuchElementException import datetime @@ -126,7 +127,7 @@ class CheckBox(Region): self.toggle() -class RadioSelect(Region): # Currently only works for yes/no radio selects +class RadioSelect(Region): # Currently only works for yes/no radio selects def set_value(self, value): if value: value = "0" @@ -138,7 +139,7 @@ class RadioSelect(Region): # Currently only works for yes/no radio selects def value(self): try: return parse_bool_from_string(self.find_element(By.CSS_SELECTOR, '.custom-control-input:checked').get_attribute("value").lower()) - except: + except NoSuchElementException: return None diff --git a/RIGS/models.py b/RIGS/models.py index be16a8ae..89ac54e9 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -728,6 +728,10 @@ class EventChecklist(models.Model, RevisionMixin): def clean(self): errdict = {} + + if self.power_mic is None: + errdict["power_mic"] = ["You must select a Power MIC"] + if self.earthing is None or self.pat is None: errdict['earthing'] = 'Fill out the electrical checks' diff --git a/RIGS/templates/hs_object_list.html b/RIGS/templates/hs_object_list.html index bd2a4937..65a07daf 100644 --- a/RIGS/templates/hs_object_list.html +++ b/RIGS/templates/hs_object_list.html @@ -20,9 +20,11 @@ Event {# mmm hax #} - {% for field in fields %} - {{ object_list.0|verbose_name:field|title }} - {% endfor %} + {% if object_list.0 != None %} + {% for field in fields %} + {{ object_list.0|verbose_name:field|title }} + {% endfor %} + {% endif %} diff --git a/RIGS/tests/pages.py b/RIGS/tests/pages.py index 1d6ee34b..39593ef0 100644 --- a/RIGS/tests/pages.py +++ b/RIGS/tests/pages.py @@ -162,6 +162,24 @@ class CreateEvent(FormPage): return '/create' not 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') + + @property + def success(self): + return '/duplicate' not in self.driver.current_url + + +class EditEvent(CreateEvent): + URL_TEMPLATE = 'event/{event_id}/edit' + _submit_locator = (By.XPATH, '/html/body/div[1]/form/div/div[5]/div/button') + + @property + def success(self): + return '/edit' not in self.driver.current_url + + class CreateRiskAssessment(FormPage): URL_TEMPLATE = 'event/{event_id}/ra/' @@ -176,7 +194,6 @@ class CreateRiskAssessment(FormPage): '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')), @@ -203,24 +220,50 @@ class CreateRiskAssessment(FormPage): 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') - @property - def success(self): - return '/duplicate' not in self.driver.current_url - - -class EditEvent(CreateEvent): - URL_TEMPLATE = 'event/{event_id}/edit' - _submit_locator = (By.XPATH, '/html/body/div[1]/form/div/div[5]/div/button') +class EditRiskAssessment(CreateRiskAssessment): + URL_TEMPLATE = 'event/ra/{pk}/edit' @property def success(self): return '/edit' not in self.driver.current_url +class CreateEventChecklist(FormPage): + URL_TEMPLATE = 'event/{event_id}/checklist' + + _submit_locator = (By.XPATH, "//button[@type='submit' and contains(., 'Save')]") + _power_mic_selector = (By.CSS_SELECTOR, ".bootstrap-select") + _add_vehicle_locator = (By.XPATH, "//button[contains(., 'Vehicle')]") + _add_crew_locator = (By.XPATH, "//button[contains(., 'Crew')]") + + form_items = { + 'safe_parking': (regions.CheckBox, (By.ID, 'id_safe_parking')), + 'safe_packing': (regions.CheckBox, (By.ID, 'id_safe_packing')), + 'exits': (regions.CheckBox, (By.ID, 'id_exits')), + 'trip_hazard': (regions.CheckBox, (By.ID, 'id_trip_hazard')), + 'warning_signs': (regions.CheckBox, (By.ID, 'id_warning_signs')), + 'ear_plugs': (regions.CheckBox, (By.ID, 'id_ear_plugs')), + 'hs_location': (regions.TextBox, (By.ID, 'id_hs_location')), + 'extinguishers_location': (regions.TextBox, (By.ID, 'id_extinguishers_location')), + 'rcds': (regions.CheckBox, (By.ID, 'id_rcds')), + 'supply_test': (regions.CheckBox, (By.ID, 'id_supply_test')), + 'earthing': (regions.CheckBox, (By.ID, 'id_earthing')), + 'pat': (regions.CheckBox, (By.ID, 'id_pat')), + } + + def select_size(self, size): + self.find_element(By.XPATH, '//button[.="{}"]'.format(size)).click() + + @property + def power_mic(self): + return regions.BootstrapSelectElement(self, self.find_element(*self._power_mic_selector)) + + @property + def success(self): + return '{event_id}' not in self.driver.current_url + + class GenericList(BasePage): _search_selector = (By.CSS_SELECTOR, 'div.input-group:nth-child(2) > input:nth-child(1)') _search_go_selector = (By.ID, 'id_search') diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py index 610d15f7..f083d762 100644 --- a/RIGS/tests/test_functional.py +++ b/RIGS/tests/test_functional.py @@ -868,7 +868,6 @@ class TECEventAuthorisationTest(TestCase): self.assertIsNotNone(self.event.auth_request_at) - @screenshot_failure_cls class TestHealthAndSafety(BaseRigboardTest): def setUp(self): @@ -876,7 +875,7 @@ class TestHealthAndSafety(BaseRigboardTest): self.profile = models.Profile.objects.get_or_create( first_name='Test', last_name='TEC User', - username='eventauthtest', + username='eventtest', email='teccie@functional.test', is_superuser=True # lazily grant all permissions )[0] @@ -884,28 +883,10 @@ class TestHealthAndSafety(BaseRigboardTest): 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() + person=self.client) self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + # TODO Can I loop through all the boolean fields and test them at once? def test_ra_creation(self): self.page = pages.CreateRiskAssessment(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() @@ -945,3 +926,58 @@ class TestHealthAndSafety(BaseRigboardTest): self.page.submit() self.assertTrue(self.page.success) + + # Test that we can't make another one + self.page = pages.CreateRiskAssessment(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + self.assertIn('edit', self.driver.current_url) + + def test_ra_edit(self): + # Create assessment to edit + self.page = pages.CreateRiskAssessment(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + 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.toggle() + self.assertFalse(self.page.power_mic.is_open) + self.page.remove_all_required() + self.page.submit() + self.page = pages.EditRiskAssessment(self.driver, self.live_server_url, pk=models.RiskAssessment.objects.get(event=self.testEvent.pk).pk).open() + self.page.nonstandard_equipment = nse = True + self.page.general_notes = gn = "There are some notes, but I've not written them here as that would be helpful" + self.page.submit() + self.assertTrue(self.page.success) + # Check that data is right + ra = models.RiskAssessment.objects.get(event=self.testEvent.pk) + self.assertEqual(ra.general_notes, gn) + self.assertEqual(ra.nonstandard_equipment, nse) + + def test_ec_create_small(self): + self.page = pages.CreateEventChecklist(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + self.page.safe_parking = True + self.page.safe_packing = True + self.page.exits = True + self.page.trip_hazard = True + self.page.warning_signs = True + self.page.ear_plugs = True + self.page.hs_location = "The Moon" + self.page.extinguishers_location = "With the rest of the fire" + # If we do this first the search fails, for ... reasons + self.page.power_mic.search(self.profile.name) + self.page.power_mic.toggle() + self.assertFalse(self.page.power_mic.is_open) + + self.page.select_size('Small') + self.wait.until(animation_is_finished()) + self.page.earthing = True + self.page.rcds = True + self.page.supply_test = True + self.page.pat = True + + self.page.submit() + self.assertTrue(self.page.success) diff --git a/RIGS/urls.py b/RIGS/urls.py index 4bfa351f..a03425a6 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -71,25 +71,25 @@ urlpatterns = [ name='event_duplicate'), # Event H&S - path('event/hs/', permission_required_with_403('RIGS.change_event')(hs.HSList.as_view()), name='hs_list'), + path('event/hs/', permission_required_with_403('RIGS.view_riskassessment')(hs.HSList.as_view()), name='hs_list'), - path('event//ra/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentCreate.as_view()), + path('event//ra/', permission_required_with_403('RIGS.add_riskassessment')(hs.EventRiskAssessmentCreate.as_view()), name='event_ra'), - path('event/ra//', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentDetail.as_view()), + path('event/ra//', permission_required_with_403('RIGS.view_riskassessment')(hs.EventRiskAssessmentDetail.as_view()), name='ra_detail'), - path('event/ra//edit/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentEdit.as_view()), + path('event/ra//edit/', permission_required_with_403('RIGS.change_riskassessment')(hs.EventRiskAssessmentEdit.as_view()), name='ra_edit'), - path('event/ra/list', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentList.as_view()), + path('event/ra/list', permission_required_with_403('RIGS.view_riskassessment')(hs.EventRiskAssessmentList.as_view()), name='ra_list'), path('event/ra//review/', permission_required_with_403('RIGS.review_riskassessment')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'), - path('event//checklist/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistCreate.as_view()), + path('event//checklist/', permission_required_with_403('RIGS.add_eventchecklist')(hs.EventChecklistCreate.as_view()), name='event_ec'), - path('event/checklist//', permission_required_with_403('RIGS.change_event')(hs.EventChecklistDetail.as_view()), + path('event/checklist//', permission_required_with_403('RIGS.view_eventchecklist')(hs.EventChecklistDetail.as_view()), name='ec_detail'), - path('event/checklist//edit/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistEdit.as_view()), + path('event/checklist//edit/', permission_required_with_403('RIGS.change_eventchecklist')(hs.EventChecklistEdit.as_view()), name='ec_edit'), - path('event/checklist/list', permission_required_with_403('RIGS.change_event')(hs.EventChecklistList.as_view()), + path('event/checklist/list', permission_required_with_403('RIGS.view_eventchecklist')(hs.EventChecklistList.as_view()), name='ec_list'), path('event/checklist//review/', permission_required_with_403('RIGS.review_eventchecklist')(hs.EventChecklistReview.as_view()), name='ec_review'),