From 928d5cd8e6d7cb4c0e606dae4dbc3ee63704fbbc Mon Sep 17 00:00:00 2001 From: Arona Date: Sun, 24 May 2020 19:16:09 +0100 Subject: [PATCH] Deduplication of testing code --- RIGS/tests/pages.py | 34 +++++++ RIGS/tests/test_functional.py | 148 ----------------------------- RIGS/tests/test_rigs.py | 174 +++++++++++++++++++--------------- 3 files changed, 132 insertions(+), 224 deletions(-) diff --git a/RIGS/tests/pages.py b/RIGS/tests/pages.py index f389b0f5..b993aa62 100644 --- a/RIGS/tests/pages.py +++ b/RIGS/tests/pages.py @@ -47,7 +47,33 @@ class Rigboard(BasePage): @property def events(self): return [self.EventListRow(self, i) for i in self.find_elements(*self._event_row_locator)] + +class EventDetail(BasePage): + URL_TEMPLATE = 'event/{event_id}' + + # TODO Refactor into regions to match template fragmentation + _event_name_selector = (By.XPATH, '//h1') + _person_panel_selector = (By.XPATH, '//div[contains(text(), "Contact Details")]/..') + _name_selector = (By.XPATH, '//dt[text()="Person"]/following-sibling::dd[1]') + _email_selector = (By.XPATH, '//dt[text()="Email"]/following-sibling::dd[1]') + _phone_selector = (By.XPATH, '//dt[text()="Phone Number"]/following-sibling::dd[1]') + + @property + def event_name(self): + return self.find_element(*self._event_name_selector).text + + @property + def name(self): + return self.find_element(*self._person_panel_selector).find_element(*self._name_selector).text + + @property + def email(self): + return self.find_element(*self._person_panel_selector).find_element(*self._email_selector).text + + @property + def phone(self): + return self.find_element(*self._person_panel_selector).find_element(*self._phone_selector).text class CreateEvent(FormPage): URL_TEMPLATE = reverse('event_create') @@ -135,6 +161,14 @@ class DuplicateEvent(CreateEvent): @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 GenericList(BasePage): _search_selector = (By.CSS_SELECTOR, 'div.input-group:nth-child(2) > input:nth-child(1)') diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py index 8fcaed3d..cd228df4 100644 --- a/RIGS/tests/test_functional.py +++ b/RIGS/tests/test_functional.py @@ -28,154 +28,6 @@ from django.conf import settings import sys - -class EventTest(LiveServerTestCase): - def setUp(self): - self.profile = models.Profile( - username="EventTest", first_name="Event", last_name="Test", initials="ETU", is_superuser=True) - self.profile.set_password("EventTestPassword") - self.profile.save() - - self.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1') - - self.browser = create_browser() - self.browser.implicitly_wait(10) # Set implicit wait session wide - # self.browser.maximize_window() - - os.environ['RECAPTCHA_TESTING'] = 'True' - - def tearDown(self): - self.browser.quit() - os.environ['RECAPTCHA_TESTING'] = 'False' - - def authenticate(self, n=None): - self.assertIn( - self.live_server_url + '/user/login/', self.browser.current_url) - if n: - self.assertIn('?next=%s' % n, self.browser.current_url) - username = self.browser.find_element_by_id('id_username') - password = self.browser.find_element_by_id('id_password') - submit = self.browser.find_element_by_css_selector( - 'input[type=submit]') - - username.send_keys("EventTest") - password.send_keys("EventTestPassword") - submit.click() - - self.assertEqual(self.live_server_url + n, self.browser.current_url) - - def testEventDetail(self): - with transaction.atomic(), reversion.create_revision(): - person = models.Person(name="Event Detail Person", email="eventdetail@person.tests.rigs", phone="123 123") - person.save() - with transaction.atomic(), reversion.create_revision(): - organisation = models.Organisation(name="Event Detail Organisation", - email="eventdetail@organisation.tests.rigs", phone="123 456").save() - with transaction.atomic(), reversion.create_revision(): - venue = models.Venue(name="Event Detail Venue").save() - with transaction.atomic(), reversion.create_revision(): - event = models.Event( - name="Detail Test", - description="This is an event to test the detail view", - notes="It is going to be aweful", - person=person, - organisation=organisation, - start_date='2015-06-04' - ) - event.save() - with transaction.atomic(), reversion.create_revision(): - item1 = models.EventItem( - event=event, - name="Detail Item 1", - cost="10.00", - quantity="1", - order=1 - ).save() - item2 = models.EventItem( - event=event, - name="Detail Item 2", - description="Foo", - cost="9.72", - quantity="3", - order=2, - ).save() - - self.browser.get(self.live_server_url + '/event/%d' % event.pk) - self.authenticate('/event/%d/' % event.pk) - self.assertIn("N%05d | %s" % (event.pk, event.name), self.browser.find_element_by_xpath('//h1').text) - - personPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Contact Details")]/..') - self.assertEqual(person.name, - personPanel.find_element_by_xpath('//dt[text()="Person"]/following-sibling::dd[1]').text) - self.assertEqual(person.email, - personPanel.find_element_by_xpath('//dt[text()="Email"]/following-sibling::dd[1]').text) - self.assertEqual(person.phone, - personPanel.find_element_by_xpath('//dt[text()="Phone Number"]/following-sibling::dd[1]').text) - - organisationPanel = self.browser.find_element_by_xpath('//div[contains(text(), "Contact Details")]/..') - - def testEventEdit(self): - person = models.Person.objects.create(name="Event Edit Person", email="eventdetail@person.tests.rigs", - phone="123 123") - organisation = models.Organisation.objects.create(name="Event Edit Organisation", - email="eventdetail@organisation.tests.rigs", phone="123 456") - venue = models.Venue.objects.create(name="Event Detail Venue") - - eventData = { - 'name': "Detail Test", - 'description': "This is an event to test the detail view", - 'notes': "It is going to be awful", - 'person': person, - 'organisation': organisation, - 'venue': venue, - 'mic': self.profile, - 'start_date': date(2015, 0o6, 0o4), - 'end_date': date(2015, 0o6, 0o5), - 'start_time': time(10, 00), - 'end_time': time(15, 00), - 'meet_at': self.create_datetime(2015, 0o6, 0o4, 10, 00), - 'access_at': self.create_datetime(2015, 0o6, 0o4, 10, 00), - 'collector': 'A Person' - } - - event = models.Event(**eventData) - event.save() - - item1Data = { - 'event': event, - 'name': "Detail Item 1", - 'cost': "10.00", - 'quantity': "1", - 'order': 1 - } - - models.EventItem(**item1Data).save() - - self.browser.get(self.live_server_url + '/event/%d/edit/' % event.pk) - self.authenticate('/event/%d/edit/' % event.pk) - - save = self.browser.find_element_by_xpath('(//button[@type="submit"])[1]') - save.click() - - successTitle = self.browser.find_element_by_xpath('//h1').text - self.assertIn("N%05d | Detail Test" % event.pk, successTitle) - - reloadedEvent = models.Event.objects.get(name='Detail Test') - reloadedItem = models.EventItem.objects.get(name='Detail Item 1') - - # Check the event - for key, value in eventData.items(): - self.assertEqual(str(getattr(reloadedEvent, key)), str(value)) - - # Check the item - for key, value in item1Data.items(): - self.assertEqual(str(getattr(reloadedItem, key)), str(value)) - - def create_datetime(self, year, month, day, hour, min): - tz = pytz.timezone(settings.TIME_ZONE) - return tz.localize(datetime(year, month, day, hour, min)).astimezone(pytz.utc) - - class IcalTest(LiveServerTestCase): def setUp(self): self.all_events = set(range(1, 18)) diff --git a/RIGS/tests/test_rigs.py b/RIGS/tests/test_rigs.py index f3277095..31466f2e 100644 --- a/RIGS/tests/test_rigs.py +++ b/RIGS/tests/test_rigs.py @@ -18,29 +18,57 @@ import datetime from datetime import date, time, timedelta from django.utils import timezone from selenium.webdriver.common.action_chains import ActionChains +from django.db import transaction -class TestRigboard(AutoLoginTest): +class BaseRigboardTest(AutoLoginTest): def setUp(self): - super().setUp() - client = models.Person.objects.create(name='Rigboard Test Person', email='rigboard@functional.test') self.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1') + super().setUp() + self.client = models.Person.objects.create(name='Rigboard Test Person', email='rigboard@functional.test') 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=client, - auth_request_by=self.profile, - auth_request_at=base.create_datetime(2015, 0o6, 0o4, 10, 00), - auth_request_to="some@email.address") - self.testEvent2 = models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL, - start_date=date.today() + timedelta(days=8), - description="start future no end, later", - purchase_order='TESTPO', - person=client, + 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.wait = WebDriverWait(self.driver, 5) + + def select_event_type(self, event_type): + self.wait.until(animation_is_finished()) + self.assertFalse(self.page.is_expanded) + self.page.select_event_type(event_type) + self.wait.until(animation_is_finished()) + self.assertTrue(self.page.is_expanded) + +class TestRigboard(BaseRigboardTest): + def setUp(self): + super().setUp() + self.testEvent2 = models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL, + start_date=date.today() + timedelta(days=8), + description="start future no end, later", + 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") self.page = pages.Rigboard(self.driver, self.live_server_url).open() def test_buttons(self): @@ -67,20 +95,13 @@ class TestRigboard(AutoLoginTest): # Ideally get a response object to assert 200 on -class TestEventCreate(AutoLoginTest): +class TestEventCreate(BaseRigboardTest): def setUp(self): super().setUp() - self.client = models.Person.objects.create(name='Creation Test Person', email='god@functional.test') - self.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1') self.page = pages.CreateEvent(self.driver, self.live_server_url).open() - self.wait = WebDriverWait(self.driver, 5) def test_rig_creation(self): - self.wait.until(animation_is_finished()) - self.assertFalse(self.page.is_expanded) - self.page.select_event_type("Rig") - self.wait.until(animation_is_finished()) - self.assertTrue(self.page.is_expanded) + self.select_event_type("Rig") self.page.person_selector.toggle() self.assertTrue(self.page.person_selector.is_open) @@ -107,11 +128,7 @@ class TestEventCreate(AutoLoginTest): # TODO def test_modals(self): - self.wait.until(animation_is_finished()) - self.assertFalse(self.page.is_expanded) - self.page.select_event_type("Rig") - self.wait.until(animation_is_finished()) - self.assertTrue(self.page.is_expanded) + self.select_event_type("Rig") # Create new person modal = self.page.add_person() # animation_is_finished doesn't work for whatever reason... @@ -127,13 +144,9 @@ class TestEventCreate(AutoLoginTest): self.assertFalse(modal.is_open) # See new person selected - select_element = self.driver.find_element(By.ID,'id_person') - select_object = Select(select_element) - - person1 = models.Person.objects.get(name=person_name) - self.assertEqual(person1.name, select_object.first_selected_option.text) - # and backend - # self.assertEqual(person1.pk, int(self.page.person_selector.get_attribute("value"))) + self.page.person_selector.toggle() + self.assertEqual(self.page.person_selector.options[0].name, person_name) + self.page.person_selector.toggle() # Change mind and add another self.wait.until(animation_is_finished()) @@ -147,15 +160,12 @@ class TestEventCreate(AutoLoginTest): modal.submit() self.wait.until(EC.invisibility_of_element_located((By.ID, 'modal'))) self.assertFalse(modal.is_open) + self.assertEqual(self.page.person_selector.options[1].name, person_name) # TODO def test_date_validation(self): - self.wait.until(animation_is_finished()) - self.assertFalse(self.page.is_expanded) - self.page.select_event_type("Rig") - self.wait.until(animation_is_finished()) - self.assertTrue(self.page.is_expanded) + self.select_event_type("Rig") self.page.person_selector.toggle() self.assertTrue(self.page.person_selector.is_open) @@ -193,11 +203,7 @@ class TestEventCreate(AutoLoginTest): self.assertTrue(self.page.success) def test_event_item_creation(self): - self.wait.until(animation_is_finished()) - self.assertFalse(self.page.is_expanded) - self.page.select_event_type("Rig") - self.wait.until(animation_is_finished()) - self.assertTrue(self.page.is_expanded) + self.select_event_type("Rig") self.page.name = "Test Event with Items" @@ -255,11 +261,7 @@ class TestEventCreate(AutoLoginTest): # TODO Testing of internal rig (approval system interface) def test_non_rig_creation(self): - self.wait.until(animation_is_finished()) - self.assertFalse(self.page.is_expanded) - self.page.select_event_type("Non-Rig") - self.wait.until(animation_is_finished()) - self.assertTrue(self.page.is_expanded) + self.select_event_type("Non-Rig") self.assertFalse(self.page.person_selector.is_open) @@ -283,37 +285,10 @@ class TestEventCreate(AutoLoginTest): pass -class TestEventDuplicate(AutoLoginTest): +class TestEventDuplicate(BaseRigboardTest): def setUp(self): super().setUp() - self.client = models.Person.objects.create(name='Duplicate Test Person', email='duplicate@functional.test') - self.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1') - 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.DuplicateEvent(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() - self.wait = WebDriverWait(self.driver, 5) def test_rig_duplicate(self): table = self.page.item_table @@ -384,3 +359,50 @@ class TestEventDuplicate(AutoLoginTest): self.assertIn("Test Item 1", table.text) self.assertIn("Test Item 2", table.text) self.assertNotIn("Test Item 3", table.text) + + +class TestEventEdit(BaseRigboardTest): + def setUp(self): + super().setUp() + self.page = pages.EditEvent(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + def test_rig_edit(self): + self.page.name = "Edited Event" + + modal = self.page.add_event_item() + self.wait.until(animation_is_finished()) + # See modal has opened + self.assertTrue(modal.is_open) + self.assertIn(self.testEvent.name, modal.header) + + modal.name = "Test Item 3" + modal.description = "This is an item description\nthat for reasons unknown spans two lines" + modal.quantity = "2" + modal.price = "23.95" + modal.submit() + self.wait.until(animation_is_finished()) + + # Attempt to save + ActionChains(self.driver).move_to_element(self.page.item_table).perform() + self.page.submit() + + self.assertTrue(self.page.success) + + self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + self.assertIn(self.page.event_name, self.testEvent.name) + self.assertEqual(self.page.name, self.testEvent.person.name) + # Check the new items are visible + table = self.page.item_table + self.assertIn("Test Item 3", table.text) + + +class TestEventDetail(BaseRigboardTest): + def setUp(self): + super().setUp() + self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + def test_rig_detail(self): + self.assertIn("N%05d | %s" % (self.testEvent.pk, self.testEvent.name), self.page.event_name) + self.assertEqual(person.name, self.page.name) + self.assertEqual(person.email, self.page.email) + self.assertEqual(person.phone, self.page.phone)