mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-16 21:12:13 +00:00
Added screenshot recording of test failures
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -110,3 +110,4 @@ crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
.vscode/
|
||||
/package-lock.json
|
||||
screenshots/
|
||||
@@ -247,3 +247,6 @@ RISK_ASSESSMENT_URL = os.environ.get('RISK_ASSESSMENT_URL') if os.environ.get(
|
||||
'RISK_ASSESSMENT_URL') else "http://example.com"
|
||||
RISK_ASSESSMENT_SECRET = os.environ.get('RISK_ASSESSMENT_SECRET') if os.environ.get(
|
||||
'RISK_ASSESSMENT_SECRET') else secrets.token_hex(15)
|
||||
|
||||
IMGUR_UPLOAD_CLIENT_ID = os.environ.get('IMGUR_UPLOAD_CLIENT_ID', '')
|
||||
IMGUR_UPLOAD_CLIENT_SECRET = os.environ.get('IMGUR_UPLOAD_CLIENT_SECRET', '')
|
||||
@@ -6,6 +6,11 @@ import os
|
||||
import pytz
|
||||
from datetime import date, time, datetime, timedelta
|
||||
from django.conf import settings
|
||||
import imgurpython
|
||||
import PyRIGS.settings
|
||||
import sys
|
||||
import pathlib
|
||||
import inspect
|
||||
|
||||
|
||||
def create_datetime(year, month, day, hour, min):
|
||||
@@ -47,6 +52,38 @@ class AutoLoginTest(BaseTest):
|
||||
loginPage.login("EventTest", "EventTestPassword")
|
||||
|
||||
|
||||
def screenshot_failure(func):
|
||||
def wrapper_func(self, *args, **kwargs):
|
||||
try:
|
||||
func(self, *args, **kwargs)
|
||||
except Exception as e:
|
||||
screenshot_name = func.__module__ + "." + func.__qualname__
|
||||
screenshot_file = "screenshots/"+func.__qualname__+".png"
|
||||
if not pathlib.Path("screenshots").is_dir():
|
||||
os.mkdir("screenshots")
|
||||
self.driver.save_screenshot(screenshot_file)
|
||||
|
||||
if settings.IMGUR_UPLOAD_CLIENT_ID != "":
|
||||
config = {
|
||||
'album': None,
|
||||
'name': screenshot_name,
|
||||
'title': screenshot_name,
|
||||
'description': ""
|
||||
}
|
||||
client = imgurpython.ImgurClient(settings.IMGUR_UPLOAD_CLIENT_ID, settings.IMGUR_UPLOAD_CLIENT_SECRET)
|
||||
image = client.upload_from_path(screenshot_file, config=config)
|
||||
print("Error in test {} is at url {}".format(screenshot_name, image['link']), file=sys.stderr)
|
||||
else:
|
||||
print("Error in test {} is at path {}".format(screenshot_name, screenshot_file), file=sys.stderr)
|
||||
raise e
|
||||
return wrapper_func
|
||||
|
||||
def screenshot_failure_cls(cls):
|
||||
for attr in cls.__dict__:
|
||||
if callable(getattr(cls, attr)) and attr.startswith("test"):
|
||||
setattr(cls, attr, screenshot_failure(getattr(cls, attr)))
|
||||
return cls
|
||||
|
||||
# Checks if animation is done
|
||||
class animation_is_finished(object):
|
||||
def __init__(self):
|
||||
|
||||
@@ -24,7 +24,7 @@ from django.core import mail, signing
|
||||
from django.http import HttpResponseBadRequest
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
@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')
|
||||
@@ -39,7 +39,7 @@ class BaseRigboardTest(AutoLoginTest):
|
||||
self.wait.until(animation_is_finished())
|
||||
self.assertTrue(self.page.is_expanded)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestRigboard(BaseRigboardTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -100,7 +100,7 @@ class TestRigboard(BaseRigboardTest):
|
||||
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()
|
||||
@@ -328,7 +328,7 @@ class TestEventCreate(BaseRigboardTest):
|
||||
def test_subhire_creation(self):
|
||||
pass
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestEventDuplicate(BaseRigboardTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -427,7 +427,7 @@ class TestEventDuplicate(BaseRigboardTest):
|
||||
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()
|
||||
@@ -487,7 +487,7 @@ class TestEventEdit(BaseRigboardTest):
|
||||
table = self.page.item_table
|
||||
self.assertIn("Test Item 3", table.text)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestEventDetail(BaseRigboardTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -523,7 +523,7 @@ class TestEventDetail(BaseRigboardTest):
|
||||
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()
|
||||
@@ -708,7 +708,7 @@ class TestCalendar(BaseRigboardTest):
|
||||
|
||||
# Wow - that was a lot of tests
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class ClientEventAuthorisationTest(TestCase):
|
||||
auth_data = {
|
||||
'name': 'Test ABC',
|
||||
@@ -814,7 +814,7 @@ class ClientEventAuthorisationTest(TestCase):
|
||||
self.assertEqual(mail.outbox[0].to, ['authemail@function.test'])
|
||||
self.assertEqual(mail.outbox[1].to, [settings.AUTHORISATION_NOTIFICATION_ADDRESS])
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TECEventAuthorisationTest(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from urllib.parse import urlparse
|
||||
from RIGS import models as rigsmodels
|
||||
from PyRIGS.tests.base import BaseTest, AutoLoginTest
|
||||
from PyRIGS.tests.base import BaseTest, AutoLoginTest, screenshot_failure_cls
|
||||
from assets import models, urls
|
||||
from reversion import revisions as reversion
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
@@ -17,7 +17,7 @@ from PyRIGS.tests.base import animation_is_finished
|
||||
import datetime
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestAssetList(AutoLoginTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -40,6 +40,7 @@ class TestAssetList(AutoLoginTest):
|
||||
self.assertIn("A light", assetDescriptions)
|
||||
self.assertIn("Working Mic", assetDescriptions)
|
||||
|
||||
|
||||
def test_asset_order(self):
|
||||
# Only the working stuff should be shown initially
|
||||
self.page.status_selector.open()
|
||||
@@ -94,7 +95,7 @@ class TestAssetList(AutoLoginTest):
|
||||
self.assertEqual("1", assetIDs[0])
|
||||
self.assertEqual("10", assetIDs[1])
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestAssetForm(AutoLoginTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -201,7 +202,7 @@ class TestAssetForm(AutoLoginTest):
|
||||
self.assertTrue(self.page.success)
|
||||
self.assertEqual(models.Asset.objects.last().description, self.parent.description)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestSupplierList(AutoLoginTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -240,7 +241,7 @@ class TestSupplierList(AutoLoginTest):
|
||||
self.page.search()
|
||||
self.assertTrue(len(self.page.suppliers) == 0)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestSupplierCreateAndEdit(AutoLoginTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -267,7 +268,7 @@ class TestSupplierCreateAndEdit(AutoLoginTest):
|
||||
self.page.submit()
|
||||
self.assertTrue(self.page.success)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestAssetAudit(AutoLoginTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -337,7 +338,7 @@ class TestAssetAudit(AutoLoginTest):
|
||||
self.assertFalse(self.driver.find_element_by_id('modal').is_displayed())
|
||||
self.assertIn("Asset with that ID does not exist!", self.page.error.text)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestSupplierValidation(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@@ -359,7 +360,7 @@ class TestSupplierValidation(TestCase):
|
||||
response = self.client.post(url, {'name': ""})
|
||||
self.assertFormError(response, 'form', 'name', 'This field is required.')
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class Test404(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@@ -379,6 +380,7 @@ class Test404(TestCase):
|
||||
|
||||
|
||||
# @tag('slow') TODO: req. Django 3.0
|
||||
@screenshot_failure_cls
|
||||
class TestAccessLevels(TestCase):
|
||||
@override_settings(DEBUG=True)
|
||||
def setUp(self):
|
||||
@@ -448,7 +450,7 @@ class TestAccessLevels(TestCase):
|
||||
|
||||
# def test_finance_access(self): Level not used in assets currently
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestFormValidation(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@@ -516,7 +518,7 @@ class TestFormValidation(TestCase):
|
||||
self.assertFormError(response, 'form', 'length', 'The length of a cable must be more than 0')
|
||||
self.assertFormError(response, 'form', 'csa', 'The CSA of a cable must be more than 0')
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestSampleDataGenerator(TestCase):
|
||||
@override_settings(DEBUG=True)
|
||||
def test_generate_sample_data(self):
|
||||
@@ -540,7 +542,7 @@ class TestSampleDataGenerator(TestCase):
|
||||
self.assertRaisesRegex(CommandError, ".*production", call_command, 'generateSampleAssetsData')
|
||||
self.assertRaisesRegex(CommandError, ".*production", call_command, 'deleteSampleData')
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestVersioningViews(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
@@ -583,7 +585,7 @@ class TestVersioningViews(TestCase):
|
||||
response = self.client.get(request_url, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
@screenshot_failure_cls
|
||||
class TestEmbeddedViews(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
|
||||
@@ -23,3 +23,4 @@ simplejson==3.17.0
|
||||
whitenoise==5.0.1
|
||||
reportlab==3.4.0
|
||||
z3c.rml==3.9.1
|
||||
imgurpython==1.1.7
|
||||
Reference in New Issue
Block a user