Skip to content

Commit

Permalink
Playwright test for --demo (#120)
Browse files Browse the repository at this point in the history
* abstract the server, so we can pass in different CLI info

* app fixture

* Stub demo test

* Make sure the tooltip is not there on default

* named tuple and a rename
  • Loading branch information
mccalluc authored Nov 4, 2024
1 parent 650d28f commit 02ef2ad
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 39 deletions.
4 changes: 2 additions & 2 deletions dp_creator_ii/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""DP Creator II makes it easier to get started with Differential Privacy."""

import shiny
from dp_creator_ii.utils.argparse_helpers import get_csv_contrib_from_cli
from dp_creator_ii.utils.argparse_helpers import get_cli_info


__version__ = "0.0.1"
Expand All @@ -10,7 +10,7 @@
def main(): # pragma: no cover
# We only call this here so "--help" is handled,
# and to validate inputs before starting the server.
get_csv_contrib_from_cli()
get_cli_info()

shiny.run_app(
app="dp_creator_ii.app",
Expand Down
56 changes: 29 additions & 27 deletions dp_creator_ii/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from shiny import App, ui, reactive

from dp_creator_ii.utils.argparse_helpers import get_csv_contrib_from_cli
from dp_creator_ii.utils.argparse_helpers import get_cli_info
from dp_creator_ii.app import analysis_panel, dataset_panel, results_panel


Expand All @@ -25,29 +25,31 @@ def ctrl_c_reminder(): # pragma: no cover
print("Session ended (Press CTRL+C to quit)")


def server(input, output, session): # pragma: no cover
(csv_path_from_cli, contributions_from_cli, is_demo) = get_csv_contrib_from_cli()
csv_path = reactive.value(csv_path_from_cli)
contributions = reactive.value(contributions_from_cli)

dataset_panel.dataset_server(
input,
output,
session,
csv_path=csv_path,
contributions=contributions,
is_demo=is_demo,
)
analysis_panel.analysis_server(
input,
output,
session,
csv_path=csv_path,
contributions=contributions,
is_demo=is_demo,
)
results_panel.results_server(input, output, session)
session.on_ended(ctrl_c_reminder)


app = App(app_ui, server)
def make_server_from_cli_info(cli_info):
def server(input, output, session): # pragma: no cover
csv_path = reactive.value(cli_info.csv_path)
contributions = reactive.value(cli_info.contributions)

dataset_panel.dataset_server(
input,
output,
session,
csv_path=csv_path,
contributions=contributions,
is_demo=cli_info.is_demo,
)
analysis_panel.analysis_server(
input,
output,
session,
csv_path=csv_path,
contributions=contributions,
is_demo=cli_info.is_demo,
)
results_panel.results_server(input, output, session)
session.on_ended(ctrl_c_reminder)

return server


app = App(app_ui, make_server_from_cli_info(get_cli_info()))
10 changes: 6 additions & 4 deletions dp_creator_ii/app/dataset_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

from shiny import ui, reactive, render

from dp_creator_ii.utils.argparse_helpers import get_csv_contrib_from_cli
from dp_creator_ii.utils.argparse_helpers import get_cli_info
from dp_creator_ii.app.components.outputs import output_code_sample, demo_tooltip
from dp_creator_ii.utils.templates import make_privacy_unit_block


def dataset_ui():
(csv_path, contributions, is_demo) = get_csv_contrib_from_cli()
csv_placeholder = None if csv_path is None else Path(csv_path).name
cli_info = get_cli_info()
csv_placeholder = (
None if cli_info.csv_path is None else Path(cli_info.csv_path).name
)

return ui.nav_panel(
"Select Dataset",
Expand All @@ -28,7 +30,7 @@ def dataset_ui():
ui.input_numeric(
"contributions",
["Contributions", ui.output_ui("contributions_demo_tooltip_ui")],
contributions,
cli_info.contributions,
),
ui.output_ui("python_tooltip_ui"),
output_code_sample("Unit of Privacy", "unit_of_privacy_python"),
Expand Down
12 changes: 9 additions & 3 deletions dp_creator_ii/utils/argparse_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import csv
import random
from warnings import warn
from collections import namedtuple


def _existing_csv_type(arg):
Expand Down Expand Up @@ -102,13 +103,18 @@ def _get_demo_csv_contrib():
}
)

return (csv_path, contributions, True)
return CLIInfo(csv_path=csv_path, contributions=contributions, is_demo=True)


def get_csv_contrib_from_cli(): # pragma: no cover
CLIInfo = namedtuple("CLIInfo", ["csv_path", "contributions", "is_demo"])


def get_cli_info(): # pragma: no cover
args = _get_args()
if args.demo:
if args.csv_path is not None:
warn('"--demo" overrides "--csv" and "--contrib"')
return _get_demo_csv_contrib()
return (args.csv_path, args.contributions, False)
return CLIInfo(
csv_path=args.csv_path, contributions=args.contributions, is_demo=False
)
16 changes: 16 additions & 0 deletions tests/fixtures/default_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from shiny import App


from dp_creator_ii.app import app_ui, make_server_from_cli_info
from dp_creator_ii.utils.argparse_helpers import CLIInfo

app = App(
app_ui,
make_server_from_cli_info(
CLIInfo(
csv_path=None,
contributions=None,
is_demo=False,
)
),
)
16 changes: 16 additions & 0 deletions tests/fixtures/demo_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from shiny import App

from dp_creator_ii.app import app_ui, make_server_from_cli_info
from dp_creator_ii.utils.argparse_helpers import CLIInfo


app = App(
app_ui,
make_server_from_cli_info(
CLIInfo(
csv_path=None,
contributions=None,
is_demo=True,
)
),
)
18 changes: 15 additions & 3 deletions tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,23 @@
from shiny.pytest import create_app_fixture


app = create_app_fixture("../dp_creator_ii/app/__init__.py")
demo_app = create_app_fixture(Path(__file__).parent / "fixtures/demo_app.py")
default_app = create_app_fixture(Path(__file__).parent / "fixtures/default_app.py")
tooltip = "#choose_csv_demo_tooltip_ui svg"
for_the_demo = "For the demo, we'll imagine"


# TODO: Why is incomplete coverage reported here?
# https://github.com/opendp/dp-creator-ii/issues/18
def test_app(page: Page, app: ShinyAppProc): # pragma: no cover
def test_demo_app(page: Page, demo_app: ShinyAppProc): # pragma: no cover
page.goto(demo_app.url)
expect(page).to_have_title("DP Creator II")
expect(page.get_by_text(for_the_demo)).not_to_be_visible()
page.locator(tooltip).hover()
expect(page.get_by_text(for_the_demo)).to_be_visible()


def test_default_app(page: Page, default_app: ShinyAppProc): # pragma: no cover
pick_dataset_text = "How many rows of the CSV"
perform_analysis_text = "Select numeric columns of interest"
download_results_text = "You can now make a differentially private release"
Expand All @@ -25,8 +36,9 @@ def expect_no_error():
expect(page.locator(".shiny-output-error")).not_to_be_attached()

# -- Select dataset --
page.goto(app.url)
page.goto(default_app.url)
expect(page).to_have_title("DP Creator II")
expect(page.locator(tooltip)).to_have_count(0)
expect_visible(pick_dataset_text)
expect_not_visible(perform_analysis_text)
expect_not_visible(download_results_text)
Expand Down

0 comments on commit 02ef2ad

Please sign in to comment.