Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test input task button and extended task decorator #1099

Merged
merged 26 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5d4b87b
add test for input task button
karangattu Jan 30, 2024
5dbb53b
Merge branch 'main' into test-extended-task
karangattu Feb 1, 2024
1493f2a
Verify the sum calculation takes place
karangattu Feb 1, 2024
53c19ea
Refactor test to reduce sleep times
karangattu Feb 1, 2024
df9266b
fix pyright issues
karangattu Feb 1, 2024
35ea991
linting issues
karangattu Feb 1, 2024
211bb70
remove comments
karangattu Feb 1, 2024
b21fc34
fix pyright issues
karangattu Feb 1, 2024
712812d
see if this import fixes pyright error
karangattu Feb 1, 2024
5ac19b4
imports are incorrectly sorted
karangattu Feb 1, 2024
80f3e00
Update shiny/api-examples/extended_task/app-core.py
karangattu Feb 2, 2024
1514d7f
Update shiny/api-examples/extended_task/app-core.py
karangattu Feb 2, 2024
a428c32
Update shiny/api-examples/extended_task/app-core.py
karangattu Feb 2, 2024
6588eef
Update shiny/api-examples/extended_task/app-core.py
karangattu Feb 2, 2024
59a5d68
Update tests/playwright/shiny/inputs/input_task_button/test_input_tas…
karangattu Feb 2, 2024
47e5848
Update tests/playwright/shiny/inputs/input_task_button/test_input_tas…
karangattu Feb 2, 2024
ab5f9b4
Update tests/playwright/shiny/inputs/input_task_button/test_input_tas…
karangattu Feb 2, 2024
bc677da
Update tests/playwright/shiny/inputs/input_task_button/test_input_tas…
karangattu Feb 2, 2024
68fcc61
Update tests/playwright/shiny/inputs/input_task_button/test_input_tas…
karangattu Feb 2, 2024
6219c16
revert changes to app.py in examples
karangattu Feb 2, 2024
a385751
change the id of button to btn_block
karangattu Feb 2, 2024
538641c
Merge branch 'main' into test-extended-task
karangattu Feb 2, 2024
b55df77
Mark accordion test as flaky
karangattu Feb 2, 2024
389c64a
Update tests/playwright/controls.py
karangattu Feb 2, 2024
e286906
Change the name of the task buttons
karangattu Feb 2, 2024
0bcea66
Linting errors
karangattu Feb 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions shiny/api-examples/extended_task/app-core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,18 @@ async def slow_compute(a: int, b: int) -> int:
return a + b

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move these testing changes to a local test app, rather than updating the api-examples.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for suggesting the updates here and not in the local test app. (This file should not be changed in the PR.)


# @ui.bind_task_button(button_id="btn2")
karangattu marked this conversation as resolved.
Show resolved Hide resolved
async def slow_input_compute(a: int, b: int) -> int:
karangattu marked this conversation as resolved.
Show resolved Hide resolved
await asyncio.sleep(3)
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", "Compute, slowly")
karangattu marked this conversation as resolved.
Show resolved Hide resolved
ui.input_task_button("btn2", "Compute 2 slowly")
karangattu marked this conversation as resolved.
Show resolved Hide resolved
ui.input_action_button("btn_cancel", "Cancel")

@reactive.Effect
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@reactive.Effect
@reactive.effect

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not suggest a change on the next line to update input.btn to input.btn_task

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can not suggest a change to rename handle_click() to handle_task_click()

Expand All @@ -37,6 +44,13 @@ def handle_click():
# slow_compute.cancel()
slow_compute(input.x(), input.y())

@reactive.Effect
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@reactive.Effect
@reactive.effect

@reactive.event(input.btn2, ignore_none=False)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@reactive.event(input.btn2, ignore_none=False)
@reactive.event(input.btn_block, ignore_none=False)

async def handle_click2():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
async def handle_click2():
async def handle_block_click():

# slow_compute.cancel()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# slow_compute.cancel()

val = await slow_input_compute(input.x(), input.y())
print(val)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print(val)


@reactive.Effect
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@reactive.Effect
@reactive.effect

@reactive.event(input.btn_cancel)
def handle_cancel():
Expand Down
42 changes: 42 additions & 0 deletions tests/playwright/controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,45 @@ def __init__(
)


class InputTaskButton(
_WidthLocM,
_InputActionBase,
):
# id: str,
# label: TagChild,
# *args: TagChild,
# icon: TagChild = None,
schloerke marked this conversation as resolved.
Show resolved Hide resolved
# label_busy: TagChild = "Processing...",
# icon_busy: TagChild | MISSING_TYPE = MISSING,
# width: Optional[str] = None,
# type: Optional[str] = "primary",
# auto_reset: bool = True,
schloerke marked this conversation as resolved.
Show resolved Hide resolved
# **kwargs: TagAttrValue,
def __init__(
self,
page: Page,
id: str,
) -> None:
super().__init__(
page,
id=id,
loc=f"button#{id}.bslib-task-button.shiny-bound-input",
)

def expect_state(self, state: str, *, timeout: Timeout = None):
expect_attr(
self.loc.locator("> bslib-switch-inline"),
name="case",
value=state,
timeout=timeout,
)

def expect_label_text(self, value: list[str], *, timeout: Timeout = None):
karangattu marked this conversation as resolved.
Show resolved Hide resolved
playwright_expect(
self.loc.locator("> bslib-switch-inline > span")
).to_have_text(value, timeout=timeout)


class InputActionLink(_InputActionBase):
# label: TagChild,
# icon: TagChild = None,
Expand Down Expand Up @@ -2169,6 +2208,9 @@ def __init__(
) -> None:
super().__init__(page, id=id, loc=f"#{id}.shiny-text-output")

def get_value(self, *, timeout: Timeout = None) -> str:
return self.loc.inner_text(timeout=timeout)


class OutputCode(_OutputTextValue):
def __init__(self, page: Page, id: str) -> None:
Expand Down
62 changes: 62 additions & 0 deletions tests/playwright/shiny/inputs/input_task_button/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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")
@reactive.extended_task
async def slow_compute(a: int, b: int) -> int:
await asyncio.sleep(3)
return a + b


# @ui.bind_task_button(button_id="btn2")
async def slow_input_compute(a: int, b: int) -> int:
await asyncio.sleep(3)
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", "Compute, slowly")
ui.input_task_button("btn2", "Compute 2 slowly", label_busy="Blocking...")
ui.input_action_button("btn_cancel", "Cancel")

@reactive.Effect
@reactive.event(input.btn, ignore_none=False)
def handle_click():
# slow_compute.cancel()
slow_compute(input.x(), input.y())

@reactive.Effect
@reactive.event(input.btn2, 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())
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from __future__ import annotations

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,
button_label: list[str],
) -> str:
button.expect_state("ready")
button.expect_label_text(button_label)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this out of the function and have it live in the test code directly. (It is unrelated to clicking the button)

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")
current_time.expect.not_to_be_empty()
karangattu marked this conversation as resolved.
Show resolved Hide resolved

result.expect_value("3")
karangattu marked this conversation as resolved.
Show resolved Hide resolved

# extended task
button1 = InputTaskButton(page, "btn")
time1 = click_extended_task_button(
button1, current_time, button_label=["Compute, slowly", "\n \n Processing..."]
)
current_time.expect.not_to_have_text(time1, timeout=500)
karangattu marked this conversation as resolved.
Show resolved Hide resolved

result.expect_value("3", timeout=0)
result.expect_value("5", timeout=(3 + 1) * 1000)
y.set("15")
result.expect_value("5")
karangattu marked this conversation as resolved.
Show resolved Hide resolved

# extended task with blocking
button2 = InputTaskButton(page, "btn2")
time2 = click_extended_task_button(
button2, current_time, button_label=["Compute 2 slowly", "\n \n Blocking..."]
)
current_time.expect_value(time2, timeout=0)
karangattu marked this conversation as resolved.
Show resolved Hide resolved
Loading