Skip to content
Merged
Changes from all commits
Commits
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
66 changes: 9 additions & 57 deletions tests/test_explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,12 @@ class TestExplorerCrossFiltering:
"""Cross-filtering: clicking a facet should update counts in other facets."""

def _wait_for_facets(self, page):
"""Wait for facet count labels to render (requires cross-filter PR)."""
"""Wait for facet count labels to render (requires DuckDB-WASM init)."""
facet = page.locator(".facet-count[data-facet='source']")
# These data attributes only exist after the cross-filtering code is deployed
try:
facet.first.wait_for(state="attached", timeout=30000)
facet.first.wait_for(state="attached", timeout=60000)
except Exception:
pytest.skip("Cross-filter data attributes not yet deployed")
pytest.skip("Facet count labels not rendered (DuckDB-WASM may not have loaded)")

def _get_count(self, page, facet, value):
"""Extract the numeric count from a facet-count label."""
Expand All @@ -91,73 +90,26 @@ def _get_count(self, page, facet, value):
text = el.first.text_content() # e.g. "(4,389,231)"
return int(text.strip("() ").replace(",", ""))

def _click_checkbox(self, page, label):
"""Click a checkbox by its visible label text."""
page.get_by_text(label, exact=True).first.click()

def test_baseline_sesar_count_matches_summaries(self, explorer_page):
"""Before any interaction, SESAR count should match the facet summary."""
self._wait_for_facets(explorer_page)
count = self._get_count(explorer_page, "source", "SESAR")
assert count is not None, "SESAR facet-count element not found"
assert count > 4_000_000, f"SESAR baseline count too low: {count}"

@pytest.mark.skip(reason="Observable Inputs.checkbox ignores programmatic clicks in headless Playwright")
def test_clicking_source_updates_material_counts(self, explorer_page):
"""Checking SESAR should lower material counts (no archaeology materials)."""
self._wait_for_facets(explorer_page)
# Record a material count before filtering
before = self._get_count(explorer_page, "material",
"https://w3id.org/isample/vocabulary/material/1.0/organicmaterial")
assert before is not None, "organicmaterial facet-count not found"

# Click SESAR checkbox
self._click_checkbox(explorer_page, "SESAR")

# Wait for cross-filter update (labels update in-place via DOM mutation)
explorer_page.wait_for_timeout(5000)

after = self._get_count(explorer_page, "material",
"https://w3id.org/isample/vocabulary/material/1.0/organicmaterial")
assert after is not None
assert after < before, (
f"organicmaterial count should decrease with SESAR filter: {before} -> {after}"
)
"""Checking SESAR should lower material counts (no archaeology materials).
Cannot be automated: Observable's reactive system only triggers from real
user interaction, not from programmatic .click() or dispatchEvent()."""

@pytest.mark.skip(reason="Observable Inputs.checkbox ignores programmatic clicks in headless Playwright")
def test_clearing_filter_restores_baseline(self, explorer_page):
"""Unchecking a source should restore baseline counts."""
self._wait_for_facets(explorer_page)
baseline = self._get_count(explorer_page, "material",
"https://w3id.org/isample/vocabulary/material/1.0/earthmaterial")

# Activate then deactivate SESAR
self._click_checkbox(explorer_page, "SESAR")
explorer_page.wait_for_timeout(5000)
filtered = self._get_count(explorer_page, "material",
"https://w3id.org/isample/vocabulary/material/1.0/earthmaterial")

self._click_checkbox(explorer_page, "SESAR")
explorer_page.wait_for_timeout(5000)
restored = self._get_count(explorer_page, "material",
"https://w3id.org/isample/vocabulary/material/1.0/earthmaterial")

assert filtered != baseline, "Filter should have changed the count"
assert restored == baseline, (
f"Count should restore to baseline after clearing: {baseline} -> {restored}"
)

@pytest.mark.skip(reason="Observable Inputs.checkbox ignores programmatic clicks in headless Playwright")
def test_zero_count_items_are_dimmed(self, explorer_page):
"""Facet values with 0 matches should have reduced opacity."""
self._wait_for_facets(explorer_page)

# SMITHSONIAN is smallest source — filtering to it should zero some facets
self._click_checkbox(explorer_page, "SMITHSONIAN")
explorer_page.wait_for_timeout(5000)

# Find any facet-count with "(0)" and check opacity
zero_counts = explorer_page.locator(".facet-count").filter(has_text="(0)")
if zero_counts.count() > 0:
opacity = zero_counts.first.evaluate("el => getComputedStyle(el).opacity")
assert float(opacity) < 1.0, "Zero-count items should be dimmed"

def test_new_parquet_endpoints_reachable(self, explorer_page):
"""The cross-filter and sample_facets parquet files should be accessible."""
Expand Down
Loading