test_media.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. """Integration tests for media components."""
  2. from typing import Generator
  3. import pytest
  4. from selenium.webdriver.common.by import By
  5. from reflex.testing import AppHarness
  6. def MediaApp():
  7. """Reflex app with generated images."""
  8. import httpx
  9. from PIL import Image
  10. import reflex as rx
  11. class State(rx.State):
  12. def _blue(self, format=None) -> Image.Image:
  13. img = Image.new("RGB", (200, 200), "blue")
  14. if format is not None:
  15. img.format = format # type: ignore
  16. return img
  17. @rx.var(cache=True)
  18. def img_default(self) -> Image.Image:
  19. return self._blue()
  20. @rx.var(cache=True)
  21. def img_bmp(self) -> Image.Image:
  22. return self._blue(format="BMP")
  23. @rx.var(cache=True)
  24. def img_jpg(self) -> Image.Image:
  25. return self._blue(format="JPEG")
  26. @rx.var(cache=True)
  27. def img_png(self) -> Image.Image:
  28. return self._blue(format="PNG")
  29. @rx.var(cache=True)
  30. def img_gif(self) -> Image.Image:
  31. return self._blue(format="GIF")
  32. @rx.var(cache=True)
  33. def img_webp(self) -> Image.Image:
  34. return self._blue(format="WEBP")
  35. @rx.var(cache=True)
  36. def img_from_url(self) -> Image.Image:
  37. img_url = "https://picsum.photos/id/1/200/300"
  38. img_resp = httpx.get(img_url, follow_redirects=True)
  39. return Image.open(img_resp) # type: ignore
  40. app = rx.App()
  41. @app.add_page
  42. def index():
  43. return rx.vstack(
  44. rx.input(
  45. value=State.router.session.client_token,
  46. read_only=True,
  47. id="token",
  48. ),
  49. rx.image(src=State.img_default, alt="Default image", id="default"),
  50. rx.image(src=State.img_bmp, alt="BMP image", id="bmp"),
  51. rx.image(src=State.img_jpg, alt="JPG image", id="jpg"),
  52. rx.image(src=State.img_png, alt="PNG image", id="png"),
  53. rx.image(src=State.img_gif, alt="GIF image", id="gif"),
  54. rx.image(src=State.img_webp, alt="WEBP image", id="webp"),
  55. rx.image(src=State.img_from_url, alt="Image from URL", id="from_url"),
  56. )
  57. @pytest.fixture()
  58. def media_app(tmp_path) -> Generator[AppHarness, None, None]:
  59. """Start MediaApp app at tmp_path via AppHarness.
  60. Args:
  61. tmp_path: pytest tmp_path fixture
  62. Yields:
  63. running AppHarness instance
  64. """
  65. with AppHarness.create(
  66. root=tmp_path,
  67. app_source=MediaApp,
  68. ) as harness:
  69. yield harness
  70. @pytest.mark.asyncio
  71. async def test_media_app(media_app: AppHarness):
  72. """Display images, ensure the data uri mime type is correct and images load.
  73. Args:
  74. media_app: harness for MediaApp app
  75. """
  76. assert media_app.app_instance is not None, "app is not running"
  77. driver = media_app.frontend()
  78. # wait for the backend connection to send the token
  79. token_input = driver.find_element(By.ID, "token")
  80. token = media_app.poll_for_value(token_input)
  81. assert token
  82. # check out the images
  83. default_img = driver.find_element(By.ID, "default")
  84. bmp_img = driver.find_element(By.ID, "bmp")
  85. jpg_img = driver.find_element(By.ID, "jpg")
  86. png_img = driver.find_element(By.ID, "png")
  87. gif_img = driver.find_element(By.ID, "gif")
  88. webp_img = driver.find_element(By.ID, "webp")
  89. from_url_img = driver.find_element(By.ID, "from_url")
  90. def check_image_loaded(img, check_width=" == 200", check_height=" == 200"):
  91. return driver.execute_script(
  92. "console.log(arguments); return arguments[1].complete "
  93. '&& typeof arguments[1].naturalWidth != "undefined" '
  94. f"&& arguments[1].naturalWidth {check_width} ",
  95. '&& typeof arguments[1].naturalHeight != "undefined" '
  96. f"&& arguments[1].naturalHeight {check_height} ",
  97. img,
  98. )
  99. default_img_src = default_img.get_attribute("src")
  100. assert default_img_src is not None
  101. assert default_img_src.startswith("data:image/png;base64")
  102. assert check_image_loaded(default_img)
  103. bmp_img_src = bmp_img.get_attribute("src")
  104. assert bmp_img_src is not None
  105. assert bmp_img_src.startswith("data:image/bmp;base64")
  106. assert check_image_loaded(bmp_img)
  107. jpg_img_src = jpg_img.get_attribute("src")
  108. assert jpg_img_src is not None
  109. assert jpg_img_src.startswith("data:image/jpeg;base64")
  110. assert check_image_loaded(jpg_img)
  111. png_img_src = png_img.get_attribute("src")
  112. assert png_img_src is not None
  113. assert png_img_src.startswith("data:image/png;base64")
  114. assert check_image_loaded(png_img)
  115. gif_img_src = gif_img.get_attribute("src")
  116. assert gif_img_src is not None
  117. assert gif_img_src.startswith("data:image/gif;base64")
  118. assert check_image_loaded(gif_img)
  119. webp_img_src = webp_img.get_attribute("src")
  120. assert webp_img_src is not None
  121. assert webp_img_src.startswith("data:image/webp;base64")
  122. assert check_image_loaded(webp_img)
  123. from_url_img_src = from_url_img.get_attribute("src")
  124. assert from_url_img_src is not None
  125. assert from_url_img_src.startswith("data:image/jpeg;base64")
  126. assert check_image_loaded(
  127. from_url_img,
  128. check_width=" == 200",
  129. check_height=" == 300",
  130. )