Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion site/content/learn/playwright/checkout-testing-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ node checkout.js
{{< /tab >}}
{{< /tabs >}}

Note: In some cases, users will need to [log in](/learn/headless/e2e-login/) before they can proceed to a purchase. When users are allowed to buy both with and without having a pre-existing account on the platform, it might be worthwhile to test both flows separately.
Note: In some cases, users will need to [log in](/learn/playwright/login-automation/) before they can proceed to a purchase. When users are allowed to buy both with and without having a pre-existing account on the platform, it might be worthwhile to test both flows separately.

## Limitations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,4 @@ $ node basic-click-type.js

## Further reading
1. The related official documentation of [Playwright](https://playwright.dev/docs/input#mouse-click)
2. [Finding effective selectors](/learn/headless/basics-selectors/)
2. [Finding effective selectors](/learn/playwright/selectors/)
8 changes: 4 additions & 4 deletions site/content/learn/playwright/debugging-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ More often than not, beginners will be looking for a solution to the "obvious" c

To help avoid stressful and unsuccessful debugging sessions, it might help to consider different possible causes depending on the error you are confronted with:

1. [Error: element not found](/learn/headless/error-element-not-found/)
2. [Error: element not visible](/learn/headless/error-element-not-visible/)
3. [Error: target closed](/learn/headless/error-target-closed/)
4. [Error: wait not respected](/learn/headless/error-wait-not-respected/)
1. [Error: element not found](/learn/playwright/error-element-not-found/)
2. [Error: element not visible](/learn/playwright/error-element-not-visible/)
3. [Error: target closed](/learn/playwright/error-target-closed/)
4. [Error: wait not respected](/learn/playwright/error-wait-not-respected/)
8 changes: 4 additions & 4 deletions site/content/learn/playwright/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ When approaching a debugging session, make sure the above points are taken care

Error messages are not present in every scenario: we might be trying to understand why a script _passes_, or why it takes longer than expected. But when we have access to an error message, we can use it to guide us.

The error, in and of its own, is not always enough to understand what is going wrong with your script. Oftentimes, there can be multiple degrees of separation between the error and its root cause. For example: an ["Element not found"](/learn/headless/error-element-not-found/) error might be alerting you to the fact that an element is not being found on the page, but that itself might be because the browser was made to load the wrong URL in the first place.
The error, in and of its own, is not always enough to understand what is going wrong with your script. Oftentimes, there can be multiple degrees of separation between the error and its root cause. For example: an ["Element not found"](/learn/playwright/error-element-not-found/) error might be alerting you to the fact that an element is not being found on the page, but that itself might be because the browser was made to load the wrong URL in the first place.

Do not fall into the easy trap of reading the error message and immediately jumping to conclusions. Rather, take the error message, research it if needed, combine it with your [knowledge of script and app under test](#awareness-comes-first) and treat it as the first piece to the puzzle, rather than the point of arrival of your investigation.

Expand Down Expand Up @@ -104,13 +104,13 @@ If we are using Playwright, we can also run in debug mode with `PWDEBUG=console

The Playwright Inspector is a GUI tool which exposes additional debugging functionality, and can be launched using `PWDEBUG=1 npm run test`.

The Inspector allows us to easily step through each instruction of our script, while giving us clear information on the duration, outcome, and functioning of each. This can be helpful in [getting to the root cause](/learn/headless/debugging-challenges/) of some of the more generic errors.
The Inspector allows us to easily step through each instruction of our script, while giving us clear information on the duration, outcome, and functioning of each. This can be helpful in [getting to the root cause](/learn/playwright/debugging-errors/) of some of the more generic errors.

![playwright inspector debugging](/samples/images/debugging-inspector.png)

> The Inspector includes additional handy features such as selector generation and debugging, as well as script recording.

## Further reading

1. [Debugging challenges](/learn/headless/debugging-challenges/)
2. [Working with selectors](/learn/headless/basics-selectors/)
1. [Debugging challenges](/learn/playwright/debugging-errors/)
2. [Working with selectors](/learn/playwright/selectors/)
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,5 @@ const iPhone = devices['iPhone SE'];

## Further reading

1. [Measuring page performance](/learn/headless/basics-performance/)
1. [Measuring page performance](/learn/playwright/performance/)
2. [Playwright's emulation documentation](https://playwright.dev/docs/emulation)
6 changes: 3 additions & 3 deletions site/content/learn/playwright/error-element-not-found.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ UnhandledPromiseRejectionWarning: Error: No node found for selector: ...

## Possible causes

- **Obvious possible cause #1:** the selector is wrong. See [working with selectors](/learn/headless/basics-selectors/).
- **Obvious possible cause #2:** the element is not on the page and the automation tool is not automatically waiting for it to appear. An [explicit wait](/learn/headless/basics-navigation/) might fix the problem.
- **Not-so-obvious possible cause:** the click on the previous element [did not actually go through](/learn/headless/error-click-not-executed/). From the perspective of our automation tool, everything went fine, but from ours what happened is more similar to a silent failure. We are now looking for the right element but are on the wrong page (or the page is in the wrong state), and the target element is therefore not found.
- **Obvious possible cause #1:** the selector is wrong. See [working with selectors](/learn/playwright/selectors/).
- **Obvious possible cause #2:** the element is not on the page and the automation tool is not automatically waiting for it to appear. An [explicit wait](/learn/playwright/navigation/) might fix the problem.
- **Not-so-obvious possible cause:** the click on the previous element [did not actually go through](/learn/playwright/error-click-not-executed/). From the perspective of our automation tool, everything went fine, but from ours what happened is more similar to a silent failure. We are now looking for the right element but are on the wrong page (or the page is in the wrong state), and the target element is therefore not found.

## How to avoid confusion

Expand Down
4 changes: 2 additions & 2 deletions site/content/learn/playwright/file-download.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ This example runs against our [test webshop](https://danube-web.shop/) and proce
2. Navigating to the account page
3. Downloading a linked file

We will check that the downloaded file is as expected by comparing it to a [fixture file](/learn/headless/test-data-intro/) in our final assertion.
We will check that the downloaded file is as expected by comparing it to a [fixture file](/learn/playwright/handling-test-data/) in our final assertion.

We can approach this scenario in different ways. One possibility is to perform the first two steps, then [extract](/learn/headless/basics-scraping/) the `href` value and use it to retrieve the file with a `GET` request (performed with [axios](https://github.com/axios/axios), for example).
We can approach this scenario in different ways. One possibility is to perform the first two steps, then [extract](/learn/playwright/web-scraping/) the `href` value and use it to retrieve the file with a `GET` request (performed with [axios](https://github.com/axios/axios), for example).

{{< tabs "1" >}}
{{< tab "Playwright" >}}
Expand Down
22 changes: 21 additions & 1 deletion site/content/learn/playwright/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,27 @@ menu:

The [official documentation](https://playwright.dev/) for Playwright reads:

> Playwright provides a set of APIs to automate Chromium, Firefox and WebKit browsers. By using the Playwright API, you can write JavaScript, Typescript [and other languages](https://playwright.dev/docs/languages) to create new browser pages, navigate to URLs and then interact with elements on a page. Our focus in this guide will be on the Javascript & Typescript side of things.


Playwright is an open-source framework for cross-browser automation and end-to-end web application testing. It was designed to be a fast, reliable, robust, and evergreen test automation framework. Playwright provides a set of APIs to automate Chromium, Firefox and WebKit browsers. By using the Playwright API, you can write JavaScript, Typescript [and other languages](https://playwright.dev/docs/languages) to create new browser pages, navigate to URLs and then interact with elements on a page. Our focus in this guide will be on the Javascript & Typescript side of things.

You can import Playwright's provided [`test`](https://playwright.dev/docs/api/class-test) and [`expect`](https://jestjs.io/docs/expect) functions to declare tests and add assertions. We'll be using these throughout our e2e examples as a best practice.
<!-- more -->

## Playwright Features

1. **Mobile Emulation**: Playwright allows you to emulate mobile devices, such as iPhones and iPads, and test how your web application behaves on different screen sizes and orientations.
2. **Headless Mode**: You can run your tests in a headless browser, which is useful for CI/CD pipelines and for running tests in environments where a graphical interface is not available.
3. **Video Recording**: Playwright automatically records videos of your tests, which can be useful for debugging and for creating visual regression tests.
4. **Cross Browser Testing**: Playwright supports multiple browsers, including Chromium, Firefox, and WebKit, allowing you to test your application across different browsers.
5. **Programming Language Support**: Playwright is available in several programming languages, including JavaScript, TypeScript, Python, .NET, and Java, making it accessible to a wide range of developers.
6. **Comprehensive API**: Playwright provides a comprehensive API for automating browser actions, such as navigation, page interaction, and element manipulation.
7. **CI/CD Integration**: Playwright integrates seamlessly with popular CI/CD platforms, such as GitHub Actions, Jenkins, and CircleCI, allowing you to run your tests as part of your continuous integration and delivery process.
8. **Visual Testing**: Playwright supports visual testing, allowing you to compare screenshots of your web application and detect visual changes.
9. **Code Generation**: Playwright includes a code generator that can generate code for your tests, saving you time and reducing the risk of errors.



## Main use cases
1. **Test automation in modern web applications:** verifying that the features we are exposing our users/customers to are actually behaving as expected.
2. **Cross-browser testing:** ensuring applications are working consistently across browsers and rendering engines.
Expand All @@ -31,6 +47,10 @@ You can import Playwright's provided [`test`](https://playwright.dev/docs/api/cl

In this guide you will find multiple examples showing how to leverage Playwright, with a focus on test automation / active reliability.

## Growth and Adoption

Since its release in January 2020 by Microsoft, Playwright has experienced a surge in usage and popularity. As of March 2023, its GitHub repository has received 48.4k stars and 2.4k forks, and is currently averaging more than 1.2 million NPM downloads per week. Playwright is used by enterprise and open-source development projects alike, including Adobe Spectrum, Visual Studio Code, and React Navigation.

## Further reading
1. [Official Playwright API documentation](https://playwright.dev/)
2. [Official Playwright GitHub repo](https://github.com/microsoft/playwright)
2 changes: 1 addition & 1 deletion site/content/learn/playwright/intercept-requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Request interception enables us to observe which requests and responses are bein
{{< /tab >}}
{{< /tabs >}}

We might want to intervene and filter the outgoing requests. For example, when [scraping web pages](/learn/headless/basics-scraping/), we might want to block unnecessary elements from loading in order to speed up the procedure and lower bandwidth usage.
We might want to intervene and filter the outgoing requests. For example, when [scraping web pages](/learn/playwright/web-scraping/), we might want to block unnecessary elements from loading in order to speed up the procedure and lower bandwidth usage.


{{< tabs "2" >}}
Expand Down
2 changes: 1 addition & 1 deletion site/content/learn/playwright/managing-cookies.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ In case you need to clear cookies, you can use [`browserContext.clearCookies()`]

## localStorage and sessionStorage

Cookies are sent with every request, potentially deteriorating [performance](/learn/headless/basics-performance/) if used for storing large amounts of data. The [localStorage and sessionStorage](https://javascript.info/localstorage) APIs can help us offload some of this data to the browser. Just like with cookies, Playwright makes accessing localStorage and sessionStorage straightforward.
Cookies are sent with every request, potentially deteriorating [performance](/learn/playwright/performance/) if used for storing large amounts of data. The [localStorage and sessionStorage](https://javascript.info/localstorage) APIs can help us offload some of this data to the browser. Just like with cookies, Playwright makes accessing localStorage and sessionStorage straightforward.

Our test site, [Danube](https://danube-web.shop/), actually uses localStorage to keep track of things such as the content of your cart. Let's see how we can access this state and then replicate it in a later session.

Expand Down
2 changes: 1 addition & 1 deletion site/content/learn/playwright/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Which of these options is useful to you depends on your situation:
- You server render and load in some non-crucial element in a lazy fashion? go for one of the `networkidle` variant.


Now that we know how to start a browser and navigate to a URL, the clear next step is to learn how to [interact with a webpage](/learn/headless/basics-clicking-typing/).
Now that we know how to start a browser and navigate to a URL, the clear next step is to learn how to [interact with a webpage](/learn/playwright/clicking-typing-hovering/).

## Further reading
1. [Playwright general navigation docs](https://playwright.dev/docs/navigations)
Expand Down
2 changes: 1 addition & 1 deletion site/content/learn/playwright/playwright-vs-others.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ menu:

## Puppeteer vs Playwright

The resemblance to Google's [Puppeteer](/learn/headless/basics-puppeteer-intro/) is striking, and for good reason.
The resemblance to Google's [Puppeteer](https://developer.chrome.com/docs/puppeteer) is striking, and for good reason.

In the words of the authors:

Expand Down
4 changes: 2 additions & 2 deletions site/content/learn/playwright/scraping-behind-login.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ node scraping-example-purchases.js

> Under the hood, Amazon can change quite quickly. You might need to adjust the locators and/or flow slightly to have the script work for you.

> ⚠️ Websites might [restrict headless browser traffic](/learn/headless/challenging-flows/) in order to protect their users from fraud. 2FA will also interfere with the script if enabled.
> ⚠️ Websites might [restrict headless browser traffic](/learn/playwright/challenging-flows/) in order to protect their users from fraud. 2FA will also interfere with the script if enabled.

## Takeaways
1. We can scrape information available behind a login wall with Playwright.
2. Some websites might not allow scraping. Always make sure you check their terms of service beforehand.

## Further reading
1. [Basic scraping](/learn/headless/basics-scraping/) with Playwright
1. [Basic scraping](/learn/playwright/web-scraping/) with Playwright
4 changes: 2 additions & 2 deletions site/content/learn/playwright/script-recorders.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ Regardless of your chosen approach, you will want to inspect the output scripts

Double-check the newly created scripts and tweak it when necessary, especially keeping an eye out for:

1. Selectors, which should be in line with common [best practices](/learn/headless/basics-selectors/).
2. [Waits](/learn/headless/basics-navigation/), which should ensure the right element is present and/or ready for interaction at the right time; also, make sure you get rid of unnecessary waits.
1. Selectors, which should be in line with common [best practices](/learn/playwright/selectors/).
2. [Waits](/learn/playwright/navigation/), which should ensure the right element is present and/or ready for interaction at the right time; also, make sure you get rid of unnecessary waits.
3. Any sort of needless duplication.

## Takeaways
Expand Down
6 changes: 3 additions & 3 deletions site/content/learn/playwright/waits-and-timeouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ In such a situation, the following can happen:

![playwright hard wait time too short](/learn/images/[email protected])

In this case, our hard wait terminates and our click action is attempted too early. The script terminates with an error, possibly of the ["Element not found"](/learn/headless/error-element-not-found/) sort.
In this case, our hard wait terminates and our click action is attempted too early. The script terminates with an error, possibly of the ["Element not found"](/learn/playwright/error-element-not-found/) sort.

2. The element can load before our hard wait has expired.

Expand Down Expand Up @@ -86,11 +86,11 @@ All the above default to waiting for the `{{< newtabref title="load" href="https

> {{< newtabref title="Lazy-loaded pages" href="https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading" >}} might require extra attention when waiting for the content to load, often demanding explicitly waiting for specific UI elements. See the following section.

Additionally, we can also wait until a specific request is sent out or a specific response is received with `{{< newtabref title="page.waitForRequest" href="https://playwright.dev/docs/api/class-page#page-wait-for-request" >}}` and `{{< newtabref title="page.waitForResponse" href="https://playwright.dev/docs/api/class-page#page-wait-for-response" >}}`. These two methods are key for implementing [request and response interception](/learn/headless/request-interception/).
Additionally, we can also wait until a specific request is sent out or a specific response is received with `{{< newtabref title="page.waitForRequest" href="https://playwright.dev/docs/api/class-page#page-wait-for-request" >}}` and `{{< newtabref title="page.waitForResponse" href="https://playwright.dev/docs/api/class-page#page-wait-for-response" >}}`. These two methods are key for implementing [request and response interception](/learn/playwright/intercept-requests/).

### Waiting for an element

We can also explicitly wait for a specific element to appear on the page. This is normally done via `{{< newtabref title="page.waitForSelector" href="https://playwright.dev/docs/api/class-page#page-wait-for-selector" >}}`. A good knowledge of [selectors](/learn/headless/basics-selectors/) is key to enable us to select precisely the element we need to wait for.
We can also explicitly wait for a specific element to appear on the page. This is normally done via `{{< newtabref title="page.waitForSelector" href="https://playwright.dev/docs/api/class-page#page-wait-for-selector" >}}`. A good knowledge of [selectors](/learn/playwright/selectors/) is key to enable us to select precisely the element we need to wait for.

### Waiting on page events

Expand Down
2 changes: 1 addition & 1 deletion site/content/learn/playwright/web-scraping.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,5 @@ $ node scraping.js

## Further reading
1. [Playwright](https://playwright.dev/docs/assertions#text-content)'s official API reference on the topic
2. An [E2E example test](/learn/headless/e2e-coupon/) asserting agains an element's `innerText`
2. An [E2E example test](/learn/playwright/testing-coupons/) asserting agains an element's `innerText`

Loading
Loading