forked from microsoft/playwright-python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_queryselector.py
164 lines (142 loc) · 5.54 KB
/
test_queryselector.py
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import pytest
from playwright.async_api import Error, Page
async def test_selectors_register_should_work(selectors, browser):
tag_selector = """
{
create(root, target) {
return target.nodeName;
},
query(root, selector) {
return root.querySelector(selector);
},
queryAll(root, selector) {
return Array.from(root.querySelectorAll(selector));
}
}"""
# Register one engine before creating context.
await selectors.register("tag", tag_selector)
context = await browser.new_context()
# Register another engine after creating context.
await selectors.register("tag2", tag_selector)
page = await context.new_page()
await page.set_content("<div><span></span></div><div></div>")
assert await page.eval_on_selector("tag=DIV", "e => e.nodeName") == "DIV"
assert await page.eval_on_selector("tag=SPAN", "e => e.nodeName") == "SPAN"
assert await page.eval_on_selector_all("tag=DIV", "es => es.length") == 2
assert await page.eval_on_selector("tag2=DIV", "e => e.nodeName") == "DIV"
assert await page.eval_on_selector("tag2=SPAN", "e => e.nodeName") == "SPAN"
assert await page.eval_on_selector_all("tag2=DIV", "es => es.length") == 2
# Selector names are case-sensitive.
with pytest.raises(Error) as exc:
await page.query_selector("tAG=DIV")
assert 'Unknown engine "tAG" while parsing selector tAG=DIV' in exc.value.message
await context.close()
async def test_selectors_register_should_work_with_path(
selectors, page: Page, utils, assetdir
):
await utils.register_selector_engine(
selectors, "foo", path=assetdir / "sectionselectorengine.js"
)
await page.set_content("<section></section>")
assert await page.eval_on_selector("foo=whatever", "e => e.nodeName") == "SECTION"
async def test_selectors_register_should_work_in_main_and_isolated_world(
selectors, page: Page, utils
):
dummy_selector_script = """{
create(root, target) { },
query(root, selector) {
return window.__answer;
},
queryAll(root, selector) {
return window['__answer'] ? [window['__answer'], document.body, document.documentElement] : [];
}
}"""
await utils.register_selector_engine(selectors, "main", dummy_selector_script)
await utils.register_selector_engine(
selectors, "isolated", dummy_selector_script, content_script=True
)
await page.set_content("<div><span><section></section></span></div>")
await page.evaluate('() => window.__answer = document.querySelector("span")')
# Works in main if asked.
assert await page.eval_on_selector("main=ignored", "e => e.nodeName") == "SPAN"
assert (
await page.eval_on_selector("css=div >> main=ignored", "e => e.nodeName")
== "SPAN"
)
assert await page.eval_on_selector_all(
"main=ignored", "es => window.__answer !== undefined"
)
assert (
await page.eval_on_selector_all(
"main=ignored", "es => es.filter(e => e).length"
)
== 3
)
# Works in isolated by default.
assert await page.query_selector("isolated=ignored") is None
assert await page.query_selector("css=div >> isolated=ignored") is None
# $$eval always works in main, to avoid adopting nodes one by one.
assert await page.eval_on_selector_all(
"isolated=ignored", "es => window.__answer !== undefined"
)
assert (
await page.eval_on_selector_all(
"isolated=ignored", "es => es.filter(e => e).length"
)
== 3
)
# At least one engine in main forces all to be in main.
assert (
await page.eval_on_selector(
"main=ignored >> isolated=ignored", "e => e.nodeName"
)
== "SPAN"
)
assert (
await page.eval_on_selector(
"isolated=ignored >> main=ignored", "e => e.nodeName"
)
== "SPAN"
)
# Can be chained to css.
assert (
await page.eval_on_selector("main=ignored >> css=section", "e => e.nodeName")
== "SECTION"
)
async def test_selectors_register_should_handle_errors(selectors, page: Page, utils):
with pytest.raises(Error) as exc:
await page.query_selector("neverregister=ignored")
assert (
'Unknown engine "neverregister" while parsing selector neverregister=ignored'
in exc.value.message
)
dummy_selector_engine_script = """{
create(root, target) {
return target.nodeName;
},
query(root, selector) {
return root.querySelector('dummy');
},
queryAll(root, selector) {
return Array.from(root.query_selector_all('dummy'));
}
}"""
with pytest.raises(Error) as exc:
await selectors.register("$", dummy_selector_engine_script)
assert (
exc.value.message
== "Selector engine name may only contain [a-zA-Z0-9_] characters"
)
# Selector names are case-sensitive.
await utils.register_selector_engine(
selectors, "dummy", dummy_selector_engine_script
)
await utils.register_selector_engine(
selectors, "duMMy", dummy_selector_engine_script
)
with pytest.raises(Error) as exc:
await selectors.register("dummy", dummy_selector_engine_script)
assert exc.value.message == '"dummy" selector engine has been already registered'
with pytest.raises(Error) as exc:
await selectors.register("css", dummy_selector_engine_script)
assert exc.value.message == '"css" is a predefined selector engine'