mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-17 05:22:16 +00:00
* Upgrade to heroku-20 stack * Move some gulp deps to dev rather than prod * npm upgrade * Fix audit time check in asset audit test * Attempt at parallelising tests where possible * Add basic calendar button test Mainly to pickup on FullCalendar loading errors * Upgrade python deps * Tends to help if I push valid yaml * You valid now? * Fix whoops in requirements.txt * Change python ver * Define service in coveralls task * Run parallelised RIGS tests as one matrix job * Update python version in tests * Cache python dependencies Should majorly speedup parallelillelelised testing * Purge old vagrant config * No Ruby compass bodge, no need for rubocop! * Purge old .idea config * Switch to gh-a artifact uploading instead of imgur 'hack' For test failure screenshots. Happy now @mattysmith22? ;p * Oops, remove unused import * Exclude tests from the coverage stats Seems to be artifically deflating our stats * Refactor asset audit tests with better selectors Also fixed a silly title error with the modal * Add title checking to the slightly insane assets test * Fix unauth test to not just immediately pass out * Upload failure screenshots as individual artifacts not a zip Turns out I can't unzip things from my phone, which is a pain * Should fix asset test on CI * What about this? * What about this? Swear I spend my life jiggerypokerying the damn test suite... * Does this help the coverage be less weird? * Revert "Does this help the coverage be less weird?" This reverts commit39ab9df836. * Use pytest as our test runner for better parallelism Also rewrote some asset tests to be in the pytest style. May do some more. Some warnings cleaned up in the process. * Bah, codestyle * Oops, remove obsolete if check * Fix screenshot uploading on CI (again) * Try this way of parallel coverage * Add codeclimate maintainability badge * Remove some unused gulp dependencies * Run asset building serverside * Still helps if I commit valid YAML * See below * Different approach to CI dependencies * Exclude node_modules from codestyle * Does this work? * Parallel parallel builds were giving me a headache, try this * Update codeclimate settings, purge some config files * Well the YAML was *syntactically* valid.... * Switch back to old coveralls method * Fix codeclimate config, mark 2 * Attempt to bodge asset test * Oops, again Probably bedtime.. * Might fix heroku building * Attempt #2 at fixing heroku * Belt and braces approach to coverage * Github, you need a Actions YAML validator! * Might fix actions? * Try ignoring some third party deprecation warnings * Another go at making coverage show up * Some template cleanup * Minor python cleanup * Import optimisation * Revert "Minor python cleanup" This reverts commit6a4620a2e5. * Add format arg to coverage command * Ignore test directories from Heroku slug * Maybe this works to purge deps postbuild * Bunch of test refactoring * Restore signals import, screw you import optimisation * Further template refactoring * Add support for running tests with geckodriver, do this on CI * Screw you codestyle * Disable firefox tests for now That was way more errors than I expected * Run cleanup script from the right location * Plausibly fix tests * Helps if I don't delete the pipeline folder prior to collectstatic * Enable whitenoise * Can I delete pipeline here? * Allow seconds difference in assert_times_equal * Disable codeclimate * Remove not working rm command * Maybe this fixes coverage? * Try different coverage reporter * Fix search_help to need login * Made versioning magic a bit less expansive We have more apps than I thought... * Fix IDI0T error in Assets URLS * Refactor 'no access to unauthed' test to cover all of PyRIGS * Add RAs/Checklists to sample data generator * Fix some HTML errors in templates Which apparently only Django's HTML parser cares about, browsers DGAF... * Port title test to project level * Fix more HTML * Fix cable type detail
903 lines
42 KiB
Python
903 lines
42 KiB
Python
import datetime
|
|
from datetime import date, time, timedelta
|
|
|
|
from django.test.client import Client
|
|
from django.utils import timezone
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
|
|
from PyRIGS.tests import base
|
|
from PyRIGS.tests import regions as base_regions
|
|
from PyRIGS.tests.base import (AutoLoginTest, screenshot_failure_cls)
|
|
from PyRIGS.tests.pages import animation_is_finished
|
|
from RIGS import models
|
|
from RIGS.tests import regions
|
|
from . import pages
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class BaseRigboardTest(AutoLoginTest):
|
|
def setUp(self):
|
|
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.wait = WebDriverWait(self.driver, 10)
|
|
|
|
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)
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestRigboard(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
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.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):
|
|
header = regions.Header(self.page, self.driver.find_element(By.CSS_SELECTOR, '.navbar'))
|
|
# TODO Switch to checking reversed links (difficult because of arguments)
|
|
header.find_link("Rigboard").click()
|
|
self.assertEqual(
|
|
self.live_server_url + '/rigboard/', self.driver.current_url)
|
|
header.find_link("Archive").click()
|
|
self.assertEqual(
|
|
self.live_server_url + '/event/archive/', self.driver.current_url)
|
|
# TODO - This fails for some reason
|
|
# header.find_link("New").click()
|
|
# self.assertEqual(
|
|
# self.live_server_url + '/event/create/', self.driver.current_url)
|
|
|
|
def test_event_order(self):
|
|
self.assertIn(self.testEvent.start_date.strftime('%a %d/%m/%Y'), self.page.events[0].dates)
|
|
self.assertIn(self.testEvent2.start_date.strftime('%a %d/%m/%Y'), self.page.events[1].dates)
|
|
|
|
def test_add_button(self):
|
|
self.page.add()
|
|
self.assertIn('create', self.driver.current_url)
|
|
# Ideally get a response object to assert 200 on
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestEventCreate(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.page = pages.CreateEvent(self.driver, self.live_server_url).open()
|
|
|
|
def test_rig_creation(self):
|
|
self.select_event_type("Rig")
|
|
|
|
self.page.person_selector.search(self.client.name)
|
|
self.page.person_selector.set_option(self.client.name, True)
|
|
self.page.person_selector.toggle()
|
|
self.assertFalse(self.page.person_selector.is_open)
|
|
|
|
self.page.name = "Test Rig"
|
|
|
|
# Both dates, no times, end before start
|
|
self.page.start_date = datetime.date(2020, 1, 10)
|
|
self.page.end_date = datetime.date(2020, 1, 1)
|
|
# Expected to fail
|
|
self.page.submit()
|
|
self.assertFalse(self.page.success)
|
|
self.assertIn("Unless you've invented time travel, the event can't finish before it has started.", self.page.errors["End date"])
|
|
self.wait.until(animation_is_finished())
|
|
|
|
# Fix it
|
|
self.page.end_date = datetime.date(2020, 1, 11)
|
|
self.page.access_at = datetime.datetime(2020, 1, 1, 9)
|
|
self.page.dry_hire = True
|
|
self.page.status = "Booked"
|
|
self.page.collected_by = "Fred"
|
|
self.page.po = "1234"
|
|
self.page.notes = "A note!"
|
|
|
|
self.page.submit()
|
|
self.assertTrue(self.page.success)
|
|
|
|
# TODO
|
|
def test_modals(self):
|
|
self.select_event_type("Rig")
|
|
# Create new person
|
|
modal = self.page.add_person()
|
|
# animation_is_finished doesn't work for whatever reason...
|
|
self.wait.until(EC.visibility_of_element_located((By.ID, 'modal')))
|
|
self.assertTrue(modal.is_open)
|
|
self.assertIn("Create Person", modal.header)
|
|
|
|
# Fill person form out and submit
|
|
person_name = "Test Person"
|
|
modal.name = person_name
|
|
modal.submit()
|
|
self.wait.until(EC.invisibility_of_element_located((By.ID, 'modal')))
|
|
self.assertFalse(modal.is_open)
|
|
|
|
# See new person selected
|
|
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())
|
|
modal = self.page.add_person()
|
|
self.wait.until(EC.visibility_of_element_located((By.ID, 'modal')))
|
|
self.assertTrue(modal.is_open)
|
|
self.assertIn("Create Person", modal.header)
|
|
|
|
person_name = "Test Person 2"
|
|
modal.name = person_name
|
|
modal.submit()
|
|
self.wait.until(EC.invisibility_of_element_located((By.ID, 'modal')))
|
|
self.assertFalse(modal.is_open)
|
|
self.page.person_selector.toggle()
|
|
self.assertEqual(self.page.person_selector.options[0].name, person_name)
|
|
self.page.person_selector.toggle()
|
|
|
|
# TODO
|
|
|
|
def test_event_item_creation(self):
|
|
self.select_event_type("Rig")
|
|
|
|
self.page.name = "Test Event with Items"
|
|
|
|
self.page.person_selector.search(self.client.name)
|
|
self.page.person_selector.set_option(self.client.name, True)
|
|
# TODO This should not be necessary, normally closes automatically
|
|
self.page.person_selector.toggle()
|
|
self.assertFalse(self.page.person_selector.is_open)
|
|
|
|
# Note to self, don't set dates before 2014, which is the beginning of VAT as far as the tests are concerned...
|
|
self.page.start_date = datetime.date(2084, 1, 1)
|
|
|
|
modal = self.page.add_event_item()
|
|
self.wait.until(animation_is_finished())
|
|
# See modal has opened
|
|
self.assertTrue(modal.is_open)
|
|
self.assertIn("New Event", modal.header)
|
|
|
|
modal.name = "Test Item 1"
|
|
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())
|
|
|
|
# Confirm item has been saved to json field
|
|
objectitems = self.driver.execute_script("return objectitems;")
|
|
self.assertEqual(1, len(objectitems))
|
|
testitem = objectitems["-1"]['fields'] # as we are deliberately creating this we know the ID
|
|
self.assertEqual("Test Item 1", testitem['name'])
|
|
self.assertEqual("2", testitem['quantity']) # test a couple of "worse case" fields
|
|
|
|
total = self.driver.find_element_by_id('total')
|
|
ActionChains(self.driver).move_to_element(total).perform()
|
|
|
|
# See new item appear in table
|
|
row = self.page.item_row("-1") # ID number is known, see above
|
|
self.assertIn("Test Item 1", row.name)
|
|
self.assertIn("This is an item description",
|
|
row.description)
|
|
self.assertEqual('23.95', row.price)
|
|
self.assertEqual("2", row.quantity)
|
|
self.assertEqual('47.90', row.subtotal)
|
|
|
|
# Check totals TODO convert to page properties
|
|
self.assertEqual("47.90", self.driver.find_element_by_id('sumtotal').text)
|
|
self.assertIn("(TBC)", self.driver.find_element_by_id('vat-rate').text)
|
|
self.assertEqual("9.58", self.driver.find_element_by_id('vat').text)
|
|
self.assertEqual("57.48", total.text)
|
|
|
|
self.page.submit()
|
|
|
|
# TODO Testing of internal rig (approval system interface)
|
|
|
|
def test_non_rig_creation(self):
|
|
self.select_event_type("Non-Rig")
|
|
|
|
self.assertFalse(self.page.person_selector.is_open)
|
|
|
|
rig_name = "Test Non-Rig"
|
|
self.page.name = rig_name
|
|
|
|
# Double-check we don't lose data when swapping
|
|
self.page.select_event_type("Rig")
|
|
self.wait.until(animation_is_finished())
|
|
self.assertEqual(self.page.name, rig_name)
|
|
self.wait.until(animation_is_finished())
|
|
self.page.select_event_type("Non-Rig")
|
|
|
|
self.page.start_date = datetime.date(2020, 1, 1)
|
|
self.page.status = "Confirmed"
|
|
|
|
self.page.submit()
|
|
self.assertTrue(self.page.success)
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestEventDuplicate(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
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()
|
|
|
|
def test_rig_duplicate(self):
|
|
table = self.page.item_table
|
|
self.assertIn("Test Item 1", table.text)
|
|
self.assertIn("Test Item 2", table.text)
|
|
|
|
# Check the info message is visible
|
|
self.assertIn("Event data duplicated but not yet saved", self.page.warning)
|
|
|
|
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
|
|
self.page.submit()
|
|
|
|
# TODO Rewrite when EventDetail page is implemented
|
|
newEvent = models.Event.objects.latest('pk')
|
|
|
|
self.assertEqual(newEvent.auth_request_to, None)
|
|
self.assertEqual(newEvent.auth_request_by, None)
|
|
self.assertEqual(newEvent.auth_request_at, None)
|
|
|
|
self.assertFalse(newEvent.authorised)
|
|
|
|
self.assertNotIn("N%05d" % self.testEvent.pk, self.driver.find_element_by_xpath('//h1').text)
|
|
self.assertNotIn("Event data duplicated but not yet saved", self.page.warning) # Check info message not visible
|
|
|
|
# Check the new items are visible
|
|
table = self.page.item_table
|
|
self.assertIn("Test Item 1", table.text)
|
|
self.assertIn("Test Item 2", table.text)
|
|
self.assertIn("Test Item 3", table.text)
|
|
|
|
infoPanel = self.driver.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
|
|
self.assertIn("N%05d" % self.testEvent.pk,
|
|
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
|
# Check the PO hasn't carried through
|
|
self.assertNotIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
|
|
|
|
self.assertIn("N%05d" % self.testEvent.pk,
|
|
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
|
|
|
self.driver.get(self.live_server_url + '/event/' + str(self.testEvent.pk)) # Go back to the old event
|
|
|
|
# Check that based-on hasn't crept into the old event
|
|
infoPanel = self.driver.find_element_by_xpath('//div[contains(text(), "Event Info")]/..')
|
|
self.assertNotIn("N%05d" % self.testEvent.pk,
|
|
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
|
# Check the PO remains on the old event
|
|
self.assertIn("TESTPO", infoPanel.find_element_by_xpath('//dt[text()="PO"]/following-sibling::dd[1]').text)
|
|
|
|
self.assertNotIn("N%05d" % self.testEvent.pk,
|
|
infoPanel.find_element_by_xpath('//dt[text()="Based On"]/following-sibling::dd[1]').text)
|
|
|
|
# Check the items are as they were
|
|
table = self.page.item_table # ID number is known, see above
|
|
self.assertIn("Test Item 1", table.text)
|
|
self.assertIn("Test Item 2", table.text)
|
|
self.assertNotIn("Test Item 3", table.text)
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestEventEdit(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
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.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.testEvent.refresh_from_db()
|
|
self.assertIn(self.testEvent.name, self.page.event_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)
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestEventDetail(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
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_rig_detail(self):
|
|
self.assertIn("N%05d | %s" % (self.testEvent.pk, self.testEvent.name), self.page.event_name)
|
|
self.assertEqual(self.client.name, self.page.name)
|
|
self.assertEqual(self.client.email, self.page.email)
|
|
self.assertEqual(self.client.phone, None)
|
|
|
|
|
|
@screenshot_failure_cls
|
|
class TestCalendar(BaseRigboardTest):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.all_events = set(range(1, 18))
|
|
self.current_events = (1, 2, 3, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18)
|
|
self.not_current_events = set(self.all_events) - set(self.current_events)
|
|
|
|
# produce 7 normal events - 5 current - 1 last week - 1 two years ago - 2 provisional - 2 confirmed - 3 booked
|
|
models.Event.objects.create(name="TE E1", status=models.Event.PROVISIONAL,
|
|
start_date=date.today() + timedelta(days=6), description="start future no end")
|
|
models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL, start_date=date.today(),
|
|
description="start today no end")
|
|
models.Event.objects.create(name="TE E3", status=models.Event.CONFIRMED, start_date=date.today(),
|
|
end_date=date.today(), description="start today with end today")
|
|
models.Event.objects.create(name="TE E4", status=models.Event.CONFIRMED,
|
|
start_date=date.today() - timedelta(weeks=104),
|
|
description="start past 2 years no end")
|
|
models.Event.objects.create(name="TE E5", status=models.Event.BOOKED,
|
|
start_date=date.today() - timedelta(days=7),
|
|
end_date=date.today() - timedelta(days=1),
|
|
description="start past 1 week with end past")
|
|
models.Event.objects.create(name="TE E6", status=models.Event.BOOKED,
|
|
start_date=date.today() - timedelta(days=2),
|
|
start_time=time(8, 00),
|
|
end_date=date.today() + timedelta(days=2),
|
|
end_time=time(23, 00), description="start past, end future")
|
|
models.Event.objects.create(name="TE E7", status=models.Event.BOOKED,
|
|
start_date=date.today() + timedelta(days=2),
|
|
end_date=date.today() + timedelta(days=2), description="start + end in future")
|
|
|
|
# 2 cancelled - 1 current
|
|
models.Event.objects.create(name="TE E8", start_date=date.today() + timedelta(days=2),
|
|
end_date=date.today() + timedelta(days=2), status=models.Event.CANCELLED,
|
|
description="cancelled in future")
|
|
models.Event.objects.create(name="TE E9", start_date=date.today() - timedelta(days=1),
|
|
end_date=date.today() + timedelta(days=2), status=models.Event.CANCELLED,
|
|
description="cancelled and started")
|
|
|
|
# 5 dry hire - 3 current - 1 cancelled
|
|
models.Event.objects.create(name="TE E10", start_date=date.today(), dry_hire=True, description="dryhire today")
|
|
models.Event.objects.create(name="TE E11", start_date=date.today(), dry_hire=True, checked_in_by=self.profile,
|
|
description="dryhire today, checked in")
|
|
models.Event.objects.create(name="TE E12", start_date=date.today() - timedelta(days=1), dry_hire=True,
|
|
status=models.Event.BOOKED, description="dryhire past")
|
|
models.Event.objects.create(name="TE E13", start_date=date.today() - timedelta(days=2), dry_hire=True,
|
|
checked_in_by=self.profile, description="dryhire past checked in")
|
|
models.Event.objects.create(name="TE E14", start_date=date.today(), dry_hire=True,
|
|
status=models.Event.CANCELLED, description="dryhire today cancelled")
|
|
|
|
# 4 non rig - 3 current
|
|
models.Event.objects.create(name="TE E15", start_date=date.today(), is_rig=False, description="non rig today")
|
|
models.Event.objects.create(name="TE E16", start_date=date.today() + timedelta(days=1), is_rig=False,
|
|
description="non rig tomorrow")
|
|
models.Event.objects.create(name="TE E17", start_date=date.today() - timedelta(days=1), is_rig=False,
|
|
description="non rig yesterday")
|
|
models.Event.objects.create(name="TE E18", start_date=date.today(), is_rig=False, status=models.Event.CANCELLED,
|
|
description="non rig today cancelled")
|
|
|
|
self.page = pages.UserPage(self.driver, self.live_server_url).open()
|
|
|
|
def test_api_key_generation(self):
|
|
# Completes and comes back to /user/
|
|
# Checks that no api key is displayed
|
|
self.assertEqual("No API Key Generated", self.page.api_key)
|
|
|
|
# Now creates an API key, and check a URL is displayed one
|
|
self.page.generate_key()
|
|
self.assertIn("rigs.ics", self.page.cal_url)
|
|
self.assertNotIn("?", self.page.cal_url)
|
|
|
|
# Lets change everything so it's not the default value
|
|
self.page.toggle_filter('rig')
|
|
self.page.toggle_filter('non-rig')
|
|
self.page.toggle_filter('dry-hire')
|
|
self.page.toggle_filter('cancelled')
|
|
self.page.toggle_filter('provisional')
|
|
self.page.toggle_filter('confirmed')
|
|
|
|
# and then check the url is correct
|
|
self.assertIn(
|
|
"rigs.ics?rig=false&non-rig=false&dry-hire=false&cancelled=true&provisional=false&confirmed=false",
|
|
self.page.cal_url)
|
|
|
|
# Awesome - all seems to work
|
|
|
|
def test_ics_files(self):
|
|
specialEvent = models.Event.objects.get(name="TE E6")
|
|
|
|
# Now creates an API key, and check a URL is displayed one
|
|
self.page.generate_key()
|
|
|
|
c = Client()
|
|
|
|
# Default settings - should have all non-cancelled events
|
|
# Get the ical file (can't do this in selanium because reasons)
|
|
icalUrl = self.page.cal_url
|
|
response = c.get(self.page.cal_url)
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
# content = response.content.decode('utf-8')
|
|
|
|
# Check has entire file
|
|
self.assertContains(response, "BEGIN:VCALENDAR")
|
|
self.assertContains(response, "END:VCALENDAR")
|
|
|
|
expectedIn = [1, 2, 3, 5, 6, 7, 10, 11, 12, 13, 15, 16, 17]
|
|
for test in range(1, 18):
|
|
if test in expectedIn:
|
|
self.assertContains(response, "TE E" + str(test) + " ")
|
|
else:
|
|
self.assertNotContains(response, "TE E" + str(test) + " ")
|
|
|
|
# Check that times have been included correctly
|
|
self.assertContains(response,
|
|
specialEvent.start_date.strftime('%Y%m%d') + 'T' + specialEvent.start_time.strftime(
|
|
'%H%M%S'))
|
|
self.assertContains(response,
|
|
specialEvent.end_date.strftime('%Y%m%d'))
|
|
self.assertContains(response,
|
|
specialEvent.end_time.strftime('%H%M%S'))
|
|
|
|
# Only non rigs
|
|
self.page.toggle_filter('rig')
|
|
self.page.toggle_filter('non-rig')
|
|
|
|
icalUrl = self.page.cal_url
|
|
response = c.get(icalUrl)
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
expectedIn = [10, 11, 12, 13]
|
|
for test in range(1, 18):
|
|
if test in expectedIn:
|
|
self.assertContains(response, "TE E" + str(test) + " ")
|
|
else:
|
|
self.assertNotContains(response, "TE E" + str(test) + " ")
|
|
|
|
# Only provisional rigs
|
|
self.page.toggle_filter('rig')
|
|
self.page.toggle_filter('dry-hire')
|
|
self.page.toggle_filter('confirmed')
|
|
|
|
icalUrl = self.page.cal_url
|
|
response = c.get(icalUrl)
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
expectedIn = [1, 2]
|
|
for test in range(1, 18):
|
|
if test in expectedIn:
|
|
self.assertContains(response, "TE E" + str(test) + " ")
|
|
else:
|
|
self.assertNotContains(response, "TE E" + str(test) + " ")
|
|
|
|
# Only cancelled non-rigs
|
|
self.page.toggle_filter('rig')
|
|
self.page.toggle_filter('non-rig')
|
|
self.page.toggle_filter('provisional')
|
|
self.page.toggle_filter('cancelled')
|
|
|
|
icalUrl = self.page.cal_url
|
|
response = c.get(icalUrl)
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
expectedIn = [18]
|
|
for test in range(1, 18):
|
|
if test in expectedIn:
|
|
self.assertContains(response, "TE E" + str(test) + " ")
|
|
else:
|
|
self.assertNotContains(response, "TE E" + str(test) + " ")
|
|
|
|
# Nothing selected
|
|
self.page.toggle_filter('non-rig')
|
|
self.page.toggle_filter('cancelled')
|
|
|
|
icalUrl = self.page.cal_url
|
|
response = c.get(icalUrl)
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
expectedIn = []
|
|
for test in range(1, 18):
|
|
if test in expectedIn:
|
|
self.assertContains(response, "TE E" + str(test) + " ")
|
|
else:
|
|
self.assertNotContains(response, "TE E" + str(test) + " ")
|
|
|
|
def test_calendar_buttons(self): # If FullCalendar fails to load for whatever reason, the buttons don't work
|
|
self.page = pages.CalendarPage(self.driver, self.live_server_url).open()
|
|
self.assertIn(timezone.now().strftime("%Y-%m"), self.driver.current_url)
|
|
|
|
target_date = datetime.date(2020, 1, 1)
|
|
self.page.target_date.set_value(target_date)
|
|
self.page.go()
|
|
self.assertIn(self.page.target_date.value.strftime("%Y-%m"), self.driver.current_url)
|
|
|
|
self.page.next()
|
|
target_date += datetime.timedelta(days=32)
|
|
self.assertIn(target_date.strftime("%m"), self.driver.current_url)
|
|
|
|
|
|
@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='eventtest',
|
|
email='teccie@functional.test',
|
|
is_superuser=True # lazily grant all permissions
|
|
)[0]
|
|
self.venue = models.Venue.objects.create(name="Venue 1")
|
|
|
|
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,
|
|
venue=self.venue)
|
|
self.testEvent2 = models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL,
|
|
start_date=date.today() + timedelta(days=6),
|
|
description="start future no end",
|
|
purchase_order='TESTPO',
|
|
person=self.client,
|
|
venue=self.venue)
|
|
self.testEvent3 = models.Event.objects.create(name="TE E3", status=models.Event.PROVISIONAL,
|
|
start_date=date.today() + timedelta(days=6),
|
|
description="start future no end",
|
|
purchase_order='TESTPO',
|
|
person=self.client,
|
|
venue=self.venue)
|
|
self.testRA = models.RiskAssessment.objects.create(event=self.testEvent2, supervisor_consulted=False, nonstandard_equipment=False,
|
|
nonstandard_use=False,
|
|
contractors=False,
|
|
other_companies=False,
|
|
crew_fatigue=False,
|
|
big_power=False,
|
|
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=False,
|
|
barrier_required=False,
|
|
nonstandard_emergency_procedure=False,
|
|
special_structures=False,
|
|
suspended_structures=False,
|
|
outside=False)
|
|
self.testRA2 = models.RiskAssessment.objects.create(event=self.testEvent3, supervisor_consulted=False, nonstandard_equipment=False,
|
|
nonstandard_use=False,
|
|
contractors=False,
|
|
other_companies=False,
|
|
crew_fatigue=False,
|
|
big_power=True,
|
|
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=False,
|
|
barrier_required=False,
|
|
nonstandard_emergency_procedure=False,
|
|
special_structures=False,
|
|
suspended_structures=False,
|
|
outside=False)
|
|
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()
|
|
|
|
# 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.outside = 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 = False
|
|
self.page.safe_loading = False
|
|
self.page.safe_storage = False
|
|
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 = True
|
|
# TODO Test for this proper
|
|
self.page.rigging_plan = "https://nottinghamtec.sharepoint.com/test/"
|
|
self.page.submit()
|
|
self.assertFalse(self.page.success)
|
|
|
|
self.page.suspended_structures = False
|
|
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):
|
|
self.page = pages.EditRiskAssessment(self.driver, self.live_server_url, pk=self.testRA.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.assertFalse(self.page.success)
|
|
self.page.supervisor_consulted = True
|
|
self.page.submit()
|
|
self.assertTrue(self.page.success)
|
|
# Check that data is right
|
|
ra = models.RiskAssessment.objects.get(pk=self.testRA.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.testEvent2.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)
|
|
|
|
# Gotta scroll to make the button clickable
|
|
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
|
|
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)
|
|
|
|
def test_ec_create_medium(self):
|
|
self.page = pages.CreateEventChecklist(self.driver, self.live_server_url, event_id=self.testEvent3.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 = "Death Valley"
|
|
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)
|
|
|
|
# Gotta scroll to make the button clickable
|
|
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
|
|
|
|
self.page.earthing = True
|
|
self.page.pat = True
|
|
self.page.source_rcd = True
|
|
self.page.labelling = True
|
|
self.page.fd_voltage_l1 = 240
|
|
self.page.fd_voltage_l2 = 235
|
|
self.page.fd_voltage_l3 = 0
|
|
self.page.fd_phase_rotation = True
|
|
self.page.fd_earth_fault = 666
|
|
self.page.fd_pssc = 1984
|
|
self.page.w1_description = "In the carpark, by the bins"
|
|
self.page.w1_polarity = True
|
|
self.page.w1_voltage = 240
|
|
self.page.w1_earth_fault = 333
|
|
|
|
self.page.submit()
|
|
self.assertTrue(self.page.success)
|
|
|
|
def test_ec_create_extras(self):
|
|
eid = self.testEvent2.pk
|
|
self.page = pages.CreateEventChecklist(self.driver, self.live_server_url, event_id=eid).open()
|
|
self.page.add_vehicle()
|
|
self.page.add_crew()
|
|
|
|
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)
|
|
|
|
vehicle_name = 'Brian'
|
|
self.driver.find_element(By.XPATH, '//*[@name="vehicle_-1"]').send_keys(vehicle_name)
|
|
driver = base_regions.BootstrapSelectElement(self.page, self.driver.find_element(By.XPATH, '//tr[@id="vehicles_-1"]//div[contains(@class, "bootstrap-select")]'))
|
|
driver.search(self.profile.name)
|
|
|
|
crew = self.profile
|
|
role = "MIC"
|
|
crew_select = base_regions.BootstrapSelectElement(self.page, self.driver.find_element(By.XPATH, '//tr[@id="crew_-1"]//div[contains(@class, "bootstrap-select")]'))
|
|
start_time = base_regions.DateTimePicker(self.page, self.driver.find_element(By.XPATH, '//*[@name="start_-1"]'))
|
|
end_time = base_regions.DateTimePicker(self.page, self.driver.find_element(By.XPATH, '//*[@name="end_-1"]'))
|
|
|
|
start_time.set_value(timezone.make_aware(datetime.datetime(2015, 1, 1, 9, 0)))
|
|
# TODO Test validation of end before start
|
|
end_time.set_value(timezone.make_aware(datetime.datetime(2015, 1, 1, 10, 30)))
|
|
crew_select.search(crew.name)
|
|
self.driver.find_element(By.XPATH, '//*[@name="role_-1"]').send_keys(role)
|
|
|
|
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)
|
|
|
|
checklist = models.EventChecklist.objects.get(event=eid)
|
|
vehicle = models.EventChecklistVehicle.objects.get(checklist=checklist.pk)
|
|
self.assertEqual(vehicle_name, vehicle.vehicle)
|
|
crew_obj = models.EventChecklistCrew.objects.get(checklist=checklist.pk)
|
|
self.assertEqual(crew.pk, crew_obj.crewmember.pk)
|
|
self.assertEqual(role, crew_obj.role)
|