@@ -17,27 +17,30 @@ Here's the inspection panel for the search input element on the result page:
17
17
This element also has an ID,
18
18
so we can use the ` #search_form_input ` selector to uniquely identify it.
19
19
20
- To get the textual value inside this input element,
21
- you might think that we should use the
22
- [ ` inner_text ` ] ( https://playwright.dev/python/docs/api/class-page#page-inner-text ) method
23
- or the [ ` text_content ` ] ( https://playwright.dev/python/docs/api/class-page#page-text-content ) method.
24
- However, neither of these are correct.
25
- To get the value of an input element, you need to get its ` value ` attribute.
26
- Thankfully, Playwright provides a convenient method named
27
- [ ` input_value ` ] ( https://playwright.dev/python/docs/api/class-page#page-input-value ) to get this.
20
+ To verify the textual value inside this input element,
21
+ we should use Playwright's ` expect ` function.
22
+ ` expect ` connects page and locator calls to Playwright's assertions.
28
23
29
- Add the following line to the test case :
24
+ Import the ` expect ` function like this :
30
25
31
26
``` python
32
- assert ' panda' == page.input_value(' #search_form_input' )
27
+ from playwright.sync_api import expect, Page
28
+ ```
29
+
30
+ Then, add the following line to the test case:
31
+
32
+ ``` python
33
+ expect(page.locator(' #search_form_input' )).to_have_value(' panda' )
33
34
```
34
35
35
36
This line will get the input value from the target element and assert that it is equal to the original search phrase.
36
37
37
38
The full test case should now look like this:
38
39
39
40
``` python
40
- def test_basic_duckduckgo_search (page ):
41
+ from playwright.sync_api import expect, Page
42
+
43
+ def test_basic_duckduckgo_search (page : Page) -> None :
41
44
42
45
# Given the DuckDuckGo home page is displayed
43
46
page.goto(' https://www.duckduckgo.com' )
@@ -47,7 +50,7 @@ def test_basic_duckduckgo_search(page):
47
50
page.click(' #search_button_homepage' )
48
51
49
52
# Then the search result query is the phrase
50
- assert ' panda ' == page.input_value (' #search_form_input' )
53
+ expect( page.locator (' #search_form_input' )).to_have_value( ' panda ' )
51
54
52
55
# And the search result links pertain to the phrase
53
56
# And the search result title contains the phrase
@@ -63,10 +66,18 @@ Is this a problem?
63
66
Thankfully, in this case, there is no problem.
64
67
Playwright automatically waits for elements to be ready before interacting with them.
65
68
So, even though the test does not perform any * explicit* waiting for the result page,
66
- the ` input_value ` method performs * implicit* waiting for the element to be ready .
69
+ the ` expect ` function performs * implicit* waiting for the element to satisfy the ` to_have_value ` condition .
67
70
Check the [ Auto-waiting] ( https://playwright.dev/python/docs/actionability ) page
68
71
for a full list of actionability checks for each interaction.
69
72
73
+ > You could use the following assert statement for this verification:
74
+ >
75
+ > ` assert 'panda' == page.input_value('#search_form_input') `
76
+ >
77
+ > However, while this call will wait for the element to appear,
78
+ > it will not wait for the input value to become ` 'panda' ` .
79
+ > The recommended practice is to use ` expect ` with locator objects.
80
+
70
81
Rerun the test using the same pytest command (` python3 -m pytest tests --headed --slowmo 1000 ` ).
71
82
This time, you should see the result page for a good second or two before the browser window closes.
72
83
The test should still pass.
@@ -110,7 +121,7 @@ Explicit waiting will be tricky.
110
121
Add the following line to the test:
111
122
112
123
``` python
113
- page.locator(' .result__title a.result__a >> nth=4 ' ).wait_for()
124
+ page.locator(' .result__title a.result__a' ). nth( 4 ).wait_for()
114
125
```
115
126
116
127
Let's break this down:
@@ -120,9 +131,9 @@ Let's break this down:
120
131
A ` Locator ` object can make many of the same calls as a page, like clicking and getting text.
121
132
However, it can also make calls for explicit waiting and calls that target multiple elements.
122
133
2 . ` .result__title a.result__a ` is the selector for the result links.
123
- 3 . ` >> nth=4 ` is an [ N-th element selector ] ( https://playwright.dev/python/docs/selectors#n-th-element-selector ) .
124
- N-th element selectors are zero-indexed and may be appended to any selector.
125
- In this ` locator ` call, it will fetch the fifth result link element.
134
+ 3 . ` nth(4) ` is an [ N-th element] ( https://playwright.dev/python/docs/api/class-locator#locator-nth ) fetcher .
135
+ N-th element fetchers are zero-indexed and may be appended to any selector.
136
+ In this call, it will fetch the fifth result link element.
126
137
4 . [ ` wait_for ` ] ( https://playwright.dev/python/docs/api/class-locator#locator-wait-for )
127
138
is a method that will wait for the target element to be visible.
128
139
@@ -168,20 +179,22 @@ Add this assertion to the test:
168
179
The full test case should now look like this:
169
180
170
181
``` python
171
- def test_basic_duckduckgo_search ( page ):
182
+ from playwright.sync_api import expect, Page
172
183
184
+ def test_basic_duckduckgo_search (page : Page) -> None :
185
+
173
186
# Given the DuckDuckGo home page is displayed
174
187
page.goto(' https://www.duckduckgo.com' )
175
188
176
189
# When the user searches for a phrase
177
- page.fill (' #search_form_input_homepage' , ' panda' )
178
- page.click (' #search_button_homepage' )
190
+ page.locator (' #search_form_input_homepage' ).fill( ' panda' )
191
+ page.locator (' #search_button_homepage' ).click( )
179
192
180
193
# Then the search result query is the phrase
181
- assert ' panda ' == page.input_value (' #search_form_input' )
194
+ expect( page.locator (' #search_form_input' )).to_have_value( ' panda ' )
182
195
183
196
# And the search result links pertain to the phrase
184
- page.locator(' .result__title a.result__a >> nth=4 ' ).wait_for()
197
+ page.locator(' .result__title a.result__a' ). nth( 4 ).wait_for()
185
198
titles = page.locator(' .result__title a.result__a' ).all_text_contents()
186
199
matches = [t for t in titles if ' panda' in t.lower()]
187
200
assert len (matches) > 0
@@ -201,13 +214,13 @@ Thankfully, this one will be short.
201
214
202
215
The page title is an attribute of the page.
203
216
It is not associated with any element on the page.
204
- We can use the [ ` title ` ] ( https://playwright.dev/python/docs/api/class-page#page-title ) method
205
- to access it directly .
217
+ We can use the [ ` title ` ] ( https://playwright.dev/python/docs/api/class-page#page-title ) method to access it directly.
218
+ For assertions, we should use ` expect ` with the ` to_have_title ` condition .
206
219
207
220
Add the following line to the test:
208
221
209
222
``` python
210
- assert ' panda' in page.title( )
223
+ expect(page).to_have_title( ' panda at DuckDuckGo ' )
211
224
```
212
225
213
226
This will make sure the search phrase appears in the page title.
@@ -217,26 +230,28 @@ Make sure the page is fully loaded first.
217
230
The full test case should now look like this:
218
231
219
232
``` python
220
- def test_basic_duckduckgo_search ( page ):
233
+ from playwright.sync_api import expect, Page
221
234
235
+ def test_basic_duckduckgo_search (page : Page) -> None :
236
+
222
237
# Given the DuckDuckGo home page is displayed
223
238
page.goto(' https://www.duckduckgo.com' )
224
239
225
240
# When the user searches for a phrase
226
- page.fill (' #search_form_input_homepage' , ' panda' )
227
- page.click (' #search_button_homepage' )
241
+ page.locator (' #search_form_input_homepage' ).fill( ' panda' )
242
+ page.locator (' #search_button_homepage' ).click( )
228
243
229
244
# Then the search result query is the phrase
230
- assert ' panda ' == page.input_value (' #search_form_input' )
245
+ expect( page.locator (' #search_form_input' )).to_have_value( ' panda ' )
231
246
232
247
# And the search result links pertain to the phrase
233
- page.locator(' .result__title a.result__a >> nth=4 ' ).wait_for()
248
+ page.locator(' .result__title a.result__a' ). nth( 4 ).wait_for()
234
249
titles = page.locator(' .result__title a.result__a' ).all_text_contents()
235
250
matches = [t for t in titles if ' panda' in t.lower()]
236
251
assert len (matches) > 0
237
252
238
253
# And the search result title contains the phrase
239
- assert ' panda' in page.title( )
254
+ expect(page).to_have_title( ' panda at DuckDuckGo ' )
240
255
```
241
256
242
257
We can remove the ` pass ` statement at the end now.
@@ -245,11 +260,6 @@ Rerun the test again to make sure it works.
245
260
If it does, congrats!
246
261
You have just completed a full test case in Python using Playwright with pytest.
247
262
248
- Playwright's [ ` Page ` ] ( https://playwright.dev/python/docs/api/class-page ) class
249
- provides several methods for interacting with pages and getting state from them.
250
- Read the docs to familiarize yourself with them.
251
- ` Page ` provides methods to interact with * every* type of web element.
252
-
253
263
Notice how concise this code is.
254
264
Unfortunately, it's not very reusable.
255
265
If other tests needed to perform DuckDuckGo searches,
0 commit comments