utils.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. def __init__(self, driver: WebDriver):
  28. """Initialize the class.
  29. Args:
  30. driver: WebDriver instance.
  31. """
  32. self.driver = driver
  33. def __len__(self) -> int:
  34. """Get the number of items in local storage.
  35. Returns:
  36. The number of items in local storage.
  37. """
  38. return int(self.driver.execute_script("return window.localStorage.length;"))
  39. def items(self) -> dict[str, str]:
  40. """Get all items in local storage.
  41. Returns:
  42. A dict mapping keys to values.
  43. """
  44. return self.driver.execute_script(
  45. "var ls = window.localStorage, items = {}; "
  46. "for (var i = 0, k; i < ls.length; ++i) "
  47. " items[k = ls.key(i)] = ls.getItem(k); "
  48. "return items; "
  49. )
  50. def keys(self) -> list[str]:
  51. """Get all keys in local storage.
  52. Returns:
  53. A list of keys.
  54. """
  55. return self.driver.execute_script(
  56. "var ls = window.localStorage, keys = []; "
  57. "for (var i = 0; i < ls.length; ++i) "
  58. " keys[i] = ls.key(i); "
  59. "return keys; "
  60. )
  61. def get(self, key) -> str:
  62. """Get a key from local storage.
  63. Args:
  64. key: The key to get.
  65. Returns:
  66. The value of the key.
  67. """
  68. return self.driver.execute_script(
  69. "return window.localStorage.getItem(arguments[0]);", key
  70. )
  71. def set(self, key, value) -> None:
  72. """Set a key in local storage.
  73. Args:
  74. key: The key to set.
  75. value: The value to set the key to.
  76. """
  77. self.driver.execute_script(
  78. "window.localStorage.setItem(arguments[0], arguments[1]);", key, value
  79. )
  80. def has(self, key) -> bool:
  81. """Check if key is in local storage.
  82. Args:
  83. key: The key to check.
  84. Returns:
  85. True if key is in local storage, False otherwise.
  86. """
  87. return key in self
  88. def remove(self, key) -> None:
  89. """Remove a key from local storage.
  90. Args:
  91. key: The key to remove.
  92. """
  93. self.driver.execute_script("window.localStorage.removeItem(arguments[0]);", key)
  94. def clear(self) -> None:
  95. """Clear all local storage."""
  96. self.driver.execute_script("window.localStorage.clear();")
  97. def __getitem__(self, key) -> str:
  98. """Get a key from local storage.
  99. Args:
  100. key: The key to get.
  101. Returns:
  102. The value of the key.
  103. Raises:
  104. KeyError: If key is not in local storage.
  105. """
  106. value = self.get(key)
  107. if value is None:
  108. raise KeyError(key)
  109. return value
  110. def __setitem__(self, key, value) -> None:
  111. """Set a key in local storage.
  112. Args:
  113. key: The key to set.
  114. value: The value to set the key to.
  115. """
  116. self.set(key, value)
  117. def __contains__(self, key) -> bool:
  118. """Check if key is in local storage.
  119. Args:
  120. key: The key to check.
  121. Returns:
  122. True if key is in local storage, False otherwise.
  123. """
  124. return self.has(key)
  125. def __iter__(self) -> Iterator[str]:
  126. """Iterate over the keys in local storage.
  127. Returns:
  128. An iterator over the items in local storage.
  129. """
  130. return iter(self.keys())