mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
docs: code snippet alignments (#23959)
This commit is contained in:
parent
c2127595b8
commit
fef029e98e
@ -204,6 +204,7 @@ try {
|
||||
try:
|
||||
await page.wait_for_selector(".foo")
|
||||
except TimeoutError as e:
|
||||
pass
|
||||
# do something if this is a timeout.
|
||||
```
|
||||
|
||||
@ -211,6 +212,7 @@ except TimeoutError as e:
|
||||
try:
|
||||
page.wait_for_selector(".foo")
|
||||
except TimeoutError as e:
|
||||
pass
|
||||
# do something if this is a timeout.
|
||||
```
|
||||
|
||||
@ -277,15 +279,15 @@ process inherits environment variables of the Playwright process.
|
||||
Terminates this instance of Playwright in case it was created bypassing the Python context manager. This is useful in REPL applications.
|
||||
|
||||
```py
|
||||
>>> from playwright.sync_api import sync_playwright
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
>>> playwright = sync_playwright().start()
|
||||
playwright = sync_playwright().start()
|
||||
|
||||
>>> browser = playwright.chromium.launch()
|
||||
>>> page = browser.new_page()
|
||||
>>> page.goto("https://playwright.dev/")
|
||||
>>> page.screenshot(path="example.png")
|
||||
>>> browser.close()
|
||||
browser = playwright.chromium.launch()
|
||||
page = browser.new_page()
|
||||
page.goto("https://playwright.dev/")
|
||||
page.screenshot(path="example.png")
|
||||
browser.close()
|
||||
|
||||
>>> playwright.stop()
|
||||
playwright.stop()
|
||||
```
|
||||
|
@ -1667,7 +1667,7 @@ The value might include some "tokens" that will be replaced with actual values d
|
||||
|
||||
Consider the following file structure:
|
||||
|
||||
```
|
||||
```txt
|
||||
playwright.config.ts
|
||||
tests/
|
||||
└── page/
|
||||
|
@ -16,8 +16,7 @@ Using a canary release in production might seem risky, but in practice, it's not
|
||||
A canary release passes all automated tests and is used to test e.g. the HTML report, Trace Viewer, or Playwright Inspector with end-to-end tests.
|
||||
|
||||
:::
|
||||
|
||||
```
|
||||
```txt
|
||||
npm install -D @playwright/test@next
|
||||
```
|
||||
|
||||
@ -33,7 +32,7 @@ You can see on [npm](https://www.npmjs.com/package/@playwright/test?activeTab=ve
|
||||
|
||||
## Using a Canary Release
|
||||
|
||||
```
|
||||
```txt
|
||||
npm install -D @playwright/test@next
|
||||
```
|
||||
|
||||
|
@ -138,13 +138,13 @@ Browser builds for Firefox and WebKit are built for the [glibc](https://en.wikip
|
||||
|
||||
Use [`//utils/docker/build.sh`](https://github.com/microsoft/playwright/blob/main/utils/docker/build.sh) to build the image.
|
||||
|
||||
```
|
||||
```txt
|
||||
./utils/docker/build.sh jammy playwright:localbuild-jammy
|
||||
```
|
||||
|
||||
The image will be tagged as `playwright:localbuild-jammy` and could be run as:
|
||||
|
||||
```
|
||||
```txt
|
||||
docker run --rm -it playwright:localbuild /bin/bash
|
||||
```
|
||||
|
||||
|
@ -453,7 +453,7 @@ await page.GetByRole(AriaRole.Textbox).PressAsync("$");
|
||||
|
||||
The [`method: Locator.press`] method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property of the keyboard events:
|
||||
|
||||
```
|
||||
```txt
|
||||
Backquote, Minus, Equal, Backslash, Backspace, Tab, Delete, Escape,
|
||||
ArrowDown, End, Enter, Home, Insert, PageDown, PageUp, ArrowRight,
|
||||
ArrowUp, F1 - F12, Digit0 - Digit9, KeyA - KeyZ, etc.
|
||||
|
@ -92,16 +92,16 @@ python
|
||||
and then launch Playwright within it for quick experimentation:
|
||||
|
||||
```py
|
||||
>>> from playwright.sync_api import sync_playwright
|
||||
>>> playwright = sync_playwright().start()
|
||||
from playwright.sync_api import sync_playwright
|
||||
playwright = sync_playwright().start()
|
||||
# Use playwright.chromium, playwright.firefox or playwright.webkit
|
||||
# Pass headless=False to launch() to see the browser UI
|
||||
>>> browser = playwright.chromium.launch()
|
||||
>>> page = browser.new_page()
|
||||
>>> page.goto("https://playwright.dev/")
|
||||
>>> page.screenshot(path="example.png")
|
||||
>>> browser.close()
|
||||
>>> playwright.stop()
|
||||
browser = playwright.chromium.launch()
|
||||
page = browser.new_page()
|
||||
page.goto("https://playwright.dev/")
|
||||
page.screenshot(path="example.png")
|
||||
browser.close()
|
||||
playwright.stop()
|
||||
```
|
||||
|
||||
Async REPL such as `asyncio` REPL:
|
||||
@ -111,14 +111,14 @@ python -m asyncio
|
||||
```
|
||||
|
||||
```py
|
||||
>>> from playwright.async_api import async_playwright
|
||||
>>> playwright = await async_playwright().start()
|
||||
>>> browser = await playwright.chromium.launch()
|
||||
>>> page = await browser.new_page()
|
||||
>>> await page.goto("https://playwright.dev/")
|
||||
>>> await page.screenshot(path="example.png")
|
||||
>>> await browser.close()
|
||||
>>> await playwright.stop()
|
||||
from playwright.async_api import async_playwright
|
||||
playwright = await async_playwright().start()
|
||||
browser = await playwright.chromium.launch()
|
||||
page = await browser.new_page()
|
||||
await page.goto("https://playwright.dev/")
|
||||
await page.screenshot(path="example.png")
|
||||
await browser.close()
|
||||
await playwright.stop()
|
||||
```
|
||||
|
||||
## Pyinstaller
|
||||
|
@ -15,7 +15,7 @@ The following code will intercept all the calls to `*/**/api/v1/fruits` and will
|
||||
```js
|
||||
test("mocks a fruit and doesn't call api", async ({ page }) => {
|
||||
// Mock the api call before navigating
|
||||
await page.route('*/**/api/v1/fruits', async (route) => {
|
||||
await page.route('*/**/api/v1/fruits', async route => {
|
||||
const json = [{ name: 'Strawberry', id: 21 }];
|
||||
await route.fulfill({ json });
|
||||
});
|
||||
@ -115,7 +115,7 @@ In the example below we intercept the call to the fruit API and add a new fruit
|
||||
```js
|
||||
test('gets the json from api and adds a new fruit', async ({ page }) => {
|
||||
// Get the response and add to it
|
||||
await page.route('*/**/api/v1/fruits', async (route) => {
|
||||
await page.route('*/**/api/v1/fruits', async route => {
|
||||
const response = await route.fetch();
|
||||
const json = await response.json();
|
||||
json.push({ name: 'Playwright', id: 100 });
|
||||
@ -188,7 +188,7 @@ await page.RouteAsync("*/**/api/v1/fruits", async (route) => {
|
||||
await page.GotoAsync("https://demo.playwright.dev/api-mocking");
|
||||
|
||||
// Assert that the Strawberry fruit is visible
|
||||
await Expect(page.GetByTextAsync("Playwright", new() { Exact: true })).ToBeVisibleAsync();
|
||||
await Expect(page.GetByTextAsync("Playwright", new () { Exact = true })).ToBeVisibleAsync();
|
||||
```
|
||||
|
||||
```java
|
||||
@ -266,10 +266,8 @@ def records_or_updates_the_har_file(page: Page):
|
||||
```csharp
|
||||
// Get the response from the HAR file
|
||||
await page.RouteFromHARAsync("./hars/fruit.har", new () {
|
||||
{
|
||||
Url = "*/**/api/v1/fruits",
|
||||
Update = true,
|
||||
}
|
||||
});
|
||||
|
||||
// Go to the page
|
||||
|
@ -894,9 +894,11 @@ We recommend [chaining locators](./locators.md#chaining-locators) instead.
|
||||
Selectors defined as `engine=body` or in short-form can be combined with the `>>` token, e.g. `selector1 >> selector2 >> selectors3`. When selectors are chained, the next one is queried relative to the previous one's result.
|
||||
|
||||
For example,
|
||||
```
|
||||
|
||||
```txt
|
||||
css=article >> css=.bar > .baz >> css=span[attr=value]
|
||||
```
|
||||
|
||||
is equivalent to
|
||||
|
||||
```js browser
|
||||
|
@ -305,7 +305,7 @@ All the same methods are also available on [Locator], [FrameLocator] and [Frame]
|
||||
|
||||
- [`method: LocatorAssertions.toHaveAttribute`] with an empty value does not match missing attribute anymore. For example, the following snippet will succeed when `button` **does not** have a `disabled` attribute.
|
||||
|
||||
```js
|
||||
```java
|
||||
assertThat(page.getByRole(AriaRole.BUTTON)).hasAttribute("disabled", "");
|
||||
```
|
||||
|
||||
@ -340,7 +340,7 @@ This version was also tested against the following stable channels:
|
||||
A bunch of Playwright APIs already support the `setWaitUntil(WaitUntilState.DOMCONTENTLOADED)` option.
|
||||
For example:
|
||||
|
||||
```js
|
||||
```java
|
||||
page.navigate("https://playwright.dev", new Page.NavigateOptions().setWaitUntil(WaitUntilState.DOMCONTENTLOADED));
|
||||
```
|
||||
|
||||
|
@ -930,7 +930,7 @@ Read more about [component testing with Playwright](./test-components).
|
||||
use: {
|
||||
serviceWorkers: 'block',
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
* Using `.zip` path for `recordHar` context option automatically zips the resulting HAR:
|
||||
```ts
|
||||
|
@ -300,7 +300,7 @@ All the same methods are also available on [Locator], [FrameLocator] and [Frame]
|
||||
|
||||
- [`method: LocatorAssertions.toHaveAttribute`] with an empty value does not match missing attribute anymore. For example, the following snippet will succeed when `button` **does not** have a `disabled` attribute.
|
||||
|
||||
```js
|
||||
```python
|
||||
expect(page.get_by_role("button")).to_have_attribute("disabled", "")
|
||||
```
|
||||
|
||||
|
@ -33,30 +33,6 @@ await page.goto('/example-with-a-service-worker.html');
|
||||
const serviceworker = await serviceWorkerPromise;
|
||||
```
|
||||
|
||||
```python async
|
||||
async with context.expect_event("serviceworker") as event_info:
|
||||
await page.goto('/example-with-a-service-worker.html')
|
||||
serviceworker = await event_info.value
|
||||
```
|
||||
|
||||
```python sync
|
||||
with context.expect_event("serviceworker") as event_info:
|
||||
page.goto('/example-with-a-service-worker.html')
|
||||
serviceworker = event_info.value
|
||||
```
|
||||
|
||||
```csharp
|
||||
var waitForServiceWorkerTask = page.WaitForServiceWorkerAsync();
|
||||
await page.GotoAsync('/example-with-a-service-worker.html');
|
||||
var serviceworker = await waitForServiceWorkerTask;
|
||||
```
|
||||
|
||||
```java
|
||||
Worker serviceWorker = page.waitForRequest(() -> {
|
||||
page.navigate('/example-with-a-service-worker.html');
|
||||
});
|
||||
```
|
||||
|
||||
[`event: BrowserContext.serviceWorker`] is fired ***before*** the Service Worker's main script has been evaluated, so ***before*** calling service[`method: Worker.evaluate`] you should wait on its activation.
|
||||
|
||||
There are more idiomatic methods of waiting for a Service Worker to be activated, but the following is an implementation agnostic method:
|
||||
@ -70,44 +46,6 @@ await page.evaluate(async () => {
|
||||
});
|
||||
```
|
||||
|
||||
```python async
|
||||
await page.evaluate("""async () => {
|
||||
const registration = await window.navigator.serviceWorker.getRegistration();
|
||||
if (registration.active?.state === 'activated')
|
||||
return;
|
||||
await new Promise(res => window.navigator.serviceWorker.addEventListener('controllerchange', res));
|
||||
}""")
|
||||
```
|
||||
|
||||
```python sync
|
||||
page.evaluate("""async () => {
|
||||
const registration = await window.navigator.serviceWorker.getRegistration();
|
||||
if (registration.active?.state === 'activated')
|
||||
return;
|
||||
await new Promise(res => window.navigator.serviceWorker.addEventListener('controllerchange', res));
|
||||
}""")
|
||||
```
|
||||
|
||||
```csharp
|
||||
await page.EvaluateAsync(@"async () => {
|
||||
const registration = await window.navigator.serviceWorker.getRegistration();
|
||||
if (registration.active?.state === 'activated')
|
||||
return;
|
||||
await new Promise(res => window.navigator.serviceWorker.addEventListener('controllerchange', res));
|
||||
}");
|
||||
```
|
||||
|
||||
```java
|
||||
page.evaluate(
|
||||
"async () => {"
|
||||
" const registration = await window.navigator.serviceWorker.getRegistration();" +
|
||||
" if (registration.active?.state === 'activated')" +
|
||||
" return;" +
|
||||
" await new Promise(res => window.navigator.serviceWorker.addEventListener('controllerchange', res));" +
|
||||
"}"
|
||||
)
|
||||
```
|
||||
|
||||
### Network Events and Routing
|
||||
|
||||
Any network request made by the **Service Worker** will have:
|
||||
@ -248,34 +186,6 @@ await page.evaluate(() => fetch('/tracker.js'));
|
||||
await page.evaluate(() => fetch('/fallthrough.txt'));
|
||||
```
|
||||
|
||||
```python async
|
||||
await page.evaluate("fetch('/addressbook.json')")
|
||||
await page.evaluate("fetch('/foo')")
|
||||
await page.evaluate("fetch('/tracker.js')")
|
||||
await page.evaluate("fetch('/fallthrough.txt')")
|
||||
```
|
||||
|
||||
```python sync
|
||||
page.evaluate("fetch('/addressbook.json')")
|
||||
page.evaluate("fetch('/foo')")
|
||||
page.evaluate("fetch('/tracker.js')")
|
||||
page.evaluate("fetch('/fallthrough.txt')")
|
||||
```
|
||||
|
||||
```csharp
|
||||
await page.EvaluateAsync("fetch('/addressbook.json')");
|
||||
await page.EvaluateAsync("fetch('/foo')");
|
||||
await page.EvaluateAsync("fetch('/tracker.js')");
|
||||
await page.EvaluateAsync("fetch('/fallthrough.txt')");
|
||||
```
|
||||
|
||||
```java
|
||||
page.evaluate("fetch('/addressbook.json')")
|
||||
page.evaluate("fetch('/foo')")
|
||||
page.evaluate("fetch('/tracker.js')")
|
||||
page.evaluate("fetch('/fallthrough.txt')")
|
||||
```
|
||||
|
||||
The following Request/Response events would be emitted:
|
||||
|
||||
| Event | Owner | URL | Routed | [`method: Response.fromServiceWorker`] |
|
||||
@ -313,56 +223,6 @@ await context.route('**', async route => {
|
||||
});
|
||||
```
|
||||
|
||||
```python async
|
||||
async def handle(route: Route):
|
||||
if route.request.service_worker:
|
||||
# NB: calling route.request.frame here would THROW
|
||||
await route.fulfill(content_type='text/plain', status=200, body='from sw');
|
||||
else:
|
||||
await route.continue_()
|
||||
await context.route('**', handle)
|
||||
```
|
||||
|
||||
```python sync
|
||||
def handle(route: Route):
|
||||
if route.request.service_worker:
|
||||
# NB: calling route.request.frame here would THROW
|
||||
route.fulfill(content_type='text/plain', status=200, body='from sw');
|
||||
else:
|
||||
route.continue_()
|
||||
context.route('**', handle)
|
||||
```
|
||||
|
||||
```csharp
|
||||
await context.RouteAsync("**", async route => {
|
||||
if (route.request().serviceWorker() != null) {
|
||||
// NB: calling route.request.frame here would THROW
|
||||
await route.FulfillAsync(new ()
|
||||
{
|
||||
ContentType = "text/plain",
|
||||
Status = 200,
|
||||
Body = "from sw"
|
||||
});
|
||||
} else {
|
||||
await route.Continue()Async();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
```java
|
||||
browserContext.route("**", route -> {
|
||||
if (route.request()) {
|
||||
// calling route.request().frame() here would THROW
|
||||
route.fulfill(new Route.FulfillOptions()
|
||||
.setStatus(200)
|
||||
.setContentType("text/plain")
|
||||
.setBody("from sw"));
|
||||
} else {
|
||||
route.resume();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
|
||||
Requests for updated Service Worker main script code currently cannot be routed (https://github.com/microsoft/playwright/issues/14711).
|
||||
|
@ -498,7 +498,7 @@ await mount(app);
|
||||
|
||||
results in
|
||||
|
||||
```
|
||||
```txt
|
||||
undefined: TypeError: Cannot read properties of undefined (reading 'map')
|
||||
```
|
||||
|
||||
|
@ -40,6 +40,7 @@ This plugin configures Playwright-specific [fixtures for pytest](https://docs.py
|
||||
|
||||
```py
|
||||
def test_my_app_is_working(fixture_name):
|
||||
pass
|
||||
# Test using fixture_name
|
||||
# ...
|
||||
```
|
||||
|
@ -15,7 +15,8 @@ test('example test', async ({ page }) => {
|
||||
```
|
||||
|
||||
When you run above for the first time, test runner will say:
|
||||
```
|
||||
|
||||
```txt
|
||||
Error: A snapshot doesn't exist at example.spec.ts-snapshots/example-test-1-chromium-darwin.png, writing actual.
|
||||
```
|
||||
|
||||
|
@ -16,7 +16,7 @@ Playwright Test enforces a timeout for each test, 30 seconds by default. Time sp
|
||||
|
||||
Timed out test produces the following error:
|
||||
|
||||
```
|
||||
```txt
|
||||
example.spec.ts:3:1 › basic test ===========================
|
||||
|
||||
Timeout of 30000ms exceeded.
|
||||
@ -86,7 +86,7 @@ API reference: [`method: TestInfo.setTimeout`].
|
||||
|
||||
Web-first assertions like `expect(locator).toHaveText()` have a separate timeout, 5 seconds by default. Assertion timeout is unrelated to the test timeout. It produces the following error:
|
||||
|
||||
```
|
||||
```txt
|
||||
example.spec.ts:3:1 › basic test ===========================
|
||||
|
||||
Error: expect(received).toHaveText(expected)
|
||||
@ -114,7 +114,7 @@ export default defineConfig({
|
||||
|
||||
Playwright Test supports a timeout for the whole test run. This prevents excess resource usage when everything went wrong. There is no default global timeout, but you can set a reasonable one in the config, for example one hour. Global timeout produces the following error:
|
||||
|
||||
```
|
||||
```txt
|
||||
Running 1000 tests using 10 workers
|
||||
|
||||
514 skipped
|
||||
|
@ -11,7 +11,7 @@ Playwright will pick up `tsconfig.json` for each source file it loads. Note that
|
||||
|
||||
We recommend setting up a separate `tsconfig.json` in the tests directory so that you can change some preferences specifically for the tests. Here is an example directory structure.
|
||||
|
||||
```
|
||||
```txt
|
||||
src/
|
||||
source.ts
|
||||
|
||||
|
4
packages/playwright-test/types/test.d.ts
vendored
4
packages/playwright-test/types/test.d.ts
vendored
@ -1151,7 +1151,7 @@ interface TestConfig {
|
||||
*
|
||||
* Consider the following file structure:
|
||||
*
|
||||
* ```
|
||||
* ```txt
|
||||
* playwright.config.ts
|
||||
* tests/
|
||||
* └── page/
|
||||
@ -6324,7 +6324,7 @@ interface TestProject {
|
||||
*
|
||||
* Consider the following file structure:
|
||||
*
|
||||
* ```
|
||||
* ```txt
|
||||
* playwright.config.ts
|
||||
* tests/
|
||||
* └── page/
|
||||
|
@ -360,7 +360,7 @@ class TypesGenerator {
|
||||
flavor = match[3];
|
||||
line = line.replace(/tab=js-\w+/, '').replace(/```\w+/, '```ts');
|
||||
}
|
||||
skipExample = !["html", "yml", "bash", "js"].includes(lang) || flavor !== 'ts';
|
||||
skipExample = !["html", "yml", "bash", "js", "txt"].includes(lang) || flavor !== 'ts';
|
||||
} else if (skipExample && line.trim().startsWith('```')) {
|
||||
skipExample = false;
|
||||
continue;
|
||||
|
Loading…
x
Reference in New Issue
Block a user