diff --git a/plugin/src/py/android_screenshot_tests/recorder.py b/plugin/src/py/android_screenshot_tests/recorder.py index 3d07c4e3..4a7988a2 100644 --- a/plugin/src/py/android_screenshot_tests/recorder.py +++ b/plugin/src/py/android_screenshot_tests/recorder.py @@ -88,12 +88,39 @@ def _clean(self): shutil.rmtree(self._output) os.makedirs(self._output) + def _draw_diff_outline(self, failure_file, diff, image_to_draw_on): + draw = ImageDraw.Draw(image_to_draw_on) + draw.rectangle(list(diff), outline=(255, 0, 0)) + image_to_draw_on.save(failure_file) + def _is_image_same(self, file1, file2, failure_file): with Image.open(file1) as im1, Image.open(file2) as im2: diff_image = ImageChops.difference(im1, im2) try: diff = diff_image.getbbox() if diff is None: + if (im1.size != im2.size) or (im1.getbbox() != im2.getbbox()): + # First image is longer than the second + if im1.getbbox()[3] > im2.getbbox()[3]: + diff = [(0, im2.getbbox()[3]), (im1.getbbox()[2]-1, im1.getbbox()[3] - 1)] + self._draw_diff_outline(failure_file, diff, im1) + + # First image is shorter than the first + if im1.getbbox()[3] < im2.getbbox()[3]: + diff = [(0, im1.getbbox()[3]), (im2.getbbox()[2]-1, im2.getbbox()[3] - 1)] + self._draw_diff_outline(failure_file, diff, im2) + + # First image is wider than the second + if im1.getbbox()[2] > im2.getbbox()[2]: + diff = [(im2.getbbox()[2], 0), (im1.getbbox()[2]-1, im1.getbbox()[3] - 1)] + self._draw_diff_outline(failure_file, diff, im1) + + # First image is narrower than the first + if im1.getbbox()[2] < im2.getbbox()[2]: + diff = [(im1.getbbox()[2], 0), (im2.getbbox()[2]-1, im2.getbbox()[3] - 1)] + self._draw_diff_outline(failure_file, diff, im2) + + return False return True else: if failure_file: diff --git a/plugin/src/py/android_screenshot_tests/test_recorder.py b/plugin/src/py/android_screenshot_tests/test_recorder.py index 0dcb391b..c89f6dee 100644 --- a/plugin/src/py/android_screenshot_tests/test_recorder.py +++ b/plugin/src/py/android_screenshot_tests/test_recorder.py @@ -243,6 +243,221 @@ def test_verify_failure(self): self.assertEqual((0, 128, 0, 255), im.getpixel((1, 1))) self.assertEqual((0, 128, 0, 255), im.getpixel((9, 1))) + def test_verify_different_sizes_longer(self): + self.create_temp_image("foobar.png", (10, 10), "blue") + self.make_metadata( + # language=json + """ + [ + { + "name": "foobar", + "tileWidth": 1, + "tileHeight": 1 + } + ]""" + ) + + self.recorder.record() + os.unlink(join(self.inputdir, "foobar.png")) + self.create_temp_image("foobar.png", (10, 20), "blue") + + try: + self.recorder.verify() + self.fail("expected exception") + except VerifyError: + pass # expected + + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_actual.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_expected.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_diff.png"))) + + # check colored diff + with Image.open(join(self.failureDir, "foobar_diff.png")) as im: + (w, h) = im.size + self.assertEqual(10, w) + self.assertEqual(20, h) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 5))) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 5))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((5, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 15))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((5, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 15))) + + def test_verify_different_sizes_shorter(self): + self.create_temp_image("foobar.png", (10, 20), "blue") + self.make_metadata( + # language=json + """ + [ + { + "name": "foobar", + "tileWidth": 1, + "tileHeight": 1 + } + ]""" + ) + + self.recorder.record() + os.unlink(join(self.inputdir, "foobar.png")) + self.create_temp_image("foobar.png", (10, 10), "blue") + + try: + self.recorder.verify() + self.fail("expected exception") + except VerifyError: + pass # expected + + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_actual.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_expected.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_diff.png"))) + + # check colored diff + with Image.open(join(self.failureDir, "foobar_diff.png")) as im: + (w, h) = im.size + self.assertEqual(10, w) + self.assertEqual(20, h) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 5))) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 5))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((5, 10))) + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 15))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((0, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((5, 19))) + self.assertEqual((255, 0, 0, 255), im.getpixel((9, 15))) + + def test_verify_different_sizes_wider(self): + self.create_temp_image("foobar.png", (10, 10), "blue") + self.make_metadata( + # language=json + """ + [ + { + "name": "foobar", + "tileWidth": 1, + "tileHeight": 1 + } + ]""" + ) + + self.recorder.record() + os.unlink(join(self.inputdir, "foobar.png")) + self.create_temp_image("foobar.png", (20, 10), "blue") + + try: + self.recorder.verify() + self.fail("expected exception") + except VerifyError: + pass # expected + + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_actual.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_expected.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_diff.png"))) + + # check colored diff + with Image.open(join(self.failureDir, "foobar_diff.png")) as im: + (w, h) = im.size + self.assertEqual(20, w) + self.assertEqual(10, h) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 5))) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 5))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 0))) + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 9))) + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 5))) + self.assertEqual((255, 0, 0, 255), im.getpixel((15, 0))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 0))) + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 9))) + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 5))) + self.assertEqual((255, 0, 0, 255), im.getpixel((15, 9))) + + def test_verify_different_sizes_narrower(self): + self.create_temp_image("foobar.png", (20, 10), "blue") + self.make_metadata( + # language=json + """ + [ + { + "name": "foobar", + "tileWidth": 1, + "tileHeight": 1 + } + ]""" + ) + + self.recorder.record() + os.unlink(join(self.inputdir, "foobar.png")) + self.create_temp_image("foobar.png", (10, 10), "blue") + + try: + self.recorder.verify() + self.fail("expected exception") + except VerifyError: + pass # expected + + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_actual.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_expected.png"))) + self.assertTrue(os.path.exists(join(self.failureDir, "foobar_diff.png"))) + + # check colored diff + with Image.open(join(self.failureDir, "foobar_diff.png")) as im: + (w, h) = im.size + self.assertEqual(20, w) + self.assertEqual(10, h) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 5))) + + self.assertEqual((0, 0, 255, 255), im.getpixel((0, 0))) + self.assertEqual((0, 0, 255, 255), im.getpixel((9, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 9))) + self.assertEqual((0, 0, 255, 255), im.getpixel((5, 5))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 0))) + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 9))) + self.assertEqual((255, 0, 0, 255), im.getpixel((10, 5))) + self.assertEqual((255, 0, 0, 255), im.getpixel((15, 0))) + + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 0))) + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 9))) + self.assertEqual((255, 0, 0, 255), im.getpixel((19, 5))) + self.assertEqual((255, 0, 0, 255), im.getpixel((15, 9))) if __name__ == "__main__": unittest.main()