docs: code snippet alignments (#23959)

This commit is contained in:
Max Schmitt 2023-06-29 18:26:19 +02:00 committed by GitHub
parent c2127595b8
commit fef029e98e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 69 additions and 206 deletions

View File

@ -202,16 +202,18 @@ try {
```python async
try:
await page.wait_for_selector(".foo")
await page.wait_for_selector(".foo")
except TimeoutError as e:
# do something if this is a timeout.
pass
# do something if this is a timeout.
```
```python sync
try:
page.wait_for_selector(".foo")
page.wait_for_selector(".foo")
except TimeoutError as e:
# do something if this is a timeout.
pass
# do something if this is a timeout.
```
## property: Playwright.firefox
@ -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()
```

View File

@ -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/

View File

@ -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
```

View File

@ -15,7 +15,7 @@ const { chromium } = require('playwright');
(async () => {
const pathToExtension = require('path').join(__dirname, 'my-extension');
const userDataDir = '/tmp/test-user-data-dir';
const browserContext = await chromium.launchPersistentContext(userDataDir,{
const browserContext = await chromium.launchPersistentContext(userDataDir, {
headless: false,
args: [
`--disable-extensions-except=${pathToExtension}`,

View File

@ -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
```

View File

@ -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.

View File

@ -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

View File

@ -15,13 +15,13 @@ 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 });
});
// Go to the page
await page.goto('https://demo.playwright.dev/api-mocking');
// Assert that the Strawberry fruit is visible
await expect(page.getByText('Strawberry')).toBeVisible();
});
@ -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
@ -265,11 +265,9 @@ 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,
}
await page.RouteFromHARAsync("./hars/fruit.har", new () {
Url = "*/**/api/v1/fruits",
Update = true,
});
// Go to the page
@ -289,7 +287,7 @@ page.goto("https://demo.playwright.dev/api-mocking");
### Modifying a HAR file
Once you have recorded a HAR file you can modify it by opening the hashed .txt file inside your 'hars' folder and editing the JSON. This file should be committed to your source control. Anytime you run this test with `update: true` it will update your HAR file with the request from the API.
Once you have recorded a HAR file you can modify it by opening the hashed .txt file inside your 'hars' folder and editing the JSON. This file should be committed to your source control. Anytime you run this test with `update: true` it will update your HAR file with the request from the API.
```json
[

View File

@ -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

View File

@ -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));
```

View File

@ -691,11 +691,11 @@ This version was also tested against the following stable channels:
```ts
test('should work', async ({ page }) => {
const pageTitle = await test.step('get title', async () => {
await page.goto('https://playwright.dev');
return await page.title();
});
console.log(pageTitle);
const pageTitle = await test.step('get title', async () => {
await page.goto('https://playwright.dev');
return await page.title();
});
console.log(pageTitle);
});
```
@ -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

View File

@ -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", "")
```

View File

@ -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).

View File

@ -498,7 +498,7 @@ await mount(app);
results in
```
```txt
undefined: TypeError: Cannot read properties of undefined (reading 'map')
```

View File

@ -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
# ...
```

View File

@ -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.
```

View File

@ -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

View File

@ -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

View File

@ -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/

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
//@ts-check
// @ts-check
const path = require('path');
const toKebabCase = require('lodash/kebabCase')
const devices = require('../../packages/playwright-core/lib/server/deviceDescriptors');
@ -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;