Skip to content

Commit

Permalink
Use ui.notification for ui.notify to simplify user simulation tests (#…
Browse files Browse the repository at this point in the history
…3369)

* use ui.notification for ui.notify to simplify user simulation tests

* code review

---------

Co-authored-by: Falko Schindler <falko@zauberzeug.com>
  • Loading branch information
rodja and falkoschindler committed Jul 18, 2024
1 parent d6c31c7 commit 8b519dc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 28 deletions.
1 change: 1 addition & 0 deletions nicegui/element_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def _iterate(self, parent: Element, *, visited: Optional[List[Element]] = None)
(element.source if isinstance(element, SourceElement) else ''),
element._props.get('placeholder', ''),
(element._props.get('value', '') or ''), # NOTE the value could be None
element._props.get('options', {}).get('message', ''),
]
content = ' '.join(str(c) for c in element_contents)

Expand Down
41 changes: 23 additions & 18 deletions nicegui/elements/notification.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import asyncio
from typing import Any, Callable, Literal, Optional, Union
from typing import Any, Callable, Dict, Literal, Optional, Union

from typing_extensions import Self

Expand Down Expand Up @@ -41,6 +41,7 @@ def __init__(self,
spinner: bool = False,
timeout: Optional[float] = 5.0,
on_dismiss: Optional[Callable] = None,
options: Optional[Dict] = None,
**kwargs: Any,
) -> None:
"""Notification element
Expand All @@ -59,28 +60,32 @@ def __init__(self,
:param spinner: display a spinner in the notification (default: False)
:param timeout: optional timeout in seconds after which the notification is dismissed (default: 5.0)
:param on_dismiss: optional callback to be invoked when the notification is dismissed
:param options: optional dictionary with all options (overrides all other arguments)
Note: You can pass additional keyword arguments according to `Quasar's Notify API <https://quasar.dev/quasar-plugins/notify#notify-api>`_.
"""
with context.client.layout:
super().__init__()
self._props['options'] = {
'message': str(message),
'position': position,
'multiLine': multi_line,
'spinner': spinner,
'closeBtn': close_button,
'timeout': (timeout or 0) * 1000,
'group': False,
'attrs': {'data-id': f'nicegui-dialog-{self.id}'},
}
if type is not None:
self._props['options']['type'] = type
if color is not None:
self._props['options']['color'] = color
if icon is not None:
self._props['options']['icon'] = icon
self._props['options'].update(kwargs)
if options:
self._props['options'] = options
else:
self._props['options'] = {
'message': str(message),
'position': position,
'multiLine': multi_line,
'spinner': spinner,
'closeBtn': close_button,
'timeout': (timeout or 0) * 1000,
'group': False,
'attrs': {'data-id': f'nicegui-dialog-{self.id}'},
}
if type is not None:
self._props['options']['type'] = type
if color is not None:
self._props['options']['color'] = color
if icon is not None:
self._props['options']['icon'] = icon
self._props['options'].update(kwargs)

if on_dismiss:
self.on_dismiss(on_dismiss)
Expand Down
5 changes: 2 additions & 3 deletions nicegui/functions/notify.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import Any, Literal, Optional, Union

from ..context import context
from ..elements.notification import Notification

ARG_MAP = {
'close_button': 'closeBtn',
Expand Down Expand Up @@ -49,5 +49,4 @@ 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)
client = context.client
client.outbox.enqueue_message('notify', options, client.id)
Notification(options=options)
1 change: 0 additions & 1 deletion nicegui/static/nicegui.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ 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;
Expand Down
7 changes: 1 addition & 6 deletions nicegui/testing/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import socketio
from typing_extensions import Self

from nicegui import Client, ElementFilter, background_tasks, context, ui
from nicegui import Client, ElementFilter, background_tasks, ui
from nicegui.element import Element
from nicegui.logging import log
from nicegui.nicegui import Slot, _on_handshake
Expand Down Expand Up @@ -95,11 +95,6 @@ async def should_see(self,
with self.client:
if self._gather_elements(target, kind, marker, content):
return
if isinstance(target, str):
content = target
for _, message_type, message_data in context.client.outbox.messages:
if content is not None and message_type == 'notify' and content in message_data['message']:
return
await asyncio.sleep(0.1)
raise AssertionError('expected to see at least one ' + self._build_error_message(target, kind, marker, content))

Expand Down
15 changes: 15 additions & 0 deletions tests/test_user_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@ def page():
await user.should_see('Hello')


async def test_should_not_see_notification(user: User) -> None:
@ui.page('/')
def page():
ui.button('Notify', on_click=lambda: ui.notification('Hello'))

await user.open('/')
await user.should_not_see('Hello')
user.find('Notify').click()
await user.should_see('Hello')
with pytest.raises(AssertionError):
await user.should_not_see('Hello')
user.find('Hello').trigger('dismiss')
await user.should_not_see('Hello')


async def test_trigger_event(user: User) -> None:
@ui.page('/')
def page():
Expand Down

0 comments on commit 8b519dc

Please sign in to comment.