From 44ac4dc0681517b1e473175aa4b09f758f62642b Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Tue, 18 Jul 2023 20:49:07 -0700 Subject: [PATCH 1/6] Add E2E test for sidebar component --- e2e/conftest.py | 7 ++++++ e2e/controls.py | 40 ++++++++++++++++++++++++++++++++ e2e/experimental/test_sidebar.py | 18 ++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 e2e/experimental/test_sidebar.py diff --git a/e2e/conftest.py b/e2e/conftest.py index 12c2f99b2..4c03b863f 100644 --- a/e2e/conftest.py +++ b/e2e/conftest.py @@ -200,6 +200,13 @@ def create_doc_example_fixture(example_name: str, scope: str = "module"): ) +def x_create_doc_example_fixture(example_name: str, scope: str = "module"): + """Used to create app fixtures from apps in py-shiny/shiny/examples""" + return create_app_fixture( + here / "../shiny/experimental/api-examples" / example_name / "app.py", scope + ) + + @pytest.fixture(scope="module") def local_app(request: pytest.FixtureRequest) -> Generator[ShinyAppProc, None, None]: sa = run_shiny_app(PurePath(request.path).parent / "app.py", wait_for_start=False) diff --git a/e2e/controls.py b/e2e/controls.py index 4091bf4bf..0798981cb 100644 --- a/e2e/controls.py +++ b/e2e/controls.py @@ -2336,3 +2336,43 @@ def expect_n_row( n, timeout=timeout, ) + + +class Sidebar( + _WidthLocM, + _InputWithContainer, +): + # *args: TagChild | TagAttrs, + # width: CssUnit = 250, + # position: Literal["left", "right"] = "left", + # open: Literal["desktop", "open", "closed", "always"] = "desktop", + # id: Optional[str] = None, + # title: TagChild | str = None, + # bg: Optional[str] = None, + # fg: Optional[str] = None, + # class_: Optional[str] = None, # TODO-future; Consider using `**kwargs` instead + # max_height_mobile: Optional[str | float] = None, + def __init__(self, page: Page, id: str) -> None: + super().__init__( + page, + id=id, + loc=f"> div#{id}", + loc_container="div.bslib-sidebar-layout", + ) + + self.loc_toggle = self.loc.locator("..").locator("button.collapse-toggle") + self.loc_toggle_true = self.loc.locator("..").locator( + "button.collapse-toggle[aria-expanded='true']" + ) + self.loc_toggle_false = self.loc.locator("..").locator( + "button.collapse-toggle[aria-expanded='false']" + ) + + def expect_toggle_button(self, open: bool, *, timeout: Timeout = None) -> None: + playwright_expect(self.loc_toggle).to_have_count(int(open), timeout=timeout) + + def expect_toggle_to_be_true(self, *, timeout: Timeout = None) -> None: + playwright_expect(self.loc_toggle_true).to_have_count(1, timeout=timeout) + + def expect_toggle_to_be_false(self, *, timeout: Timeout = None) -> None: + playwright_expect(self.loc_toggle_false).to_have_count(1, timeout=timeout) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py new file mode 100644 index 000000000..143a1224d --- /dev/null +++ b/e2e/experimental/test_sidebar.py @@ -0,0 +1,18 @@ +from conftest import ShinyAppProc, x_create_doc_example_fixture +from controls import OutputTextVerbatim, Sidebar +from playwright.sync_api import Page + +app = x_create_doc_example_fixture("sidebar") + + +def test_autoresize(page: Page, app: ShinyAppProc) -> None: + page.goto(app.url) + + left_sidebar = Sidebar(page, "sidebar_left") + output_txt_left = OutputTextVerbatim(page, "state_left") + output_txt_left.expect_value("input.sidebar_left(): True") + left_sidebar.expect_toggle_button(True) + left_sidebar.expect_toggle_to_be_true() + left_sidebar.loc_toggle.click() + left_sidebar.expect_toggle_to_be_false() + output_txt_left.expect_value("input.sidebar_left(): False") From 9219b84d2bb0619bc9cf67a3bbecccb7804c517b Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Wed, 19 Jul 2023 22:32:33 -0700 Subject: [PATCH 2/6] Add sidebar tests --- e2e/experimental/test_sidebar.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py index 143a1224d..0505dd583 100644 --- a/e2e/experimental/test_sidebar.py +++ b/e2e/experimental/test_sidebar.py @@ -16,3 +16,28 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: left_sidebar.loc_toggle.click() left_sidebar.expect_toggle_to_be_false() output_txt_left.expect_value("input.sidebar_left(): False") + + right_sidebar = Sidebar(page, "sidebar_right") + output_txt_right = OutputTextVerbatim(page, "state_right") + output_txt_right.expect_value("input.sidebar_right(): True") + right_sidebar.expect_toggle_button(True) + right_sidebar.expect_toggle_to_be_true() + right_sidebar.loc_toggle.click() + right_sidebar.expect_toggle_to_be_false() + output_txt_right.expect_value("input.sidebar_right(): False") + + closed_sidebar = Sidebar(page, "sidebar_closed") + output_txt_closed = OutputTextVerbatim(page, "state_closed") + output_txt_closed.expect_value("input.sidebar_closed(): False") + closed_sidebar.expect_toggle_button(True) + closed_sidebar.expect_toggle_to_be_false() + closed_sidebar.loc_toggle.click() + closed_sidebar.expect_toggle_to_be_true() + output_txt_closed.expect_value("input.sidebar_closed(): True") + + always_sidebar = Sidebar(page, "sidebar_always") + output_txt_always = OutputTextVerbatim(page, "state_always") + output_txt_always.expect_value("input.sidebar_always(): False") + always_sidebar.expect_toggle_button(False) + + From 947c0eb349ecc2563fe5cadd04fcfb031a4cbfb7 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Wed, 19 Jul 2023 22:37:50 -0700 Subject: [PATCH 3/6] add more tests --- e2e/controls.py | 3 +++ e2e/experimental/test_sidebar.py | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/e2e/controls.py b/e2e/controls.py index 0798981cb..b8254bc84 100644 --- a/e2e/controls.py +++ b/e2e/controls.py @@ -2368,6 +2368,9 @@ def __init__(self, page: Page, id: str) -> None: "button.collapse-toggle[aria-expanded='false']" ) + def expect_sidebar(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: + playwright_expect(self.loc).to_have_text(value, timeout=timeout) + def expect_toggle_button(self, open: bool, *, timeout: Timeout = None) -> None: playwright_expect(self.loc_toggle).to_have_count(int(open), timeout=timeout) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py index 0505dd583..9e2154891 100644 --- a/e2e/experimental/test_sidebar.py +++ b/e2e/experimental/test_sidebar.py @@ -10,6 +10,7 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: left_sidebar = Sidebar(page, "sidebar_left") output_txt_left = OutputTextVerbatim(page, "state_left") + left_sidebar.expect_sidebar("Left sidebar content") output_txt_left.expect_value("input.sidebar_left(): True") left_sidebar.expect_toggle_button(True) left_sidebar.expect_toggle_to_be_true() @@ -19,6 +20,7 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: right_sidebar = Sidebar(page, "sidebar_right") output_txt_right = OutputTextVerbatim(page, "state_right") + right_sidebar.expect_sidebar("Right sidebar content") output_txt_right.expect_value("input.sidebar_right(): True") right_sidebar.expect_toggle_button(True) right_sidebar.expect_toggle_to_be_true() @@ -32,12 +34,12 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: closed_sidebar.expect_toggle_button(True) closed_sidebar.expect_toggle_to_be_false() closed_sidebar.loc_toggle.click() + closed_sidebar.expect_sidebar("Closed sidebar content") closed_sidebar.expect_toggle_to_be_true() output_txt_closed.expect_value("input.sidebar_closed(): True") always_sidebar = Sidebar(page, "sidebar_always") output_txt_always = OutputTextVerbatim(page, "state_always") + always_sidebar.expect_sidebar("Always sidebar content") output_txt_always.expect_value("input.sidebar_always(): False") always_sidebar.expect_toggle_button(False) - - From 2f2f7a0d8e473fd9c9f16518100a4a5883ec39c5 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Thu, 20 Jul 2023 10:04:08 -0700 Subject: [PATCH 4/6] modify functions --- e2e/controls.py | 21 ++++++++------------- e2e/experimental/test_sidebar.py | 29 +++++++++++++++-------------- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/e2e/controls.py b/e2e/controls.py index b8254bc84..2ab7e71e2 100644 --- a/e2e/controls.py +++ b/e2e/controls.py @@ -2361,21 +2361,16 @@ def __init__(self, page: Page, id: str) -> None: ) self.loc_toggle = self.loc.locator("..").locator("button.collapse-toggle") - self.loc_toggle_true = self.loc.locator("..").locator( - "button.collapse-toggle[aria-expanded='true']" - ) - self.loc_toggle_false = self.loc.locator("..").locator( - "button.collapse-toggle[aria-expanded='false']" - ) - def expect_sidebar(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: + def expect_title(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: playwright_expect(self.loc).to_have_text(value, timeout=timeout) - def expect_toggle_button(self, open: bool, *, timeout: Timeout = None) -> None: + def expect_toggle(self, open: bool, *, timeout: Timeout = None) -> None: playwright_expect(self.loc_toggle).to_have_count(int(open), timeout=timeout) - def expect_toggle_to_be_true(self, *, timeout: Timeout = None) -> None: - playwright_expect(self.loc_toggle_true).to_have_count(1, timeout=timeout) - - def expect_toggle_to_be_false(self, *, timeout: Timeout = None) -> None: - playwright_expect(self.loc_toggle_false).to_have_count(1, timeout=timeout) + def expect_toggle_expanded(self, open: bool, *, timeout: Timeout = None) -> None: + playwright_expect( + self.loc.locator("..").locator( + f"button.collapse-toggle[aria-expanded='{str(open).lower()}']" + ) + ).to_have_count(int(open), timeout=timeout) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py index 9e2154891..8b2c4b221 100644 --- a/e2e/experimental/test_sidebar.py +++ b/e2e/experimental/test_sidebar.py @@ -10,36 +10,37 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: left_sidebar = Sidebar(page, "sidebar_left") output_txt_left = OutputTextVerbatim(page, "state_left") - left_sidebar.expect_sidebar("Left sidebar content") + left_sidebar.expect_title("Left sidebar content") output_txt_left.expect_value("input.sidebar_left(): True") - left_sidebar.expect_toggle_button(True) - left_sidebar.expect_toggle_to_be_true() + left_sidebar.expect_toggle(True) + left_sidebar.expect_toggle_expanded(True) left_sidebar.loc_toggle.click() - left_sidebar.expect_toggle_to_be_false() + left_sidebar.expect_toggle_expanded(False) output_txt_left.expect_value("input.sidebar_left(): False") right_sidebar = Sidebar(page, "sidebar_right") output_txt_right = OutputTextVerbatim(page, "state_right") - right_sidebar.expect_sidebar("Right sidebar content") + right_sidebar.expect_title("Right sidebar content") output_txt_right.expect_value("input.sidebar_right(): True") - right_sidebar.expect_toggle_button(True) - right_sidebar.expect_toggle_to_be_true() + right_sidebar.expect_toggle(True) + right_sidebar.expect_toggle_expanded(True) right_sidebar.loc_toggle.click() - right_sidebar.expect_toggle_to_be_false() + right_sidebar.expect_toggle_expanded(False) output_txt_right.expect_value("input.sidebar_right(): False") closed_sidebar = Sidebar(page, "sidebar_closed") output_txt_closed = OutputTextVerbatim(page, "state_closed") output_txt_closed.expect_value("input.sidebar_closed(): False") - closed_sidebar.expect_toggle_button(True) - closed_sidebar.expect_toggle_to_be_false() + closed_sidebar.expect_toggle(True) + # why is it not working + # closed_sidebar.expect_toggle_expanded(False) closed_sidebar.loc_toggle.click() - closed_sidebar.expect_sidebar("Closed sidebar content") - closed_sidebar.expect_toggle_to_be_true() + closed_sidebar.expect_title("Closed sidebar content") + # closed_sidebar.expect_toggle_expanded(True) output_txt_closed.expect_value("input.sidebar_closed(): True") always_sidebar = Sidebar(page, "sidebar_always") output_txt_always = OutputTextVerbatim(page, "state_always") - always_sidebar.expect_sidebar("Always sidebar content") + always_sidebar.expect_title("Always sidebar content") output_txt_always.expect_value("input.sidebar_always(): False") - always_sidebar.expect_toggle_button(False) + always_sidebar.expect_toggle(False) From 2f9d4128eb376a421762a5a3f97f8b09b99e9907 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Thu, 20 Jul 2023 11:45:37 -0700 Subject: [PATCH 5/6] Make code changes --- e2e/controls.py | 13 +++++++------ e2e/experimental/test_sidebar.py | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/e2e/controls.py b/e2e/controls.py index 2ab7e71e2..de48e3ea2 100644 --- a/e2e/controls.py +++ b/e2e/controls.py @@ -2359,18 +2359,19 @@ def __init__(self, page: Page, id: str) -> None: loc=f"> div#{id}", loc_container="div.bslib-sidebar-layout", ) - - self.loc_toggle = self.loc.locator("..").locator("button.collapse-toggle") + # change self.loc > self.loc_container + self.loc_handle = self.loc.locator("..").locator("button.collapse-toggle") def expect_title(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: playwright_expect(self.loc).to_have_text(value, timeout=timeout) - def expect_toggle(self, open: bool, *, timeout: Timeout = None) -> None: - playwright_expect(self.loc_toggle).to_have_count(int(open), timeout=timeout) + def expect_handle(self, exists: bool, *, timeout: Timeout = None) -> None: + playwright_expect(self.loc_handle).to_have_count(int(exists), timeout=timeout) - def expect_toggle_expanded(self, open: bool, *, timeout: Timeout = None) -> None: + # use to have attribute instead of to have count + def expect_open(self, open: bool, *, timeout: Timeout = None) -> None: playwright_expect( self.loc.locator("..").locator( f"button.collapse-toggle[aria-expanded='{str(open).lower()}']" ) - ).to_have_count(int(open), timeout=timeout) + ).to_have_count(1, timeout=timeout) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py index 8b2c4b221..e809bc1d4 100644 --- a/e2e/experimental/test_sidebar.py +++ b/e2e/experimental/test_sidebar.py @@ -12,29 +12,29 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: output_txt_left = OutputTextVerbatim(page, "state_left") left_sidebar.expect_title("Left sidebar content") output_txt_left.expect_value("input.sidebar_left(): True") - left_sidebar.expect_toggle(True) - left_sidebar.expect_toggle_expanded(True) - left_sidebar.loc_toggle.click() - left_sidebar.expect_toggle_expanded(False) + left_sidebar.expect_handle(True) + left_sidebar.expect_open(True) + left_sidebar.loc_handle.click() + left_sidebar.expect_open(False) output_txt_left.expect_value("input.sidebar_left(): False") right_sidebar = Sidebar(page, "sidebar_right") output_txt_right = OutputTextVerbatim(page, "state_right") right_sidebar.expect_title("Right sidebar content") output_txt_right.expect_value("input.sidebar_right(): True") - right_sidebar.expect_toggle(True) - right_sidebar.expect_toggle_expanded(True) - right_sidebar.loc_toggle.click() - right_sidebar.expect_toggle_expanded(False) + right_sidebar.expect_handle(True) + right_sidebar.expect_open(True) + right_sidebar.loc_handle.click() + right_sidebar.expect_open(False) output_txt_right.expect_value("input.sidebar_right(): False") closed_sidebar = Sidebar(page, "sidebar_closed") output_txt_closed = OutputTextVerbatim(page, "state_closed") output_txt_closed.expect_value("input.sidebar_closed(): False") - closed_sidebar.expect_toggle(True) + closed_sidebar.expect_handle(True) # why is it not working - # closed_sidebar.expect_toggle_expanded(False) - closed_sidebar.loc_toggle.click() + closed_sidebar.expect_open(False) + closed_sidebar.loc_handle.click() closed_sidebar.expect_title("Closed sidebar content") # closed_sidebar.expect_toggle_expanded(True) output_txt_closed.expect_value("input.sidebar_closed(): True") @@ -43,4 +43,4 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: output_txt_always = OutputTextVerbatim(page, "state_always") always_sidebar.expect_title("Always sidebar content") output_txt_always.expect_value("input.sidebar_always(): False") - always_sidebar.expect_toggle(False) + always_sidebar.expect_handle(False) From 368e772fe8c3e06233c5e0c5e370735840e01ecf Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Thu, 20 Jul 2023 13:06:05 -0700 Subject: [PATCH 6/6] refactor functions in controls.py --- e2e/controls.py | 12 ++++-------- e2e/experimental/test_sidebar.py | 3 +-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/e2e/controls.py b/e2e/controls.py index de48e3ea2..f3cbd9d53 100644 --- a/e2e/controls.py +++ b/e2e/controls.py @@ -2359,8 +2359,7 @@ def __init__(self, page: Page, id: str) -> None: loc=f"> div#{id}", loc_container="div.bslib-sidebar-layout", ) - # change self.loc > self.loc_container - self.loc_handle = self.loc.locator("..").locator("button.collapse-toggle") + self.loc_handle = self.loc_container.locator("button.collapse-toggle") def expect_title(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: playwright_expect(self.loc).to_have_text(value, timeout=timeout) @@ -2368,10 +2367,7 @@ def expect_title(self, value: PatternOrStr, *, timeout: Timeout = None) -> None: def expect_handle(self, exists: bool, *, timeout: Timeout = None) -> None: playwright_expect(self.loc_handle).to_have_count(int(exists), timeout=timeout) - # use to have attribute instead of to have count def expect_open(self, open: bool, *, timeout: Timeout = None) -> None: - playwright_expect( - self.loc.locator("..").locator( - f"button.collapse-toggle[aria-expanded='{str(open).lower()}']" - ) - ).to_have_count(1, timeout=timeout) + playwright_expect(self.loc_handle).to_have_attribute( + "aria-expanded", str(open).lower(), timeout=timeout + ) diff --git a/e2e/experimental/test_sidebar.py b/e2e/experimental/test_sidebar.py index e809bc1d4..b2f8f9da0 100644 --- a/e2e/experimental/test_sidebar.py +++ b/e2e/experimental/test_sidebar.py @@ -32,11 +32,10 @@ def test_autoresize(page: Page, app: ShinyAppProc) -> None: output_txt_closed = OutputTextVerbatim(page, "state_closed") output_txt_closed.expect_value("input.sidebar_closed(): False") closed_sidebar.expect_handle(True) - # why is it not working closed_sidebar.expect_open(False) closed_sidebar.loc_handle.click() closed_sidebar.expect_title("Closed sidebar content") - # closed_sidebar.expect_toggle_expanded(True) + closed_sidebar.expect_open(True) output_txt_closed.expect_value("input.sidebar_closed(): True") always_sidebar = Sidebar(page, "sidebar_always")