Skip to content

Commit

Permalink
feat(roll): roll to ToT Playwright (02-08-23) (#1113)
Browse files Browse the repository at this point in the history
  • Loading branch information
playwrightmachine authored Aug 2, 2023
1 parent 676ece0 commit b5f636d
Show file tree
Hide file tree
Showing 31 changed files with 242 additions and 151 deletions.
2 changes: 2 additions & 0 deletions dotnet/docs/api/class-frame.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,8 @@ Frame.ParentFrame

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>frame.SetContentAsync</x-search>

This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.

**Usage**

```csharp
Expand Down
2 changes: 2 additions & 0 deletions dotnet/docs/api/class-page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,8 @@ await Page.ScreenshotAsync(options);

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>page.SetContentAsync</x-search>

This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.

**Usage**

```csharp
Expand Down
6 changes: 4 additions & 2 deletions dotnet/docs/writing-tests.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public class Tests : PageTest
// Click the get started link.
await getStarted.ClickAsync();

// Expects the URL to contain intro.
await Expect(Page).ToHaveURLAsync(new Regex(".*intro"));
// Expects page to have a heading with the name of Installation.
await Expect(page
.GetByRole(AriaRole.Heading, new() { Name = "Installation" }))
.ToBeVisibleAsync();
}
}
```
Expand Down
2 changes: 2 additions & 0 deletions java/docs/api/class-frame.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,8 @@ Frame.parentFrame();

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>frame.setContent</x-search>

This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.

**Usage**

```java
Expand Down
2 changes: 2 additions & 0 deletions java/docs/api/class-page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,8 @@ Page.screenshot(options);
<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>page.setContent</x-search>
This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.
**Usage**
```java
Expand Down
5 changes: 3 additions & 2 deletions java/docs/writing-tests.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ public class App {
// Click the get started link.
getStarted.click();

// Expects the URL to contain intro.
assertThat(page).hasURL(Pattern.compile(".*intro"));
// Expects page to have a heading with the name of Installation.
assertThat(page.getByRole(AriaRole.HEADING,
new Page.GetByRoleOptions().setName("Installation"))).isVisible();
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions nodejs/docs/accessibility-testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ For example, you can use [`AxeBuilder.include()`](https://github.com/dequelabs/a
`AxeBuilder.analyze()` will scan the page *in its current state* when you call it. To scan parts of a page that are revealed based on UI interactions, use [Locators](./locators.mdx) to interact with the page before invoking `analyze()`:

```js
test('navigation menu flyout should not have automatically detectable accessibility violations', async ({ page }) => {
test('navigation menu should not have automatically detectable accessibility violations', async ({
page,
}) => {
await page.goto('https://your-site.com/');

await page.getByRole('button', { name: 'Navigation Menu' }).click();
Expand Down Expand Up @@ -144,7 +146,9 @@ This is usually the simplest option, but it has some important downsides:
Here is an example of excluding one element from being scanned in one specific test:

```js
test('should not have any accessibility violations outside of elements with known issues', async ({ page }) => {
test('should not have any accessibility violations outside of elements with known issues', async ({
page,
}) => {
await page.goto('https://your-site.com/page-with-known-issues');

const accessibilityScanResults = await new AxeBuilder({ page })
Expand All @@ -164,7 +168,9 @@ If your application contains many different pre-existing violations of a specifi
You can find the rule IDs to pass to `disableRules()` in the `id` property of the violations you want to suppress. A [complete list of axe's rules](https://github.com/dequelabs/axe-core/blob/master/doc/rule-descriptions.md) can be found in `axe-core`'s documentation.

```js
test('should not have any accessibility violations outside of rules with known issues', async ({ page }) => {
test('should not have any accessibility violations outside of rules with known issues', async ({
page,
}) => {
await page.goto('https://your-site.com/page-with-known-issues');

const accessibilityScanResults = await new AxeBuilder({ page })
Expand Down
32 changes: 25 additions & 7 deletions nodejs/docs/api-testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,9 @@ test('last created issue should be on the server', async ({ page }) => {
await page.getByText('Submit new issue').click();
const issueId = page.url().substr(page.url().lastIndexOf('/'));

const newIssue = await apiContext.get(`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`);
const newIssue = await apiContext.get(
`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`
);
expect(newIssue.ok()).toBeTruthy();
expect(newIssue.json()).toEqual(expect.objectContaining({
title: 'Bug report 1'
Expand Down Expand Up @@ -289,19 +291,26 @@ There are two types of [APIRequestContext]:
The main difference is that [APIRequestContext] accessible via [browserContext.request](/api/class-browsercontext.mdx#browser-context-request) and [page.request](/api/class-page.mdx#page-request) will populate request's `Cookie` header from the browser context and will automatically update browser cookies if [APIResponse] has `Set-Cookie` header:

```js
test('context request will share cookie storage with its browser context', async ({ page, context }) => {
test('context request will share cookie storage with its browser context', async ({
page,
context,
}) => {
await context.route('https://www.github.com/', async route => {
// Send an API request that shares cookie storage with the browser context.
const response = await context.request.fetch(route.request());
const responseHeaders = response.headers();

// The response will have 'Set-Cookie' header.
const responseCookies = new Map(responseHeaders['set-cookie'].split('\n').map(c => c.split(';', 2)[0].split('=')));
const responseCookies = new Map(responseHeaders['set-cookie']
.split('\n')
.map(c => c.split(';', 2)[0].split('=')));
// The response will have 3 cookies in 'Set-Cookie' header.
expect(responseCookies.size).toBe(3);
const contextCookies = await context.cookies();
// The browser context will already contain all the cookies from the API response.
expect(new Map(contextCookies.map(({ name, value }) => [name, value]))).toEqual(responseCookies);
expect(new Map(contextCookies.map(({ name, value }) =>
[name, value])
)).toEqual(responseCookies);

route.fulfill({
response,
Expand All @@ -315,14 +324,21 @@ test('context request will share cookie storage with its browser context', async
If you don't want [APIRequestContext] to use and update cookies from the browser context, you can manually create a new instance of [APIRequestContext] which will have its own isolated cookies:

```js
test('global context request has isolated cookie storage', async ({ page, context, browser, playwright }) => {
test('global context request has isolated cookie storage', async ({
page,
context,
browser,
playwright
}) => {
// Create a new instance of APIRequestContext with isolated cookie storage.
const request = await playwright.request.newContext();
await context.route('https://www.github.com/', async route => {
const response = await request.fetch(route.request());
const responseHeaders = response.headers();

const responseCookies = new Map(responseHeaders['set-cookie'].split('\n').map(c => c.split(';', 2)[0].split('=')));
const responseCookies = new Map(responseHeaders['set-cookie']
.split('\n')
.map(c => c.split(';', 2)[0].split('=')));
// The response will have 3 cookies in 'Set-Cookie' header.
expect(responseCookies.size).toBe(3);
const contextCookies = await context.cookies();
Expand All @@ -335,7 +351,9 @@ test('global context request has isolated cookie storage', async ({ page, contex
const browserContext2 = await browser.newContext({ storageState });
const contextCookies2 = await browserContext2.cookies();
// The new browser context will already contain all the cookies from the API response.
expect(new Map(contextCookies2.map(({ name, value }) => [name, value]))).toEqual(responseCookies);
expect(
new Map(contextCookies2.map(({ name, value }) => [name, value]))
).toEqual(responseCookies);

route.fulfill({
response,
Expand Down
8 changes: 6 additions & 2 deletions nodejs/docs/api/class-android.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ const { _android: android } = require('playwright');
const webview = await device.webView({ pkg: 'org.chromium.webview_shell' });

// Fill the input box.
await device.fill({ res: 'org.chromium.webview_shell:id/url_field' }, 'github.com/microsoft/playwright');
await device.press({ res: 'org.chromium.webview_shell:id/url_field' }, 'Enter');
await device.fill({
res: 'org.chromium.webview_shell:id/url_field',
}, 'github.com/microsoft/playwright');
await device.press({
res: 'org.chromium.webview_shell:id/url_field',
}, 'Enter');

// Work with WebView's page as usual.
const page = await webview.page();
Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/api/class-browsercontext.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,9 @@ const crypto = require('crypto');
(async () => {
const browser = await webkit.launch({ headless: false });
const context = await browser.newContext();
await context.exposeFunction('sha256', text => crypto.createHash('sha256').update(text).digest('hex'));
await context.exposeFunction('sha256', text =>
crypto.createHash('sha256').update(text).digest('hex'),
);
const page = await context.newPage();
await page.setContent(`
<script>
Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/api/class-elementhandle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ If `pageFunction` returns a [Promise], then [elementHandle.$$eval()](/api/class-

```js
const feedHandle = await page.$('.feed');
expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))).toEqual(['Hello!', 'Hi!']);
expect(await feedHandle.$$eval('.tweet', nodes =>
nodes.map(n => n.innerText))).toEqual(['Hello!', 'Hi!'],
);
```

**Arguments**
Expand Down
10 changes: 8 additions & 2 deletions nodejs/docs/api/class-frame.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ console.log(await frame.evaluate('1 + 2')); // prints "3"

```js
const bodyHandle = await frame.evaluate('document.body');
const html = await frame.evaluate(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
const html = await frame.evaluate(([body, suffix]) =>
body.innerHTML + suffix, [bodyHandle, 'hello'],
);
await bodyHandle.dispose();
```

Expand Down Expand Up @@ -264,7 +266,9 @@ const aHandle = await frame.evaluateHandle('document'); // Handle for the 'docum

```js
const aHandle = await frame.evaluateHandle(() => document.body);
const resultHandle = await frame.evaluateHandle(([body, suffix]) => body.innerHTML + suffix, [aHandle, 'hello']);
const resultHandle = await frame.evaluateHandle(([body, suffix]) =>
body.innerHTML + suffix, [aHandle, 'hello'],
);
console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
```
Expand Down Expand Up @@ -866,6 +870,8 @@ frame.parentFrame();

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>frame.setContent</x-search>

This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.

**Usage**

```js
Expand Down
18 changes: 14 additions & 4 deletions nodejs/docs/api/class-page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ console.log(await page.evaluate(`1 + ${x}`)); // prints "11"

```js
const bodyHandle = await page.evaluate('document.body');
const html = await page.evaluate<string, HTMLElement>(([body, suffix]) => body.innerHTML + suffix, [bodyHandle, 'hello']);
const html = await page.evaluate<string, HTMLElement>(([body, suffix]) =>
body.innerHTML + suffix, [bodyHandle, 'hello']
);
await bodyHandle.dispose();
```

Expand Down Expand Up @@ -538,7 +540,9 @@ const crypto = require('crypto');
(async () => {
const browser = await webkit.launch({ headless: false });
const page = await browser.newPage();
await page.exposeFunction('sha256', text => crypto.createHash('sha256').update(text).digest('hex'));
await page.exposeFunction('sha256', text =>
crypto.createHash('sha256').update(text).digest('hex'),
);
await page.setContent(`
<script>
async function onClick() {
Expand Down Expand Up @@ -1536,6 +1540,8 @@ await page.screenshot(options);

<font size="2" style={{position: "relative", top: "-20px"}}>Added in: v1.8</font><x-search>page.setContent</x-search>

This method internally calls [document.write()](https://developer.mozilla.org/en-US/docs/Web/API/Document/write), inheriting all its specific characteristics and behaviors.

**Usage**

```js
Expand Down Expand Up @@ -1900,7 +1906,9 @@ await page.getByText('trigger request').click();
const request = await requestPromise;

// Alternative way with a predicate. Note no await.
const requestPromise = page.waitForRequest(request => request.url() === 'https://example.com' && request.method() === 'GET');
const requestPromise = page.waitForRequest(request =>
request.url() === 'https://example.com' && request.method() === 'GET',
);
await page.getByText('trigger request').click();
const request = await requestPromise;
```
Expand Down Expand Up @@ -1934,7 +1942,9 @@ await page.getByText('trigger response').click();
const response = await responsePromise;

// Alternative way with a predicate. Note no await.
const responsePromise = page.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
const responsePromise = page.waitForResponse(response =>
response.url() === 'https://example.com' && response.status() === 200
);
await page.getByText('trigger response').click();
const response = await responsePromise;
```
Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/api/class-reporter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ You can create a custom reporter by implementing a class with some of the report
<TabItem value="ts">

```js title="my-awesome-reporter.ts"
import type { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
import type {
Reporter, FullConfig, Suite, TestCase, TestResult, FullResult
} from '@playwright/test/reporter';

class MyReporter implements Reporter {
constructor(options: { customOption?: string } = {}) {
Expand Down
5 changes: 4 additions & 1 deletion nodejs/docs/api/class-test.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,10 @@ Returns information about the currently running test. This method can only be ca
```js
test('example test', async ({ page }) => {
// ...
await test.info().attach('screenshot', { body: await page.screenshot(), contentType: 'image/png' });
await test.info().attach('screenshot', {
body: await page.screenshot(),
contentType: 'image/png',
});
});
```

Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/chrome-extensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ const pathToExtension = path.join(__dirname, 'my-extension');
const context = await chromium.launchPersistentContext('', {
headless: false,
args: [
`--headless=new`, // the new headless arg for chrome v109+. Use '--headless=chrome' as arg for browsers v94-108.
// the new headless arg for chrome v109+. Use '--headless=chrome'
// as arg for browsers v94-108.
`--headless=new`,
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`,
],
Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/other-locators.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ Pipe operator (`|`) can be used to specify multiple selectors in XPath. It will

```js
// Waits for either confirmation dialog or load spinner.
await page.locator(`//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']`).waitFor();
await page.locator(
`//span[contains(@class, 'spinner__loading')]|//div[@id='confirmation']`
).waitFor();
```
## Label to form control retargeting
Expand Down
18 changes: 15 additions & 3 deletions nodejs/docs/pom.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ export class PlaywrightDevPage {
this.page = page;
this.getStartedLink = page.locator('a', { hasText: 'Get started' });
this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' });
this.pomLink = page.locator('li', { hasText: 'Guides' }).locator('a', { hasText: 'Page Object Model' });
this.pomLink = page.locator('li', {
hasText: 'Guides',
}).locator('a', {
hasText: 'Page Object Model',
});
this.tocList = page.locator('article div.markdown ul > li > a');
}

Expand Down Expand Up @@ -76,7 +80,11 @@ exports.PlaywrightDevPage = class PlaywrightDevPage {
this.page = page;
this.getStartedLink = page.locator('a', { hasText: 'Get started' });
this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' });
this.pomLink = page.locator('li', { hasText: 'Guides' }).locator('a', { hasText: 'Page Object Model' });
this.pomLink = page.locator('li', {
hasText: 'Guides',
}).locator('a', {
hasText: 'Page Object Model',
});
this.tocList = page.locator('article div.markdown ul > li > a');
}

Expand Down Expand Up @@ -108,7 +116,11 @@ class PlaywrightDevPage {
this.page = page;
this.getStartedLink = page.locator('a', { hasText: 'Get started' });
this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' });
this.pomLink = page.locator('li', { hasText: 'Playwright Test' }).locator('a', { hasText: 'Page Object Model' });
this.pomLink = page.locator('li', {
hasText: 'Playwright Test',
}).locator('a', {
hasText: 'Page Object Model',
});
this.tocList = page.locator('article div.markdown ul > li > a');
}
async getStarted() {
Expand Down
4 changes: 3 additions & 1 deletion nodejs/docs/service-workers-experimental-network-events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ 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));
await new Promise(res =>
window.navigator.serviceWorker.addEventListener('controllerchange', res),
);
});
```
Expand Down
5 changes: 4 additions & 1 deletion nodejs/docs/test-annotations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,10 @@ It's also possible to add custom metadata in the form of annotations to your tes
```js title="example.spec.ts"
test('user profile', async ({ page }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/<some-issue>' });
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/<some-issue>',
});
// ...
});
```
Expand Down
Loading

0 comments on commit b5f636d

Please sign in to comment.