diff --git a/README.md b/README.md index 464af77ac9..ca416b2397 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🎭 Playwright -[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-128.0.6613.27-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-128.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) +[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-128.0.6613.27-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-129.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.0-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) ## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright) @@ -10,7 +10,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr | :--- | :---: | :---: | :---: | | Chromium 128.0.6613.27 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 18.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | -| Firefox 128.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Firefox 129.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details. diff --git a/docs/src/accessibility-testing-java.md b/docs/src/accessibility-testing-java.md index 9db8246bcb..d62bac64fa 100644 --- a/docs/src/accessibility-testing-java.md +++ b/docs/src/accessibility-testing-java.md @@ -14,8 +14,6 @@ A few examples of problems this can catch include: The following examples rely on the [`com.deque.html.axe-core/playwright`](https://mvnrepository.com/artifact/com.deque.html.axe-core/playwright) Maven package which adds support for running the [axe accessibility testing engine](https://www.deque.com/axe/) as part of your Playwright tests. - - ## Disclaimer Automated accessibility tests can detect some common accessibility problems such as missing or invalid properties. But many accessibility problems can only be discovered through manual testing. We recommend using a combination of automated testing, manual accessibility assessments, and inclusive user testing. diff --git a/docs/src/api-testing-csharp.md b/docs/src/api-testing-csharp.md index f68ff8a8f7..6a8482e244 100644 --- a/docs/src/api-testing-csharp.md +++ b/docs/src/api-testing-csharp.md @@ -18,8 +18,6 @@ All of that could be achieved via [APIRequestContext] methods. The following examples rely on the [`Microsoft.Playwright.MSTest`](./test-runners.md) package which creates a Playwright and Page instance for each test. - - ## Writing API Test [APIRequestContext] can send all kinds of HTTP(S) requests over network. diff --git a/docs/src/api-testing-java.md b/docs/src/api-testing-java.md index 41265776a5..987aad5de8 100644 --- a/docs/src/api-testing-java.md +++ b/docs/src/api-testing-java.md @@ -16,8 +16,6 @@ A few examples where it may come in handy: All of that could be achieved via [APIRequestContext] methods. - - ## Writing API Test [APIRequestContext] can send all kinds of HTTP(S) requests over network. diff --git a/docs/src/api-testing-js.md b/docs/src/api-testing-js.md index 680b085a3c..325d9984b4 100644 --- a/docs/src/api-testing-js.md +++ b/docs/src/api-testing-js.md @@ -16,8 +16,6 @@ A few examples where it may come in handy: All of that could be achieved via [APIRequestContext] methods. - - ## Writing API Test [APIRequestContext] can send all kinds of HTTP(S) requests over network. diff --git a/docs/src/api-testing-python.md b/docs/src/api-testing-python.md index 9930605a52..68f2626111 100644 --- a/docs/src/api-testing-python.md +++ b/docs/src/api-testing-python.md @@ -18,8 +18,6 @@ All of that could be achieved via [APIRequestContext] methods. The following examples rely on the [`pytest-playwright`](./test-runners.md) package which add Playwright fixtures to the Pytest test-runner. - - ## Writing API Test [APIRequestContext] can send all kinds of HTTP(S) requests over network. diff --git a/docs/src/junit-java.md b/docs/src/junit-java.md index 7ea43399dd..ef6afcb5fd 100644 --- a/docs/src/junit-java.md +++ b/docs/src/junit-java.md @@ -10,8 +10,6 @@ With a few lines of code, you can hook up Playwright to your favorite Java test In [JUnit](https://junit.org/junit5/), you can use Playwright [fixtures](./junit.md#fixtures) to automatically initialize [Playwright], [Browser], [BrowserContext] or [Page]. In the example below, all three test methods use the same [Browser]. Each test uses its own [BrowserContext] and [Page]. - - ```java package org.example; diff --git a/docs/src/screenshots.md b/docs/src/screenshots.md index 28aca1200b..d1c7e0e04f 100644 --- a/docs/src/screenshots.md +++ b/docs/src/screenshots.md @@ -33,8 +33,6 @@ await Page.ScreenshotAsync(new() [Screenshots API](./api/class-page#page-screenshot) accepts many parameters for image format, clip area, quality, etc. Make sure to check them out. - - ## Full page screenshots Full page screenshot is a screenshot of a full scrollable page, as if you had a very diff --git a/docs/src/test-runners-java.md b/docs/src/test-runners-java.md index d29da2e8ba..1aaa7135c4 100644 --- a/docs/src/test-runners-java.md +++ b/docs/src/test-runners-java.md @@ -11,8 +11,6 @@ Playwright and Browser instances can be reused between tests for better performa recommend running each test case in a new BrowserContext, this way browser state will be isolated between the tests. - - ## JUnit In [JUnit](https://junit.org/junit5/) you can initialize [Playwright] and [Browser] in [@BeforeAll](https://junit.org/junit5/docs/current/api/org.junit.jupiter.api/org/junit/jupiter/api/BeforeAll.html) method and diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 168ea708ef..251b3c5ef7 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -9,25 +9,25 @@ }, { "name": "chromium-tip-of-tree", - "revision": "1247", + "revision": "1248", "installByDefault": false, - "browserVersion": "129.0.6640.0" + "browserVersion": "129.0.6644.0" }, { "name": "firefox", - "revision": "1458", + "revision": "1462", "installByDefault": true, - "browserVersion": "128.0" + "browserVersion": "129.0" }, { "name": "firefox-beta", - "revision": "1461", + "revision": "1462", "installByDefault": false, "browserVersion": "130.0b2" }, { "name": "webkit", - "revision": "2056", + "revision": "2061", "installByDefault": true, "revisionOverrides": { "mac10.14": "1446", diff --git a/packages/playwright-core/src/server/deviceDescriptorsSource.json b/packages/playwright-core/src/server/deviceDescriptorsSource.json index 2cacc98f00..36bd4b6527 100644 --- a/packages/playwright-core/src/server/deviceDescriptorsSource.json +++ b/packages/playwright-core/src/server/deviceDescriptorsSource.json @@ -1592,7 +1592,7 @@ "defaultBrowserType": "chromium" }, "Desktop Firefox HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0", "screen": { "width": 1792, "height": 1120 @@ -1652,7 +1652,7 @@ "defaultBrowserType": "chromium" }, "Desktop Firefox": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0", "screen": { "width": 1920, "height": 1080 diff --git a/packages/playwright-core/src/server/firefox/protocol.d.ts b/packages/playwright-core/src/server/firefox/protocol.d.ts index 7ebe32283b..1da6d70122 100644 --- a/packages/playwright-core/src/server/firefox/protocol.d.ts +++ b/packages/playwright-core/src/server/firefox/protocol.d.ts @@ -220,11 +220,6 @@ export module Protocol { }|null; }; export type setDefaultViewportReturnValue = void; - export type setScrollbarsHiddenParameters = { - browserContextId?: string; - hidden: boolean; - }; - export type setScrollbarsHiddenReturnValue = void; export type setInitScriptsParameters = { browserContextId?: string; scripts: { @@ -1116,7 +1111,6 @@ export module Protocol { "Browser.setDownloadOptions": Browser.setDownloadOptionsParameters; "Browser.setTouchOverride": Browser.setTouchOverrideParameters; "Browser.setDefaultViewport": Browser.setDefaultViewportParameters; - "Browser.setScrollbarsHidden": Browser.setScrollbarsHiddenParameters; "Browser.setInitScripts": Browser.setInitScriptsParameters; "Browser.addBinding": Browser.addBindingParameters; "Browser.grantPermissions": Browser.grantPermissionsParameters; @@ -1197,7 +1191,6 @@ export module Protocol { "Browser.setDownloadOptions": Browser.setDownloadOptionsReturnValue; "Browser.setTouchOverride": Browser.setTouchOverrideReturnValue; "Browser.setDefaultViewport": Browser.setDefaultViewportReturnValue; - "Browser.setScrollbarsHidden": Browser.setScrollbarsHiddenReturnValue; "Browser.setInitScripts": Browser.setInitScriptsReturnValue; "Browser.addBinding": Browser.addBindingReturnValue; "Browser.grantPermissions": Browser.grantPermissionsReturnValue; diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 8176a1ba82..fe37e16269 100644 --- a/packages/playwright-core/src/server/page.ts +++ b/packages/playwright-core/src/server/page.ts @@ -31,7 +31,7 @@ import * as accessibility from './accessibility'; import { FileChooser } from './fileChooser'; import type { Progress } from './progress'; import { ProgressController } from './progress'; -import { LongStandingScope, assert, createGuid, isError } from '../utils'; +import { LongStandingScope, assert, createGuid } from '../utils'; import { ManualPromise } from '../utils/manualPromise'; import { debugLogger } from '../utils/debugLogger'; import type { ImageComparatorOptions } from '../utils/comparators'; @@ -851,10 +851,7 @@ export class PageBinding { } context.evaluate(deliverResult, { name, seq, result }).catch(e => debugLogger.log('error', e)); } catch (error) { - if (isError(error)) - context.evaluate(deliverError, { name, seq, message: error.message, stack: error.stack }).catch(e => debugLogger.log('error', e)); - else - context.evaluate(deliverErrorValue, { name, seq, error }).catch(e => debugLogger.log('error', e)); + context.evaluate(deliverResult, { name, seq, error }).catch(e => debugLogger.log('error', e)); } function takeHandle(arg: { name: string, seq: number }) { @@ -863,21 +860,13 @@ export class PageBinding { return handle; } - function deliverResult(arg: { name: string, seq: number, result: any }) { - (globalThis as any)[arg.name]['callbacks'].get(arg.seq).resolve(arg.result); - (globalThis as any)[arg.name]['callbacks'].delete(arg.seq); - } - - function deliverError(arg: { name: string, seq: number, message: string, stack: string | undefined }) { - const error = new Error(arg.message); - error.stack = arg.stack; - (globalThis as any)[arg.name]['callbacks'].get(arg.seq).reject(error); - (globalThis as any)[arg.name]['callbacks'].delete(arg.seq); - } - - function deliverErrorValue(arg: { name: string, seq: number, error: any }) { - (globalThis as any)[arg.name]['callbacks'].get(arg.seq).reject(arg.error); - (globalThis as any)[arg.name]['callbacks'].delete(arg.seq); + function deliverResult(arg: { name: string, seq: number, result?: any, error?: any }) { + const callbacks = (globalThis as any)[arg.name]['callbacks']; + if ('error' in arg) + callbacks.get(arg.seq).reject(arg.error); + else + callbacks.get(arg.seq).resolve(arg.result); + callbacks.delete(arg.seq); } } } diff --git a/packages/playwright-core/src/server/webkit/protocol.d.ts b/packages/playwright-core/src/server/webkit/protocol.d.ts index 9e71534a17..80b30f28fb 100644 --- a/packages/playwright-core/src/server/webkit/protocol.d.ts +++ b/packages/playwright-core/src/server/webkit/protocol.d.ts @@ -4452,19 +4452,23 @@ might return multiple quads for inline nodes. savedResultIndex?: number; } /** - * Sets whether the given URL should be in the list of blackboxed scripts, which are ignored when pausing/stepping/debugging. + * Sets whether the given URL should be in the list of blackboxed scripts, which are ignored when pausing. */ export type setShouldBlackboxURLParameters = { url: string; shouldBlackbox: boolean; /** - * If true, url is case sensitive. + * If true, url is case sensitive. */ caseSensitive?: boolean; /** - * If true, treat url as regular expression. + * If true, treat url as regular expression. */ isRegex?: boolean; + /** + * If provided, limits where in the script the debugger will skip pauses. Expected structure is a repeated [startLine, startColumn, endLine, endColumn]. Ignored if shouldBlackbox is false. + */ + sourceRanges?: number[]; } export type setShouldBlackboxURLReturnValue = { } diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index c5a3f5d9dd..28bc7798b5 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -4815,9 +4815,9 @@ export type Fixtures | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in Exclude]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in Exclude]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit'; diff --git a/packages/recorder/src/index.tsx b/packages/recorder/src/index.tsx index 246052a4c1..5956eab725 100644 --- a/packages/recorder/src/index.tsx +++ b/packages/recorder/src/index.tsx @@ -17,11 +17,10 @@ import '@web/common.css'; import { applyTheme } from '@web/theme'; import '@web/third_party/vscode/codicon.css'; -import * as ReactDOM from 'react-dom'; +import * as ReactDOM from 'react-dom/client'; import { Main } from './main'; (async () => { applyTheme(); - // TODO: we'd like to migrate this to React 18, but concurrent mode seems to break some of our tests. - ReactDOM.render(
, document.querySelector('#root')); + ReactDOM.createRoot(document.querySelector('#root')!).render(
); })(); diff --git a/packages/recorder/src/main.tsx b/packages/recorder/src/main.tsx index 5980716d1e..2f7ea3ac4c 100644 --- a/packages/recorder/src/main.tsx +++ b/packages/recorder/src/main.tsx @@ -30,12 +30,14 @@ export const Main: React.FC = ({ window.playwrightSetSources = setSources; window.playwrightSetPaused = setPaused; window.playwrightUpdateLogs = callLogs => { - const newLog = new Map(log); - for (const callLog of callLogs) { - callLog.reveal = !log.has(callLog.id); - newLog.set(callLog.id, callLog); - } - setLog(newLog); + setLog(log => { + const newLog = new Map(log); + for (const callLog of callLogs) { + callLog.reveal = !log.has(callLog.id); + newLog.set(callLog.id, callLog); + } + return newLog; + }); }; window.playwrightSourcesEchoForTest = sources; diff --git a/packages/trace-viewer/src/ui/attachmentsTab.tsx b/packages/trace-viewer/src/ui/attachmentsTab.tsx index 375f28cb65..8c72c7fee3 100644 --- a/packages/trace-viewer/src/ui/attachmentsTab.tsx +++ b/packages/trace-viewer/src/ui/attachmentsTab.tsx @@ -131,7 +131,7 @@ export const AttachmentsTab: React.FunctionComponent<{ })} {attachments.size ?
Attachments
: undefined} {[...attachments.values()].map((a, i) => { - return
+ return
; })} @@ -154,3 +154,7 @@ function downloadURL(attachment: Attachment) { params.dct = attachment.contentType; return attachmentURL(attachment, params); } + +function attachmentKey(attachment: Attachment, index: number) { + return index + '-' + (attachment.sha1 ? `sha1-` + attachment.sha1 : `path-` + attachment.path); +} diff --git a/packages/trace-viewer/src/ui/logTab.tsx b/packages/trace-viewer/src/ui/logTab.tsx index be0469ab91..4fcb8a6f43 100644 --- a/packages/trace-viewer/src/ui/logTab.tsx +++ b/packages/trace-viewer/src/ui/logTab.tsx @@ -63,6 +63,6 @@ export const LogTab: React.FunctionComponent<{ {entry.time} {entry.message}
} - noHighlightOnHover={true} + notSelectable={true} />; }; diff --git a/packages/trace-viewer/src/ui/sourceTab.css b/packages/trace-viewer/src/ui/sourceTab.css index 9a3352aea7..3b9a8261c8 100644 --- a/packages/trace-viewer/src/ui/sourceTab.css +++ b/packages/trace-viewer/src/ui/sourceTab.css @@ -29,3 +29,9 @@ align-items: center; flex: 1 1 auto; } + +.source-tab-file-name div { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/packages/trace-viewer/src/ui/sourceTab.tsx b/packages/trace-viewer/src/ui/sourceTab.tsx index cfa6e2ccd4..cf704a8438 100644 --- a/packages/trace-viewer/src/ui/sourceTab.tsx +++ b/packages/trace-viewer/src/ui/sourceTab.tsx @@ -95,6 +95,7 @@ export const SourceTab: React.FunctionComponent<{ }, [onOpenExternally, location]); const showStackFrames = (stack?.length ?? 0) > 1; + const shortFileName = getFileName(fileName); return { fileName && - {fileName} - +
+
{shortFileName}
+
+ {location && }
} diff --git a/packages/web/src/components/gridView.tsx b/packages/web/src/components/gridView.tsx index 43a40d55b4..f9ba7eb50a 100644 --- a/packages/web/src/components/gridView.tsx +++ b/packages/web/src/components/gridView.tsx @@ -121,7 +121,7 @@ export function GridView(model: GridViewProps) { onIconClicked={model.onIconClicked} noItemsMessage={model.noItemsMessage} dataTestId={model.dataTestId} - noHighlightOnHover={model.noHighlightOnHover} + notSelectable={model.notSelectable} > ; diff --git a/packages/web/src/components/listView.css b/packages/web/src/components/listView.css index cc8c769332..3b7791b83d 100644 --- a/packages/web/src/components/listView.css +++ b/packages/web/src/components/listView.css @@ -34,6 +34,10 @@ padding-left: 5px; } +.list-view-content.not-selectable > .list-view-entry { + cursor: inherit; +} + .list-view-entry.highlighted:not(.selected) { background-color: var(--vscode-list-inactiveSelectionBackground) !important; } diff --git a/packages/web/src/components/listView.tsx b/packages/web/src/components/listView.tsx index a932bf7435..5186a3d02a 100644 --- a/packages/web/src/components/listView.tsx +++ b/packages/web/src/components/listView.tsx @@ -16,6 +16,7 @@ import * as React from 'react'; import './listView.css'; +import { clsx } from '@web/uiUtils'; export type ListViewProps = { name: string, @@ -36,7 +37,7 @@ export type ListViewProps = { onIconClicked?: (item: T, index: number) => void, noItemsMessage?: string, dataTestId?: string, - noHighlightOnHover?: boolean, + notSelectable?: boolean, }; const scrollPositions = new Map(); @@ -60,7 +61,7 @@ export function ListView({ onIconClicked, noItemsMessage, dataTestId, - noHighlightOnHover, + notSelectable, }: ListViewProps) { const itemListRef = React.useRef(null); const [highlightedItem, setHighlightedItem] = React.useState(); @@ -85,9 +86,9 @@ export function ListView({ itemListRef.current.scrollTop = scrollPositions.get(name) || 0; }, [name]); - return
0 ? 'list' : undefined} data-testid={dataTestId || (name + '-list')}> + return
0 ? 'list' : undefined} data-testid={dataTestId || (name + '-list')}>
{ if (selectedItem && event.key === 'Enter') { @@ -134,18 +135,19 @@ export function ListView({ > {noItemsMessage && items.length === 0 &&
{noItemsMessage}
} {items.map((item, index) => { - const selectedSuffix = selectedItem === item ? ' selected' : ''; - const highlightedSuffix = !noHighlightOnHover && highlightedItem === item ? ' highlighted' : ''; - const errorSuffix = isError?.(item, index) ? ' error' : ''; - const warningSuffix = isWarning?.(item, index) ? ' warning' : ''; - const infoSuffix = isInfo?.(item, index) ? ' info' : ''; const indentation = indent?.(item, index) || 0; const rendered = render(item, index); return
onAccepted?.(item, index)} role='listitem' - className={'list-view-entry' + selectedSuffix + highlightedSuffix + errorSuffix + warningSuffix + infoSuffix} + className={clsx( + 'list-view-entry', + selectedItem === item && 'selected', + !notSelectable && highlightedItem === item && 'highlighted', + isError?.(item, index) && 'error', + isWarning?.(item, index) && 'warning', + isInfo?.(item, index) && 'info')} onClick={() => onSelected?.(item, index)} onMouseEnter={() => setHighlightedItem(item)} onMouseLeave={() => setHighlightedItem(undefined)} diff --git a/tests/library/global-fetch.spec.ts b/tests/library/global-fetch.spec.ts index b3bea9e432..5de98fe9ee 100644 --- a/tests/library/global-fetch.spec.ts +++ b/tests/library/global-fetch.spec.ts @@ -21,7 +21,7 @@ import { expect, playwrightTest as base } from '../config/browserTest'; import { kTargetClosedErrorMessage } from 'tests/config/errors'; const it = base.extend({ - context: async () => { + context: async ({}, use) => { throw new Error('global fetch tests should not use context'); } }); diff --git a/tests/page/page-goto.spec.ts b/tests/page/page-goto.spec.ts index 830a25e203..a613a7e036 100644 --- a/tests/page/page-goto.spec.ts +++ b/tests/page/page-goto.spec.ts @@ -179,7 +179,9 @@ it('should work with Cross-Origin-Opener-Policy after redirect', async ({ page, expect(firstRequest.url()).toBe(server.PREFIX + '/redirect'); }); -it('should properly cancel Cross-Origin-Opener-Policy navigation', async ({ page, server }) => { +it('should properly cancel Cross-Origin-Opener-Policy navigation', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32107' }, +}, async ({ page, server }) => { server.setRoute('/empty.html', (req, res) => { res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); res.end(); diff --git a/tests/page/page-request-continue.spec.ts b/tests/page/page-request-continue.spec.ts index dd7ed68b49..7487b3e35b 100644 --- a/tests/page/page-request-continue.spec.ts +++ b/tests/page/page-request-continue.spec.ts @@ -393,9 +393,12 @@ it('should continue preload link requests', async ({ page, server, browserName } expect(color).toBe('rgb(255, 192, 203)'); }); -it('continue should propagate headers to redirects', async ({ page, server, browserName }) => { - it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/28758' }); - it.fixme(browserName === 'firefox'); +it('continue should propagate headers to redirects', { + annotation: [ + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/28758' }, + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32045' }, + ] +}, async ({ page, server }) => { await server.setRedirect('/redirect', '/empty.html'); await page.route('**/redirect', route => { void route.continue({ @@ -413,9 +416,11 @@ it('continue should propagate headers to redirects', async ({ page, server, brow }); it('redirected requests should report overridden headers', { - annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31351' } -}, async ({ page, server, browserName }) => { - it.fixme(browserName === 'firefox'); + annotation: [ + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31351' }, + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32045' }, + ] +}, async ({ page, server }) => { await server.setRedirect('/redirect', '/empty.html'); await page.route('**/redirect', route => { const headers = route.request().headers(); @@ -433,9 +438,12 @@ it('redirected requests should report overridden headers', { expect((await response.request().allHeaders())['custom']).toBe('value'); }); -it('continue should delete headers on redirects', async ({ page, server, browserName }) => { - it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/13106' }); - it.fixme(browserName === 'firefox'); +it('continue should delete headers on redirects', { + annotation: [ + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/13106' }, + { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/32045' }, + ] +}, async ({ page, server }) => { await page.goto(server.PREFIX + '/empty.html'); server.setRoute('/something', (request, response) => { response.writeHead(200, { 'Access-Control-Allow-Origin': '*' }); diff --git a/tests/playwright-test/types.spec.ts b/tests/playwright-test/types.spec.ts index da8d88a38b..c34c586f7a 100644 --- a/tests/playwright-test/types.spec.ts +++ b/tests/playwright-test/types.spec.ts @@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures'; test('should check types of fixtures', async ({ runTSC }) => { const result = await runTSC({ 'helper.ts': ` - import { test as base, expect } from '@playwright/test'; + import { test as base, expect, Page } from '@playwright/test'; export type MyOptions = { foo: string, bar: number }; export const test = base.extend<{ foo: string }, { bar: number }>({ foo: 'foo', @@ -71,7 +71,7 @@ test('should check types of fixtures', async ({ runTSC }) => { // @ts-expect-error baz: true, }); - const fail9 = test.extend<{ foo: string }>({ + const fail9 = test.extend({ foo: [ async ({}, use) => { await use('foo'); // @ts-expect-error @@ -100,7 +100,21 @@ test('should check types of fixtures', async ({ runTSC }) => { return y; }); }, - }) + }); + + const chain1 = base.extend({ + page: async ({ page }, use) => { + await use(page); + }, + }); + const chain2 = chain1.extend<{ pageAsUser: Page }>({ + pageAsUser: async ({ page }, use) => { + // @ts-expect-error + const x: number = page; + // @ts-expect-error + await use(x); + }, + }); `, 'playwright.config.ts': ` import { MyOptions } from './helper'; diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 3a42d27f83..5c108d7b25 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -144,9 +144,9 @@ export type Fixtures | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in Exclude]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in Exclude]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit';