def test_stop_thread(self): """ Thread should be stopped and instance deleted """ inst = DiffComputer.get_instance() DiffComputer.stopThread() self.assertIsNone(DiffComputer._instance)
def test_remove_ref_with_different_browser(self): """ Test the case where we remove a ref a we want to make sure that the new reference is searched with the same browsert """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) # snapshot associated to same version, same test case, but other environment as 'initialRefSnapshot' snapshot_other_browser = Snapshot( stepResult=self.step_result_other_env, refSnapshot=None, pixelsDiff=None) snapshot_other_browser.save() snapshot_other_browser.image.save("img", img) snapshot_other_browser.save() # reference snapshot associated to same version / test case / environment / browser as 'initialRefSnapshot' snapshot_ref_same_env = Snapshot(stepResult=self.sr1, refSnapshot=None, pixelsDiff=None) snapshot_ref_same_env.save() snapshot_ref_same_env.image.save("img", img) snapshot_ref_same_env.save() # snapshot associated to same version / test case / environment / browser as 'snapshot_ref_same_env' snapshot_same_env = Snapshot(stepResult=self.step_result_same_env, refSnapshot=snapshot_ref_same_env, pixelsDiff=None) snapshot_same_env.save() snapshot_same_env.image.save("img", img) snapshot_same_env.save() response = self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': self.tcs1.id, 'testStepId': 1 }) + "?makeRef=False&snapshotId=" + str(snapshot_ref_same_env.id)) # check display self.assertEqual(response.context['captureList'][0]['reference'], self.initialRefSnapshot, "new reference should be the first snapshot") self.assertEqual( response.context['captureList'][0]['stepSnapshot'].refSnapshot, self.initialRefSnapshot, "new reference should be the first snapshot") self.assertIsNotNone( response.context['captureList'][0]['stepSnapshot'].pixelsDiff) DiffComputer.stopThread() # check 'snapshot_same_env' ref as been changed and its reference snapshot is 'initialRefSnapshot' becaus it's the same environment / test case / version self.assertEqual( Snapshot.objects.get(id=snapshot_same_env.id).refSnapshot, self.initialRefSnapshot, "ref snapshot for 'snapshot_same_env' should have changed to first snapshot, not 'snapshot_other_browser'" )
def test_compute_diff_with_tolerance_lower_than_difference(self): """ Check that tooManyDiffs is True as % of differences is higher than tolerance """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as reference: with open("snapshotServer/tests/data/test_Image1Mod.png", 'rb') as step: img_reference = ImageFile(reference) img_step = ImageFile(step) ref_snapshot = Snapshot( stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) ref_snapshot.save() ref_snapshot.image.save("img", img_reference) ref_snapshot.save() step_snapshot = Snapshot( stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None, diffTolerance=0.005) step_snapshot.save() step_snapshot.image.save("img", img_step) step_snapshot.save() DiffComputer.get_instance().compute_now( ref_snapshot, step_snapshot) # something has been computed self.assertIsNotNone(step_snapshot.pixelsDiff) self.assertTrue(step_snapshot.tooManyDiffs)
def test_compute_now(self): """ Check thread is not started when computing is requested to be done now """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) s1 = Snapshot(stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) s1.save() s1.image.save("img", img) s1.save() s2 = Snapshot(stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) s2.save() s2.image.save("img", img) s2.save() self.assertFalse(s1.computed) self.assertFalse(s2.computed) DiffComputer.get_instance().compute_now(s1, s2) # something has been computed self.assertIsNotNone(s2.pixelsDiff) self.assertEqual(s2.refSnapshot, s1, "refSnapshot should have been updated") self.assertFalse( s1.computed) # reference picture, computed flag remains False self.assertTrue(s2.computed) # diff computed, flag changed
def test_create_instance(self): """ Check we always have the same instance """ self.assertIsNone(DiffComputer._instance) inst = DiffComputer.get_instance() self.assertIsNotNone(inst, "an instance should have been created") self.assertEqual(DiffComputer.get_instance(), inst, "the same instance should always be returned")
def test_error_message_reset(self): """ Check that if an error occurs during _compute_diff() method, 'computed' flag is still set to 'True' whatever the result is, and 'computingError' is filled If an other computing is done, and no error occurs, then, 'computingError' is reset to an empty string """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as reference: with open("snapshotServer/tests/data/test_Image1Mod.png", 'rb') as step: img_reference = ImageFile(reference) img_step = ImageFile(step) ref_snapshot = Snapshot( stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) ref_snapshot.save() ref_snapshot.image.save("img", img_reference) ref_snapshot.save() step_snapshot = Snapshot( stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) step_snapshot.save() step_snapshot.image.save("img", img_step) step_snapshot.save() diff_computer = DiffComputer.get_instance() diff_computer.mark_diff = MagicMock( side_effect=Exception("error while computing")) diff_computer.add_jobs(ref_snapshot, step_snapshot, check_test_mode=True) time.sleep(1) self.assertIsNotNone(DiffComputer._instance, "thread should still be running") # check error has been saved self.assertTrue( Snapshot.objects.get(id=step_snapshot.id).computed) self.assertEqual( Snapshot.objects.get(id=step_snapshot.id).computingError, "error while computing") # check error has been removed as computing is ok DiffComputer.stopThread() # reset DiffComputer instance diff_computer_ok = DiffComputer.get_instance() diff_computer_ok.add_jobs(ref_snapshot, step_snapshot, check_test_mode=True) time.sleep(1) self.assertTrue( Snapshot.objects.get(id=step_snapshot.id).computed) self.assertEqual( Snapshot.objects.get(id=step_snapshot.id).computingError, "")
def test_remove_ref(self): """ From a picture which is a reference (snapshot_ref_same_env), remove the reference flag. Next snpashots (snapshot_same_env) should then refere to the last reference available """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) snapshot_ref_same_env = Snapshot(stepResult=self.sr1, refSnapshot=None, pixelsDiff=None) snapshot_ref_same_env.save() snapshot_ref_same_env.image.save("img", img) snapshot_ref_same_env.save() snapshot_same_env = Snapshot(stepResult=self.step_result_same_env, refSnapshot=snapshot_ref_same_env, pixelsDiff=None) snapshot_same_env.save() snapshot_same_env.image.save("img", img) snapshot_same_env.save() response = self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': self.tcs1.id, 'testStepId': 1 }) + "?makeRef=False&snapshotId=" + str(snapshot_ref_same_env.id)) # check display self.assertEqual(response.context['captureList'][0]['reference'], self.initialRefSnapshot, "new reference should be the first snapshot") self.assertEqual( response.context['captureList'][0]['stepSnapshot'].refSnapshot, self.initialRefSnapshot, "new reference should be the first snapshot") self.assertIsNotNone( response.context['captureList'][0]['stepSnapshot'].pixelsDiff) self.assertEqual( response.context['captureList'][0]['diffPercentage'], 0.0) DiffComputer.stopThread() # check snapshot_same_env ref as been changed self.assertEqual( Snapshot.objects.get(id=snapshot_same_env.id).refSnapshot, self.initialRefSnapshot, "ref snapshot for snapshot_same_env should have changed to first snapshot" )
def test_add_jobs(self): """ Check we can add jobs and they get computed """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) s1 = Snapshot(stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) s1.save() s1.image.save("img", img) s1.save() s2 = Snapshot(stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) s2.save() s2.image.save("img", img) s2.save() s3 = Snapshot(stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) s3.save() s3.image.save("img", img) s3.save() diff_computer = DiffComputer.get_instance() diff_computer.add_jobs(s1, s2, check_test_mode=False) diff_computer.add_jobs(s1, s3, check_test_mode=False) time.sleep(1) diff_computer.stopThread() # something has been computed self.assertIsNotNone(s2.pixelsDiff) self.assertIsNotNone(s3.pixelsDiff)
def test_remove_very_first_ref(self): """ From a picture which is the first reference for a testCase/testStep couple, try to remove the reference It should not be possible We use - model: snapshotServer.testcaseinsession pk: 3 fields: testCase: 3 session: 4 testSteps: [1] - model: snapshotServer.stepresult pk: 3 fields: step: 1 testCase: 3 result: true - model: snapshotServer.snapshot pk: 3 fields: stepResult: 3 image: documents/test_Image1.png """ response = self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': 3, 'testStepId': 1 }) + "?makeRef=False&snapshotId=3") # check display self.assertIsNone(response.context['captureList'][0]['reference'], "picture is still a reference") self.assertIsNone( response.context['captureList'][0]['stepSnapshot'].refSnapshot, "new reference should be the snapshot itself") self.assertIsNone( response.context['captureList'][0]['stepSnapshot'].pixelsDiff, "no diff as we have a reference") DiffComputer.stopThread()
def test_ref_is_none(self): """ Check no error is raised when reference is None. Nothing happens for the stepSnapshot """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) s2 = Snapshot(stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=b'') s2.save() s2.image.save("img", img) s2.save() DiffComputer.get_instance().compute_now(None, s2) # something has been computed self.assertIsNone(s2.pixelsDiff) self.assertIsNone(s2.refSnapshot, "refSnapshot should have not been updated")
def test_compute_using_exclude_zones_from_step(self): """ issue #57: Check that computing takes into account exclude zone from step snapshot that could be added by seleniumRobot """ with patch.object(DiffComputer.picture_comparator, 'get_changed_pixels', wraps=DiffComputer.picture_comparator. get_changed_pixels) as wrapped_get_changed_pixels: with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) ref_snapshot = Snapshot( stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) ref_snapshot.save() ref_snapshot.image.save("img", img) ref_snapshot.save() step_snapshot = Snapshot( stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) step_snapshot.save() step_snapshot.image.save("img", img) step_snapshot.save() exclusion1 = ExcludeZone(x=0, y=0, width=10, height=10, snapshot=step_snapshot) exclusion1.save() DiffComputer.get_instance().compute_now( ref_snapshot, step_snapshot) # check exclude zone has been used for comparison wrapped_get_changed_pixels.assert_called_with( ref_snapshot.image.path, step_snapshot.image.path, [exclusion1.toRectangle()])
def test_compute_now_no_save(self): """ Check snapshot is not saved if it's not requested """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile, name="img.png") s1 = Snapshot(stepResult=StepResult.objects.get(id=1), image=img, refSnapshot=None, pixelsDiff=None) # as we do not save any snapshot, image has to be copied manually where DiffComputer expects it shutil.copyfile("snapshotServer/tests/data/test_Image1.png", settings.MEDIA_ROOT + os.sep + "img.png") s2 = Snapshot(stepResult=StepResult.objects.get(id=2), image=img, refSnapshot=None, pixelsDiff=None) self.assertFalse(s1.computed) self.assertFalse(s2.computed) DiffComputer.get_instance().compute_now(s1, s2, save_snapshot=False) # something has been computed self.assertIsNotNone(s2.pixelsDiff) self.assertEqual(s2.refSnapshot, s1, "refSnapshot should have been updated") self.assertIsNone(s1.id) self.assertIsNone(s2.id) self.assertFalse( s1.computed) # reference picture, computed flag remains False self.assertTrue(s2.computed) # diff computed, flag changed
def test_ref_image_is_none(self): """ Check no error is raised when image data is missing """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) s1 = Snapshot(stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) s1.save() s2 = Snapshot(stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=b'') s2.save() s2.image.save("img", img) s2.save() DiffComputer.get_instance().compute_now(s1, s2) # something has been computed self.assertIsNone(s2.pixelsDiff) self.assertEqual(s2.refSnapshot, s1, "refSnapshot should have been updated")
def test_compute_diff_without_tolerance(self): """ Check difference is found between two different images """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as reference: with open("snapshotServer/tests/data/test_Image1Mod.png", 'rb') as step: img_reference = ImageFile(reference) img_step = ImageFile(step) ref_snapshot = Snapshot( stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) ref_snapshot.save() ref_snapshot.image.save("img", img_reference) ref_snapshot.save() step_snapshot = Snapshot( stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) step_snapshot.save() step_snapshot.image.save("img", img_step) step_snapshot.save() DiffComputer.get_instance().compute_now( ref_snapshot, step_snapshot) # something has been computed self.assertIsNotNone(step_snapshot.pixelsDiff) self.assertTrue(step_snapshot.tooManyDiffs) self.assertEqual(step_snapshot.refSnapshot, ref_snapshot, "refSnapshot should have been updated") self.assertTrue(step_snapshot.computed) self.assertTrue(step_snapshot.computingError == '')
def submission_delete(sender, instance, **kwargs): """ When a snapshot is deleted, remove the associated picture Also rebuild reference tree for snapshots that could have referenced this one """ from snapshotServer.controllers.DiffComputer import DiffComputer # deletion of image file instance.image.delete(False) # recompute references if this snapshot is a reference for other for snapshot in instance.snapshotsUntilNextRef(instance): test_case = instance.stepResult.testCase # search any reference snapshot that exists previously ref_snapshots = Snapshot.objects.filter( stepResult__testCase__testCase__name=test_case.testCase.name, stepResult__testCase__session__version=test_case.session.version, stepResult__testCase__session__environment=test_case.session. environment, stepResult__testCase__session__browser=test_case.session.browser, stepResult__step=snapshot.stepResult.step, refSnapshot=None, id__lt=snapshot.id, name=snapshot.name).exclude(id=instance.id) # we find a reference snapshot, recompute diff if len(ref_snapshots) > 0: snapshot.refSnapshot = ref_snapshots.last() snapshot.save() diff_computer = DiffComputer.get_instance() # recompute diff pixels diff_computer.compute_now(snapshot.refSnapshot, snapshot) # recompute all following snapshot as they will depend on a previous ref for snap in snapshot.snapshotsUntilNextRef(snapshot): diff_computer.add_jobs(snapshot.refSnapshot, snap) # no reference snapshot found, only remove information about reference which makes this snapshot a reference else: snapshot.refSnapshot = None snapshot.save()
def test_error_while_computing(self): """ Check that if an error occurs during computing, """ s1 = Snapshot(stepResult=StepResult.objects.get(id=1), refSnapshot=None, pixelsDiff=None) s1.save() s2 = Snapshot(stepResult=StepResult.objects.get(id=2), refSnapshot=None, pixelsDiff=None) s2.save() diff_computer = DiffComputer.get_instance() diff_computer._compute_diff = MagicMock( side_effect=Exception("error while computing")) diff_computer.add_jobs(s1, s2, check_test_mode=False) time.sleep(0.7) self.assertIsNotNone(DiffComputer._instance, "thread should still be running")
def post(self, request, *args, **kwargs): try: step_snapshot = Snapshot.objects.get(pk=args[0]) # compute has sense when a reference exists if step_snapshot.refSnapshot: diff_computer = DiffComputer.get_instance() diff_computer.compute_now(step_snapshot.refSnapshot, step_snapshot) # start computing differences for other snapshots sharing the same reference for snap in step_snapshot.snapshotWithSameRef(): diff_computer.add_jobs(step_snapshot.refSnapshot, snap) return HttpResponse(status=200) else: return HttpResponse(status=304) except Exception as e: return HttpResponse(status=404)
def test_make_new_ref(self): """ From a picture which is not a reference (snapshot_future_ref_same_env), make it a new ref 'snapshot_same_env' should then have 'snapshot_future_ref_same_env' as reference because it has a higher id than 'initialRefSnapshot' and same name / browser / environment / version """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: img = ImageFile(imgFile) snapshot_future_ref_same_env = Snapshot( stepResult=self.sr1, refSnapshot=self.initialRefSnapshot, pixelsDiff=None) snapshot_future_ref_same_env.save() snapshot_future_ref_same_env.image.save("img", img) snapshot_future_ref_same_env.save() exclusion1 = ExcludeZone(x=0, y=0, width=10, height=10, snapshot=self.initialRefSnapshot) exclusion1.save() exclusion2 = ExcludeZone(x=10, y=10, width=10, height=10, snapshot=self.initialRefSnapshot) exclusion2.save() self.assertEqual( len( ExcludeZone.objects.filter( snapshot=self.initialRefSnapshot)), 2) self.assertEqual( len( ExcludeZone.objects.filter( snapshot=snapshot_future_ref_same_env)), 0) snapshot_same_env = Snapshot(stepResult=self.step_result_same_env, refSnapshot=self.initialRefSnapshot, pixelsDiff=None) snapshot_same_env.save() snapshot_same_env.image.save("img", img) snapshot_same_env.save() response = self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': self.tcs1.id, 'testStepId': 1 }) + "?makeRef=True&snapshotId=" + str(snapshot_future_ref_same_env.id)) # check display self.assertIsNone(response.context['captureList'][0]['reference'], "new reference should be the snapshot itself") self.assertIsNone( response.context['captureList'][0]['stepSnapshot'].refSnapshot, "new reference should be the snapshot itself") self.assertIsNone( response.context['captureList'][0]['stepSnapshot'].pixelsDiff) DiffComputer.stopThread() # check snapshot_same_env ref as been changed self.assertEqual( Snapshot.objects.get(id=snapshot_same_env.id).refSnapshot, snapshot_future_ref_same_env, "ref snapshot for snapshot_same_env should have changed to snapshot_future_ref_same_env" ) self.assertEqual( Snapshot.objects.get(id=2).refSnapshot, self.initialRefSnapshot, "snapshot previous to snapshot_future_ref_same_env should not have change" ) # check 'initialRefSnapshot' has kept its references self.assertEqual( len( ExcludeZone.objects.filter( snapshot=self.initialRefSnapshot)), 2) # check new ref 'snapshot_future_ref_same_env' has got a copy of the exclusion zones self.assertEqual( len( ExcludeZone.objects.filter( snapshot=snapshot_future_ref_same_env)), 2)
def compare_or_store_snapshot(self, form, step_result): image = form.cleaned_data['image'] # the image file name = form.cleaned_data['name'] # name of the image store_snapshot = form.cleaned_data[ 'storeSnapshot'] # do we store the image or not. If False, only comparison is returned diff_tolerance = form.cleaned_data.get( 'diffTolerance', 0.0) # percentage of admissible error compare_option = form.cleaned_data.get('compare', 'true') # how we compare image # check if a reference exists for this step in the same test case / same application / same version / same environment / same browser / same name most_recent_reference_snapshot = Snapshot.objects.filter( stepResult__step=step_result.step, # same step in the test case stepResult__testCase__testCase__name=step_result.testCase.testCase. name, # same test case stepResult__testCase__session__version=step_result.testCase. session.version, # same version stepResult__testCase__session__environment=step_result.testCase. session.environment, # same environment stepResult__testCase__session__browser=step_result.testCase. session.browser, # same browser refSnapshot=None, # a reference image name=name).order_by('pk').last() # same snapshot name # check for a reference in previous versions if not most_recent_reference_snapshot: for app_version in reversed( step_result.testCase.session.version.previousVersions()): most_recent_reference_snapshot = Snapshot.objects.filter( stepResult__step=step_result.step, stepResult__testCase__testCase__name=step_result.testCase. testCase.name, stepResult__testCase__session__version=app_version, stepResult__testCase__session__environment=step_result. testCase.session.environment, stepResult__testCase__session__browser=step_result. testCase.session.browser, refSnapshot=None, name=name).order_by('pk').last() if most_recent_reference_snapshot: break diff_pixels_percentage = 0.0 if most_recent_reference_snapshot: step_snapshot = Snapshot( stepResult=step_result, image=image, refSnapshot=most_recent_reference_snapshot, name=name, compareOption=compare_option, diffTolerance=diff_tolerance) if store_snapshot: step_snapshot.save() # compute difference if a reference already exist DiffComputer.get_instance().add_jobs( most_recent_reference_snapshot, step_snapshot) else: try: # as we don't save step_snapshot (it's temp computation), we still save the image data temporary at the location it's expected with open(step_snapshot.image.path, 'wb') as img: img.write(image.read()) img.flush() DiffComputer.get_instance().compute_now( most_recent_reference_snapshot, step_snapshot, save_snapshot=False) finally: try: os.remove(step_snapshot.image.path) except Exception as e: pass if step_snapshot.pixelsDiff is not None: with io.BytesIO(step_snapshot.pixelsDiff) as input: diff_pixels_percentage = 100 * ( sum(list(Image.open(input).getdata(3))) / 255) / (step_snapshot.image.width * step_snapshot.image.height) else: # snapshot is marked as computed as this is a reference snapshot step_snapshot = Snapshot(stepResult=step_result, image=image, refSnapshot=None, name=name, compareOption=compare_option, computed=True, diffTolerance=diff_tolerance) if store_snapshot: step_snapshot.save() return HttpResponse(json.dumps({ 'id': step_snapshot.id, 'computed': step_snapshot.computed, 'computingError': step_snapshot.computingError, 'diffPixelPercentage': diff_pixels_percentage, 'tooManyDiffs': step_snapshot.tooManyDiffs }), content_type='application/json', status=201)
def test_make_new_ref_diff_image(self): """ Compare 2 pictures (force computation to be sure we have diff data) Check we get the diff percentage """ with open("snapshotServer/tests/data/test_Image1.png", 'rb') as imgFile: with open("snapshotServer/tests/data/test_Image1Mod.png", 'rb') as img_file_mod: img = ImageFile(imgFile) img_mod = ImageFile(img_file_mod) snapshot_future_ref_same_env = Snapshot( stepResult=self.sr1, refSnapshot=self.initialRefSnapshot, pixelsDiff=None) snapshot_future_ref_same_env.save() snapshot_future_ref_same_env.image.save("img", img) snapshot_future_ref_same_env.save() exclusion1 = ExcludeZone(x=0, y=0, width=10, height=10, snapshot=self.initialRefSnapshot) exclusion1.save() exclusion2 = ExcludeZone(x=10, y=10, width=10, height=10, snapshot=self.initialRefSnapshot) exclusion2.save() self.assertEqual( len( ExcludeZone.objects.filter( snapshot=self.initialRefSnapshot)), 2) self.assertEqual( len( ExcludeZone.objects.filter( snapshot=snapshot_future_ref_same_env)), 0) snapshot_same_env = Snapshot( stepResult=self.step_result_same_env, refSnapshot=self.initialRefSnapshot, pixelsDiff=None) snapshot_same_env.save() snapshot_same_env.image.save("img", img_mod) snapshot_same_env.save() # force computing self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': self.tcs1.id, 'testStepId': 1 }) + "?makeRef=True&snapshotId=" + str(snapshot_future_ref_same_env.id)) DiffComputer.stopThread() # ask for the step snapshot and look for data response = self.client.get( reverse('pictureView', kwargs={ 'testCaseInSessionId': self.tcs_same_env.id, 'testStepId': 1 }) + "?snapshotId=" + str(snapshot_same_env.id)) self.assertIsNotNone(response.context['captureList'][0] ['stepSnapshot'].pixelsDiff) self.assertTrue(response.context['captureList'][0] ['diffPercentage'] > 0.086)
def tearDown(self): DiffComputer.stopThread() logging.error("Stop threads") super().tearDown()
def get_context_data(self, **kwargs): """ Look for the snapshot of our session @param sessionId @param testCaseId a TestCaseInSession object id @param testStepId a TestStep object id """ context = super(PictureView, self).get_context_data(**kwargs) context['captureList'] = [] context['testCaseId'] = self.kwargs['testCaseInSessionId'] context['testStepId'] = self.kwargs['testStepId'] step = TestStep.objects.get(pk=self.kwargs['testStepId']) context['testStepName'] = step.name context['status'] = step.isOkWithSnapshots( self.kwargs['testCaseInSessionId']) # check that the user has permissions to edit exclusion zones. If not buttons will be disabled authenticated_to_edit = not self.security_api_enabled or ( self.security_api_enabled and self.request.user.is_authenticated) allowed_to_edit = not self.security_enabled or ( self.security_enabled and self.request.user.has_perms([ 'snapshotServer.add_excludezone', 'snapshotServer.change_excludezone', 'snapshotServer.delete_excludezone' ])) context['editable'] = authenticated_to_edit and allowed_to_edit if context['editable']: context['editButtonText'] = 'Edit' elif not authenticated_to_edit: context['editButtonText'] = 'You must log in to edit.' elif not allowed_to_edit: context['editButtonText'] = "You don't have right to edit" step_snapshots = Snapshot.objects.filter( stepResult__testCase=self.kwargs['testCaseInSessionId'], stepResult__step=self.kwargs['testStepId']).order_by('id') for step_snapshot in step_snapshots: if step_snapshot: # request should contain the snapshotId when makeRef is sent. Filter on it if 'makeRef' in self.request.GET and 'snapshotId' in self.request.GET and int( self.request.GET['snapshotId'] ) == step_snapshot.id and context['editable']: if self.request.GET[ 'makeRef'] == 'True' and step_snapshot.refSnapshot is not None: previous_snapshot = step_snapshot.refSnapshot step_snapshot.refSnapshot = None step_snapshot.pixelsDiff = None step_snapshot.save() # Compute differences for the following snapshots as they will depend on this new ref for snap in step_snapshot.snapshotsUntilNextRef( previous_snapshot): DiffComputer.get_instance().add_jobs( step_snapshot, snap) # copy exclude zones to the new ref so that they may be processed independently for exclude_zone in ExcludeZone.objects.filter( snapshot=previous_snapshot): exclude_zone.copy_to_snapshot(step_snapshot) elif self.request.GET[ 'makeRef'] == 'False' and step_snapshot.refSnapshot is None: # search a reference with a lower id, meaning that it has been recorded before our step # search with the same test case name / same step name / same application version / same environment / same browser / same image name so that comparison # is done on same basis # TODO: reference could be searched in previous versions test_case = TestCaseInSession.objects.get( pk=self.kwargs['testCaseInSessionId']) ref_snapshots = Snapshot.objects.filter( stepResult__testCase__testCase__name=test_case. testCase.name, stepResult__testCase__session__version=test_case. session.version, stepResult__testCase__session__environment=test_case .session.environment, stepResult__testCase__session__browser=test_case. session.browser, stepResult__step=self.kwargs['testStepId'], refSnapshot=None, id__lt=step_snapshot.id, name=step_snapshot.name) # do not remove reference flag if our snapshot is the very first one if len(ref_snapshots) > 0: step_snapshot.refSnapshot = ref_snapshots.last() step_snapshot.save() diff_computer = DiffComputer.get_instance() # recompute diff pixels diff_computer.compute_now( step_snapshot.refSnapshot, step_snapshot) # recompute all following snapshot as they will depend on a previous ref for snap in step_snapshot.snapshotsUntilNextRef( step_snapshot): diff_computer.add_jobs( step_snapshot.refSnapshot, snap) ref_snapshot = step_snapshot.refSnapshot # extract difference pixel. Recompute in case this step is no more a reference diff_pixels_bin = step_snapshot.pixelsDiff if os.path.isfile(settings.MEDIA_ROOT + os.sep + step_snapshot.image.name): snapshot_width = step_snapshot.image.width snapshot_height = step_snapshot.image.height else: snapshot_height = 0 snapshot_width = 0 if diff_pixels_bin and snapshot_width and snapshot_height: try: diff_pixels = pickle.loads(diff_pixels_bin) diff_picture = base64.b64encode( DiffComputer.get_instance().mark_diff( step_snapshot.image.width, step_snapshot.image.height, diff_pixels)).decode('ascii') diff_pixels_percentage = 0.0 except Exception: # diff_picture_bin diff_picture = base64.b64encode( diff_pixels_bin).decode('ascii') with io.BytesIO(diff_pixels_bin) as input: diff_pixels_percentage = 100 * ( sum(list(Image.open(input).getdata(3))) / 255) / (step_snapshot.image.width * step_snapshot.image.height) else: diff_pixels = [] diff_picture = None diff_pixels_percentage = 0.0 # not snapshot has been recorded for this session else: ref_snapshot = None diff_pixels = [] diff_picture = None diff_pixels_percentage = 0.0 step_snapshot_context = { 'name': step_snapshot.name, 'reference': ref_snapshot, 'stepSnapshot': step_snapshot, 'width': snapshot_width, 'height': snapshot_height, 'diffB64': diff_picture, 'diffPercentage': diff_pixels_percentage } context['captureList'].append(step_snapshot_context) return context