Sfoglia il codice sorgente

Fix JavaScript error caused by new `ui.notify` (#3457)

* fix `ui.notify`

* fix user tests involving notifications

* reset ui.notify during teardown
Falko Schindler 9 mesi fa
parent
commit
fca2b5503c

+ 3 - 2
nicegui/functions/notify.py

@@ -1,6 +1,6 @@
 from typing import Any, Literal, Optional, Union
 
-from ..elements.notification import Notification
+from ..context import context
 
 ARG_MAP = {
     'close_button': 'closeBtn',
@@ -49,4 +49,5 @@ def notify(message: Any, *,
     options = {ARG_MAP.get(key, key): value for key, value in locals().items() if key != 'kwargs' and value is not None}
     options['message'] = str(message)
     options.update(kwargs)
-    Notification(options=options)
+    client = context.client
+    client.outbox.enqueue_message('notify', options, client.id)

+ 1 - 0
nicegui/static/nicegui.js

@@ -358,6 +358,7 @@ function createApp(elements, options) {
           window.open(url, target);
         },
         download: (msg) => download(msg.src, msg.filename, msg.media_type, options.prefix),
+        notify: (msg) => Quasar.Notify.create(msg),
       };
       const socketMessageQueue = [];
       let isProcessingSocketMessage = false;

+ 3 - 0
nicegui/testing/plugin.py

@@ -14,6 +14,7 @@ from starlette.routing import Route
 import nicegui.storage
 from nicegui import Client, app, binding, core, run, ui
 from nicegui.functions.navigate import Navigate
+from nicegui.functions.notify import notify
 from nicegui.page import page
 
 from .screen import Screen
@@ -143,6 +144,7 @@ async def user(nicegui_reset_globals,  # pylint: disable=unused-argument
         async with httpx.AsyncClient(app=core.app, base_url='http://test') as client:
             yield User(client)
     ui.navigate = Navigate()
+    ui.notify = notify
 
 
 @pytest.fixture
@@ -155,6 +157,7 @@ async def create_user(nicegui_reset_globals,  # pylint: disable=unused-argument
     async with core.app.router.lifespan_context(core.app):
         yield lambda: User(httpx.AsyncClient(app=core.app, base_url='http://test'))
     ui.navigate = Navigate()
+    ui.notify = notify
 
 
 @pytest.fixture()

+ 8 - 5
nicegui/testing/user.py

@@ -2,7 +2,7 @@ from __future__ import annotations
 
 import asyncio
 import re
-from typing import List, Optional, Set, Type, TypeVar, Union, overload
+from typing import Any, List, Optional, Set, Type, TypeVar, Union, overload
 from uuid import uuid4
 
 import httpx
@@ -14,6 +14,7 @@ from nicegui.nicegui import _on_handshake
 
 from .user_interaction import UserInteraction
 from .user_navigate import UserNavigate
+from .user_notify import UserNotify
 
 # pylint: disable=protected-access
 
@@ -31,10 +32,12 @@ class User:
         self.back_history: List[str] = []
         self.forward_history: List[str] = []
         self.navigate = UserNavigate(self)
+        self.notify = UserNotify()
 
-    def __getattribute__(self, name: str) -> asyncio.Any:
-        if name != 'navigate':  # NOTE: avoid infinite recursion
+    def __getattribute__(self, name: str) -> Any:
+        if name not in {'notify', 'navigate'}:  # NOTE: avoid infinite recursion
             ui.navigate = self.navigate
+            ui.notify = self.notify
         return super().__getattribute__(name)
 
     async def open(self, path: str, *, clear_forward_history: bool = True) -> None:
@@ -91,7 +94,7 @@ class User:
         assert self.client
         for _ in range(retries):
             with self.client:
-                if self._gather_elements(target, kind, marker, content):
+                if self.notify.contains(target) or self._gather_elements(target, kind, marker, content):
                     return
                 await asyncio.sleep(0.1)
         raise AssertionError('expected to see at least one ' + self._build_error_message(target, kind, marker, content))
@@ -126,7 +129,7 @@ class User:
         assert self.client
         for _ in range(retries):
             with self.client:
-                if not self._gather_elements(target, kind, marker, content):
+                if not self.notify.contains(target) and not self._gather_elements(target, kind, marker, content):
                     return
                 await asyncio.sleep(0.05)
         raise AssertionError('expected not to see any ' + self._build_error_message(target, kind, marker, content))

+ 14 - 0
nicegui/testing/user_notify.py

@@ -0,0 +1,14 @@
+from typing import Any, List
+
+
+class UserNotify:
+
+    def __init__(self) -> None:
+        self.messages: List[str] = []
+
+    def __call__(self, message: str, **kwargs) -> None:
+        self.messages.append(message)
+
+    def contains(self, needle: Any) -> bool:
+        """Check if any of the messages contain the given substring."""
+        return isinstance(needle, str) and any(needle in message for message in self.messages)