Added screenshot recording of test failures

This commit is contained in:
Matthew Smith
2020-05-27 01:47:10 +01:00
parent 6ded711dd5
commit 6d47be72fe
6 changed files with 65 additions and 21 deletions

1
.gitignore vendored
View File

@@ -110,3 +110,4 @@ crashlytics.properties
crashlytics-build.properties
.vscode/
/package-lock.json
screenshots/

View File

@@ -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', '')

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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