Skip to content

Commit 4cc60c3

Browse files
Finished writing Part 2
1 parent 4af64b3 commit 4cc60c3

File tree

3 files changed

+97
-15
lines changed

3 files changed

+97
-15
lines changed

README.md

+97-15
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ def test_basic_duckduckgo_search(page):
342342
```
343343

344344
If you are familiar with Selenium WebDriver, then this command probably looks similar to the `driver.get(...)` method.
345-
However, Playwright's `goto` method is more sophisticated:
345+
However, Playwright's [`goto`](https://playwright.dev/python/docs/api/class-page#page-goto) method is more sophisticated:
346346
it waits for the page to fire the `load` event.
347347
Selenium WebDriver does not automatically wait for any event,
348348
which frequently leads to race conditions that cause flaky tests.
@@ -361,34 +361,116 @@ Let's try running our test to make sure Playwright works.
361361
Launch pytest using the following command:
362362

363363
```bash
364-
$ python3 -m pytest tests --headed
364+
$ python3 -m pytest tests --headed --slowmo 1000
365365
```
366366

367-
This invocation has a new argument: `--headed`.
367+
This invocation has two new arguments.
368+
The first one is `--headed`.
368369
By default, Playwright runs tests in *headless* mode, in which the browser is not visibly rendered.
369370
Headless mode is faster than headed mode and thus ideal for "real" testing (like in CI).
370371
However, *headed* mode is better when developing tests so that you can see what is happening.
371372

373+
The second new argument is `--slowmo`.
374+
By default, Playwright runs interactions as fast as it can.
375+
Again, this is great for "real" testing, but it might be too fast for humans to watch when developing and debugging.
376+
The `--slowmo` option lets the caller set a hard sleep time after every Playwright call.
377+
For example, `--slowmo 1000` will pause execution for 1 second (1000 ms) after each call.
378+
This option is a much better way to slow down tests than to add `time.sleep(...)` calls everywhere!
379+
372380
When you launch pytest, Chromium should pop up, navigate to the DuckDuckGo home page, and close.
373-
It should all happen very quickly.
374-
If you want the test to pause after loading the DuckDuckGo home page so that you can actually see it,
375-
temporarily add the following lines after the `goto` call:
381+
Try running it with and without the `--headed` and `--slowmo` options, too.
382+
Verify that Playwright calls work and the test passes before moving on.
383+
384+
Next, let's try to interact with page elements.
385+
Playwright is able to locate any element on the page using [selectors](https://playwright.dev/python/docs/selectors).
386+
Out of the box, Playwright supports the following types of selectors:
387+
388+
* Text
389+
* CSS
390+
* XPath
391+
* N-th element
392+
* React
393+
* Vue
394+
395+
Text and CSS selectors also pierce the Shadow DOM by default!
396+
397+
In general, you should keep selectors as simple as possible.
398+
Try to stick to text, IDs, or CSS selectors.
399+
Use more complicated selectors only as necessary.
400+
401+
This workshop will not cover recommended practices for element selectors deeply.
402+
If you want to learn more about selectors,
403+
read the [Element selectors](https://playwright.dev/python/docs/selectors) page in the Playwright docs,
404+
or take the [Web Element Locator Strategies](https://testautomationu.applitools.com/web-element-locator-strategies/) course
405+
from [Test Automation University](https://testautomationu.applitools.com/).
406+
407+
The next step in our test case is, "When the user searches for a phrase".
408+
This is actually a compound interaction with two parts:
409+
410+
1. Entering text into the search input field
411+
2. Clicking the search button
412+
413+
Let's start with the first part of the interaction: entering text into the search input field.
414+
We need to find a selector for the search input.
415+
One of the best ways to find selectors is to inspect elements through Chrome DevTools.
416+
In Chrome, simply right-click any page and select "Inspect" to open DevTools.
417+
418+
Here's the inspection panel for the search input element:
419+
420+
![Inspecting the search input element](images/inspect-search-input.png)
421+
422+
Thankfully, this element has an ID.
423+
We can use the selector `#search_form_input_homepage` to uniquely identify this element.
424+
425+
To enter text into this input element, we must use Playwright's
426+
[`fill`](https://playwright.dev/python/docs/api/class-page#page-fill) method.
427+
Append the following line to the test case:
376428

377429
```python
378-
import time
379-
time.sleep(5)
430+
page.fill('#search_form_input_homepage', 'panda')
380431
```
381432

382-
Verify that Playwright calls work and the test passes before moving on.
433+
Using Selenium WebDriver, we would need to locate the element and then send the interaction to it.
434+
However, in Playwright, these two parts are combined into a single call.
435+
We are arbitrarily using the phrase `'panda'` as our search phrase because, well, why not?
383436

437+
Let's handle the second part of the interaction: clicking the search button.
438+
Here's the inspection panel for the search button:
384439

385-
TBD
440+
![Inspecting the search button element](images/inspect-search-button.png)
441+
442+
This element also has an ID: `#search_button_homepage`. Nice!
443+
444+
To click an element, we must use Playwright's
445+
[`click`](https://playwright.dev/python/docs/api/class-page#page-click) method.
446+
Append the following line to the test case:
447+
448+
```python
449+
page.click('#search_button_homepage')
450+
```
451+
452+
Again, Playwright is nice and concise.
453+
454+
Our test case should now look like this:
455+
456+
```python
457+
def test_basic_duckduckgo_search(page):
458+
459+
# Given the DuckDuckGo home page is displayed
460+
page.goto('https://www.duckduckgo.com')
461+
462+
# When the user searches for a phrase
463+
page.fill('#search_form_input_homepage', 'panda')
464+
page.click('#search_button_homepage')
465+
466+
# Then the search result query is the phrase
467+
# And the search result links pertain to the phrase
468+
# And the search result title contains the phrase
469+
pass
470+
```
386471

387-
* pytest fixtures
388-
* Playwright API
389-
* load a page
390-
* fill and click
391-
* run
472+
Rerun the test using `python3 -m pytest tests --headed --slowmo 1000`.
473+
Now, you should see the test actually perform the search!
392474

393475

394476
### Part 3: Refactoring using page objects

images/inspect-search-button.png

1.12 MB
Loading

images/inspect-search-input.png

1.08 MB
Loading

0 commit comments

Comments
 (0)