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
7 changes: 3 additions & 4 deletions browser_patches/firefox/juggler/NetworkObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,12 @@ class NetworkRequest {
const proxy = this._networkObserver._targetRegistry.getProxyInfo(aChannel);
credentials = proxy ? {username: proxy.username, password: proxy.password} : null;
} else {
credentials = pageNetwork._target.browserContext().httpCredentials;
const origin = (aChannel.URI.scheme + '://' + aChannel.URI.hostPort).toLowerCase();
const httpCredentials = pageNetwork._target.browserContext().httpCredentials || [];
credentials = httpCredentials.find(c => !c.origin || c.origin.toLowerCase() === origin) || null;
}
if (!credentials)
return false;
const origin = aChannel.URI.scheme + '://' + aChannel.URI.hostPort;
if (credentials.origin && origin.toLowerCase() !== credentials.origin.toLowerCase())
return false;
authInfo.username = credentials.username;
authInfo.password = credentials.password;
// This will produce a new request with respective auth header set.
Expand Down
2 changes: 1 addition & 1 deletion browser_patches/firefox/juggler/protocol/Protocol.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ const Browser = {
'setHTTPCredentials': {
params: {
browserContextId: t.Optional(t.String),
credentials: t.Nullable(networkTypes.HTTPCredentials),
credentials: t.Nullable(t.Array(networkTypes.HTTPCredentials)),
},
},
'setRequestInterception': {
Expand Down
16 changes: 16 additions & 0 deletions docs/src/test-reporters-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,23 @@ export default defineConfig({
});
```

You can omit test tags that are automatically appended to test titles:

```js title="playwright.config.ts"
import { defineConfig } from '@playwright/test';

export default defineConfig({
reporter: [['list', { omitTags: true }]],
});
```

List report supports the following configuration options and environment variables:

| Environment Variable Name | Reporter Config Option| Description | Default
|---|---|---|---|
| `PLAYWRIGHT_LIST_PRINT_STEPS` | `printSteps` | Whether to print each step on its own line. | `false`
| `PLAYWRIGHT_LIST_PRINT_FAILURES_INLINE` | `printFailuresInline` | Whether to print failure details immediately after a failed test instead of at the end. | `false`
| `PLAYWRIGHT_LIST_OMIT_TAGS` | `omitTags` | Whether to omit test tags that are automatically appended to test titles. | `false`
| `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise.
| `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise.
| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset
Expand Down Expand Up @@ -152,6 +163,7 @@ Line report supports the following configuration options and environment variabl

| Environment Variable Name | Reporter Config Option| Description | Default
|---|---|---|---|
| `PLAYWRIGHT_LINE_OMIT_TAGS` | `omitTags` | Whether to omit test tags that are automatically appended to test titles. | `false`
| `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise.
| `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise.
| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset
Expand Down Expand Up @@ -195,6 +207,7 @@ Dot report supports the following configuration options and environment variable

| Environment Variable Name | Reporter Config Option| Description | Default
|---|---|---|---|
| `PLAYWRIGHT_DOT_OMIT_TAGS` | `omitTags` | Whether to omit test tags that are automatically appended to test titles. | `false`
| `PLAYWRIGHT_FORCE_TTY` | | Whether to produce output suitable for a live terminal. Supports `true`, `1`, `false`, `0`, `[WIDTH]`, and `[WIDTH]x[HEIGHT]`. `[WIDTH]` and `[WIDTH]x[HEIGHT]` specifies the TTY dimensions. | `true` when terminal is in TTY mode, `false` otherwise.
| `FORCE_COLOR` | | Whether to produce colored output. | `true` when terminal is in TTY mode, `false` otherwise.
| `NO_COLOR` | | Whether to disable colored output ([no-color.org](https://no-color.org/)). Any non-empty value disables colors. | unset
Expand Down Expand Up @@ -414,6 +427,7 @@ JUnit report supports following configuration options and environment variables:
| `PLAYWRIGHT_JUNIT_OUTPUT_FILE` | `outputFile` | Full path to the output file. If defined, `PLAYWRIGHT_JUNIT_OUTPUT_DIR` and `PLAYWRIGHT_JUNIT_OUTPUT_NAME` will be ignored. | JUnit report is printed to the stdout.
| `PLAYWRIGHT_JUNIT_STRIP_ANSI` | `stripANSIControlSequences` | Whether to remove ANSI control sequences from the text before writing it in the report. | By default output text is added as is.
| `PLAYWRIGHT_JUNIT_INCLUDE_PROJECT_IN_TEST_NAME` | `includeProjectInTestName` | Whether to include Playwright project name in every test case as a name prefix. | By default not included.
| `PLAYWRIGHT_JUNIT_OMIT_TAGS` | `omitTags` | Whether to omit test tags that are automatically appended to failure details. | `false`
| `PLAYWRIGHT_JUNIT_SUITE_ID` | | Value of the `id` attribute on the root `<testsuites/>` report entry. | Empty string.
| `PLAYWRIGHT_JUNIT_SUITE_NAME` | | Value of the `name` attribute on the root `<testsuites/>` report entry. | Empty string.

Expand All @@ -435,6 +449,8 @@ export default defineConfig({
});
```

The `github` reporter accepts `omitTags` (or the `PLAYWRIGHT_GITHUB_OMIT_TAGS` environment variable) to suppress test tags in its annotations, for example `reporter: [['github', { omitTags: true }]]`.

## Custom reporters

You can create a custom reporter by implementing a class with some of the reporter methods. Learn more about the [Reporter] API.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/playwright-core/browsers.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
{
"name": "firefox",
"revision": "1538",
"revision": "1539",
"installByDefault": true,
"browserVersion": "153.0",
"title": "Firefox"
Expand All @@ -45,7 +45,7 @@
},
{
"name": "webkit",
"revision": "2336",
"revision": "2337",
"installByDefault": true,
"revisionOverrides": {
"mac14": "2251",
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/firefox/ffBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export class FFBrowserContext extends BrowserContext {
let credentials = null;
if (httpCredentials) {
const { username, password, origin } = httpCredentials;
credentials = { username, password, origin };
credentials = [{ username, password, origin }];
}
await this._browser.session.send('Browser.setHTTPCredentials', { browserContextId: this._browserContextId, credentials });
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/firefox/protocol.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export namespace Protocol {
username: string;
password: string;
origin?: string;
}|null;
}[]|null;
};
export type setHTTPCredentialsReturnValue = void;
export type setRequestInterceptionParameters = {
Expand Down
17 changes: 13 additions & 4 deletions packages/playwright-core/src/server/webkit/protocol.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4373,6 +4373,17 @@ might return multiple quads for inline nodes.
}

export namespace Emulation {
/**
* Credentials for HTTP authentication.
*/
export interface AuthCredentials {
username: string;
password: string;
/**
* When specified, the credentials are only used for challenges from the matching origin.
*/
origin?: string;
}


/**
Expand All @@ -4395,12 +4406,10 @@ might return multiple quads for inline nodes.
export type setJavaScriptEnabledReturnValue = {
}
/**
* Credentials to use during HTTP authentication.
* Credentials to use during HTTP authentication. The first credentials with matching origin are used. When missing, automation handling of authentication challenges is disabled.
*/
export type setAuthCredentialsParameters = {
username?: string;
password?: string;
origin?: string;
credentials?: AuthCredentials[];
}
export type setAuthCredentialsReturnValue = {
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright-core/src/server/webkit/wkPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ export class WKPage implements PageDelegate {

async updateHttpCredentials() {
const credentials = this._browserContext._options.httpCredentials || { username: '', password: '', origin: '' };
await this._pageProxySession.send('Emulation.setAuthCredentials', { username: credentials.username, password: credentials.password, origin: credentials.origin });
await this._pageProxySession.send('Emulation.setAuthCredentials', { credentials: [{ username: credentials.username, password: credentials.password, origin: credentials.origin }] });
}

async updateFileChooserInterception() {
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/tools/backend/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTool } from './tool';

const cookieList = defineTool({
Expand Down Expand Up @@ -137,7 +138,7 @@ const cookieDelete = defineTool({
handle: async (context, params, response) => {
const browserContext = await context.ensureBrowserContext();
await browserContext.clearCookies({ name: params.name });
response.addCode(`await page.context().clearCookies({ name: '${params.name}' });`);
response.addCode(`await page.context().clearCookies({ name: ${escapeWithQuotes(params.name)} });`);
},
});

Expand Down
9 changes: 5 additions & 4 deletions packages/playwright-core/src/tools/backend/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTabTool } from './tool';
import { elementSchema } from './snapshot';

Expand All @@ -33,7 +34,7 @@ const press = defineTabTool({

handle: async (tab, params, response) => {
response.addCode(`// Press ${params.key}`);
response.addCode(`await page.keyboard.press('${params.key}');`);
response.addCode(`await page.keyboard.press(${escapeWithQuotes(params.key)});`);
if (params.key === 'Enter') {
response.setIncludeSnapshot();
await tab.waitForCompletion(async () => {
Expand Down Expand Up @@ -62,7 +63,7 @@ const pressSequentially = defineTabTool({

handle: async (tab, params, response) => {
response.addCode(`// Press ${params.text}`);
response.addCode(`await page.keyboard.type('${params.text}');`);
response.addCode(`await page.keyboard.type(${escapeWithQuotes(params.text)});`);
await tab.page.keyboard.type(params.text);
if (params.submit) {
response.addCode(`await page.keyboard.press('Enter');`);
Expand Down Expand Up @@ -133,7 +134,7 @@ const keydown = defineTabTool({
},

handle: async (tab, params, response) => {
response.addCode(`await page.keyboard.down('${params.key}');`);
response.addCode(`await page.keyboard.down(${escapeWithQuotes(params.key)});`);
await tab.page.keyboard.down(params.key);
},
});
Expand All @@ -153,7 +154,7 @@ const keyup = defineTabTool({
},

handle: async (tab, params, response) => {
response.addCode(`await page.keyboard.up('${params.key}');`);
response.addCode(`await page.keyboard.up(${escapeWithQuotes(params.key)});`);
await tab.page.keyboard.up(params.key);
},
});
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/tools/backend/navigate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTool, defineTabTool } from './tool';

const navigate = defineTool({
Expand All @@ -35,7 +36,7 @@ const navigate = defineTool({
const url = await tab.checkUrlAndNavigate(params.url);

response.setIncludeSnapshot();
response.addCode(`await page.goto('${url}');`);
response.addCode(`await page.goto(${escapeWithQuotes(url)});`);
},
});

Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/tools/backend/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTool } from './tool';

import type * as playwright from '../../..';
Expand Down Expand Up @@ -81,7 +82,7 @@ const route = defineTool({

await context.addRoute(entry);
response.addTextResult(`Route added for pattern: ${params.pattern}`);
response.addCode(`await page.context().route('${params.pattern}', async route => { /* route handler */ });`);
response.addCode(`await page.context().route(${escapeWithQuotes(params.pattern)}, async route => { /* route handler */ });`);
},
});

Expand Down
5 changes: 3 additions & 2 deletions packages/playwright-core/src/tools/backend/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTool } from './tool';

const storageState = defineTool({
Expand All @@ -35,7 +36,7 @@ const storageState = defineTool({
const state = await browserContext.storageState();
const serializedState = JSON.stringify(state, null, 2);
const resolvedFile = await response.resolveClientFile({ prefix: 'storage-state', ext: 'json', suggestedFilename: params.filename }, 'Storage state');
response.addCode(`await page.context().storageState({ path: '${resolvedFile.relativeName}' });`);
response.addCode(`await page.context().storageState({ path: ${escapeWithQuotes(resolvedFile.relativeName)} });`);
await response.addFileResult(resolvedFile, serializedState);
},
});
Expand All @@ -58,7 +59,7 @@ const setStorageState = defineTool({
const resolvedFilename = await response.resolveClientFilename(params.filename);
await browserContext.setStorageState(resolvedFilename);
response.addTextResult(`Storage state restored from ${params.filename}`);
response.addCode(`await page.context().setStorageState('${params.filename}');`);
response.addCode(`await page.context().setStorageState(${escapeWithQuotes(params.filename)});`);
},
});

Expand Down
3 changes: 2 additions & 1 deletion packages/playwright-core/src/tools/backend/tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTool } from './tool';
import { renderTabsMarkdown } from './response';

Expand Down Expand Up @@ -44,7 +45,7 @@ const browserTabs = defineTool({
if (params.url) {
const url = await tab.checkUrlAndNavigate(params.url);
response.setIncludeSnapshot();
response.addCode(`await page.goto('${url}');`);
response.addCode(`await page.goto(${escapeWithQuotes(url)});`);
}
break;
}
Expand Down
13 changes: 7 additions & 6 deletions packages/playwright-core/src/tools/backend/webstorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import * as z from 'zod';
import { escapeWithQuotes } from '@isomorphic/stringUtils';
import { defineTabTool } from './tool';

const localStorageList = defineTabTool({
Expand Down Expand Up @@ -59,7 +60,7 @@ const localStorageGet = defineTabTool({
response.addTextResult(`localStorage key '${params.key}' not found`);
else
response.addTextResult(`${params.key}=${value}`);
response.addCode(`await page.localStorage.getItem('${params.key}');`);
response.addCode(`await page.localStorage.getItem(${escapeWithQuotes(params.key)});`);
},
});

Expand All @@ -79,7 +80,7 @@ const localStorageSet = defineTabTool({

handle: async (tab, params, response) => {
await tab.page.localStorage.setItem(params.key, params.value);
response.addCode(`await page.localStorage.setItem('${params.key}', '${params.value}');`);
response.addCode(`await page.localStorage.setItem(${escapeWithQuotes(params.key)}, ${escapeWithQuotes(params.value)});`);
},
});

Expand All @@ -98,7 +99,7 @@ const localStorageDelete = defineTabTool({

handle: async (tab, params, response) => {
await tab.page.localStorage.removeItem(params.key);
response.addCode(`await page.localStorage.removeItem('${params.key}');`);
response.addCode(`await page.localStorage.removeItem(${escapeWithQuotes(params.key)});`);
},
});

Expand Down Expand Up @@ -163,7 +164,7 @@ const sessionStorageGet = defineTabTool({
response.addTextResult(`sessionStorage key '${params.key}' not found`);
else
response.addTextResult(`${params.key}=${value}`);
response.addCode(`await page.sessionStorage.getItem('${params.key}');`);
response.addCode(`await page.sessionStorage.getItem(${escapeWithQuotes(params.key)});`);
},
});

Expand All @@ -183,7 +184,7 @@ const sessionStorageSet = defineTabTool({

handle: async (tab, params, response) => {
await tab.page.sessionStorage.setItem(params.key, params.value);
response.addCode(`await page.sessionStorage.setItem('${params.key}', '${params.value}');`);
response.addCode(`await page.sessionStorage.setItem(${escapeWithQuotes(params.key)}, ${escapeWithQuotes(params.value)});`);
},
});

Expand All @@ -202,7 +203,7 @@ const sessionStorageDelete = defineTabTool({

handle: async (tab, params, response) => {
await tab.page.sessionStorage.removeItem(params.key);
response.addCode(`await page.sessionStorage.removeItem('${params.key}');`);
response.addCode(`await page.sessionStorage.removeItem(${escapeWithQuotes(params.key)});`);
},
});

Expand Down
Loading
Loading