Skip to content
Merged
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Fixed output controller `OutputDataFrame` in `shiny.playwright.controller` to correctly assert the number of rows in `.expect_nrow()` as the total number of virtual rows, not the number of currently displaying rows. (#1719)

* Fixed issue where `@render.download` did not respect the module namespacing. (Thanks, @nsiicm0) (#1732)
* Fixed issue where `@render.download` did not respect the module namespacing. (Thanks, @nsiicm0!) (#1732)

* Added workaround in `Accordion` in `shiny.playwright.controller` where `.expect_open()` and `.expect_panels()` would hang while resolving a playwright locator. (Thanks, @joesho112358!) (#1165)

## [1.1.0] - 2024-09-03

Expand Down
2 changes: 2 additions & 0 deletions shiny/playwright/controller/_accordion.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ def expect_open(
arr=value,
key="data-value",
timeout=timeout,
alt_verify=True,
)

def expect_panels(
Expand All @@ -281,6 +282,7 @@ def expect_panels(
arr=value,
key="data-value",
timeout=timeout,
alt_verify=True,
)

def set(
Expand Down
45 changes: 30 additions & 15 deletions shiny/playwright/controller/_expect.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ def expect_locator_values_in_list(
is_checked: bool | MISSING_TYPE = MISSING,
timeout: Timeout = None,
key: str = "value",
alt_verify: bool = False,
) -> None:
"""
Expect the locator to contain the values in the list.
Expand All @@ -171,6 +172,11 @@ def expect_locator_values_in_list(
The timeout for the expectation. Defaults to `None`.
key
The key. Defaults to `"value"`.
alt_verify
Determines if multiple expectations should be performed.
Defaults to `False`, a single (and very complicated) locator is asserted.
`True` will perform multiple assertions, which have the possibility of being invalid.
Use in playwright bug situations only.
"""
# Make sure the locator has exactly `arr` values

Expand All @@ -195,6 +201,28 @@ def expect_locator_values_in_list(
return
loc_container_orig = loc_container

def perform_multiple_assertions():
# Expecting container to exist (count = 1)
playwright_expect(loc_container_orig).to_have_count(1, timeout=timeout)

# Expecting the container to contain {len(arr)} items
playwright_expect(loc_container_orig.locator(loc_item)).to_have_count(
len(arr), timeout=timeout
)

for item, i in zip(arr, range(len(arr))):
# Expecting item `{i}` to be `{item}`
playwright_expect(
loc_container_orig.locator(loc_item).nth(i)
).to_have_attribute(key, item, timeout=timeout)
return

if alt_verify:
# Accordion has issues where the single locator assertion waits forever within playwright.
# Perform multiple assertions until playwright fixes bug.
perform_multiple_assertions()
return

# Find all items in set
for item, i in zip(arr, range(len(arr))):
# Get all elements of type
Expand All @@ -220,21 +248,8 @@ def expect_locator_values_in_list(
try:
playwright_expect(loc_inputs).to_have_count(len(arr), timeout=timeout)
except AssertionError as e:
# Debug expections

# Expecting container to exist (count = 1)
playwright_expect(loc_container_orig).to_have_count(1, timeout=timeout)

# Expecting the container to contain {len(arr)} items
playwright_expect(loc_container_orig.locator(loc_item)).to_have_count(
len(arr), timeout=timeout
)

for item, i in zip(arr, range(len(arr))):
# Expecting item `{i}` to be `{item}`
playwright_expect(
loc_container_orig.locator(loc_item).nth(i)
).to_have_attribute(key, item, timeout=timeout)
# Debug expectations
perform_multiple_assertions()

# Could not find the reason why. Raising the original error.
raise e
17 changes: 13 additions & 4 deletions shiny/render/_data_frame_utils/_tbl_data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Any, List, TypedDict, cast
from typing import TYPE_CHECKING, Any, List, TypedDict, cast

import narwhals.stable.v1 as nw
import orjson
Expand Down Expand Up @@ -33,6 +33,9 @@
"subset_frame",
)

if TYPE_CHECKING:
import pandas as pd

########################################################################################
# Narwhals
#
Expand Down Expand Up @@ -81,15 +84,20 @@ def as_data_frame(
except TypeError as e:
try:
compatible_data = compatible_to_pandas(data)
return nw.from_native(compatible_data, eager_only=True)
ret: DataFrame[pd.DataFrame] = nw.from_native(
compatible_data, eager_only=True
)
# Cast internal data as `IntoDataFrameT` type.
# A warning has already been given to the user, so this is tolerable.
return cast(DataFrame[IntoDataFrameT], ret)
except TypeError:
# Couldn't convert to pandas, so raise the original error
raise e


def compatible_to_pandas(
data: IntoDataFrameT,
) -> IntoDataFrameT:
data: IntoDataFrame,
) -> pd.DataFrame:
"""
Convert data to pandas, if possible.

Expand All @@ -108,6 +116,7 @@ def compatible_to_pandas(
stacklevel=3,
)
return data.to_pandas()
# pyright: ignore[reportReturnType]

raise TypeError(f"Unsupported data type: {type(data)}")

Expand Down
7 changes: 2 additions & 5 deletions tests/playwright/shiny/components/accordion/test_accordion.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,6 @@ def test_accordion(page: Page, local_app: ShinyAppProc) -> None:
"input.acc(): ('updated_section_a', 'Section C', 'Section D')"
)

# TODO-karan-future; Remove return when test is able to pass. Currently it hangs indefinitely and no notification as to why.
return

toggle_efg_button.click()
acc.expect_panels(
[
Expand All @@ -92,7 +89,7 @@ def test_accordion(page: Page, local_app: ShinyAppProc) -> None:
"Section E",
"Section F",
"Section G",
]
],
)
acc.expect_open(
[
Expand All @@ -102,7 +99,7 @@ def test_accordion(page: Page, local_app: ShinyAppProc) -> None:
"Section E",
"Section F",
"Section G",
]
],
)
# Should be uncommented once https://github.com/rstudio/bslib/issues/565 is fixed
# output_txt_verbatim.expect_value(
Expand Down
Loading