pyrtan / sourcev0.14.0 · main

pyrtan / tests / test_html.py

2,282 bytes · last changed 2026-10-25 in Initial public release

1import pytest
2
3from pyrtan.html import SelectorError, compile_selector, parse
4
5DOC = """
6<html><head><title>Shop</title></head>
7<body>
8 <div id="main" class="wrap big">
9 <h1>Items</h1>
10 <table>
11 <tr class="row"><td>Apple</td><td class="qty">3</td></tr>
12 <tr class="row sold-out"><td>Pear</td><td class="qty">0</td></tr>
13 </table>
14 <a href="/one" class="story">One</a>
15 <a href="https://x/two" class="story external">Two &amp; more</a>
16 <p>Total: <b>2</b> items<br>end</p>
17 </div>
18</body></html>
19"""
20
21
22@pytest.fixture
23def doc():
24 return parse(DOC)
25
26
27def test_tag_id_class(doc):
28 assert doc.select_one("title").text == "Shop"
29 assert doc.select_one("#main").tag == "div"
30 assert [e.text for e in doc.select(".row")] == ["Apple 3", "Pear 0"]
31 assert len(doc.select(".row.sold-out")) == 1
32 assert doc.select_one("div.wrap h1").text == "Items"
33
34
35def test_attribute_selectors(doc):
36 assert [a.get("href") for a in doc.select("a[href]")] == ["/one", "https://x/two"]
37 assert doc.select_one('a[href="/one"]').text == "One"
38 assert doc.select_one("a[href^=https]").text == "Two & more"
39 assert doc.select_one("a[href$=two]").text == "Two & more"
40 assert doc.select_one("a[class*=external]").get("href") == "https://x/two"
41
42
43def test_combinators_and_pseudo(doc):
44 assert [e.text for e in doc.select("tr > td:nth-child(2)")] == ["3", "0"]
45 assert doc.select_one("tr:first-child td").text == "Apple"
46 assert doc.select_one("tr:last-child td").text == "Pear"
47 assert doc.select_one("td:contains(Pear)").text == "Pear"
48 assert [e.tag for e in doc.select("h1, title")] == ["title", "h1"]
49 assert doc.select("#main > td") == []
50 assert len(doc.select("#main td")) == 4
51
52
53def test_text_collapses_whitespace_and_void_tags(doc):
54 assert doc.select_one("p").text == "Total: 2 items end"
55
56
57def test_unsupported_selector_is_an_error():
58 with pytest.raises(SelectorError):
59 compile_selector("a ~ b")
60 with pytest.raises(SelectorError):
61 compile_selector("div:hover")
62 with pytest.raises(SelectorError):
63 compile_selector("")
64
65
66def test_malformed_html_does_not_raise():
67 doc = parse("<div><p>unclosed<div>another</p></div>")
68 assert doc.select_one("div").text.startswith("unclosed")