helpers.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. # Copyright 2021-2025 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. import json
  12. import logging
  13. import socket
  14. import time
  15. import typing as t
  16. import warnings
  17. from taipy.gui import Gui, Html, Markdown
  18. from taipy.gui._renderers.builder import _Builder
  19. from taipy.gui._warnings import TaipyGuiWarning
  20. from taipy.gui.utils._variable_directory import _reset_name_map
  21. from taipy.gui.utils.expr_var_name import _reset_expr_var_name
  22. class Helpers:
  23. @staticmethod
  24. def test_cleanup():
  25. _Builder._reset_key()
  26. _reset_name_map()
  27. _reset_expr_var_name()
  28. @staticmethod
  29. def test_control_md(gui: Gui, md_string: str, expected_values: t.Union[str, t.List]):
  30. gui.add_page("test", Markdown(md_string, frame=None))
  31. Helpers._test_control(gui, expected_values)
  32. @staticmethod
  33. def test_control_html(gui: Gui, html_string: str, expected_values: t.Union[str, t.List]):
  34. gui.add_page("test", Html(html_string, frame=None))
  35. Helpers._test_control(gui, expected_values)
  36. @staticmethod
  37. def test_control_builder(gui: Gui, builder_page, expected_values: t.Union[str, t.List]):
  38. gui.add_page("test", builder_page)
  39. Helpers._test_control(gui, expected_values)
  40. @staticmethod
  41. def _test_control(gui: Gui, expected_values: t.Union[str, t.List]):
  42. gui.run(run_server=False, single_client=True, stylekit=False)
  43. client = gui._server.test_client()
  44. response = client.get("/taipy-jsx/test")
  45. assert response.status_code == 200, f"response.status_code {response.status_code} != 200"
  46. response_data = json.loads(response.get_data().decode("utf-8", "ignore"))
  47. assert isinstance(response_data, t.Dict), "response_data is not Dict"
  48. assert "jsx" in response_data, "jsx not in response_data"
  49. jsx = response_data["jsx"]
  50. logging.getLogger().debug(jsx)
  51. if isinstance(expected_values, str):
  52. assert jsx == expected_values, f"{jsx} != {expected_values}"
  53. elif isinstance(expected_values, list):
  54. for expected_value in expected_values:
  55. assert expected_value in jsx, f"{expected_value} not in {jsx}"
  56. @staticmethod
  57. def assert_outward_ws_message(received_message, type, varname, value):
  58. assert isinstance(received_message, dict)
  59. assert "name" in received_message and received_message["name"] == "message"
  60. assert "args" in received_message
  61. args = received_message["args"]
  62. assert "type" in args and args["type"] == type
  63. assert "payload" in args
  64. payload_arr = args["payload"]
  65. found_payload = False
  66. for payload in payload_arr:
  67. if "name" in payload and varname in payload["name"]:
  68. assert "payload" in payload and "value" in payload["payload"] and payload["payload"]["value"] == value
  69. found_payload = True
  70. logging.getLogger().debug(payload["payload"]["value"])
  71. assert found_payload
  72. @staticmethod
  73. def assert_outward_simple_ws_message(received_message, type, varname, value):
  74. assert isinstance(received_message, dict)
  75. assert "name" in received_message and received_message["name"] == "message"
  76. assert "args" in received_message
  77. args = received_message["args"]
  78. assert "type" in args and args["type"] == type
  79. assert "name" in args and args["name"] == varname
  80. assert "payload" in args
  81. payload = args["payload"]
  82. assert "value" in payload and payload["value"] == value
  83. logging.getLogger().debug(payload["value"])
  84. @staticmethod
  85. def assert_outward_ws_simple_message(received_message, aType, values):
  86. assert isinstance(received_message, dict)
  87. assert "name" in received_message and received_message["name"] == "message"
  88. assert "args" in received_message
  89. args = received_message["args"]
  90. assert "type" in args and args["type"] == aType
  91. for k, v in values.items():
  92. assert k in args and args[k] == v
  93. logging.getLogger().debug(f"{k}: {args[k]}")
  94. @staticmethod
  95. def assert_outward_ws_multiple_message(received_message, type, array_len: int):
  96. assert isinstance(received_message, dict)
  97. assert "name" in received_message and received_message["name"] == "message"
  98. assert "args" in received_message
  99. args = received_message["args"]
  100. assert "type" in args and args["type"] == type
  101. assert "payload" in args
  102. payload = args["payload"]
  103. assert isinstance(payload, list)
  104. assert len(payload) == array_len
  105. logging.getLogger().debug(payload)
  106. @staticmethod
  107. def create_scope_and_get_sid(gui: Gui) -> str:
  108. sid = "test"
  109. gui._bindings()._get_or_create_scope(sid)
  110. return sid
  111. @staticmethod
  112. def port_check():
  113. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  114. s.settimeout(1)
  115. if s.connect_ex(("127.0.0.1", 5000)) == 0:
  116. s.close()
  117. return True
  118. else:
  119. s.close()
  120. return False
  121. @staticmethod
  122. def run_e2e(gui, **kwargs):
  123. kwargs["run_in_thread"] = True
  124. kwargs["single_client"] = True
  125. kwargs["run_browser"] = False
  126. kwargs["stylekit"] = kwargs.get("stylekit", False)
  127. with warnings.catch_warnings(record=True):
  128. gui.run(**kwargs)
  129. while not Helpers.port_check():
  130. time.sleep(0.1)
  131. @staticmethod
  132. def run_e2e_multi_client(gui: Gui):
  133. with warnings.catch_warnings(record=True):
  134. gui.run(run_server=False, run_browser=False, single_client=False, stylekit=False)
  135. gui._server.run(
  136. host=gui._get_config("host", "127.0.0.1"),
  137. port=gui._get_config("port", 5000),
  138. client_url=gui._get_config("client_url", "http://localhost:{port}"),
  139. debug=False,
  140. use_reloader=False,
  141. flask_log=False,
  142. run_in_thread=True,
  143. allow_unsafe_werkzeug=False,
  144. notebook_proxy=False,
  145. port_auto_ranges=gui._get_config("port_auto_ranges", None),
  146. )
  147. while not Helpers.port_check():
  148. time.sleep(0.1)
  149. @staticmethod
  150. def get_taipy_warnings(warns: t.List[warnings.WarningMessage]) -> t.List[warnings.WarningMessage]:
  151. return [w for w in warns if issubclass(w.category, TaipyGuiWarning)]