conftest.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """Shared conftest for all integration tests."""
  2. import os
  3. import re
  4. from pathlib import Path
  5. import pytest
  6. from reflex.testing import AppHarness, AppHarnessProd
  7. DISPLAY = None
  8. XVFB_DIMENSIONS = (800, 600)
  9. @pytest.fixture(scope="session", autouse=True)
  10. def xvfb():
  11. """Create virtual X display.
  12. This function is a no-op unless GITHUB_ACTIONS is set in the environment.
  13. Yields:
  14. the pyvirtualdisplay object that the browser will be open on
  15. """
  16. if os.environ.get("GITHUB_ACTIONS"):
  17. from pyvirtualdisplay.smartdisplay import ( # pyright: ignore [reportMissingImports]
  18. SmartDisplay,
  19. )
  20. global DISPLAY
  21. with SmartDisplay(visible=0, size=XVFB_DIMENSIONS) as DISPLAY:
  22. yield DISPLAY
  23. DISPLAY = None
  24. else:
  25. yield None
  26. def pytest_exception_interact(node, call, report):
  27. """Take and upload screenshot when tests fail.
  28. Args:
  29. node: The pytest item that failed.
  30. call: The pytest call describing when/where the test was invoked.
  31. report: The pytest log report object.
  32. """
  33. screenshot_dir = os.environ.get("SCREENSHOT_DIR")
  34. if DISPLAY is None or screenshot_dir is None:
  35. return
  36. screenshot_dir = Path(screenshot_dir)
  37. screenshot_dir.mkdir(parents=True, exist_ok=True)
  38. safe_filename = re.sub(
  39. r"(?u)[^-\w.]",
  40. "_",
  41. str(node.nodeid).strip().replace(" ", "_").replace(":", "_"),
  42. )
  43. try:
  44. DISPLAY.waitgrab().save(
  45. (Path(screenshot_dir) / safe_filename).with_suffix(".png"),
  46. )
  47. except Exception as e:
  48. print(f"Failed to take screenshot for {node}: {e}")
  49. @pytest.fixture(
  50. scope="session", params=[AppHarness, AppHarnessProd], ids=["dev", "prod"]
  51. )
  52. def app_harness_env(request):
  53. """Parametrize the AppHarness class to use for the test, either dev or prod.
  54. Args:
  55. request: The pytest fixture request object.
  56. Returns:
  57. The AppHarness class to use for the test.
  58. """
  59. return request.param