-
Notifications
You must be signed in to change notification settings - Fork 185
Expand file tree
/
Copy pathtest_sqlite_query_explainer.py
More file actions
74 lines (57 loc) · 3.02 KB
/
Copy pathtest_sqlite_query_explainer.py
File metadata and controls
74 lines (57 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""
Playwright tests for sqlite-query-explainer.html
The initial-state tests run offline. The full flow (loading Pyodide from the
CDN, building the example database, running annotated queries) is covered by
a single test marked as needing network access.
"""
import pathlib
import pytest
from playwright.sync_api import Page, expect
test_dir = pathlib.Path(__file__).parent.absolute()
root = test_dir.parent.absolute()
def test_initial_state(page: Page, unused_port_server):
unused_port_server.start(root)
page.goto(f"http://localhost:{unused_port_server.port}/sqlite-query-explainer.html")
expect(page).to_have_title("SQLite Query Explainer")
expect(page.locator("h1")).to_have_text("SQLite Query Explainer")
# Both database entry points are offered
expect(page.locator("#load-example")).to_be_visible()
expect(page.locator("#open-db-btn")).to_be_visible()
# Query UI and output stay hidden until a database is loaded
expect(page.locator("#query-card")).to_be_hidden()
expect(page.locator("#output")).to_be_hidden()
expect(page.locator("#schema-details")).to_be_hidden()
def test_full_flow_with_example_database(page: Page, unused_port_server):
"""Loads Pyodide from the CDN - needs network access."""
unused_port_server.start(root)
page.goto(f"http://localhost:{unused_port_server.port}/sqlite-query-explainer.html")
page.click("#load-example")
# Pyodide (~15 MB) plus building 170k rows can take a while on CI
page.wait_for_selector("#output:not([hidden])", timeout=240_000)
# The first example query auto-ran: results, plan and bytecode all render
expect(page.locator("#results-meta")).to_contain_text("row")
expect(page.locator("#eqp")).to_contain_text("Full table scan")
assert page.locator("#bytecode-table tbody tr").count() > 5
# Schema panel lists the example tables
expect(page.locator("#schema")).to_contain_text("customers")
expect(page.locator("#schema")).to_contain_text("order_items")
# Bytecode instructions cross-reference each other with address links
assert page.locator("#bytecode-table a.addr-link").count() > 3
first_link = page.locator("#bytecode-table a.addr-link").first
addr = first_link.get_attribute("data-addr")
first_link.click()
assert "flash" in (page.locator(f"#op-{addr}").get_attribute("class") or "")
# Errors are reported
page.fill("#sql", "SELECT nope FROM customers")
page.click("#run")
page.wait_for_selector("#error:not([hidden])")
expect(page.locator("#error")).to_contain_text("no such column")
# Queries are bookmarkable: running one stores it in the URL hash
page.fill("#sql", "SELECT * FROM customers WHERE id = 42")
page.click("#run")
page.wait_for_function("location.hash.includes('customers')")
# ...and reloading the page restores and re-runs it from the hash
page.reload()
page.wait_for_selector("#output:not([hidden])", timeout=240_000)
assert "WHERE id = 42" in page.input_value("#sql")
expect(page.locator("#eqp")).to_contain_text("rowid")