1
0

test_media.py 5.2 KB

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