#!/usr/bin/env python3 """Render regression checks. Requires Firefox and Pillow; the page itself needs neither.""" import subprocess import tempfile import unittest from pathlib import Path from PIL import Image, ImageChops, ImageStat HERE = Path(__file__).resolve().parent class IceRenderTest(unittest.TestCase): def test_loop_mouse_and_visible_plasma(self): subprocess.run(['python3', str(HERE / 'build_plasma.py')], check=True) with tempfile.TemporaryDirectory() as directory: root = Path(directory) profile = root / 'profile' profile.mkdir() def render(name, parameters): output = root / (name + '.png') url = (HERE / 'ice_plasma.html').as_uri() + '#shot&' + parameters subprocess.run(['firefox', '--headless', '--new-instance', '--profile', str(profile), '--window-size=320,240', '--screenshot=' + str(output), url], check=True, timeout=120, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # Exclude the on-screen instructions. with Image.open(output) as image: return image.convert('RGB').crop((0, 0, 320, 180)) start = render('start', 't=0&mx=0.5&my=0.5') loop = render('loop', 't=30&mx=0.5&my=0.5') moved = render('moved', 't=0&mx=0.9&my=0.5') halfway = render('halfway', 't=15&mx=0.5&my=0.5') difference = lambda a, b: sum(ImageStat.Stat(ImageChops.difference(a, b)).mean) / 3 self.assertLess(difference(start, loop), 1.0) self.assertGreater(difference(start, moved), 3.0) self.assertGreater(difference(start, halfway), 3.0) self.assertGreater(ImageStat.Stat(start).stddev[2], 10.0) luminance = start.convert('L').histogram() pixels = sum(luminance) self.assertLess(sum(luminance[:20]) / pixels, 0.10) # No vast black voids. self.assertGreater(sum(luminance[:35]) / pixels, 0.08) # The depth stays dark. if __name__ == '__main__': unittest.main()