utils.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. """Helper utilities for integration tests."""
  2. from __future__ import annotations
  3. from contextlib import contextmanager
  4. from typing import Generator, Iterator
  5. from selenium.webdriver.remote.webdriver import WebDriver
  6. from reflex.testing import AppHarness
  7. @contextmanager
  8. def poll_for_navigation(
  9. driver: WebDriver, timeout: int = 5
  10. ) -> Generator[None, None, None]:
  11. """Wait for driver url to change.
  12. Use as a contextmanager, and apply the navigation event inside the context
  13. block, polling will occur after the context block exits.
  14. Args:
  15. driver: WebDriver instance.
  16. timeout: Time to wait for url to change.
  17. Yields:
  18. None
  19. """
  20. prev_url = driver.current_url
  21. yield
  22. AppHarness._poll_for(lambda: prev_url != driver.current_url, timeout=timeout)
  23. class LocalStorage:
  24. """Class to access local storage.
  25. https://stackoverflow.com/a/46361900
  26. """
  27. storage_key = "localStorage"
  28. def __init__(self, driver: WebDriver):
  29. """Initialize the class.
  30. Args:
  31. driver: WebDriver instance.
  32. """
  33. self.driver = driver
  34. def __len__(self) -> int:
  35. """Get the number of items in local storage.
  36. Returns:
  37. The number of items in local storage.
  38. """
  39. return int(self.driver.execute_script("return window.localStorage.length;"))
  40. def items(self) -> dict[str, str]:
  41. """Get all items in local storage.
  42. Returns:
  43. A dict mapping keys to values.
  44. """
  45. return self.driver.execute_script(
  46. "var ls = window.localStorage, items = {}; "
  47. "for (var i = 0, k; i < ls.length; ++i) "
  48. " items[k = ls.key(i)] = ls.getItem(k); "
  49. "return items; "
  50. )
  51. def keys(self) -> list[str]:
  52. """Get all keys in local storage.
  53. Returns:
  54. A list of keys.
  55. """
  56. return self.driver.execute_script(
  57. "var ls = window.localStorage, keys = []; "
  58. "for (var i = 0; i < ls.length; ++i) "
  59. " keys[i] = ls.key(i); "
  60. "return keys; "
  61. )
  62. def get(self, key) -> str:
  63. """Get a key from local storage.
  64. Args:
  65. key: The key to get.
  66. Returns:
  67. The value of the key.
  68. """
  69. return self.driver.execute_script(
  70. "return window.localStorage.getItem(arguments[0]);", key
  71. )
  72. def set(self, key, value) -> None:
  73. """Set a key in local storage.
  74. Args:
  75. key: The key to set.
  76. value: The value to set the key to.
  77. """
  78. self.driver.execute_script(
  79. "window.localStorage.setItem(arguments[0], arguments[1]);", key, value
  80. )
  81. def has(self, key) -> bool:
  82. """Check if key is in local storage.
  83. Args:
  84. key: The key to check.
  85. Returns:
  86. True if key is in local storage, False otherwise.
  87. """
  88. return key in self
  89. def remove(self, key) -> None:
  90. """Remove a key from local storage.
  91. Args:
  92. key: The key to remove.
  93. """
  94. self.driver.execute_script("window.localStorage.removeItem(arguments[0]);", key)
  95. def clear(self) -> None:
  96. """Clear all local storage."""
  97. self.driver.execute_script("window.localStorage.clear();")
  98. def __getitem__(self, key) -> str:
  99. """Get a key from local storage.
  100. Args:
  101. key: The key to get.
  102. Returns:
  103. The value of the key.
  104. Raises:
  105. KeyError: If key is not in local storage.
  106. """
  107. value = self.get(key)
  108. if value is None:
  109. raise KeyError(key)
  110. return value
  111. def __setitem__(self, key, value) -> None:
  112. """Set a key in local storage.
  113. Args:
  114. key: The key to set.
  115. value: The value to set the key to.
  116. """
  117. self.set(key, value)
  118. def __contains__(self, key) -> bool:
  119. """Check if key is in local storage.
  120. Args:
  121. key: The key to check.
  122. Returns:
  123. True if key is in local storage, False otherwise.
  124. """
  125. return self.has(key)
  126. def __iter__(self) -> Iterator[str]:
  127. """Iterate over the keys in local storage.
  128. Returns:
  129. An iterator over the items in local storage.
  130. """
  131. return iter(self.keys())
  132. class SessionStorage(LocalStorage):
  133. """Class to access session storage.
  134. https://stackoverflow.com/a/46361900
  135. """
  136. storage_key = "sessionStorage"