diff --git a/.github/workflows/post.yml b/.github/workflows/post.yml index 62eccc1..07b1d49 100644 --- a/.github/workflows/post.yml +++ b/.github/workflows/post.yml @@ -25,9 +25,12 @@ jobs: cache: 'pip' - name: Install deps - run: pip install -r requirements.txt + run: | + pip install -r requirements.txt + playwright install + - - name: Create Screenshots + - name: Create Screenshots - CLI run: | msp simulate --length 1000 --recombination-rate 0.01 --mutation-rate 0.01 100 out.trees python -m tsbrowse preprocess out.trees @@ -35,6 +38,10 @@ jobs: python -m tsbrowse screenshot out.tsbrowse edges python -m tsbrowse screenshot out.tsbrowse nodes + - name: Create Screenshots - WEB + run: | + python -m pytest --save-screenshots tests/test_ui.py + - name: Commit Screenshots run: | git config --global user.name 'GitHub Action' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 79d25cd..af72574 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,7 +46,9 @@ jobs: cache: 'pip' - name: Install deps - run: pip install -r requirements.txt + run: | + pip install -r requirements.txt + playwright install - name: Tests with numba run: coverage run --source=tsbrowse -m pytest -x tests diff --git a/requirements.txt b/requirements.txt index ed0736f..8d34e82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,6 +9,7 @@ msprime panel pre-commit pytest +pytest-playwright selenium tskit tszip diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..54a8192 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,30 @@ +import panel as pn +import pytest + +PORT = [6000] + + +@pytest.fixture +def port(): + PORT[0] += 1 + return PORT[0] + + +@pytest.fixture(autouse=True) +def server_cleanup(): + """ + Clean up server state after each test. + """ + try: + yield + finally: + pn.state.reset() + + +def pytest_addoption(parser): + parser.addoption( + "--save-screenshots", + action="store_true", + default=False, + help="Save screenshots during tests", + ) diff --git a/tests/test_ui.py b/tests/test_ui.py new file mode 100644 index 0000000..025a71d --- /dev/null +++ b/tests/test_ui.py @@ -0,0 +1,71 @@ +import time + +import msprime +import panel as pn +import pytest +from playwright.sync_api import expect + +from tsbrowse import app +from tsbrowse import model +from tsbrowse import preprocess + + +@pytest.fixture +def save_screenshots(request): + return request.config.getoption("--save-screenshots") + + +def test_component(page, port, tmpdir, save_screenshots): + ts = msprime.sim_ancestry( + 10, sequence_length=1000, recombination_rate=1e-2, random_seed=1 + ) + ts = msprime.sim_mutations(ts, rate=1e-2, random_seed=1) + ts.dump(tmpdir / "test.trees") + preprocess.preprocess(tmpdir / "test.trees", tmpdir / "test.tsbrowse") + + tsm = model.TSModel(tmpdir / "test.tsbrowse") + component = app.App(tsm) + + url = f"http://localhost:{port}" + server = pn.serve(component.view(), port=port, threaded=True, show=False) + time.sleep(1) + page.goto(url) + page.set_viewport_size({"width": 1920, "height": 1080}) + expect(page.get_by_role("link", name="Tree Sequence")).to_be_visible() + expect(page.get_by_role("cell", name="Provenance Timestamp")).to_be_visible() + if save_screenshots: + page.screenshot(path="overview.png") + + page.get_by_role("button", name="Tables").click() + expect(page.get_by_label("Select Table")).to_be_visible() + expect(page.get_by_placeholder("Enter query expression (e.g")).to_be_visible() + page.get_by_label("Select Table").select_option("trees") + expect(page.get_by_text("total_branch_length")).to_be_visible() + if save_screenshots: + page.screenshot(path="tables.png") + + page.get_by_role("button", name="Mutations").click() + expect(page.get_by_text("Log y-axis")).to_be_visible() + expect(page.get_by_title("Reset").locator("div")).to_be_visible() + if save_screenshots: + page.screenshot(path="mutations.png") + + page.get_by_role("button", name="Edges").click() + expect(page.get_by_text("Parent node")).to_be_visible() + expect(page.get_by_title("Reset").locator("div")).to_be_visible() + if save_screenshots: + page.screenshot(path="edges.png") + + page.get_by_role("button", name="Trees").click() + expect(page.get_by_text("log y-axis")).to_be_visible() + expect(page.locator(".bk-Canvas > div:nth-child(12)").first).to_be_visible() + if save_screenshots: + page.screenshot(path="trees.png") + + page.get_by_role("button", name="Nodes").click() + expect(page.get_by_role("heading", name="Node Flags")).to_be_visible() + expect(page.get_by_title("Reset").locator("div")).to_be_visible() + if save_screenshots: + page.screenshot(path="nodes.png") + + server.stop()