Skip to content

Commit 357e7b8

Browse files
Updated part 2 instructions
1 parent 6332f3b commit 357e7b8

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

tutorial/2-first-steps.md

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,22 @@ You do not need to explicitly close the browser.
5858
> Asynchronous calls could be useful for other types of automation, such as web scraping.
5959
6060
Let's update our test stub to call the `page` fixture.
61-
In `tests/test_search.py`, change the test function signature from this:
61+
In `tests/test_search.py`, add the following import statement:
6262

6363
```python
64-
def test_basic_duckduckgo_search():
64+
from playwright.sync_api import Page
65+
```
66+
67+
Then, change the test function signature from this:
68+
69+
```python
70+
def test_basic_duckduckgo_search() -> None:
6571
```
6672

6773
To this:
6874

6975
```python
70-
def test_basic_duckduckgo_search(page):
76+
def test_basic_duckduckgo_search(page: Page) -> None:
7177
```
7278

7379
Now the test has access to a fresh page in a new browser context.
@@ -172,22 +178,32 @@ Here's the inspection panel for the search input element:
172178
Thankfully, this element has an ID.
173179
We can use the selector `#search_form_input_homepage` to uniquely identify this element.
174180

175-
To enter text into this input element, we must use Playwright's
176-
[`fill`](https://playwright.dev/python/docs/api/class-page#page-fill) method.
181+
To interact with elements with Playwright, we must use [locators](https://playwright.dev/python/docs/locators).
182+
The [Locator](https://playwright.dev/python/docs/next/api/class-locator) class
183+
takes in a selector and produces an object that can interact with the target element.
184+
185+
For example, to enter text into this input element, we must use `Locator`'s
186+
[`fill`](https://playwright.dev/python/docs/next/api/class-locator#locator-fill) method.
177187
Append the following line to the test case:
178188

179189
```python
180-
page.fill('#search_form_input_homepage', 'panda')
190+
page.locator('#search_form_input_homepage').fill('panda')
181191
```
182192

183193
> Since `search_form_input_homepage` is an ID, we could also use Playwright's
184194
> [ID attribute selector](https://playwright.dev/python/docs/selectors#id-data-testid-data-test-id-data-test-selectors):
185195
>
186-
> `page.fill('id=search_form_input_homepage', 'panda')`
196+
> `page.locator('id=search_form_input_homepage').fill('panda')`
187197
188-
Using Selenium WebDriver, we would need to locate the element and then send the interaction to it.
189-
However, in Playwright, these two parts are combined into a single call.
190-
Furthermore, Playwright waits for the target element to be visible and editable before it attempts to enter the text.
198+
> Playwright's `Page` class also provides methods for element interactions like this:
199+
>
200+
> `page.fill('#search_form_input_homepage', 'panda')`
201+
>
202+
> However, using locators is recommended over direct page calls.
203+
> Locators use "strict" mode - a locator raises an exception if its selector finds more than one element.
204+
> Locators are also more reusable, especially when using page object classes.
205+
206+
Playwright waits for the target element to be visible and editable before it attempts to enter the text.
191207
We are arbitrarily using the phrase `'panda'` as our search phrase because, well, why not?
192208

193209
Let's handle the second part of the interaction: clicking the search button.
@@ -198,11 +214,11 @@ Here's the inspection panel for the search button:
198214
This element also has an ID: `#search_button_homepage`. Nice!
199215

200216
To click an element, we must use Playwright's
201-
[`click`](https://playwright.dev/python/docs/api/class-page#page-click) method.
217+
[`click`](https://playwright.dev/python/docs/next/api/class-locator#locator-click) method.
202218
Append the following line to the test case:
203219

204220
```python
205-
page.click('#search_button_homepage')
221+
page.locator('#search_button_homepage').click()
206222
```
207223

208224
Again, Playwright is nice and concise.
@@ -211,14 +227,15 @@ The `click` method waits for the target element to be ready to receive clicks, t
211227
Our test case should now look like this:
212228

213229
```python
214-
def test_basic_duckduckgo_search(page):
230+
from playwright.sync_api import Page
215231

232+
def test_basic_duckduckgo_search(page: Page) -> None:
216233
# Given the DuckDuckGo home page is displayed
217234
page.goto('https://www.duckduckgo.com')
218235

219236
# When the user searches for a phrase
220-
page.fill('#search_form_input_homepage', 'panda')
221-
page.click('#search_button_homepage')
237+
page.locator('#search_form_input_homepage').fill('panda')
238+
page.locator('#search_button_homepage').click()
222239

223240
# Then the search result query is the phrase
224241
# And the search result links pertain to the phrase
@@ -231,5 +248,7 @@ Now, you should see the test actually perform the search!
231248

232249
Navigation, input filling, and clicking are only three of many page interactions you can do with Playwright.
233250
Anything a user can do on a web page, Playwright can do as well.
234-
Check out the Playwright [Page](https://playwright.dev/python/docs/api/class-page) API to see *all* methods and attributes.
251+
Check out the Playwright [Page](https://playwright.dev/python/docs/api/class-page)
252+
and [Locator](https://playwright.dev/python/docs/next/api/class-locator) classes
253+
to see *all* methods and attributes.
235254
We will use more of these calls in the next tutorial parts.

0 commit comments

Comments
 (0)