summaryrefslogtreecommitdiff
path: root/tests/end2end/fixtures/quteprocess.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/end2end/fixtures/quteprocess.py')
-rw-r--r--tests/end2end/fixtures/quteprocess.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py
index b1e4bbaab..6c491515e 100644
--- a/tests/end2end/fixtures/quteprocess.py
+++ b/tests/end2end/fixtures/quteprocess.py
@@ -5,8 +5,10 @@
"""Fixtures to run qutebrowser in a QProcess and communicate."""
import pathlib
+import os
import re
import sys
+import shutil
import time
import datetime
import logging
@@ -18,6 +20,7 @@ import json
import yaml
import pytest
+from PIL.ImageGrab import grab
from qutebrowser.qt.core import pyqtSignal, QUrl, QPoint
from qutebrowser.qt.gui import QImage, QColor
@@ -541,6 +544,8 @@ class QuteProc(testprocess.Process):
except AttributeError:
pass
else:
+ if call.failed:
+ self._take_x11_screenshot_of_failed_test()
if call.failed or hasattr(call, 'wasxfail') or call.skipped:
super().after_test()
return
@@ -868,6 +873,50 @@ class QuteProc(testprocess.Process):
self.send_cmd(cmd.format('no-scroll-filtering'))
self.send_cmd(cmd.format('log-scroll-pos'))
+ def _get_x11_screenshot_directory(self):
+ screenshot_path = self.request.session.stash.get("screenshot_path", None)
+ if screenshot_path:
+ return screenshot_path
+
+ screenshot_path = os.path.join(
+ os.environ.get("RUNNER_TEMP", tempfile.gettempdir()),
+ "pytest-screenshots",
+ )
+ if os.path.exists(screenshot_path):
+ shutil.rmtree(screenshot_path)
+ os.mkdir(screenshot_path)
+
+ self.request.session.stash["screenshot_path"] = screenshot_path
+ return screenshot_path
+
+ def _take_x11_screenshot_of_failed_test(self):
+ # See also, pyvirtualdisplay smartdisplay which includes some cropping
+ # logic https://github.com/ponty/PyVirtualDisplay/blob/master/pyvirtualdisplay/smartdisplay.py
+ xvfb = self.request.getfixturevalue('xvfb')
+ if not xvfb:
+ # Likely we are being run with --no-xvfb
+ return
+ # For using IMGrab we must set `xvfb_colordepth = 24` in pytest.ini to override the
+ # default of `16` in pytest-xvfb. Pillow only supports 24bit
+ # https://github.com/python-pillow/Pillow/blob/1138ea5370cbda5eb328ec9498c314d376c81265/src/display.c#L898
+ img = grab(xdisplay=f":{xvfb.display}")
+ current_test = self.request.node.nodeid
+
+ fname = f"{datetime.datetime.now().isoformat()}-{current_test.replace('/', '_')}.png"
+ # upload-artifacts says it doesn't allow these characters if it sees
+ # one of them.
+ bad_chars = '":<>|*?\r\n'
+ for char in bad_chars:
+ fname = fname.replace(char, "_")
+
+ # TODO:
+ # 1. Keep old directories around?
+ # 2. Will different runs in parallel in CI clobber the folder? Might
+ # have to put them in subdirs with the process ID if so.
+ # 4. Log a "screenshot saved to ..." message?
+ fpath = os.path.join(self._get_x11_screenshot_directory(), fname)
+ img.save(fpath)
+
class YamlLoader(yaml.SafeLoader):