Преглед на файлове

Always treat the call_script callback as a string of JS code (#3521)

Masen Furer преди 11 месеца
родител
ревизия
c2c6286537
променени са 2 файла, в които са добавени 36 реда и са изтрити 26 реда
  1. 30 22
      integration/test_call_script.py
  2. 6 4
      reflex/event.py

+ 30 - 22
integration/test_call_script.py

@@ -10,6 +10,8 @@ from selenium.webdriver.remote.webdriver import WebDriver
 
 from reflex.testing import AppHarness
 
+from .utils import SessionStorage
+
 
 def CallScript():
     """A test app for browser javascript integration."""
@@ -43,6 +45,7 @@ def CallScript():
         results: List[Optional[Union[str, Dict, List]]] = []
         inline_counter: int = 0
         external_counter: int = 0
+        value: str = "Initial"
 
         def call_script_callback(self, result):
             self.results.append(result)
@@ -145,25 +148,20 @@ def CallScript():
     @app.add_page
     def index():
         return rx.vstack(
-            rx.chakra.input(
-                value=CallScriptState.router.session.client_token,
-                is_read_only=True,
-                id="token",
-            ),
-            rx.chakra.input(
+            rx.input(
                 value=CallScriptState.inline_counter.to(str),  # type: ignore
                 id="inline_counter",
-                is_read_only=True,
+                read_only=True,
             ),
-            rx.chakra.input(
+            rx.input(
                 value=CallScriptState.external_counter.to(str),  # type: ignore
                 id="external_counter",
-                is_read_only=True,
+                read_only=True,
             ),
             rx.text_area(
                 value=CallScriptState.results.to_string(),  # type: ignore
                 id="results",
-                is_read_only=True,
+                read_only=True,
             ),
             rx.script(inline_scripts),
             rx.script(src="/external.js"),
@@ -227,6 +225,14 @@ def CallScript():
                 on_click=CallScriptState.get_external_counter,
                 id="update_external_counter",
             ),
+            rx.button(
+                CallScriptState.value,
+                on_click=rx.call_script(
+                    "'updated'",
+                    callback=CallScriptState.set_value,  # type: ignore
+                ),
+                id="update_value",
+            ),
             rx.button("Reset", id="reset", on_click=CallScriptState.reset_),
         )
 
@@ -266,25 +272,18 @@ def driver(call_script: AppHarness) -> Generator[WebDriver, None, None]:
         driver.quit()
 
 
-def assert_token(call_script: AppHarness, driver: WebDriver) -> str:
+def assert_token(driver: WebDriver) -> str:
     """Get the token associated with backend state.
 
     Args:
-        call_script: harness for CallScript app.
         driver: WebDriver instance.
 
     Returns:
         The token visible in the driver browser.
     """
-    assert call_script.app_instance is not None
-    token_input = driver.find_element(By.ID, "token")
-    assert token_input
-
-    # wait for the backend connection to send the token
-    token = call_script.poll_for_value(token_input)
-    assert token is not None
-
-    return token
+    ss = SessionStorage(driver)
+    assert AppHarness._poll_for(lambda: ss.get("token") is not None), "token not found"
+    return ss.get("token")
 
 
 @pytest.mark.parametrize("script", ["inline", "external"])
@@ -300,7 +299,7 @@ def test_call_script(
         driver: WebDriver instance.
         script: The type of script to test.
     """
-    assert_token(call_script, driver)
+    assert_token(driver)
     reset_button = driver.find_element(By.ID, "reset")
     update_counter_button = driver.find_element(By.ID, f"update_{script}_counter")
     counter = driver.find_element(By.ID, f"{script}_counter")
@@ -355,3 +354,12 @@ def test_call_script(
     )
     reset_button.click()
     assert call_script.poll_for_value(counter, exp_not_equal="1") == "0"
+
+    # Check that triggering script from event trigger calls callback
+    update_value_button = driver.find_element(By.ID, "update_value")
+    update_value_button.click()
+
+    assert (
+        call_script.poll_for_content(update_value_button, exp_not_equal="Initial")
+        == "updated"
+    )

+ 6 - 4
reflex/event.py

@@ -766,10 +766,12 @@ def call_script(
     callback_kwargs = {}
     if callback is not None:
         callback_kwargs = {
-            "callback": format.format_queue_events(
-                callback,
-                args_spec=lambda result: [result],
-            )
+            "callback": str(
+                format.format_queue_events(
+                    callback,
+                    args_spec=lambda result: [result],
+                ),
+            ),
         }
     return server_side(
         "_call_script",