-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test input task button and extended task decorator (#1099)
Co-authored-by: Barret Schloerke <barret@posit.co>
- Loading branch information
1 parent
a3389df
commit 6f4bf63
Showing
4 changed files
with
214 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
tests/playwright/shiny/components/accordion/test_accordion.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import asyncio | ||
from datetime import datetime | ||
|
||
from shiny import reactive, render | ||
from shiny.express import input, ui | ||
|
||
ui.h5("Current time") | ||
|
||
|
||
@render.text() | ||
def current_time() -> str: | ||
reactive.invalidate_later(0.1) | ||
return str(datetime.now().utcnow()) | ||
|
||
|
||
with ui.p(): | ||
"Notice that the time above updates every second, even if you click the button below." | ||
|
||
|
||
@ui.bind_task_button(button_id="btn_task") | ||
@reactive.extended_task | ||
async def slow_compute(a: int, b: int) -> int: | ||
await asyncio.sleep(1.5) | ||
return a + b | ||
|
||
|
||
async def slow_input_compute(a: int, b: int) -> int: | ||
await asyncio.sleep(1.5) | ||
return a + b | ||
|
||
|
||
with ui.layout_sidebar(): | ||
with ui.sidebar(): | ||
ui.input_numeric("x", "x", 1) | ||
ui.input_numeric("y", "y", 2) | ||
ui.input_task_button("btn_task", "Non-blocking task") | ||
ui.input_task_button("btn_block", "Block compute", label_busy="Blocking...") | ||
ui.input_action_button("btn_cancel", "Cancel") | ||
|
||
@reactive.Effect | ||
@reactive.event(input.btn_task, ignore_none=False) | ||
def handle_click(): | ||
# slow_compute.cancel() | ||
slow_compute(input.x(), input.y()) | ||
|
||
@reactive.Effect | ||
@reactive.event(input.btn_block, ignore_none=False) | ||
async def handle_click2(): | ||
# slow_compute.cancel() | ||
await slow_input_compute(input.x(), input.y()) | ||
|
||
@reactive.Effect | ||
@reactive.event(input.btn_cancel) | ||
def handle_cancel(): | ||
slow_compute.cancel() | ||
|
||
ui.h5("Sum of x and y") | ||
|
||
@render.text | ||
def show_result(): | ||
return str(slow_compute.result()) |
63 changes: 63 additions & 0 deletions
63
tests/playwright/shiny/inputs/input_task_button/test_input_task_button.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
from __future__ import annotations | ||
|
||
import time | ||
|
||
from conftest import ShinyAppProc | ||
from controls import InputNumeric, InputTaskButton, OutputText | ||
from playwright.sync_api import Page | ||
|
||
|
||
def click_extended_task_button( | ||
button: InputTaskButton, | ||
current_time: OutputText, | ||
) -> str: | ||
button.expect_state("ready") | ||
button.click(timeout=0) | ||
button.expect_state("busy", timeout=0) | ||
return current_time.get_value(timeout=0) | ||
|
||
|
||
def test_input_action_task_button(page: Page, local_app: ShinyAppProc) -> None: | ||
page.goto(local_app.url) | ||
y = InputNumeric(page, "y") | ||
y.set("4") | ||
result = OutputText(page, "show_result") | ||
current_time = OutputText(page, "current_time") | ||
# Make sure the time has content | ||
current_time.expect.not_to_be_empty() | ||
|
||
# Wait until shiny is stable | ||
result.expect_value("3") | ||
|
||
# Extended task | ||
button_task = InputTaskButton(page, "btn_task") | ||
button_task.expect_label_busy("\n \n Processing...") | ||
button_task.expect_label_ready("Non-blocking task") | ||
button_task.expect_auto_reset(True) | ||
# Click button and collect the current time from the app | ||
time1 = click_extended_task_button( | ||
button_task, | ||
current_time, | ||
) | ||
# Make sure time value updates (before the calculation finishes | ||
current_time.expect.not_to_have_text(time1, timeout=500) | ||
result.expect_value("3", timeout=0) | ||
# After the calculation time plus a buffer, make sure the calculation finishes | ||
result.expect_value("5", timeout=(1.5 + 1) * 1000) | ||
|
||
# set up Blocking test | ||
y.set("15") | ||
result.expect_value("5") | ||
|
||
# Blocking verification | ||
button_block = InputTaskButton(page, "btn_block") | ||
button_block.expect_label_busy("\n \n Blocking...") | ||
button_block.expect_label_ready("Block compute") | ||
button_block.expect_auto_reset(True) | ||
time_block = click_extended_task_button( | ||
button_block, | ||
current_time, | ||
) | ||
# Make sure time value has not changed after 500ms has ellapsed | ||
time.sleep(0.5) | ||
current_time.expect_value(time_block, timeout=0) |