diff --git a/docs/src/running-tests-csharp.md b/docs/src/running-tests-csharp.md
new file mode 100644
index 0000000000..f8d0740e68
--- /dev/null
+++ b/docs/src/running-tests-csharp.md
@@ -0,0 +1,74 @@
+---
+id: running-tests
+title: "Running Tests"
+---
+
+You can run a single test, a set of tests or all tests. Tests can be run on different browsers. By default tests are run in a headless manner meaning no browser window will be opened while running the tests and results will be seen in the terminal. If you prefer you can run your tests in headed mode by using the `headless` test run parameter.
+
+- Running all tests
+
+ ```bash
+ dotnet test
+ ```
+
+- Running a single test file
+
+ ```bash
+ dotnet test --filter "MyClassName"
+ ```
+
+- Run a set of test files
+
+ ```bash
+ dotnet test --filter "MyClassName1|MyClassName2"
+ ```
+
+- Run the test with the title
+
+ ```bash
+ dotnet test --filter "Name~TestMethod1"
+ ```
+
+- Running Tests on specific browsers
+
+ ```bash tab=bash-bash
+ BROWSER=webkit dotnet test
+ ```
+
+ ```batch tab=bash-batch
+ set BROWSER=webkit
+ dotnet test
+ ```
+
+ ```powershell tab=bash-powershell
+ $env:BROWSER="webkit"
+ dotnet test
+ ```
+
+- Running Tests on multiple browsers
+
+ To run your test on multiple browsers or configurations you need to invoke the `dotnet test` command multiple times. There you can then either specify the `BROWSER` environment variable (like the previous) or pass the `browser` via the runsettings file:
+
+ ```bash
+ dotnet test --settings:chromium.runsettings
+ dotnet test --settings:firefox.runsettings
+ dotnet test --settings:webkit.runsettings
+ ```
+
+ ```xml
+
+
+
+
+
+
+
+ ```
+
+For more information see [selective unit tests](https://docs.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=mstest) in the Microsoft docs.
+
+## What's Next
+
+- [Debug tests with the Playwright Debugger](./debug.md)
+- [Generate tests with Codegen](./codegen.md)
+- [See a trace of your tests](./trace-viewer.md)
diff --git a/docs/src/running-tests-python.md b/docs/src/running-tests-python.md
new file mode 100644
index 0000000000..6429135434
--- /dev/null
+++ b/docs/src/running-tests-python.md
@@ -0,0 +1,56 @@
+---
+id: running-tests
+title: "Running Tests"
+---
+
+You can run a single test, a set of tests or all tests. Tests can be run on one browser or multiple browsers. By default tests are run in a headless manner meaning no browser window will be opened while running the tests and results will be seen in the terminal. If you prefer you can run your tests in headed mode by using the `--headed` flag.
+
+- Running tests on Chromium
+
+ ```bash
+ pytest
+ ```
+
+- Running a single test file
+
+ ```bash
+ pytest test_login.py
+ ```
+
+- Run a set of test files
+
+ ```bash
+ pytest tests/todo-page/ tests/landing-page/
+ ```
+
+- Run the test with the function name
+
+ ```bash
+ pytest -k "test_add_a_todo_item"
+ ```
+
+- Running tests in headed mode
+
+ ```bash
+ pytest --headed test_login.py
+ ```
+
+- Running Tests on specific browsers
+
+ ```bash
+ pytest test_login.py --browser webkit
+ ```
+
+- Running Tests on multiple browsers
+
+ ```bash
+ pytest test_login.py --browser webkit --browser firefox
+ ```
+
+For more information see [Playwright Pytest usage](./test-runners.md) or the Pytest documentation for [general CLI usage](https://docs.pytest.org/en/stable/usage.html).
+
+## What's Next
+
+- [Debug tests with the Playwright Debugger](./debug.md)
+- [Generate tests with Codegen](./codegen.md)
+- [See a trace of your tests](./trace-viewer.md)
\ No newline at end of file
diff --git a/docs/src/selectors.md b/docs/src/selectors.md
index 8440cb16ab..8379fe73eb 100644
--- a/docs/src/selectors.md
+++ b/docs/src/selectors.md
@@ -5,6 +5,8 @@ title: "Selectors"
Selectors are strings that are used to create [Locator]s. Locators are used to perform actions on the elements by means of methods such as [`method: Locator.click`], [`method: Locator.fill`] and alike.
+Writing good selectors is part art, part science so be sure to checkout the [Best Practices](#best-practices) section.
+
## Quick guide
diff --git a/docs/src/test-configuration-js.md b/docs/src/test-configuration-js.md
index 91cd5c6bd1..04b2200d35 100644
--- a/docs/src/test-configuration-js.md
+++ b/docs/src/test-configuration-js.md
@@ -545,6 +545,72 @@ export default config;
However, most common ones like `headless` or `viewport` are available directly in the `use` section - see [basic options](#basic-options), [emulation](#emulation) or [network](#network).
+## Explicit Context Creation and Option Inheritance
+
+If using the built-in `browser` fixture, calling [`method: Browser.newContext`] will create a context with options inherted from the config:
+
+```js tab=js-ts
+// playwright.config.ts
+import type { PlaywrightTestConfig } from "@playwright/test";
+
+const config: PlaywrightTestConfig = {
+ use: {
+ userAgent: 'some custom ua',
+ viewport: { width: 100, height: 100 },
+ },
+};
+
+export default config;
+```
+
+```js tab=js-js
+// @ts-check
+// example.spec.js
+
+/** @type {import('@playwright/test').PlaywrightTestConfig} */
+const config = {
+ use: {
+ userAgent: 'some custom ua',
+ viewport: { width: 100, height: 100 },
+ },
+};
+
+module.exports = config;
+```
+
+An example test illustrating the initial context options are set:
+
+```js tab=js-ts
+// example.spec.ts
+import { test, expect } from "@playwright/test";
+
+test('should inherit use options on context when using built-in browser fixture', async ({
+ browser,
+}) => {
+ const context = await browser.newContext();
+ const page = await context.newPage();
+ expect(await page.evaluate(() => navigator.userAgent)).toBe('some custom ua');
+ expect(await page.evaluate(() => window.innerWidth)).toBe(100);
+ await context.close();
+});
+```
+
+```js tab=js-js
+// @ts-check
+// example.spec.ts
+const { test, expect } = require("@playwright/test");
+
+test('should inherit use options on context when using built-in browser fixture', async ({
+ browser,
+}) => {
+ const context = await browser.newContext();
+ const page = await context.newPage();
+ expect(await page.evaluate(() => navigator.userAgent)).toBe('some custom ua');
+ expect(await page.evaluate(() => window.innerWidth)).toBe(100);
+ await context.close();
+});
+```
+
## Testing options
In addition to configuring [Browser] or [BrowserContext], videos or screenshots, Playwright Test has many options to configure how your tests are run. Below are the most common ones, see [TestConfig] for the full list.
diff --git a/docs/src/test-runners-csharp.md b/docs/src/test-runners-csharp.md
index efa4fda4c8..bb0ee535b4 100644
--- a/docs/src/test-runners-csharp.md
+++ b/docs/src/test-runners-csharp.md
@@ -108,6 +108,69 @@ By default NUnit will run all test files in parallel, while running tests inside
For CPU-bound tests, we recommend using as many workers as there are cores on your system, divided by 2. For IO-bound tests you can use as many workers as you have cores.
+### Customizing [BrowserContext] options
+
+To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example:
+
+```csharp
+using Microsoft.Playwright.NUnit;
+
+namespace PlaywrightTests;
+
+[Parallelizable(ParallelScope.Self)]
+public class MyTest : PageTest
+{
+ [Test]
+ public async Task TestWithCustomContextOptions()
+ {
+ // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set:
+ await Page.GotoAsync("/login");
+ }
+
+ public override BrowserNewContextOptions ContextOptions()
+ {
+ return new BrowserNewContextOptions()
+ {
+ ColorScheme = ColorScheme.Light,
+ ViewportSize = new()
+ {
+ Width = 1920,
+ Height = 1080
+ },
+ BaseURL = "https://github.com",
+ };
+ }
+}
+```
+
+### Customizing [Browser]/launch options
+
+[Browser]/launch options can be override either using a run settings file or by setting the run settings options directly via the
+CLI. See the following example:
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+```bash tab=bash-bash
+dotnet test -- TestRunParameters.Parameter\(name=\"browser\", value=\"chromium\"\) TestRunParameters.Parameter\(name=\"headless\", value=\"false\"\) TestRunParameters.Parameter\(name=\"channel\", value=\"msedge\"\)
+```
+
+```batch tab=bash-batch
+dotnet test -- TestRunParameters.Parameter(name=\"browser\", value=\"chromium\") TestRunParameters.Parameter(name=\"headless\", value=\"false\") TestRunParameters.Parameter(name=\"channel\", value=\"msedge\")
+```
+
+```powershell tab=bash-powershell
+dotnet test -- TestRunParameters.Parameter(name=\"browser\", value=\"chromium\") TestRunParameters.Parameter(name=\"headless\", value=\"false\") TestRunParameters.Parameter(name=\"channel\", value=\"msedge\")
+```
+
### Using Verbose API Logs
When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In NUnit, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test.
@@ -247,6 +310,73 @@ By default MSTest will run all classes in parallel, while running tests inside e
dotnet test --settings:.runsettings -- MSTest.Parallelize.Workers=4
```
+### Customizing [BrowserContext] options
+
+To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example:
+
+```csharp
+using System.Threading.Tasks;
+using Microsoft.Playwright;
+using Microsoft.Playwright.MSTest;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace PlaywrightTests;
+
+[TestClass]
+public class UnitTest1 : PageTest
+{
+ [TestMethod]
+ public async Task TestWithCustomContextOptions()
+ {
+ // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set:
+ await Page.GotoAsync("/login");
+ }
+
+ public override BrowserNewContextOptions ContextOptions()
+ {
+ return new BrowserNewContextOptions()
+ {
+ ColorScheme = ColorScheme.Light,
+ ViewportSize = new()
+ {
+ Width = 1920,
+ Height = 1080
+ },
+ BaseURL = "https://github.com",
+ };
+ }
+}
+
+```
+
+### Customizing [Browser]/launch options
+
+[Browser]/launch options can be override either using a run settings file or by setting the run settings options directly via the
+CLI. See the following example:
+
+```xml
+
+
+
+
+
+
+
+
+```
+
+```bash tab=bash-bash
+dotnet test -- TestRunParameters.Parameter\(name=\"browser\", value=\"chromium\"\) TestRunParameters.Parameter\(name=\"headless\", value=\"false\"\) TestRunParameters.Parameter\(name=\"channel\", value=\"msedge\"\)
+```
+
+```batch tab=bash-batch
+dotnet test -- TestRunParameters.Parameter(name=\"browser\", value=\"chromium\") TestRunParameters.Parameter(name=\"headless\", value=\"false\") TestRunParameters.Parameter(name=\"channel\", value=\"msedge\")
+```
+
+```powershell tab=bash-powershell
+dotnet test -- TestRunParameters.Parameter(name=\"browser\", value=\"chromium\") TestRunParameters.Parameter(name=\"headless\", value=\"false\") TestRunParameters.Parameter(name=\"channel\", value=\"msedge\")
+```
+
### Using Verbose API Logs
When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In MSTest, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test.
diff --git a/docs/src/test-runners-python.md b/docs/src/test-runners-python.md
index d417d06f78..c912e8d8fe 100644
--- a/docs/src/test-runners-python.md
+++ b/docs/src/test-runners-python.md
@@ -1,42 +1,16 @@
---
id: test-runners
-title: "Pytest plugin"
+title: "Pytest Plugin Reference"
---
-Write end-to-end tests for your web apps with [Pytest](https://docs.pytest.org/en/stable/).
-
-
+Playwright provides a [Pytest](https://docs.pytest.org/en/stable/) plugin to write end-to-end tests. To get started with it, refer to the [getting started guide](./intro.md).
## Usage
-```bash
-pip install pytest-playwright
-```
-
-Use the `page` fixture to write a basic test. See [more examples](#examples).
-
-```py
-# test_my_application.py
-def test_example_is_working(page):
- page.goto("https://example.com")
- assert page.inner_text('h1') == 'Example Domain'
- page.locator("text=More information").click()
-```
-
-To run your tests, use pytest CLI.
+To run your tests, use [Pytest](https://docs.pytest.org/en/stable/) CLI.
```bash
-# Run tests (Chromium and headless by default)
-pytest
-
-# Run tests in headed mode
-pytest --headed
-
-# Run tests in a different browser (chromium, firefox, webkit)
-pytest --browser firefox
-
-# Run tests in multiple browsers
-pytest --browser chromium --browser webkit
+pytest --browser webkit --headedd
```
If you want to add the CLI arguments automatically without specifying them, you can use the [pytest.ini](https://docs.pytest.org/en/stable/reference.html#ini-options-ref) file:
diff --git a/docs/src/test-snapshots-js.md b/docs/src/test-snapshots-js.md
index 04c6c0ae1c..9ed3e54778 100644
--- a/docs/src/test-snapshots-js.md
+++ b/docs/src/test-snapshots-js.md
@@ -70,7 +70,7 @@ npx playwright test --update-snapshots
> Note that `snapshotName` also accepts an array of path segments to the snapshot file such as `expect().toHaveScreenshot(['relative', 'path', 'to', 'snapshot.png'])`.
> However, this path must stay within the snapshots directory for each test file (i.e. `a.spec.js-snapshots`), otherwise it will throw.
-Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./test-assertions#expectpageorlocatortomatchsnapshot-options) to modify its behavior:
+Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./test-assertions#page-assertions-to-have-screenshot-2) to modify its behavior:
```js tab=js-js
// example.spec.js
diff --git a/docs/src/writing-tests-csharp.md b/docs/src/writing-tests-csharp.md
new file mode 100644
index 0000000000..cac275ad9a
--- /dev/null
+++ b/docs/src/writing-tests-csharp.md
@@ -0,0 +1,238 @@
+---
+id: writing-tests
+title: "Writing Tests"
+---
+
+Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met. Playwright comes with [auto-wait](./actionability.md) built in meaning it waits for elements to be actionable prior to performing actions. Playwright provides the [Expect](./test-assertions) function to write assertions.
+
+Take a look at the example test below to see how to write a test using web first assertions, locators and selectors.
+
+
+
+
+```csharp
+using System.Text.RegularExpressions;
+using Microsoft.Playwright.NUnit;
+
+namespace PlaywrightTests;
+
+[Parallelizable(ParallelScope.Self)]
+public class Tests : PageTest
+{
+ [Test]
+ async public Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+
+ // Expect a title "to contain" a substring.
+ await Expect(Page).ToHaveTitleAsync(new Regex("Playwright"));
+
+ // create a locator
+ var getStarted = Page.Locator("text=Get Started");
+
+ // Expect an attribute "to be strictly equal" to the value.
+ await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro");
+
+ // Click the get started link.
+ await getStarted.ClickAsync();
+
+ // Expects the URL to contain intro.
+ await Expect(Page).ToHaveURLAsync(new Regex(".*intro"));
+ }
+}
+```
+
+
+
+
+```csharp
+using System.Text.RegularExpressions;
+using Microsoft.Playwright.MSTest;
+
+namespace PlaywrightTests;
+
+public class UnitTest1 : PageTest
+{
+ [TestMethod]
+ async public Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+
+ // Expect a title "to contain" a substring.
+ await Expect(Page).ToHaveTitleAsync(new Regex("Playwright"));
+
+ // create a locator
+ var getStarted = Page.Locator("text=Get Started");
+
+ // Expect an attribute "to be strictly equal" to the value.
+ await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro");
+
+ // Click the get started link.
+ await getStarted.ClickAsync();
+
+ // Expects the URL to contain intro.
+ await Expect(Page).ToHaveURLAsync(new Regex(".*intro"));
+ }
+}
+```
+
+
+
+
+### Assertions
+
+Playwright provides an async function called [Expect](./test-assertions) to assert and wait until the expected condition is met.
+
+```csharp
+await Expect(Page).ToHaveTitleAsync(new Regex("Playwright"));
+```
+
+
+### Locators
+
+[Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.ClickAsync` `.FillAsync` etc. Custom locators can be created with the [`method: Page.locator`] method.
+
+```csharp
+var getStarted = Page.Locator("text=Get Started");
+
+await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/installation");
+await getStarted.ClickAsync();
+```
+
+[Selectors](./selectors.md) are strings that are used to create Locators. Playwright supports many different selectors like [Text](./selectors.md#text-selector), [CSS](./selectors.md#css-selector), [XPath](./selectors.md#xpath-selectors) and many more. Learn more about available selectors and how to pick one in this [in-depth guide](./selectors.md).
+
+```csharp
+await Expect(Page.Locator("text=Installation")).ToBeVisibleAsync();
+```
+
+
+### Test Isolation
+
+The Playwright NUnit and MSTest test framework base classes will isolate each test from each other by providing a separate `Page` instance. Pages are isolated between tests due to the Browser Context, which is equivalent to a brand new browser profile, where every test gets a fresh environment, even when multiple tests run in a single Browser.
+
+
+
+
+```csharp
+using System.Threading.Tasks;
+using Microsoft.Playwright.NUnit;
+using NUnit.Framework;
+
+namespace PlaywrightTests;
+
+[Parallelizable(ParallelScope.Self)]
+public class Tests : PageTest
+{
+ [Test]
+ public async Task BasicTest()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+ }
+}
+```
+
+
+
+
+```csharp
+using Microsoft.Playwright.MSTest;
+
+namespace PlaywrightTests;
+
+public class UnitTest1 : PageTest
+{
+ [TestMethod]
+ public async Task BasicTest()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+ }
+}
+```
+
+
+
+
+### Using Test Hooks
+
+You can use `SetUp`/`TearDown` in NUnit or `TestInitialize`/`TestCleanup` in MSTest to prepare and clean up your test environment:
+
+
+
+
+```csharp
+using System.Threading.Tasks;
+using Microsoft.Playwright.NUnit;
+using NUnit.Framework;
+
+namespace PlaywrightTests;
+
+[Parallelizable(ParallelScope.Self)]
+public class Tests : PageTest
+{
+ [Test]
+ public async Task MainNavigation()
+ {
+ // Assertions use the expect API.
+ await Expect(Page).ToHaveURLAsync("https://playwright.dev/");
+ }
+
+ [SetUp]
+ public async Task SetUp()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+ }
+}
+```
+
+
+
+
+```csharp
+using Microsoft.Playwright.MSTest;
+
+namespace PlaywrightTests;
+
+public class UnitTest1 : PageTest
+{
+ [TestMethod]
+ public async Task MainNavigation()
+ {
+ // Assertions use the expect API.
+ await Expect(Page).ToHaveURLAsync("https://playwright.dev/");
+ }
+
+ [TestInitialize]
+ public async Task TestInitialize()
+ {
+ await Page.GotoAsync("https://playwright.dev");
+ }
+}
+```
+
+
+
+
+## What's Next
+
+- [Run single tests, multiple tests, headed mode](./running-tests.md)
+- [Debug tests with the Playwright Debugger](./debug.md)
+- [Generate tests with Codegen](./codegen.md)
+- [See a trace of your tests](./trace-viewer.md)
\ No newline at end of file
diff --git a/docs/src/writing-tests-js.md b/docs/src/writing-tests-js.md
index 28207d3a48..0e5a22c303 100644
--- a/docs/src/writing-tests-js.md
+++ b/docs/src/writing-tests-js.md
@@ -3,7 +3,7 @@ id: writing-tests
title: "Writing Tests"
---
-Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met. Playwright comes with auto-wait built in meaning it waits for elements to be actionable prior to performing actions. Playwright provides a [test](./api/class-test.md) function to declare tests and the [expect](https://jestjs.io/docs/expect) function to write assertions.
+Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met. Playwright comes with [auto-wait](./actionability.md) built in meaning it waits for elements to be actionable prior to performing actions. Playwright provides a [test](./api/class-test.md) function to declare tests and the [expect](https://jestjs.io/docs/expect) function to write assertions.
Take a look at the example test included when installing Playwright to see how to write a test using web first assertions, locators and selectors.
@@ -69,7 +69,7 @@ await expect(page).toHaveTitle(/Playwright/);
### Locators
-[Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as .click. fill etc. Custom locators can be created with the [`method: Page.locator`] method.
+[Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.click` `.fill` etc. Custom locators can be created with the [`method: Page.locator`] method.
```js
const getStarted = page.locator('text=Get Started');
@@ -78,7 +78,8 @@ await expect(getStarted).toHaveAttribute('href', '/docs/installation');
await getStarted.click();
```
-[Selectors](./selectors.md) are strings that are used to create Locators. Playwright supports many different selectors like [Text](./selectors.md#text-selector), [CSS](./selectors.md#css-selector), [XPath](./selectors.md#xpath-selectors) and many more.
+[Selectors](./selectors.md) are strings that are used to create Locators. Playwright supports many different selectors like [Text](./selectors.md#text-selector), [CSS](./selectors.md#css-selector), [XPath](./selectors.md#xpath-selectors) and many more. Learn more about available selectors and how to pick one in this [in-depth guide](./selectors.md).
+
```js
await expect(page.locator('text=Installation')).toBeVisible();
diff --git a/docs/src/writing-tests-python.md b/docs/src/writing-tests-python.md
new file mode 100644
index 0000000000..685d625046
--- /dev/null
+++ b/docs/src/writing-tests-python.md
@@ -0,0 +1,110 @@
+---
+id: writing-tests
+title: "Writing Tests"
+---
+
+Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met. Playwright comes with [auto-wait](./actionability.md) built in meaning it waits for elements to be actionable prior to performing actions. Playwright provides an [expect](./test-assertions.md) function to write assertions.
+
+Take a look at the example test below to see how to write a test using web first assertions, locators and selectors.
+
+```python
+import re
+from playwright.sync_api import Page, expect
+
+
+def test_homepage_has_Playwright_in_title_and_get_started_link_linking_to_the_intro_page(
+ page: Page, foo
+):
+ page.goto("https://playwright.dev/")
+
+ # Expect a title "to contain" a substring.
+ expect(page).to_have_title(re.compile("Playwright"))
+
+ # create a locator
+ get_started = page.locator("text=Get Started")
+
+ # Expect an attribute "to be strictly equal" to the value.
+ expect(get_started).to_have_attribute("href", "/docs/intro")
+
+ # Click the get started link.
+ get_started.click()
+
+ # Expects the URL to contain intro.
+ expect(page).to_have_url(re.compile(".*intro"))
+```
+
+
+### Assertions
+
+Playwright provides the [`expect`](./test-assertions.md) function which will wait until the expected condition is met.
+
+```python
+import re
+from playwright.sync_api import expect
+
+expect(page).to_have_title(re.compile("Playwright"))
+```
+
+
+### Locators
+
+[Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.click` `.fill` etc. Custom locators can be created with the [`method: Page.locator`] method.
+
+```python
+from playwright.sync_api import expect
+
+get_started = page.locator("text=Get Started")
+
+expect(get_started).to_have_attribute("href", "/docs/installation")
+get_started.click()
+```
+
+[Selectors](./selectors.md) are strings that are used to create Locators. Playwright supports many different selectors like [Text](./selectors.md#text-selector), [CSS](./selectors.md#css-selector), [XPath](./selectors.md#xpath-selectors) and many more. Learn more about available selectors and how to pick one in this [in-depth guide](./selectors.md).
+
+
+```python
+from playwright.sync_api import expect
+
+expect(page.locator("text=Installation")).to_be_visible()
+```
+
+
+### Test Isolation
+
+The Playwright Pytest plugin is based on the concept of test fixtures such as the [built in page fixture](./test-runners.md), which is passed into your test. Pages are isolated between tests due to the Browser Context, which is equivalent to a brand new browser profile, where every test gets a fresh environment, even when multiple tests run in a single Browser.
+
+```python
+from playwright.sync_api import Page
+
+def test_basic_test(page: Page):
+ # ...
+```
+
+### Using Test Hooks
+
+You can use various [fixtures](https://docs.pytest.org/en/6.2.x/fixture.html#autouse-fixtures-fixtures-you-don-t-have-to-request) to execute code before or after your tests and to share objects between them. A `function` scoped fixture e.g. with autouse behaves like a beforeEach/afterEach. And a `module` scoped fixture with autouse behaves like a beforeAll/afterAll which runs before all and after all the tests.
+
+```python
+import pytest
+from playwright.sync_api import Page
+
+
+@pytest.fixture(scope="function", autouse=True)
+def before_each_after_each(page: Page):
+ print("beforeEach")
+ # Go to the starting url before each test.
+ page.goto("https://playwright.dev/")
+ yield
+ print("afterEach")
+
+def test_main_navigation(page: Page):
+ # Assertions use the expect API.
+ expect(page).to_have_url("https://playwright.dev/")
+```
+
+## What's Next
+
+- [Run single tests, multiple tests, headed mode](./running-tests.md)
+- [Debug tests with the Playwright Debugger](./debug.md)
+- [Generate tests with Codegen](./codegen.md)
+- [See a trace of your tests](./trace-viewer.md)
\ No newline at end of file