diff --git a/.github/workflows/tests_others.yml b/.github/workflows/tests_others.yml index 04115ce693..783f3fe2ff 100644 --- a/.github/workflows/tests_others.yml +++ b/.github/workflows/tests_others.yml @@ -88,11 +88,15 @@ jobs: flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }} test_clock_frozen_time_linux: - name: Frozen time library + name: time library - ${{ matrix.clock }} environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }} permissions: id-token: write # This is required for OIDC login (azure/login) to succeed contents: read # This is required for actions/checkout to succeed + strategy: + fail-fast: false + matrix: + clock: [frozen, realtime] runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 @@ -101,32 +105,36 @@ jobs: node-version: 20 browsers-to-install: chromium command: npm run test -- --project=chromium-* - bot-name: "frozen-time-library-chromium-linux" + bot-name: "${{ matrix.clock }}-time-library-chromium-linux" flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }} flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }} flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }} env: - PW_FREEZE_TIME: 1 + PW_CLOCK: ${{ matrix.clock }} test_clock_frozen_time_test_runner: - name: Frozen time test runner + name: time test runner - ${{ matrix.clock }} environment: ${{ github.event_name == 'push' && 'allow-uploading-flakiness-results' || null }} runs-on: ubuntu-22.04 permissions: id-token: write # This is required for OIDC login (azure/login) to succeed contents: read # This is required for actions/checkout to succeed + strategy: + fail-fast: false + matrix: + clock: [frozen, realtime] steps: - uses: actions/checkout@v4 - uses: ./.github/actions/run-test with: node-version: 20 command: npm run ttest - bot-name: "frozen-time-runner-chromium-linux" + bot-name: "${{ matrix.clock }}-time-runner-chromium-linux" flakiness-client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }} flakiness-tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }} flakiness-subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }} env: - PW_FREEZE_TIME: 1 + PW_CLOCK: ${{ matrix.clock }} test_electron: name: Electron - ${{ matrix.os }} diff --git a/README.md b/README.md index a32d0295c4..e225e4a9ce 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-127.0.6533.5-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-127.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-17.4-blue.svg?logo=safari)](https://webkit.org/) +[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-127.0.6533.26-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-127.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-17.4-blue.svg?logo=safari)](https://webkit.org/) ## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright) @@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 127.0.6533.5 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 127.0.6533.26 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 17.4 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Firefox 127.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/browser_patches/firefox/UPSTREAM_CONFIG.sh b/browser_patches/firefox/UPSTREAM_CONFIG.sh index b13f5e0fa7..10889141a7 100644 --- a/browser_patches/firefox/UPSTREAM_CONFIG.sh +++ b/browser_patches/firefox/UPSTREAM_CONFIG.sh @@ -1,3 +1,3 @@ REMOTE_URL="https://github.com/mozilla/gecko-dev" BASE_BRANCH="release" -BASE_REVISION="f8704c84a751716bad093b9bdc482db53fe5b3ea" +BASE_REVISION="bd7e0ac24a6fb1cddde3e45ea191b7abcc90cf56" diff --git a/browser_patches/firefox/juggler/NetworkObserver.js b/browser_patches/firefox/juggler/NetworkObserver.js index 0ac5064909..8eb69d8133 100644 --- a/browser_patches/firefox/juggler/NetworkObserver.js +++ b/browser_patches/firefox/juggler/NetworkObserver.js @@ -146,6 +146,7 @@ class NetworkRequest { this._expectingInterception = false; this._expectingResumedRequest = undefined; // { method, headers, postData } this._sentOnResponse = false; + this._fulfilled = false; if (this._pageNetwork) appendExtraHTTPHeaders(httpChannel, this._pageNetwork.combinedExtraHTTPHeaders()); @@ -194,6 +195,7 @@ class NetworkRequest { // Public interception API. fulfill(status, statusText, headers, base64body) { + this._fulfilled = true; this._interceptedChannel.synthesizeStatus(status, statusText); for (const header of headers) { this._interceptedChannel.synthesizeHeader(header.name, header.value); @@ -801,7 +803,8 @@ class ResponseStorage { return; } let encodings = []; - if ((request.httpChannel instanceof Ci.nsIEncodedChannel) && request.httpChannel.contentEncodings && !request.httpChannel.applyConversion) { + // Note: fulfilled request comes with decoded body right away. + if ((request.httpChannel instanceof Ci.nsIEncodedChannel) && request.httpChannel.contentEncodings && !request.httpChannel.applyConversion && !request._fulfilled) { const encodingHeader = request.httpChannel.getResponseHeader("Content-Encoding"); encodings = encodingHeader.split(/\s*\t*,\s*\t*/); } diff --git a/browser_patches/firefox/juggler/TargetRegistry.js b/browser_patches/firefox/juggler/TargetRegistry.js index 25c5eb562e..ea7b2afa4d 100644 --- a/browser_patches/firefox/juggler/TargetRegistry.js +++ b/browser_patches/firefox/juggler/TargetRegistry.js @@ -355,6 +355,7 @@ class PageTarget { this._screencastRecordingInfo = undefined; this._dialogs = new Map(); this.forcedColors = 'no-override'; + this.disableCache = false; this.mediumOverride = ''; this.crossProcessCookie = { initScripts: [], @@ -461,12 +462,26 @@ class PageTarget { this.updateReducedMotionOverride(browsingContext); this.updateForcedColorsOverride(browsingContext); this.updateForceOffline(browsingContext); + this.updateCacheDisabled(browsingContext); } updateForceOffline(browsingContext = undefined) { (browsingContext || this._linkedBrowser.browsingContext).forceOffline = this._browserContext.forceOffline; } + setCacheDisabled(disabled) { + this.disableCache = disabled; + this.updateCacheDisabled(); + } + + updateCacheDisabled(browsingContext = this._linkedBrowser.browsingContext) { + const enableFlags = Ci.nsIRequest.LOAD_NORMAL; + const disableFlags = Ci.nsIRequest.LOAD_BYPASS_CACHE | + Ci.nsIRequest.INHIBIT_CACHING; + + browsingContext.defaultLoadFlags = (this._browserContext.disableCache || this.disableCache) ? disableFlags : enableFlags; + } + updateTouchOverride(browsingContext = undefined) { (browsingContext || this._linkedBrowser.browsingContext).touchEventsOverride = this._browserContext.touchOverride ? 'enabled' : 'none'; } @@ -837,6 +852,7 @@ class BrowserContext { this.defaultPlatform = null; this.touchOverride = false; this.forceOffline = false; + this.disableCache = false; this.colorScheme = 'none'; this.forcedColors = 'no-override'; this.reducedMotion = 'none'; @@ -938,6 +954,12 @@ class BrowserContext { page.updateForceOffline(); } + setCacheDisabled(disabled) { + this.disableCache = disabled; + for (const page of this.pages) + page.updateCacheDisabled(); + } + async setDefaultViewport(viewport) { this.defaultViewportSize = viewport ? viewport.viewportSize : undefined; this.deviceScaleFactor = viewport ? viewport.deviceScaleFactor : undefined; diff --git a/browser_patches/firefox/juggler/content/PageAgent.js b/browser_patches/firefox/juggler/content/PageAgent.js index e1aa790c4b..6aee921e87 100644 --- a/browser_patches/firefox/juggler/content/PageAgent.js +++ b/browser_patches/firefox/juggler/content/PageAgent.js @@ -152,7 +152,6 @@ class PageAgent { getFullAXTree: this._getFullAXTree.bind(this), insertText: this._insertText.bind(this), scrollIntoViewIfNeeded: this._scrollIntoViewIfNeeded.bind(this), - setCacheDisabled: this._setCacheDisabled.bind(this), setFileInputFiles: this._setFileInputFiles.bind(this), evaluate: this._runtime.evaluate.bind(this._runtime), callFunction: this._runtime.callFunction.bind(this._runtime), @@ -162,15 +161,6 @@ class PageAgent { ]; } - _setCacheDisabled({cacheDisabled}) { - const enable = Ci.nsIRequest.LOAD_NORMAL; - const disable = Ci.nsIRequest.LOAD_BYPASS_CACHE | - Ci.nsIRequest.INHIBIT_CACHING; - - const docShell = this._frameTree.mainFrame().docShell(); - docShell.defaultLoadFlags = cacheDisabled ? disable : enable; - } - _emitAllEvents(frame) { this._browserPage.emit('pageEventFired', { frameId: frame.id(), @@ -519,71 +509,16 @@ class PageAgent { false /* aIgnoreRootScrollFrame */, true /* aFlushLayout */); - const {defaultPrevented: startPrevented} = await this._dispatchTouchEvent({ + await this._dispatchTouchEvent({ type: 'touchstart', modifiers, touchPoints: [{x, y}] }); - const {defaultPrevented: endPrevented} = await this._dispatchTouchEvent({ + await this._dispatchTouchEvent({ type: 'touchend', modifiers, touchPoints: [{x, y}] }); - if (startPrevented || endPrevented) - return; - - const frame = this._frameTree.mainFrame(); - const winUtils = frame.domWindow().windowUtils; - winUtils.jugglerSendMouseEvent( - 'mousemove', - x, - y, - 0 /*button*/, - 0 /*clickCount*/, - modifiers, - false /*aIgnoreRootScrollFrame*/, - 0.0 /*pressure*/, - 5 /*inputSource*/, - true /*isDOMEventSynthesized*/, - false /*isWidgetEventSynthesized*/, - 0 /*buttons*/, - winUtils.DEFAULT_MOUSE_POINTER_ID /* pointerIdentifier */, - true /*disablePointerEvent*/ - ); - - winUtils.jugglerSendMouseEvent( - 'mousedown', - x, - y, - 0 /*button*/, - 1 /*clickCount*/, - modifiers, - false /*aIgnoreRootScrollFrame*/, - 0.0 /*pressure*/, - 5 /*inputSource*/, - true /*isDOMEventSynthesized*/, - false /*isWidgetEventSynthesized*/, - 1 /*buttons*/, - winUtils.DEFAULT_MOUSE_POINTER_ID /*pointerIdentifier*/, - true /*disablePointerEvent*/, - ); - - winUtils.jugglerSendMouseEvent( - 'mouseup', - x, - y, - 0 /*button*/, - 1 /*clickCount*/, - modifiers, - false /*aIgnoreRootScrollFrame*/, - 0.0 /*pressure*/, - 5 /*inputSource*/, - true /*isDOMEventSynthesized*/, - false /*isWidgetEventSynthesized*/, - 0 /*buttons*/, - winUtils.DEFAULT_MOUSE_POINTER_ID /*pointerIdentifier*/, - true /*disablePointerEvent*/, - ); } async _dispatchDragEvent({type, x, y, modifiers}) { diff --git a/browser_patches/firefox/juggler/protocol/BrowserHandler.js b/browser_patches/firefox/juggler/protocol/BrowserHandler.js index ba70002c3b..7de276d017 100644 --- a/browser_patches/firefox/juggler/protocol/BrowserHandler.js +++ b/browser_patches/firefox/juggler/protocol/BrowserHandler.js @@ -186,6 +186,10 @@ class BrowserHandler { this._targetRegistry.browserContextForId(browserContextId).requestInterceptionEnabled = enabled; } + ['Browser.setCacheDisabled']({browserContextId, cacheDisabled}) { + this._targetRegistry.browserContextForId(browserContextId).setCacheDisabled(cacheDisabled); + } + ['Browser.setIgnoreHTTPSErrors']({browserContextId, ignoreHTTPSErrors}) { this._targetRegistry.browserContextForId(browserContextId).setIgnoreHTTPSErrors(nullToUndefined(ignoreHTTPSErrors)); } diff --git a/browser_patches/firefox/juggler/protocol/PageHandler.js b/browser_patches/firefox/juggler/protocol/PageHandler.js index a893e1593b..8fa9a06361 100644 --- a/browser_patches/firefox/juggler/protocol/PageHandler.js +++ b/browser_patches/firefox/juggler/protocol/PageHandler.js @@ -302,8 +302,8 @@ class PageHandler { await this._pageTarget.activateAndRun(() => {}); } - async ['Page.setCacheDisabled'](options) { - return await this._contentPage.send('setCacheDisabled', options); + async ['Page.setCacheDisabled']({cacheDisabled}) { + return await this._pageTarget.setCacheDisabled(cacheDisabled); } async ['Page.addBinding']({ worldName, name, script }) { diff --git a/browser_patches/firefox/juggler/protocol/Protocol.js b/browser_patches/firefox/juggler/protocol/Protocol.js index 5cd9e84330..6c9b700f05 100644 --- a/browser_patches/firefox/juggler/protocol/Protocol.js +++ b/browser_patches/firefox/juggler/protocol/Protocol.js @@ -322,6 +322,12 @@ const Browser = { enabled: t.Boolean, }, }, + 'setCacheDisabled': { + params: { + browserContextId: t.Optional(t.String), + cacheDisabled: t.Boolean, + }, + }, 'setGeolocationOverride': { params: { browserContextId: t.Optional(t.String), diff --git a/browser_patches/firefox/patches/bootstrap.diff b/browser_patches/firefox/patches/bootstrap.diff index 9de655e886..6291e775e6 100644 --- a/browser_patches/firefox/patches/bootstrap.diff +++ b/browser_patches/firefox/patches/bootstrap.diff @@ -57,7 +57,7 @@ index 8e9bf2b413585b5a3db9370eee5d57fb6c6716ed..5a3b194b54e3813c89989f13a214c989 * Return XPCOM wrapper for the internal accessible. */ diff --git a/browser/app/winlauncher/LauncherProcessWin.cpp b/browser/app/winlauncher/LauncherProcessWin.cpp -index b40e0fceb567c0d217adf284e13f434e49cc8467..2c4e6d5fbf8da40954ad6a5b15e412493e43b14e 100644 +index 81d4ee91e9383693d794dbf68184a80b49b582c6..1a07e3511f73199fe0b248412d01d7b8a3744a66 100644 --- a/browser/app/winlauncher/LauncherProcessWin.cpp +++ b/browser/app/winlauncher/LauncherProcessWin.cpp @@ -22,6 +22,7 @@ @@ -68,7 +68,7 @@ index b40e0fceb567c0d217adf284e13f434e49cc8467..2c4e6d5fbf8da40954ad6a5b15e41249 #include #include -@@ -421,8 +422,18 @@ Maybe LauncherMain(int& argc, wchar_t* argv[], +@@ -425,8 +426,18 @@ Maybe LauncherMain(int& argc, wchar_t* argv[], HANDLE stdHandles[] = {::GetStdHandle(STD_INPUT_HANDLE), ::GetStdHandle(STD_OUTPUT_HANDLE), ::GetStdHandle(STD_ERROR_HANDLE)}; @@ -106,10 +106,10 @@ index f6d425f36a965f03ac82dbe3ab6cde06f12751ac..d60999ab2658b1e1e5f07a8aee530451 browser/chrome/browser/search-extensions/amazon/favicon.ico browser/chrome/browser/search-extensions/amazondotcn/favicon.ico diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in -index 4068c0c165fcebd0a72f4d780bc0cbd680fe7a9c..fec7f8505d22485fa6ad4193d59387f493bd1ef8 100644 +index 1b87a9ab4aec939acac1da54a2b6670cc581fe86..a638dbe8e2f260d8be550fa8eb5bf6f6c2c31080 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in -@@ -197,6 +197,9 @@ +@@ -185,6 +185,9 @@ @RESPATH@/chrome/remote.manifest #endif @@ -120,7 +120,7 @@ index 4068c0c165fcebd0a72f4d780bc0cbd680fe7a9c..fec7f8505d22485fa6ad4193d59387f4 @RESPATH@/components/extensions-toolkit.manifest @RESPATH@/browser/components/extensions-browser.manifest diff --git a/devtools/server/socket/websocket-server.js b/devtools/server/socket/websocket-server.js -index 4236ec2921bd57c58cfffdf1cdcf509d76fca3db..23d0cb1f06bb8c7a1cac8fcec94a99fba5bfe3f2 100644 +index d49c6fbf1bf83b832795fa674f6b41f223eef812..7ea3540947ff5f61b15f27fbf4b955649f8e9ff9 100644 --- a/devtools/server/socket/websocket-server.js +++ b/devtools/server/socket/websocket-server.js @@ -134,13 +134,12 @@ function writeHttpResponse(output, response) { @@ -167,31 +167,28 @@ index 4236ec2921bd57c58cfffdf1cdcf509d76fca3db..23d0cb1f06bb8c7a1cac8fcec94a99fb const transportProvider = { setListener(upgradeListener) { diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp -index 0ef5e02d2ae365b4e7b30fd49771e547c030bcfc..0787518696fc90bba3dce8c1e1c00387c3e7a6c9 100644 +index 6e1a1b689398fa6c3c73f2f243ae02c67a4476c8..9dcf71ce753cf11f295d83eb7653e940065c8e2c 100644 --- a/docshell/base/BrowsingContext.cpp +++ b/docshell/base/BrowsingContext.cpp -@@ -114,6 +114,20 @@ struct ParamTraits - mozilla::dom::PrefersColorSchemeOverride::None, - mozilla::dom::PrefersColorSchemeOverride::EndGuard_> {}; +@@ -106,8 +106,15 @@ struct ParamTraits + template <> + struct ParamTraits +- : public mozilla::dom::WebIDLEnumSerializer< +- mozilla::dom::PrefersColorSchemeOverride> {}; ++ : public mozilla::dom::WebIDLEnumSerializer {}; ++ +template <> +struct ParamTraits -+ : public ContiguousEnumSerializer< -+ mozilla::dom::PrefersReducedMotionOverride, -+ mozilla::dom::PrefersReducedMotionOverride::None, -+ mozilla::dom::PrefersReducedMotionOverride::EndGuard_> {}; ++ : public mozilla::dom::WebIDLEnumSerializer {}; + +template <> +struct ParamTraits -+ : public ContiguousEnumSerializer< -+ mozilla::dom::ForcedColorsOverride, -+ mozilla::dom::ForcedColorsOverride::None, -+ mozilla::dom::ForcedColorsOverride::EndGuard_> {}; -+ ++ : public mozilla::dom::WebIDLEnumSerializer {}; + template <> struct ParamTraits - : public ContiguousEnumSerializer< -@@ -2793,6 +2807,40 @@ void BrowsingContext::DidSet(FieldIndex, +@@ -2804,6 +2811,40 @@ void BrowsingContext::DidSet(FieldIndex, PresContextAffectingFieldChanged(); } @@ -233,10 +230,10 @@ index 0ef5e02d2ae365b4e7b30fd49771e547c030bcfc..0787518696fc90bba3dce8c1e1c00387 nsString&& aOldValue) { MOZ_ASSERT(IsTop()); diff --git a/docshell/base/BrowsingContext.h b/docshell/base/BrowsingContext.h -index 7554128cf49ce929c973aeddf5f50ede01829c28..81ae7ec9523b944654c048af6a9f6844799eb4f3 100644 +index 5ec95a61e4d3af265cbe7dd9d83f6535da1d103e..f8acafe6d58c429af27a38363e06ad546dfbfddd 100644 --- a/docshell/base/BrowsingContext.h +++ b/docshell/base/BrowsingContext.h -@@ -200,10 +200,10 @@ struct EmbedderColorSchemes { +@@ -199,10 +199,10 @@ struct EmbedderColorSchemes { FIELD(GVInaudibleAutoplayRequestStatus, GVAutoplayRequestStatus) \ /* ScreenOrientation-related APIs */ \ FIELD(CurrentOrientationAngle, float) \ @@ -249,7 +246,7 @@ index 7554128cf49ce929c973aeddf5f50ede01829c28..81ae7ec9523b944654c048af6a9f6844 FIELD(EmbedderElementType, Maybe) \ FIELD(MessageManagerGroup, nsString) \ FIELD(MaxTouchPointsOverride, uint8_t) \ -@@ -241,6 +241,10 @@ struct EmbedderColorSchemes { +@@ -240,6 +240,10 @@ struct EmbedderColorSchemes { * embedder element. */ \ FIELD(EmbedderColorSchemes, EmbedderColorSchemes) \ FIELD(DisplayMode, dom::DisplayMode) \ @@ -260,7 +257,7 @@ index 7554128cf49ce929c973aeddf5f50ede01829c28..81ae7ec9523b944654c048af6a9f6844 /* The number of entries added to the session history because of this \ * browsing context. */ \ FIELD(HistoryEntryCount, uint32_t) \ -@@ -933,6 +937,14 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { +@@ -926,6 +930,14 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { return GetPrefersColorSchemeOverride(); } @@ -275,7 +272,7 @@ index 7554128cf49ce929c973aeddf5f50ede01829c28..81ae7ec9523b944654c048af6a9f6844 bool IsInBFCache() const; bool AllowJavascript() const { return GetAllowJavascript(); } -@@ -1097,6 +1109,23 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { +@@ -1090,6 +1102,23 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache { void WalkPresContexts(Callback&&); void PresContextAffectingFieldChanged(); @@ -300,10 +297,10 @@ index 7554128cf49ce929c973aeddf5f50ede01829c28..81ae7ec9523b944654c048af6a9f6844 bool CanSet(FieldIndex, bool, ContentParent*) { diff --git a/docshell/base/CanonicalBrowsingContext.cpp b/docshell/base/CanonicalBrowsingContext.cpp -index d5f85b1e571a7840425164a3c7715e8c70ed5c8b..5ba7484b1e7f817b2bb21dd6b5b35c6ffe2c1ca5 100644 +index 84f2d2960a3fa642754e0c909f92d96865e39984..e91fc85fc7a7966d2d536839fab823ae88d1b4bd 100644 --- a/docshell/base/CanonicalBrowsingContext.cpp +++ b/docshell/base/CanonicalBrowsingContext.cpp -@@ -1466,6 +1466,12 @@ void CanonicalBrowsingContext::LoadURI(nsIURI* aURI, +@@ -1477,6 +1477,12 @@ void CanonicalBrowsingContext::LoadURI(nsIURI* aURI, return; } @@ -317,7 +314,7 @@ index d5f85b1e571a7840425164a3c7715e8c70ed5c8b..5ba7484b1e7f817b2bb21dd6b5b35c6f } diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp -index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f81b5618d7 100644 +index 3404597343e0d21c42c5adc2f2849888869cf75a..558f03f30672b9f0fdb68ba8d23a0d878d33643d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -15,6 +15,12 @@ @@ -379,7 +376,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 mAllowAuth(mItemType == typeContent), mAllowKeywordFixup(false), mDisableMetaRefreshWhenInactive(false), -@@ -3115,6 +3132,214 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) { +@@ -3101,6 +3118,214 @@ nsDocShell::GetMessageManager(ContentFrameMessageManager** aMessageManager) { return NS_OK; } @@ -594,7 +591,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 NS_IMETHODIMP nsDocShell::GetIsNavigating(bool* aOut) { *aOut = mIsNavigating; -@@ -4803,7 +5028,7 @@ nsDocShell::GetVisibility(bool* aVisibility) { +@@ -4789,7 +5014,7 @@ nsDocShell::GetVisibility(bool* aVisibility) { } void nsDocShell::ActivenessMaybeChanged() { @@ -603,7 +600,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 if (RefPtr presShell = GetPresShell()) { presShell->ActivenessMaybeChanged(); } -@@ -6722,6 +6947,10 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType, +@@ -6711,6 +6936,10 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType, return false; // no entry to save into } @@ -614,7 +611,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 MOZ_ASSERT(!mozilla::SessionHistoryInParent(), "mOSHE cannot be non-null with SHIP"); nsCOMPtr viewer = mOSHE->GetDocumentViewer(); -@@ -8454,6 +8683,12 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) { +@@ -8443,6 +8672,12 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState) { true, // aForceNoOpener getter_AddRefs(newBC)); MOZ_ASSERT(!newBC); @@ -627,7 +624,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 return rv; } -@@ -9566,6 +9801,16 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState, +@@ -9569,6 +9804,16 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState, nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr); nsCOMPtr req; @@ -644,7 +641,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 rv = DoURILoad(aLoadState, aCacheKey, getter_AddRefs(req)); if (NS_SUCCEEDED(rv)) { -@@ -12714,6 +12959,9 @@ class OnLinkClickEvent : public Runnable { +@@ -12732,6 +12977,9 @@ class OnLinkClickEvent : public Runnable { mHandler->OnLinkClickSync(mContent, mLoadState, mNoOpenerImplied, mTriggeringPrincipal); } @@ -654,7 +651,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 return NS_OK; } -@@ -12798,6 +13046,8 @@ nsresult nsDocShell::OnLinkClick( +@@ -12816,6 +13064,8 @@ nsresult nsDocShell::OnLinkClick( nsCOMPtr ev = new OnLinkClickEvent(this, aContent, loadState, noOpenerImplied, aIsTrusted, aTriggeringPrincipal); @@ -664,7 +661,7 @@ index 0b8212fbf3f81ef6264f17fc8e84f91cde39c0f7..99d43d662978c0418231b8ea55d670f8 } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h -index 9f2d9a17dc0d54be4bd09f8e04da6e85f987fe34..8ff6e67fedef0bf73297c4cfed569b8f2ced36d9 100644 +index 82ac6c9ab9dbc102a429ab0fe6cb24b8fcdf477f..f6328c25349cf39fcce973adcf908782e8721447 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -15,6 +15,7 @@ @@ -699,7 +696,7 @@ index 9f2d9a17dc0d54be4bd09f8e04da6e85f987fe34..8ff6e67fedef0bf73297c4cfed569b8f // Create a content viewer within this nsDocShell for the given // `WindowGlobalChild` actor. nsresult CreateDocumentViewerForActor( -@@ -1003,6 +1014,8 @@ class nsDocShell final : public nsDocLoader, +@@ -1004,6 +1015,8 @@ class nsDocShell final : public nsDocLoader, bool CSSErrorReportingEnabled() const { return mCSSErrorReportingEnabled; } @@ -708,7 +705,7 @@ index 9f2d9a17dc0d54be4bd09f8e04da6e85f987fe34..8ff6e67fedef0bf73297c4cfed569b8f // Handles retrieval of subframe session history for nsDocShell::LoadURI. If a // load is requested in a subframe of the current DocShell, the subframe // loadType may need to reflect the loadType of the parent document, or in -@@ -1294,6 +1307,16 @@ class nsDocShell final : public nsDocLoader, +@@ -1295,6 +1308,16 @@ class nsDocShell final : public nsDocLoader, bool mAllowDNSPrefetch : 1; bool mAllowWindowControl : 1; bool mCSSErrorReportingEnabled : 1; @@ -726,7 +723,7 @@ index 9f2d9a17dc0d54be4bd09f8e04da6e85f987fe34..8ff6e67fedef0bf73297c4cfed569b8f bool mAllowKeywordFixup : 1; bool mDisableMetaRefreshWhenInactive : 1; diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl -index 9e79b6831a74c6de7c6a6c56d9a024d29c1c704b..db5cd5586b74ec65d788480f9c5fca93eb562c21 100644 +index 21f09a517e91644f81f5bb823f556c15cd06e51f..a68d30e0a60f03a0942ac1cd8a1f83804fdfd3e0 100644 --- a/docshell/base/nsIDocShell.idl +++ b/docshell/base/nsIDocShell.idl @@ -44,6 +44,7 @@ interface nsIURI; @@ -737,7 +734,7 @@ index 9e79b6831a74c6de7c6a6c56d9a024d29c1c704b..db5cd5586b74ec65d788480f9c5fca93 interface nsIEditor; interface nsIEditingSession; interface nsIInputStream; -@@ -767,6 +768,36 @@ interface nsIDocShell : nsIDocShellTreeItem +@@ -754,6 +755,36 @@ interface nsIDocShell : nsIDocShellTreeItem */ void synchronizeLayoutHistoryState(); @@ -775,10 +772,10 @@ index 9e79b6831a74c6de7c6a6c56d9a024d29c1c704b..db5cd5586b74ec65d788480f9c5fca93 * This attempts to save any applicable layout history state (like * scroll position) in the nsISHEntry. This is normally done diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp -index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe005669767a1b196 100644 +index 4e9286a91e3b0f1114aa0a7aa6ff81dde615a73d..941a0c3dac71008ca760024a1e828f75f6af5182 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp -@@ -3705,6 +3705,9 @@ void Document::SendToConsole(nsCOMArray& aMessages) { +@@ -3676,6 +3676,9 @@ void Document::SendToConsole(nsCOMArray& aMessages) { } void Document::ApplySettingsFromCSP(bool aSpeculative) { @@ -788,7 +785,7 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 nsresult rv = NS_OK; if (!aSpeculative) { // 1) apply settings from regular CSP -@@ -3762,6 +3765,11 @@ nsresult Document::InitCSP(nsIChannel* aChannel) { +@@ -3733,6 +3736,11 @@ nsresult Document::InitCSP(nsIChannel* aChannel) { MOZ_ASSERT(!mScriptGlobalObject, "CSP must be initialized before mScriptGlobalObject is set!"); @@ -800,7 +797,7 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 // If this is a data document - no need to set CSP. if (mLoadedAsData) { return NS_OK; -@@ -4557,6 +4565,10 @@ bool Document::HasFocus(ErrorResult& rv) const { +@@ -4500,6 +4508,10 @@ bool Document::HasFocus(ErrorResult& rv) const { return false; } @@ -811,7 +808,7 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 if (!fm->IsInActiveWindow(bc)) { return false; } -@@ -18878,6 +18890,68 @@ ColorScheme Document::PreferredColorScheme(IgnoreRFP aIgnoreRFP) const { +@@ -18849,6 +18861,66 @@ ColorScheme Document::PreferredColorScheme(IgnoreRFP aIgnoreRFP) const { return PreferenceSheet::PrefsFor(*this).mColorScheme; } @@ -837,7 +834,6 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 + case dom::PrefersReducedMotionOverride::No_preference: + return false; + case dom::PrefersReducedMotionOverride::None: -+ case dom::PrefersReducedMotionOverride::EndGuard_: + break; + } + } @@ -866,7 +862,6 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 + case dom::ForcedColorsOverride::None: + return false; + case dom::ForcedColorsOverride::No_override: -+ case dom::ForcedColorsOverride::EndGuard_: + break; + } + } @@ -881,10 +876,10 @@ index 0a2f5be08d0dcad40cd11f4b064a1287b8141e2f..a845203c6aaea8384e8835cbe0056697 if (!sLoadingForegroundTopLevelContentDocument) { return false; diff --git a/dom/base/Document.h b/dom/base/Document.h -index 3f8032594868b8aa1c8bec2d25b789518170eb0e..5017b426369378b892a224a88410f18e743da45f 100644 +index a52c61addffc4a2344fa06cb0bceebe6a7ca9075..b0f8d65e5341bf277e48bef3b88cb4cc384fbc49 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h -@@ -4051,6 +4051,9 @@ class Document : public nsINode, +@@ -4044,6 +4044,9 @@ class Document : public nsINode, // color-scheme meta tag. ColorScheme DefaultColorScheme() const; @@ -895,10 +890,10 @@ index 3f8032594868b8aa1c8bec2d25b789518170eb0e..5017b426369378b892a224a88410f18e static bool AutomaticStorageAccessPermissionCanBeGranted( diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp -index d4b04f809228fecc3e2dbf33dac42151ffc24b11..39dfddff7404e878cd9fcc8f3b9bb734ab72d743 100644 +index 14a00b8ed85f69312a89990acbb5e0f9755bd832..4b07c28615920a95a2ba59247f8575515cac4235 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp -@@ -335,14 +335,18 @@ void Navigator::GetAppName(nsAString& aAppName) const { +@@ -338,14 +338,18 @@ void Navigator::GetAppName(nsAString& aAppName) const { * for more detail. */ /* static */ @@ -919,7 +914,7 @@ index d4b04f809228fecc3e2dbf33dac42151ffc24b11..39dfddff7404e878cd9fcc8f3b9bb734 // Split values on commas. for (nsDependentSubstring lang : -@@ -394,7 +398,13 @@ void Navigator::GetLanguage(nsAString& aLanguage) { +@@ -397,7 +401,13 @@ void Navigator::GetLanguage(nsAString& aLanguage) { } void Navigator::GetLanguages(nsTArray& aLanguages) { @@ -935,10 +930,10 @@ index d4b04f809228fecc3e2dbf33dac42151ffc24b11..39dfddff7404e878cd9fcc8f3b9bb734 // The returned value is cached by the binding code. The window listens to the // accept languages change and will clear the cache when needed. It has to diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h -index 998328cfc6f36fd579e4fe26629a92a1ceefa9fa..c73e48d8dfe5a66fb9eb7f6bf49527f88cabc884 100644 +index e559dc4d6aef61b7012a27f3d6c3186a12a15319..9798a50789ce972c4d9e94419e20a5cde4cd552a 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h -@@ -216,7 +216,7 @@ class Navigator final : public nsISupports, public nsWrapperCache { +@@ -215,7 +215,7 @@ class Navigator final : public nsISupports, public nsWrapperCache { StorageManager* Storage(); @@ -948,10 +943,10 @@ index 998328cfc6f36fd579e4fe26629a92a1ceefa9fa..c73e48d8dfe5a66fb9eb7f6bf49527f8 dom::MediaCapabilities* MediaCapabilities(); dom::MediaSession* MediaSession(); diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp -index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa916988872a18 100644 +index c6f1687f73df6b1849a191ff8722dc9fc26fc3eb..9fdface27d5c9bd0c61b8af229a31be2356c46b5 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp -@@ -8697,7 +8697,8 @@ nsresult nsContentUtils::SendMouseEvent( +@@ -8711,7 +8711,8 @@ nsresult nsContentUtils::SendMouseEvent( bool aIgnoreRootScrollFrame, float aPressure, unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow, PreventDefaultResult* aPreventDefault, bool aIsDOMEventSynthesized, @@ -961,7 +956,7 @@ index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa9169 nsPoint offset; nsCOMPtr widget = GetWidget(aPresShell, &offset); if (!widget) return NS_ERROR_FAILURE; -@@ -8705,6 +8706,7 @@ nsresult nsContentUtils::SendMouseEvent( +@@ -8719,6 +8720,7 @@ nsresult nsContentUtils::SendMouseEvent( EventMessage msg; Maybe exitFrom; bool contextMenuKey = false; @@ -969,7 +964,7 @@ index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa9169 if (aType.EqualsLiteral("mousedown")) { msg = eMouseDown; } else if (aType.EqualsLiteral("mouseup")) { -@@ -8729,6 +8731,12 @@ nsresult nsContentUtils::SendMouseEvent( +@@ -8743,6 +8745,12 @@ nsresult nsContentUtils::SendMouseEvent( msg = eMouseHitTest; } else if (aType.EqualsLiteral("MozMouseExploreByTouch")) { msg = eMouseExploreByTouch; @@ -982,7 +977,7 @@ index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa9169 } else { return NS_ERROR_FAILURE; } -@@ -8737,12 +8745,21 @@ nsresult nsContentUtils::SendMouseEvent( +@@ -8751,12 +8759,21 @@ nsresult nsContentUtils::SendMouseEvent( aInputSourceArg = MouseEvent_Binding::MOZ_SOURCE_MOUSE; } @@ -1006,7 +1001,7 @@ index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa9169 event.pointerId = aIdentifier; event.mModifiers = GetWidgetModifiers(aModifiers); event.mButton = aButton; -@@ -8753,8 +8770,10 @@ nsresult nsContentUtils::SendMouseEvent( +@@ -8767,8 +8784,10 @@ nsresult nsContentUtils::SendMouseEvent( event.mPressure = aPressure; event.mInputSource = aInputSourceArg; event.mClickCount = aClickCount; @@ -1018,10 +1013,10 @@ index 6d3a9f8937a7b37bf82a18362d7ee525e4e267f4..c598acdcda9d47cdd193011e8faa9169 nsPresContext* presContext = aPresShell->GetPresContext(); if (!presContext) return NS_ERROR_FAILURE; diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h -index db68b67c5a3e60ac214231ac82fd9f652a697858..529b49b2c6c5f693747d847bca85e93415b9159c 100644 +index 338fc097dede02a538f240ba4cc66307086c7f56..8345e47237bc40490bd17019a053cce4c3d74a91 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h -@@ -2958,7 +2958,8 @@ class nsContentUtils { +@@ -3055,7 +3055,8 @@ class nsContentUtils { int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure, unsigned short aInputSourceArg, uint32_t aIdentifier, bool aToWindow, mozilla::PreventDefaultResult* aPreventDefault, @@ -1032,7 +1027,7 @@ index db68b67c5a3e60ac214231ac82fd9f652a697858..529b49b2c6c5f693747d847bca85e934 static void FirePageShowEventForFrameLoaderSwap( nsIDocShellTreeItem* aItem, diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp -index 6c547a9fd8604ac7fd7b965be473bc4120b2fdf7..c9aa1951da7af70913f77c76bb7c68ba144adaeb 100644 +index 9bc8340b9009717e0feecd5c14ff02be07a03daf..70ea04c7f11e6ccfadf72a82ec1741fac10ef5fd 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -685,6 +685,26 @@ nsDOMWindowUtils::GetPresShellId(uint32_t* aPresShellId) { @@ -1110,10 +1105,10 @@ index 63968c9b7a4e418e4c0de6e7a75fa215a36a9105..decf3ea3833ccdffd49a7aded2d600f9 MOZ_CAN_RUN_SCRIPT nsresult SendTouchEventCommon( diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp -index 60f45157cdfceb7ebf4f9a1681d0e59dc1822360..964d7cc1b847cd8ef21cef29be4fdc11168b18d8 100644 +index 5a4cf78d65eee0adcbeca33787706113eca19de7..7c8016e422ccc9e86563eaa83c9acc1dad0e5967 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp -@@ -1673,6 +1673,10 @@ Maybe nsFocusManager::SetFocusInner(Element* aNewContent, +@@ -1675,6 +1675,10 @@ Maybe nsFocusManager::SetFocusInner(Element* aNewContent, (GetActiveBrowsingContext() == newRootBrowsingContext); } @@ -1124,7 +1119,27 @@ index 60f45157cdfceb7ebf4f9a1681d0e59dc1822360..964d7cc1b847cd8ef21cef29be4fdc11 // Exit fullscreen if a website focuses another window if (StaticPrefs::full_screen_api_exit_on_windowRaise() && !isElementInActiveWindow && (aFlags & FLAG_RAISE)) { -@@ -2946,7 +2950,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow, +@@ -2242,6 +2246,7 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear, + bool aIsLeavingDocument, bool aAdjustWidget, + bool aRemainActive, Element* aElementToFocus, + uint64_t aActionId) { ++ + LOGFOCUS(("<>", aActionId)); + + // hold a reference to the focused content, which may be null +@@ -2288,6 +2293,11 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear, + return true; + } + ++ // Playwright: emulate focused page by never bluring when leaving document. ++ if (XRE_IsContentProcess() && aIsLeavingDocument && docShell && nsDocShell::Cast(docShell)->ShouldOverrideHasFocus()) { ++ return true; ++ } ++ + // Keep a ref to presShell since dispatching the DOM event may cause + // the document to be destroyed. + RefPtr presShell = docShell->GetPresShell(); +@@ -2947,7 +2957,9 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow, } } @@ -1136,10 +1151,10 @@ index 60f45157cdfceb7ebf4f9a1681d0e59dc1822360..964d7cc1b847cd8ef21cef29be4fdc11 // care of lowering the present active window. This happens in // a separate runnable to avoid touching multiple windows in diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp -index a10808b95d5f7c81942d2a513f63a72c7821061e..027b9a3c87811b794816bddb90ff67bc271f7faa 100644 +index e28dcdb092b23558702377af32eece5d273d4cf3..a37ae9d6ccd978d5e84562450e7039d6a75d517b 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp -@@ -2510,10 +2510,16 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, +@@ -2509,10 +2509,16 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, }(); if (!isContentAboutBlankInChromeDocshell) { @@ -1160,7 +1175,7 @@ index a10808b95d5f7c81942d2a513f63a72c7821061e..027b9a3c87811b794816bddb90ff67bc } } -@@ -2633,6 +2639,19 @@ void nsGlobalWindowOuter::DispatchDOMWindowCreated() { +@@ -2632,6 +2638,19 @@ void nsGlobalWindowOuter::DispatchDOMWindowCreated() { } } @@ -1193,10 +1208,10 @@ index 8337a7353fb8e97372f0b57bd0fd867506a9129f..e7dedd6d26125e481e1145337a0be6ab // Outer windows only. virtual void EnsureSizeAndPositionUpToDate() override; diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp -index 11ca350f483458ba11f0ee170ce38e9785e8c70f..6bb310f6e96239388b4c92bd7bdf2d698fac8139 100644 +index d5455e559639aee9328905b50f02c52e94db950b..3fbd1e0459e5391066fc6b3a4e30a841594b31bf 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp -@@ -1362,6 +1362,61 @@ void nsINode::GetBoxQuadsFromWindowOrigin(const BoxQuadOptions& aOptions, +@@ -1365,6 +1365,61 @@ void nsINode::GetBoxQuadsFromWindowOrigin(const BoxQuadOptions& aOptions, mozilla::GetBoxQuadsFromWindowOrigin(this, aOptions, aResult, aRv); } @@ -1259,10 +1274,10 @@ index 11ca350f483458ba11f0ee170ce38e9785e8c70f..6bb310f6e96239388b4c92bd7bdf2d69 DOMQuad& aQuad, const GeometryNode& aFrom, const ConvertCoordinateOptions& aOptions, CallerType aCallerType, diff --git a/dom/base/nsINode.h b/dom/base/nsINode.h -index 0ba44cb08ffffde3bf9616e7e3b1fb33317181b6..b698e309e7bf658739b3a69a1d68f657a6c84e6e 100644 +index 3a47992cc89176fe9500f7b1d5b74e4422cb9625..27e6da8498af5e4a3c37407a3a8ab592e28dc372 100644 --- a/dom/base/nsINode.h +++ b/dom/base/nsINode.h -@@ -2235,6 +2235,10 @@ class nsINode : public mozilla::dom::EventTarget { +@@ -2248,6 +2248,10 @@ class nsINode : public mozilla::dom::EventTarget { nsTArray>& aResult, ErrorResult& aRv); @@ -1302,7 +1317,7 @@ index cceb725d393d5e5f83c8f87491089c3fa1d57cc3..e906a7fb7c3fd72554613f640dcc272e static bool DumpEnabled(); diff --git a/dom/chrome-webidl/BrowsingContext.webidl b/dom/chrome-webidl/BrowsingContext.webidl -index 8600a844634eed78e0b8470eaf11144f8ebd230b..853a4c98b78092181ad15542ae48cd41e9c49a82 100644 +index d70f3e18cc8e8f749e5057297161206129871453..2f2be2a6539203d1957bfe580a06ab70a512c053 100644 --- a/dom/chrome-webidl/BrowsingContext.webidl +++ b/dom/chrome-webidl/BrowsingContext.webidl @@ -53,6 +53,24 @@ enum PrefersColorSchemeOverride { @@ -1330,7 +1345,7 @@ index 8600a844634eed78e0b8470eaf11144f8ebd230b..853a4c98b78092181ad15542ae48cd41 /** * Allowed overrides of platform/pref default behaviour for touch events. */ -@@ -205,6 +223,12 @@ interface BrowsingContext { +@@ -209,6 +227,12 @@ interface BrowsingContext { // Color-scheme simulation, for DevTools. [SetterThrows] attribute PrefersColorSchemeOverride prefersColorSchemeOverride; @@ -1443,10 +1458,10 @@ index 7e1af00d05fbafa2d828e2c7e4dcc5c82d115f5b..e85af9718d064e4d2865bc944e9d4ba1 ~Geolocation(); diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp -index ae2c4af82c3827a521a79f8879a6f941ea68feca..92ea48eba6fb575ea1415d8713b49707b895561b 100644 +index d5a65a17555b7764611803f7fb298712b2c60fd7..fdee7deaf0b14e01702b902f8b73256c281e76b8 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp -@@ -58,6 +58,7 @@ +@@ -57,6 +57,7 @@ #include "mozilla/dom/Document.h" #include "mozilla/dom/HTMLDataListElement.h" #include "mozilla/dom/HTMLOptionElement.h" @@ -1454,11 +1469,12 @@ index ae2c4af82c3827a521a79f8879a6f941ea68feca..92ea48eba6fb575ea1415d8713b49707 #include "nsIFormControlFrame.h" #include "nsITextControlFrame.h" #include "nsIFrame.h" -@@ -784,6 +785,12 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) { +@@ -783,6 +784,13 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) { return NS_ERROR_FAILURE; } -+ nsDocShell* docShell = static_cast(win->GetDocShell()); ++ nsCOMPtr win = doc->GetWindow(); ++ nsDocShell* docShell = win ? static_cast(win->GetDocShell()) : nullptr; + if (docShell && docShell->IsFileInputInterceptionEnabled()) { + docShell->FilePickerShown(this); + return NS_OK; @@ -1468,7 +1484,7 @@ index ae2c4af82c3827a521a79f8879a6f941ea68feca..92ea48eba6fb575ea1415d8713b49707 return NS_OK; } diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl -index 564b24e3f89e0ce6e683902a7fc4e1c3a6f5faac..e4264b251e580bb13aa2941b26227541c74d3371 100644 +index 6a0df1b435cee9cea3b7d7ca30d0aff0e31f8ac0..c17b24823dd873c025e407fcc635b7c678dfd8ed 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -373,6 +373,26 @@ interface nsIDOMWindowUtils : nsISupports { @@ -1499,10 +1515,10 @@ index 564b24e3f89e0ce6e683902a7fc4e1c3a6f5faac..e4264b251e580bb13aa2941b26227541 * touchstart, touchend, touchmove, and touchcancel * diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp -index 830ad8579a39d262a1fd2c86479f2ddc77c01ae2..b840b68c9b5545fc974e1dafacac2e74372f4e41 100644 +index bdd10fdcb285e43778b55907ac05bfa973207e5e..d98808918ff8eccd6c51b4fbce1cce5e3745206a 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp -@@ -1651,6 +1651,21 @@ void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent, +@@ -1652,6 +1652,21 @@ void BrowserChild::HandleRealMouseButtonEvent(const WidgetMouseEvent& aEvent, if (postLayerization) { postLayerization->Register(); } @@ -1777,7 +1793,7 @@ index 3b39538e51840cd9b1685b2efd2ff2e9ec83608a..c7bf4f2d53b58bbacb22b3ebebf6f3fc return aGlobalOrNull; diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp -index 50730b691b06409f47cb9172570866a7bb519abc..e5ae4f31b8f93f17943c24108a82c6370470e9f2 100644 +index 11d09909f73fee425fd0f50b384c396a52e02a36..b0e668881bcd3b850de709ebf2557ae8391b8fe8 100644 --- a/dom/security/nsCSPUtils.cpp +++ b/dom/security/nsCSPUtils.cpp @@ -22,6 +22,7 @@ @@ -1824,10 +1840,10 @@ index 2f71b284ee5f7e11f117c447834b48355784448c..2640bd57123c2b03bf4b06a2419cd020 * returned quads are further translated relative to the window * origin -- which is not the layout origin. Further translation diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp -index bcfbe33925afb97e68305394fb38e42481682540..47bc46f34a93991f112292c851c539a6bc97778f 100644 +index 02efb1205382850b41c38d5f6ee47092adcdc63e..28c8d05d0b5cc415f3d13a4588248f3844faf4f2 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp -@@ -985,7 +985,7 @@ void PrefLanguagesChanged(const char* /* aPrefName */, void* /* aClosure */) { +@@ -995,7 +995,7 @@ void PrefLanguagesChanged(const char* /* aPrefName */, void* /* aClosure */) { AssertIsOnMainThread(); nsTArray languages; @@ -1836,7 +1852,7 @@ index bcfbe33925afb97e68305394fb38e42481682540..47bc46f34a93991f112292c851c539a6 RuntimeService* runtime = RuntimeService::GetService(); if (runtime) { -@@ -1172,8 +1172,7 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) { +@@ -1182,8 +1182,7 @@ bool RuntimeService::RegisterWorker(WorkerPrivate& aWorkerPrivate) { } // The navigator overridden properties should have already been read. @@ -1846,7 +1862,7 @@ index bcfbe33925afb97e68305394fb38e42481682540..47bc46f34a93991f112292c851c539a6 mNavigatorPropertiesLoaded = true; } -@@ -1772,6 +1771,13 @@ void RuntimeService::PropagateStorageAccessPermissionGranted( +@@ -1789,6 +1788,13 @@ void RuntimeService::PropagateStorageAccessPermissionGranted( } } @@ -1860,7 +1876,7 @@ index bcfbe33925afb97e68305394fb38e42481682540..47bc46f34a93991f112292c851c539a6 template void RuntimeService::BroadcastAllWorkers(const Func& aFunc) { AssertIsOnMainThread(); -@@ -2287,6 +2293,14 @@ void PropagateStorageAccessPermissionGrantedToWorkers( +@@ -2304,6 +2310,14 @@ void PropagateStorageAccessPermissionGrantedToWorkers( } } @@ -1876,10 +1892,10 @@ index bcfbe33925afb97e68305394fb38e42481682540..47bc46f34a93991f112292c851c539a6 MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(aCx); diff --git a/dom/workers/RuntimeService.h b/dom/workers/RuntimeService.h -index e6deb81f357043a937d032bb4b6c38207203f4d9..ff16582af9fbf550dfb7b5639658c34199524c45 100644 +index f51076ac1480794989999d00577bc9cf1566d5f9..fe15b2e00dc8f0bf203f2af9aad86e16c996d43d 100644 --- a/dom/workers/RuntimeService.h +++ b/dom/workers/RuntimeService.h -@@ -108,6 +108,8 @@ class RuntimeService final : public nsIObserver { +@@ -109,6 +109,8 @@ class RuntimeService final : public nsIObserver { void PropagateStorageAccessPermissionGranted( const nsPIDOMWindowInner& aWindow); @@ -1902,17 +1918,17 @@ index d10dabb5c5ff8e17851edf2bd2efc08e74584d8e..53c4070c5fde43b27fb8fbfdcf4c23d8 bool IsWorkerGlobal(JSObject* global); diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp -index acef06ba3abb006932f26f8a96fd73028f015150..940210c603d906ae0469d826b81ba8f537e7fef5 100644 +index a8643981aa966e9324a5dbdb09b4fe57210dc581..5120df2607584a7cd50ea03aa997ef5ade5c8ee2 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp -@@ -679,6 +679,18 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable { +@@ -682,6 +682,18 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable { } }; +class ResetDefaultLocaleRunnable final : public WorkerControlRunnable { + public: + explicit ResetDefaultLocaleRunnable(WorkerPrivate* aWorkerPrivate) -+ : WorkerControlRunnable(aWorkerPrivate, WorkerThread) {} ++ : WorkerControlRunnable(aWorkerPrivate, "ResetDefaultLocaleRunnable", WorkerThread) {} + + virtual bool WorkerRun(JSContext* aCx, + WorkerPrivate* aWorkerPrivate) override { @@ -1924,7 +1940,7 @@ index acef06ba3abb006932f26f8a96fd73028f015150..940210c603d906ae0469d826b81ba8f5 class UpdateLanguagesRunnable final : public WorkerRunnable { nsTArray mLanguages; -@@ -1977,6 +1989,16 @@ void WorkerPrivate::UpdateContextOptions( +@@ -1993,6 +2005,16 @@ void WorkerPrivate::UpdateContextOptions( } } @@ -1941,7 +1957,7 @@ index acef06ba3abb006932f26f8a96fd73028f015150..940210c603d906ae0469d826b81ba8f5 void WorkerPrivate::UpdateLanguages(const nsTArray& aLanguages) { AssertIsOnParentThread(); -@@ -5480,6 +5502,15 @@ void WorkerPrivate::UpdateContextOptionsInternal( +@@ -5489,6 +5511,15 @@ void WorkerPrivate::UpdateContextOptionsInternal( } } @@ -2032,10 +2048,10 @@ index 523e84c8c93f4221701f90f2e8ee146ec8e1adbd..98d5b1176e5378431b859a2dbd4d4e77 inline ClippedTime TimeClip(double time); diff --git a/js/src/debugger/Object.cpp b/js/src/debugger/Object.cpp -index c5a4f1f6dcf95922b5c8506d6bd24ad4fd2f1efc..a79bb0ad42d1bbd0434cda27c118cdd099013ab2 100644 +index 17528b0fd99ce8274e702746ff5674de4c3d4f2d..37fa52ae07381bec3504136b9bec0aa1ca110d6b 100644 --- a/js/src/debugger/Object.cpp +++ b/js/src/debugger/Object.cpp -@@ -2450,7 +2450,11 @@ Maybe DebuggerObject::call(JSContext* cx, +@@ -2468,7 +2468,11 @@ Maybe DebuggerObject::call(JSContext* cx, invokeArgs[i].set(args2[i]); } @@ -2202,10 +2218,10 @@ index dac899f7558b26d6848da8b98ed8a93555c8751a..2a07d67fa1c2840b25085566e84dc3b2 // No boxes to return return; diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp -index 4afd2b10dfdab527b63f17919c52a559b3ac3de6..787283c004d9baa7227f00c338e0322dca88f949 100644 +index 31c21c337786b76306029149a925293a44c45c28..7aa4eb0b4980bb8ecdc4e10c91b1cd70e5d0ad08 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp -@@ -10963,7 +10963,9 @@ bool PresShell::ComputeActiveness() const { +@@ -11127,7 +11127,9 @@ bool PresShell::ComputeActiveness() const { if (!browserChild->IsVisible()) { MOZ_LOG(gLog, LogLevel::Debug, (" > BrowserChild %p is not visible", browserChild)); @@ -2229,10 +2245,10 @@ index 7bb839ae18835d128dc9285b7f9dc5b5e06335af..09e3979d07447522ace740daf2b818a6 const mozilla::dom::Document*); mozilla::StylePrefersColorScheme Gecko_MediaFeatures_PrefersColorScheme( diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp -index c99eecb4867c623b8ccc6e6fb42986d71f795cc0..d127837d7e069818daaeb73ef42497226ff95e26 100644 +index f888c127d4423336a8f51e2011fc42eaf6c33f11..51d6e069f4a81c42b4bf270ba44ae4f82b8df592 100644 --- a/layout/style/nsMediaFeatures.cpp +++ b/layout/style/nsMediaFeatures.cpp -@@ -257,11 +257,11 @@ bool Gecko_MediaFeatures_MatchesPlatform(StylePlatform aPlatform) { +@@ -260,11 +260,11 @@ bool Gecko_MediaFeatures_MatchesPlatform(StylePlatform aPlatform) { } bool Gecko_MediaFeatures_PrefersReducedMotion(const Document* aDocument) { @@ -2250,7 +2266,7 @@ index c99eecb4867c623b8ccc6e6fb42986d71f795cc0..d127837d7e069818daaeb73ef4249722 bool Gecko_MediaFeatures_PrefersReducedTransparency(const Document* aDocument) { diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp -index b15f24fffd7ea5a8a00319451fa7ebf9df32ec05..0279f6626f2ac938b0456d370fd956f2a23a036b 100644 +index eb90324c37ce515e5a0fcf75412605ae57ead9ee..6733dd6c99d77399529945386caa3926960e4176 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -653,7 +653,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) @@ -2337,7 +2353,7 @@ index 155daa5cd52c4e93e1cc4559875868f4faf2c37e..02e8a2614a27a4cc9e1de760d4c48617 /** * Set the status and reason for the forthcoming synthesized response. diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp -index ca1f59e8847bd399fcf3018ede95d318265c374c..d114f0bcaddedc3553780ff7b97e395e28aff91e 100644 +index d849eab7507f0665a8a79a1b11759afa3481f1ad..3a95d5201a1c1f2161a95e15beae86f2833a875f 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -167,6 +167,7 @@ static auto CreateDocumentLoadInfo(CanonicalBrowsingContext* aBrowsingContext, @@ -2387,10 +2403,10 @@ index c58fbc96391f8dcb585bd00b5ae8cba9088abd82..c121c891b61c9d60df770020c4ad0952 if (mPump && mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) { mPump->PeekStream(CallTypeSniffers, static_cast(this)); diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp -index 3cb38dcf28a5cb3a8e70c336c8b1c822be59268f..4d9ae3ab666d4ba7b42730d50367720870f0183f 100644 +index f2c47c42a6b6448ede3a6fef1510a3982336d5af..9e35df57102c93238de2e4d548bbe1205d227f3b 100644 --- a/parser/html/nsHtml5TreeOpExecutor.cpp +++ b/parser/html/nsHtml5TreeOpExecutor.cpp -@@ -1381,6 +1381,10 @@ void nsHtml5TreeOpExecutor::UpdateReferrerInfoFromMeta( +@@ -1382,6 +1382,10 @@ void nsHtml5TreeOpExecutor::UpdateReferrerInfoFromMeta( void nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); @@ -2498,10 +2514,10 @@ index 73c83e526be1a3a252f995d0718e3975d50bffa7..db5977c54221e19e107a8325a0834302 (lazy.isRunningTests || Cu.isInAutomation) && this.SERVER_URL == "data:,#remote-settings-dummy/v1" diff --git a/servo/components/style/gecko/media_features.rs b/servo/components/style/gecko/media_features.rs -index c9ad30b28b069a122cf01c5e97b83dc68ef022ff..f32dbcfe26fe2f6b8a0d066d6dfd208f1afc510d 100644 +index 8de45d95c2b942f069c898c93702bc7db2219369..be72e9678c3de31b1eaa72cfcb2c8be886f4a80f 100644 --- a/servo/components/style/gecko/media_features.rs +++ b/servo/components/style/gecko/media_features.rs -@@ -293,10 +293,15 @@ pub enum ForcedColors { +@@ -292,10 +292,15 @@ pub enum ForcedColors { /// https://drafts.csswg.org/mediaqueries-5/#forced-colors fn eval_forced_colors(context: &Context, query_value: Option) -> bool { @@ -2597,10 +2613,10 @@ index 209af157a35cf9c4586424421ee19b3f680796b6..1feb61e2f18e9a13631addc935f00da0 /** diff --git a/toolkit/mozapps/update/UpdateService.sys.mjs b/toolkit/mozapps/update/UpdateService.sys.mjs -index 290344c58bf488b4aa955c2c58bdaa11048e2f48..2d419b90e6c5a910d3038380cd6c819eb8b0c768 100644 +index 34bf1b9e19ae54f78d134b023af96820bc13a905..b85793edcd1996833420a026cb08706d648ece14 100644 --- a/toolkit/mozapps/update/UpdateService.sys.mjs +++ b/toolkit/mozapps/update/UpdateService.sys.mjs -@@ -3853,6 +3853,8 @@ UpdateService.prototype = { +@@ -3852,6 +3852,8 @@ UpdateService.prototype = { }, get disabledForTesting() { @@ -2610,7 +2626,7 @@ index 290344c58bf488b4aa955c2c58bdaa11048e2f48..2d419b90e6c5a910d3038380cd6c819e (Cu.isInAutomation || lazy.Marionette.running || diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild -index f554b692f7e874dd21be1ef783e899ba602ee7f3..dd6c94f8723ca227611c8390d9dcd4f292939703 100644 +index b697eb1e3b02b0ffcc95a6e492dc23eb888488cc..0f4059341dbb3c2ecb2c46be0850e0d56e2a7453 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -155,6 +155,7 @@ if CONFIG["ENABLE_WEBDRIVER"]: @@ -2622,7 +2638,7 @@ index f554b692f7e874dd21be1ef783e899ba602ee7f3..dd6c94f8723ca227611c8390d9dcd4f2 ] diff --git a/toolkit/xre/nsWindowsWMain.cpp b/toolkit/xre/nsWindowsWMain.cpp -index 7eb9e1104682d4eb47060654f43a1efa8b2a6bb2..a8315d6decf654b5302bea5beeea34140c300ded 100644 +index 2a91deec5c10f87ed09f99b659baab77b2b638f2..78f4f30a0efe314563c6405f7b0848d2c3ca0551 100644 --- a/toolkit/xre/nsWindowsWMain.cpp +++ b/toolkit/xre/nsWindowsWMain.cpp @@ -14,8 +14,10 @@ @@ -2636,10 +2652,10 @@ index 7eb9e1104682d4eb47060654f43a1efa8b2a6bb2..a8315d6decf654b5302bea5beeea3414 #include #ifdef __MINGW32__ -@@ -114,6 +116,19 @@ static void FreeAllocStrings(int argc, char** argv) { - int wmain(int argc, WCHAR** argv) { +@@ -137,6 +139,19 @@ int wmain(int argc, WCHAR** argv) { SanitizeEnvironmentVariables(); SetDllDirectoryW(L""); + RemovePrefetchArguments(argc, argv); + bool hasJugglerPipe = + mozilla::CheckArg(argc, argv, "juggler-pipe", nullptr, + mozilla::CheckArgFlag::None) == mozilla::ARG_FOUND; @@ -2793,7 +2809,7 @@ index 4573e28470c5112f5ac2c5dd53e7a9d1ceedb943..b53b86d8e39f1de4b0d0f1a8d5d7295e // OnStartRequest) mDialog = nullptr; diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h -index 205f73cfa127e15e171854165c92551fea957e84..6399525ea0abb55655c824b086a043d022392113 100644 +index 1f77e095dbfa3acc046779114007d83fc1cfa087..2354abbab7af6f6bdc3bd628722f03ea401d236a 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.h +++ b/uriloader/exthandler/nsExternalHelperAppService.h @@ -257,6 +257,8 @@ class nsExternalHelperAppService : public nsIExternalHelperAppService, @@ -2886,7 +2902,7 @@ index 1c25e9d9a101233f71e92288a0f93125b81ac1c5..22cf67b0f6e3ddd2b3ed725a314ba6a9 } #endif diff --git a/widget/MouseEvents.h b/widget/MouseEvents.h -index ea714704df53af78a55065ce7626798e0e674a23..a108e0459aeac9789adac7d7ec166abf94646454 100644 +index d29b406524c8b4afe437b559e33b4b2b5824ee58..6bef9c1657f93f90f96735d76fedb6ba3888b5c1 100644 --- a/widget/MouseEvents.h +++ b/widget/MouseEvents.h @@ -258,6 +258,7 @@ class WidgetMouseEvent : public WidgetMouseEventBase, @@ -2935,7 +2951,7 @@ diff --git a/widget/cocoa/NativeKeyBindings.mm b/widget/cocoa/NativeKeyBindings. index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce8050630a1aa 100644 --- a/widget/cocoa/NativeKeyBindings.mm +++ b/widget/cocoa/NativeKeyBindings.mm -@@ -528,6 +528,13 @@ void NativeKeyBindings::GetEditCommandsForTests( +@@ -528,6 +528,13 @@ break; case KEY_NAME_INDEX_ArrowLeft: if (aEvent.IsAlt()) { @@ -2949,7 +2965,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805 break; } if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) { -@@ -550,6 +557,13 @@ void NativeKeyBindings::GetEditCommandsForTests( +@@ -550,6 +557,13 @@ break; case KEY_NAME_INDEX_ArrowRight: if (aEvent.IsAlt()) { @@ -2963,7 +2979,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805 break; } if (aEvent.IsMeta() || (aEvent.IsControl() && aEvent.IsShift())) { -@@ -572,6 +586,10 @@ void NativeKeyBindings::GetEditCommandsForTests( +@@ -572,6 +586,10 @@ break; case KEY_NAME_INDEX_ArrowUp: if (aEvent.IsControl()) { @@ -2974,7 +2990,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805 break; } if (aEvent.IsMeta()) { -@@ -582,7 +600,7 @@ void NativeKeyBindings::GetEditCommandsForTests( +@@ -582,7 +600,7 @@ !aEvent.IsShift() ? ToObjcSelectorPtr(@selector(moveToBeginningOfDocument:)) : ToObjcSelectorPtr( @@ -2983,7 +2999,7 @@ index e4bdf715e2fb899e97a5bfeb2e147127460d6047..3554f919480278b7353617481c7ce805 aCommands); break; } -@@ -609,6 +627,10 @@ void NativeKeyBindings::GetEditCommandsForTests( +@@ -609,6 +627,10 @@ break; case KEY_NAME_INDEX_ArrowDown: if (aEvent.IsControl()) { diff --git a/browser_patches/webkit/UPSTREAM_CONFIG.sh b/browser_patches/webkit/UPSTREAM_CONFIG.sh index 71ae625752..069f24571c 100644 --- a/browser_patches/webkit/UPSTREAM_CONFIG.sh +++ b/browser_patches/webkit/UPSTREAM_CONFIG.sh @@ -1,3 +1,3 @@ REMOTE_URL="https://github.com/WebKit/WebKit.git" BASE_BRANCH="main" -BASE_REVISION="e225c278f4c06f451ea92cc68b12986dd2a99979" +BASE_REVISION="b2ca06dc3d84b356d01cdf09a82049f80515fbfe" diff --git a/browser_patches/webkit/patches/bootstrap.diff b/browser_patches/webkit/patches/bootstrap.diff index 538f932738..5df5d455da 100644 --- a/browser_patches/webkit/patches/bootstrap.diff +++ b/browser_patches/webkit/patches/bootstrap.diff @@ -1,8 +1,8 @@ diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt -index 598c68f5ad80520cec7aa886d931a93b425dcac0..743a677b61d67db06eb8e76bcca0729fb45914ed 100644 +index dcd4c26b1cd99333e9498a483ff4139a8d42d14b..f041439eff7f2649b1560faf18661165b1fd7771 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt -@@ -1419,22 +1419,27 @@ set(JavaScriptCore_INSPECTOR_DOMAINS +@@ -1400,22 +1400,27 @@ set(JavaScriptCore_INSPECTOR_DOMAINS ${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json @@ -1635,7 +1635,7 @@ index 52920cded24a9c6b0ef6fb4e518664955db4f9fa..bbbabc4e7259088b9404e8cc07eecd6f }, { diff --git a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp -index e91e5ed0b72d5a3a4c8455ce1da31647f63b2011..7ebd9a28c78ad4c2296ed3c603ff81723719fdbd 100644 +index dd1286cec6e77895f519911c89719b6064db6949..b732e0eab0fd29e1a1c9a2179cc86a951768c062 100644 --- a/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp +++ b/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp @@ -28,7 +28,6 @@ @@ -1659,7 +1659,7 @@ index 72c81757450ad5ebacd5fd20d2a16095514802ec..b7d8ab1e04d3850180079870468b28ef private: enum ArgumentRequirement { ArgumentRequired, ArgumentNotRequired }; diff --git a/Source/ThirdParty/libwebrtc/CMakeLists.txt b/Source/ThirdParty/libwebrtc/CMakeLists.txt -index bff7beb4674150d0620513ccdbd30c970bb78554..79532335e892aeb209d54fa26312380d6b1da5b2 100644 +index d6b1e73b1268a1224c2d77b936ce46347be62dac..acd1950327608988059a7e972fb4d40f9efc0c68 100644 --- a/Source/ThirdParty/libwebrtc/CMakeLists.txt +++ b/Source/ThirdParty/libwebrtc/CMakeLists.txt @@ -452,6 +452,7 @@ set(webrtc_SOURCES @@ -1682,7 +1682,7 @@ index bff7beb4674150d0620513ccdbd30c970bb78554..79532335e892aeb209d54fa26312380d Source/third_party/libyuv/source/compare.cc Source/third_party/libyuv/source/compare_common.cc Source/third_party/libyuv/source/compare_gcc.cc -@@ -2262,6 +2268,10 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE +@@ -2270,6 +2276,10 @@ set(webrtc_INCLUDE_DIRECTORIES PRIVATE Source/third_party/libsrtp/config Source/third_party/libsrtp/crypto/include Source/third_party/libsrtp/include @@ -1951,7 +1951,7 @@ index f5f1d0ef71f7fcf175b016ddaefd99f18d96c1c3..5632dcb4919eb22133a62810b91e1433 isa = XCConfigurationList; buildConfigurations = ( diff --git a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml -index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0f541003a 100644 +index 110e762586d9dc98b3a11a5cf5d1501334b2463f..870e1950740d745588cbfdc8abd3f3709867ab8f 100644 --- a/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml +++ b/Source/WTF/Scripts/Preferences/UnifiedWebPreferences.yaml @@ -562,6 +562,7 @@ ApplePayEnabled: @@ -1971,7 +1971,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 WebCore: default: false -@@ -1851,9 +1852,10 @@ CrossOriginEmbedderPolicyEnabled: +@@ -1739,9 +1740,10 @@ CrossOriginEmbedderPolicyEnabled: WebCore: default: false @@ -1983,7 +1983,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 category: security humanReadableName: "Cross-Origin-Opener-Policy (COOP) header" humanReadableDescription: "Support for Cross-Origin-Opener-Policy (COOP) header" -@@ -1861,7 +1863,7 @@ CrossOriginOpenerPolicyEnabled: +@@ -1749,7 +1751,7 @@ CrossOriginOpenerPolicyEnabled: WebKitLegacy: default: false WebKit: @@ -1992,7 +1992,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 WebCore: default: false -@@ -1905,7 +1907,7 @@ CustomPasteboardDataEnabled: +@@ -1793,7 +1795,7 @@ CustomPasteboardDataEnabled: WebKitLegacy: default: false WebKit: @@ -2001,7 +2001,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 default: false CustomStateSetEnabled: -@@ -1964,6 +1966,7 @@ DOMAudioSessionFullEnabled: +@@ -1852,6 +1854,7 @@ DOMAudioSessionFullEnabled: WebCore: default: false @@ -2009,7 +2009,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 DOMPasteAccessRequestsEnabled: type: bool status: internal -@@ -1975,7 +1978,7 @@ DOMPasteAccessRequestsEnabled: +@@ -1863,7 +1866,7 @@ DOMPasteAccessRequestsEnabled: default: false WebKit: "PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(VISION)": true @@ -2018,7 +2018,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 WebCore: default: false -@@ -3414,6 +3417,7 @@ InspectorAttachmentSide: +@@ -3232,6 +3235,7 @@ InspectorAttachmentSide: WebKit: default: 0 @@ -2026,7 +2026,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 InspectorStartsAttached: type: bool status: embedder -@@ -3421,7 +3425,7 @@ InspectorStartsAttached: +@@ -3239,7 +3243,7 @@ InspectorStartsAttached: exposed: [ WebKit ] defaultValue: WebKit: @@ -2035,7 +2035,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 InspectorWindowFrame: type: String -@@ -3776,9 +3780,10 @@ LayoutViewportHeightExpansionFactor: +@@ -3593,9 +3597,10 @@ LayoutViewportHeightExpansionFactor: WebCore: default: 0 @@ -2047,7 +2047,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 category: html humanReadableName: "Lazy iframe loading" humanReadableDescription: "Enable lazy iframe loading support" -@@ -3786,9 +3791,9 @@ LazyIframeLoadingEnabled: +@@ -3603,9 +3608,9 @@ LazyIframeLoadingEnabled: WebKitLegacy: default: true WebKit: @@ -2059,7 +2059,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 LazyImageLoadingEnabled: type: bool -@@ -5210,6 +5215,19 @@ PitchCorrectionAlgorithm: +@@ -5028,6 +5033,19 @@ PitchCorrectionAlgorithm: WebCore: default: MediaPlayerEnums::PitchCorrectionAlgorithm::BestAllAround @@ -2076,10 +2076,10 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 + WebCore: + default: true + - PopoverAttributeEnabled: + PointerLockOptionsEnabled: type: bool - status: stable -@@ -6946,6 +6964,7 @@ UseCGDisplayListsForDOMRendering: + status: testable +@@ -6778,6 +6796,7 @@ UseCGDisplayListsForDOMRendering: WebKit: default: true @@ -2087,7 +2087,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 UseGPUProcessForCanvasRenderingEnabled: type: bool status: stable -@@ -6958,7 +6977,7 @@ UseGPUProcessForCanvasRenderingEnabled: +@@ -6790,7 +6809,7 @@ UseGPUProcessForCanvasRenderingEnabled: defaultValue: WebKit: "ENABLE(GPU_PROCESS_BY_DEFAULT)": true @@ -2096,7 +2096,16 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 default: false UseGPUProcessForDOMRenderingEnabled: -@@ -7000,6 +7019,7 @@ UseGPUProcessForMediaEnabled: +@@ -6800,7 +6819,7 @@ UseGPUProcessForDOMRenderingEnabled: + humanReadableName: "GPU Process: DOM Rendering" + humanReadableDescription: "Enable DOM rendering in GPU Process" + webcoreBinding: none +- condition: ENABLE(GPU_PROCESS) ++ condition: ENABLE(GPU_PROCESS) && !PLATFORM(WIN) + exposed: [ WebKit ] + defaultValue: + WebKit: +@@ -6832,6 +6851,7 @@ UseGPUProcessForMediaEnabled: "ENABLE(GPU_PROCESS_BY_DEFAULT)": true default: false @@ -2104,7 +2113,7 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 UseGPUProcessForWebGLEnabled: type: bool status: internal -@@ -7011,7 +7031,7 @@ UseGPUProcessForWebGLEnabled: +@@ -6843,7 +6863,7 @@ UseGPUProcessForWebGLEnabled: default: false WebKit: "ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true @@ -2114,10 +2123,10 @@ index c7812f1c9eed5b85cfd0f2c95224509743572eef..df12b644468fe5cba5592be5265147a0 WebCore: "ENABLE(GPU_PROCESS_BY_DEFAULT) && ENABLE(GPU_PROCESS_WEBGL_BY_DEFAULT)": true diff --git a/Source/WTF/wtf/PlatformEnable.h b/Source/WTF/wtf/PlatformEnable.h -index 6fbfe8530da9b3f0c537f42ff66ec4ff7bc18eef..1b777bff1c688c4c0d1e8b81eff345e44c5068ef 100644 +index 6f547f01a22d1aba86b813fc77679124a643ef72..34fbae99c2e64f2a34a83d878da76f9c75d0bea5 100644 --- a/Source/WTF/wtf/PlatformEnable.h +++ b/Source/WTF/wtf/PlatformEnable.h -@@ -409,7 +409,7 @@ +@@ -401,7 +401,7 @@ // ORIENTATION_EVENTS should never get enabled on Desktop, only Mobile. #if !defined(ENABLE_ORIENTATION_EVENTS) @@ -2126,7 +2135,7 @@ index 6fbfe8530da9b3f0c537f42ff66ec4ff7bc18eef..1b777bff1c688c4c0d1e8b81eff345e4 #endif #if !defined(ENABLE_OVERFLOW_SCROLLING_TOUCH) -@@ -514,7 +514,7 @@ +@@ -506,7 +506,7 @@ #endif #if !defined(ENABLE_TOUCH_EVENTS) @@ -2136,10 +2145,10 @@ index 6fbfe8530da9b3f0c537f42ff66ec4ff7bc18eef..1b777bff1c688c4c0d1e8b81eff345e4 #if !defined(ENABLE_TOUCH_ACTION_REGIONS) diff --git a/Source/WTF/wtf/PlatformEnableCocoa.h b/Source/WTF/wtf/PlatformEnableCocoa.h -index ced4314427247eeccfec1792da08ac8c4138f229..ff97e57bd8e70a7025959469d9fed7b20762f887 100644 +index d797c28eccac0578c7c504fa0c7b34d517746b17..32e815241e2513c979d1af01ef88b494851a2409 100644 --- a/Source/WTF/wtf/PlatformEnableCocoa.h +++ b/Source/WTF/wtf/PlatformEnableCocoa.h -@@ -791,7 +791,7 @@ +@@ -775,7 +775,7 @@ #endif #if !defined(ENABLE_SEC_ITEM_SHIM) @@ -2149,7 +2158,7 @@ index ced4314427247eeccfec1792da08ac8c4138f229..ff97e57bd8e70a7025959469d9fed7b2 #if !defined(ENABLE_SERVER_PRECONNECT) diff --git a/Source/WTF/wtf/PlatformHave.h b/Source/WTF/wtf/PlatformHave.h -index c4f3e13ed22dcd09335804ea248437ed42269f2c..0cdb4fd452ef373fdd95cb5ec0195c1456f16813 100644 +index cb5e806040f4e6e2bf94a4c27b05892af7e4301d..81fd915ce2643522b225139661da9f7dedf32469 100644 --- a/Source/WTF/wtf/PlatformHave.h +++ b/Source/WTF/wtf/PlatformHave.h @@ -419,7 +419,7 @@ @@ -2172,7 +2181,7 @@ index c4f3e13ed22dcd09335804ea248437ed42269f2c..0cdb4fd452ef373fdd95cb5ec0195c14 #if !defined(HAVE_LOCKDOWN_MODE_PDF_ADDITIONS) && \ diff --git a/Source/WTF/wtf/unicode/UTF8Conversion.h b/Source/WTF/wtf/unicode/UTF8Conversion.h -index 8c27e4ca50e6208262966834dbd9f08214294c5f..40898c535e48536418eebf1ed151887c8b0348af 100644 +index f45ef73d81bd02c0b542e98ff01f59d88f57b8a0..0fb91174b8e6641d20b4ee084ec48910cdf7b836 100644 --- a/Source/WTF/wtf/unicode/UTF8Conversion.h +++ b/Source/WTF/wtf/unicode/UTF8Conversion.h @@ -28,6 +28,10 @@ @@ -2187,10 +2196,10 @@ index 8c27e4ca50e6208262966834dbd9f08214294c5f..40898c535e48536418eebf1ed151887c namespace Unicode { diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make -index 4ab111cd6c9090f3ff912b6e0249df92da0d6523..dfd80b0297e5ee657a29375241eed77cab4e039e 100644 +index 9dd05dd4e7ad824cae7c47d61117a2bbde10c3e5..015b2ce422f594860a77b0382e9a3857f2db4ff6 100644 --- a/Source/WebCore/DerivedSources.make +++ b/Source/WebCore/DerivedSources.make -@@ -1147,6 +1147,10 @@ JS_BINDING_IDLS := \ +@@ -1149,6 +1149,10 @@ JS_BINDING_IDLS := \ $(WebCore)/dom/Slotable.idl \ $(WebCore)/dom/StaticRange.idl \ $(WebCore)/dom/StringCallback.idl \ @@ -2201,7 +2210,7 @@ index 4ab111cd6c9090f3ff912b6e0249df92da0d6523..dfd80b0297e5ee657a29375241eed77c $(WebCore)/dom/Text.idl \ $(WebCore)/dom/TextDecoder.idl \ $(WebCore)/dom/TextDecoderStream.idl \ -@@ -1736,9 +1740,6 @@ JS_BINDING_IDLS := \ +@@ -1735,9 +1739,6 @@ JS_BINDING_IDLS := \ ADDITIONAL_BINDING_IDLS = \ DocumentTouch.idl \ GestureEvent.idl \ @@ -2212,10 +2221,10 @@ index 4ab111cd6c9090f3ff912b6e0249df92da0d6523..dfd80b0297e5ee657a29375241eed77c vpath %.in $(WEBKITADDITIONS_HEADER_SEARCH_PATHS) diff --git a/Source/WebCore/Modules/geolocation/Geolocation.cpp b/Source/WebCore/Modules/geolocation/Geolocation.cpp -index d27f967de68f36c5a4cb2b9df6d011380b48b593..82fc33a1d0ab8c5368842385ed74e4981e1d6a72 100644 +index 32fde85425cbb82eb30bcc7aef58155026d2b7b7..a35495d97fcf0346e4696e26df80cf4a8fb890d6 100644 --- a/Source/WebCore/Modules/geolocation/Geolocation.cpp +++ b/Source/WebCore/Modules/geolocation/Geolocation.cpp -@@ -362,8 +362,9 @@ bool Geolocation::shouldBlockGeolocationRequests() +@@ -357,8 +357,9 @@ bool Geolocation::shouldBlockGeolocationRequests() bool isSecure = SecurityOrigin::isSecure(document()->url()) || document()->isSecureContext(); bool hasMixedContent = !document()->foundMixedContent().isEmpty(); bool isLocalOrigin = securityOrigin()->isLocal(); @@ -2263,10 +2272,10 @@ index 506ebb25fa290f27a75674a6fe5506fc311910d6..07d34c567b42aca08b188243c3f036f6 [self sendSpeechEndIfNeeded]; diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake -index 5c4d75ebdab0739a2d7f37e87f63f9c62bd297f4..1ac5a96ea17ec88dc4906c3b9d24d30026380968 100644 +index c6a03b56d8358316c9ce422c1a11438bd216f80f..69fbd319b7cd084ca125a8db1b5d92ef6a4dc10f 100644 --- a/Source/WebCore/PlatformWPE.cmake +++ b/Source/WebCore/PlatformWPE.cmake -@@ -57,6 +57,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS +@@ -60,6 +60,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS platform/graphics/libwpe/PlatformDisplayLibWPE.h platform/graphics/wayland/PlatformDisplayWayland.h @@ -2275,10 +2284,10 @@ index 5c4d75ebdab0739a2d7f37e87f63f9c62bd297f4..1ac5a96ea17ec88dc4906c3b9d24d300 set(CSS_VALUE_PLATFORM_DEFINES "HAVE_OS_DARK_MODE_SUPPORT=1") diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt -index 9fd175c505e01a219000c92dbf83fd5cacd428a2..e8be3e733db6a49b1993ef1edb062298849e05f2 100644 +index eece14fded1942140af81dede0861fb5f79fb532..cd3c5ebaccd268695d9e7bc0b96f30522c42e43e 100644 --- a/Source/WebCore/SourcesCocoa.txt +++ b/Source/WebCore/SourcesCocoa.txt -@@ -712,3 +712,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm +@@ -713,3 +713,9 @@ testing/cocoa/WebViewVisualIdentificationOverlay.mm platform/graphics/angle/GraphicsContextGLANGLE.cpp @no-unify platform/graphics/cocoa/GraphicsContextGLCocoa.mm @no-unify platform/graphics/cv/GraphicsContextGLCVCocoa.cpp @no-unify @@ -2289,10 +2298,10 @@ index 9fd175c505e01a219000c92dbf83fd5cacd428a2..e8be3e733db6a49b1993ef1edb062298 +JSTouchList.cpp +// Playwright end diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt -index 867352b020400643f6aeff8acc4c2c874c5aec83..3bf8903963d0128b015879bb6cfa192d4b302c39 100644 +index af2081f34b9d8d97864a6e9507805abc9e8eb6d7..06ed467b2c6e529baba22a04e03a4858f8552e19 100644 --- a/Source/WebCore/SourcesGTK.txt +++ b/Source/WebCore/SourcesGTK.txt -@@ -107,3 +107,10 @@ platform/unix/LoggingUnix.cpp +@@ -110,3 +110,10 @@ platform/unix/LoggingUnix.cpp platform/unix/SharedMemoryUnix.cpp platform/xdg/MIMETypeRegistryXdg.cpp @@ -2304,10 +2313,10 @@ index 867352b020400643f6aeff8acc4c2c874c5aec83..3bf8903963d0128b015879bb6cfa192d +JSSpeechSynthesisEventInit.cpp +// Playwright: end. diff --git a/Source/WebCore/SourcesWPE.txt b/Source/WebCore/SourcesWPE.txt -index e24a29cf23786daa6bce604694db462d3ccf67a4..ed61fb29cafea30491a52fdd8f8f4dce3e1e3a3a 100644 +index 92f1879df295fc63a9194dc54d3f7499c5fe3041..67c40d056aee6a8149ed1ff16ce4c835e19f7f6c 100644 --- a/Source/WebCore/SourcesWPE.txt +++ b/Source/WebCore/SourcesWPE.txt -@@ -45,6 +45,8 @@ editing/libwpe/EditorLibWPE.cpp +@@ -46,6 +46,8 @@ editing/libwpe/EditorLibWPE.cpp loader/soup/ResourceLoaderSoup.cpp @@ -2316,7 +2325,7 @@ index e24a29cf23786daa6bce604694db462d3ccf67a4..ed61fb29cafea30491a52fdd8f8f4dce page/linux/ResourceUsageOverlayLinux.cpp page/linux/ResourceUsageThreadLinux.cpp -@@ -84,6 +86,17 @@ platform/text/LocaleICU.cpp +@@ -87,6 +89,17 @@ platform/text/LocaleICU.cpp platform/unix/LoggingUnix.cpp platform/unix/SharedMemoryUnix.cpp @@ -2335,10 +2344,10 @@ index e24a29cf23786daa6bce604694db462d3ccf67a4..ed61fb29cafea30491a52fdd8f8f4dce +JSSpeechSynthesisEventInit.cpp +// Playwright: end. diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj -index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4afc4e335e1 100644 +index 8807578bc8e503fce83e9acc30029cef75b7f071..7fffb6499c200dca0c3ee777feaf284999d5d763 100644 --- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj -@@ -6215,6 +6215,13 @@ +@@ -6216,6 +6216,13 @@ EDE3A5000C7A430600956A37 /* ColorMac.h in Headers */ = {isa = PBXBuildFile; fileRef = EDE3A4FF0C7A430600956A37 /* ColorMac.h */; settings = {ATTRIBUTES = (Private, ); }; }; EDEC98030AED7E170059137F /* WebCorePrefix.h in Headers */ = {isa = PBXBuildFile; fileRef = EDEC98020AED7E170059137F /* WebCorePrefix.h */; }; EFCC6C8F20FE914400A2321B /* CanvasActivityRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -2352,7 +2361,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af F12171F616A8CF0B000053CA /* WebVTTElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F12171F416A8BC63000053CA /* WebVTTElement.h */; }; F32BDCD92363AACA0073B6AE /* UserGestureEmulationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = F32BDCD72363AACA0073B6AE /* UserGestureEmulationScope.h */; }; F344C7141125B82C00F26EEE /* InspectorFrontendClient.h in Headers */ = {isa = PBXBuildFile; fileRef = F344C7121125B82C00F26EEE /* InspectorFrontendClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; -@@ -20080,6 +20087,14 @@ +@@ -20126,6 +20133,14 @@ EDEC98020AED7E170059137F /* WebCorePrefix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebCorePrefix.h; sourceTree = ""; tabWidth = 4; usesTabs = 0; }; EFB7287B2124C73D005C2558 /* CanvasActivityRecord.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasActivityRecord.cpp; sourceTree = ""; }; EFCC6C8D20FE914000A2321B /* CanvasActivityRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasActivityRecord.h; sourceTree = ""; }; @@ -2367,7 +2376,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af F12171F316A8BC63000053CA /* WebVTTElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebVTTElement.cpp; sourceTree = ""; }; F12171F416A8BC63000053CA /* WebVTTElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTElement.h; sourceTree = ""; }; F32BDCD52363AAC90073B6AE /* UserGestureEmulationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UserGestureEmulationScope.cpp; sourceTree = ""; }; -@@ -27690,6 +27705,11 @@ +@@ -27745,6 +27760,11 @@ BC4A5324256055590028C592 /* TextDirectionSubmenuInclusionBehavior.h */, 2D4F96F11A1ECC240098BF88 /* TextIndicator.cpp */, 2D4F96F21A1ECC240098BF88 /* TextIndicator.h */, @@ -2379,7 +2388,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af F48570A42644C76D00C05F71 /* TranslationContextMenuInfo.h */, F4E1965F21F26E4E00285078 /* UndoItem.cpp */, 2ECDBAD521D8906300F00ECD /* UndoItem.h */, -@@ -33986,6 +34006,8 @@ +@@ -34075,6 +34095,8 @@ 29E4D8DF16B0940F00C84704 /* PlatformSpeechSynthesizer.h */, 1AD8F81A11CAB9E900E93E54 /* PlatformStrategies.cpp */, 1AD8F81911CAB9E900E93E54 /* PlatformStrategies.h */, @@ -2388,7 +2397,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af 0FD7C21D23CE41E30096D102 /* PlatformWheelEvent.cpp */, 935C476A09AC4D4F00A6AAB4 /* PlatformWheelEvent.h */, F491A66A2A9FEFA300F96146 /* PlatformWheelEvent.serialization.in */, -@@ -36653,6 +36675,7 @@ +@@ -36745,6 +36767,7 @@ AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */, 6BDB5DC1227BD3B800919770 /* DocumentStorageAccess.cpp */, 6BDB5DC0227BD3B800919770 /* DocumentStorageAccess.h */, @@ -2396,7 +2405,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af 7CE7FA5B1EF882300060C9D6 /* DocumentTouch.cpp */, 7CE7FA591EF882300060C9D6 /* DocumentTouch.h */, A8185F3209765765005826D9 /* DocumentType.cpp */, -@@ -41383,6 +41406,8 @@ +@@ -41482,6 +41505,8 @@ F4E90A3C2B52038E002DA469 /* PlatformTextAlternatives.h in Headers */, 0F7D07331884C56C00B4AF86 /* PlatformTextTrack.h in Headers */, 074E82BB18A69F0E007EF54C /* PlatformTimeRanges.h in Headers */, @@ -2405,7 +2414,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af CDD08ABD277E542600EA3755 /* PlatformTrackConfiguration.h in Headers */, CD1F9B022700323D00617EB6 /* PlatformVideoColorPrimaries.h in Headers */, CD1F9B01270020B700617EB6 /* PlatformVideoColorSpace.h in Headers */, -@@ -42660,6 +42685,7 @@ +@@ -42762,6 +42787,7 @@ 0F54DD081881D5F5003EEDBB /* Touch.h in Headers */, 71B7EE0D21B5C6870031C1EF /* TouchAction.h in Headers */, 0F54DD091881D5F5003EEDBB /* TouchEvent.h in Headers */, @@ -2413,7 +2422,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af 0F54DD0A1881D5F5003EEDBB /* TouchList.h in Headers */, 070334D71459FFD5008D8D45 /* TrackBase.h in Headers */, BE88E0C21715CE2600658D98 /* TrackListBase.h in Headers */, -@@ -43788,6 +43814,8 @@ +@@ -43910,6 +43936,8 @@ 2D22830323A8470700364B7E /* CursorMac.mm in Sources */, 5CBD59592280E926002B22AA /* CustomHeaderFields.cpp in Sources */, 07E4BDBF2A3A5FAB000D5509 /* DictationCaretAnimator.cpp in Sources */, @@ -2422,7 +2431,7 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af 7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */, 4667EA3E2968D9DA00BAB1E2 /* GameControllerHapticEffect.mm in Sources */, 46FE73D32968E52000B8064C /* GameControllerHapticEngines.mm in Sources */, -@@ -43875,6 +43903,9 @@ +@@ -43997,6 +44025,9 @@ CE88EE262414467B007F29C2 /* TextAlternativeWithRange.mm in Sources */, BE39137129B267F500FA5D4F /* TextTransformCocoa.cpp in Sources */, 51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */, @@ -2433,18 +2442,18 @@ index 426658f2035cb425d913c21ad621a8f1a8f03f14..1a462ad491fdf8044c2cad77c43da4af 538EC8021F96AF81004D22A8 /* UnifiedSource1.cpp in Sources */, 538EC8051F96AF81004D22A8 /* UnifiedSource2-mm.mm in Sources */, diff --git a/Source/WebCore/accessibility/AccessibilityObject.cpp b/Source/WebCore/accessibility/AccessibilityObject.cpp -index ed50745a2ae8973604461d1f91994656cb6ba26f..f69247170ffc45a2dc6e477a9e1f6a48d9862ea2 100644 +index 9253fbb9de00b2768dd67c6efa20a2242e2e6621..c758a4e9b6f779458a611b6458ba89de1c17e4c8 100644 --- a/Source/WebCore/accessibility/AccessibilityObject.cpp +++ b/Source/WebCore/accessibility/AccessibilityObject.cpp -@@ -65,6 +65,7 @@ - #include "HTMLParserIdioms.h" +@@ -66,6 +66,7 @@ + #include "HTMLSlotElement.h" #include "HTMLTextAreaElement.h" #include "HitTestResult.h" +#include "InspectorInstrumentation.h" #include "LocalFrame.h" #include "LocalizedStrings.h" #include "MathMLNames.h" -@@ -4063,9 +4064,14 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const +@@ -4075,9 +4076,14 @@ AccessibilityObjectInclusion AccessibilityObject::defaultObjectInclusion() const if (roleValue() == AccessibilityRole::ApplicationDialog) return AccessibilityObjectInclusion::IncludeObject; @@ -2475,7 +2484,7 @@ index f20ac9d4d61a6f396e9ed796c8e6c5b8a7ea0577..3151b5e54ea17c0d979d22a0cc43c5ce macro(DynamicsCompressorNode) \ macro(ElementInternals) \ diff --git a/Source/WebCore/css/query/MediaQueryFeatures.cpp b/Source/WebCore/css/query/MediaQueryFeatures.cpp -index bae4d73a2e54a59595843bc64eb34252ca421a4a..a9ed264d3c5a46224d0f9a3bdabfbf19079be063 100644 +index 9892fda4291cae0e0d338fac8b0f98cd0126807d..7ecfd659809ab30e82a9c00ec7710292a1bd5611 100644 --- a/Source/WebCore/css/query/MediaQueryFeatures.cpp +++ b/Source/WebCore/css/query/MediaQueryFeatures.cpp @@ -368,7 +368,11 @@ const FeatureSchema& forcedColors() @@ -2502,7 +2511,7 @@ index bae4d73a2e54a59595843bc64eb34252ca421a4a..a9ed264d3c5a46224d0f9a3bdabfbf19 case ForcedAccessibilityValue::On: return true; diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp -index 4cc52397bbf1397aaa210e1d73831d178a3ff443..16eb5f885aeb17f61611109287ba2ce11a458ab6 100644 +index b56c600b6159973dc8a33db1deba0cfbb77abf48..a347a85381888e2f6423393552d619938ad34f21 100644 --- a/Source/WebCore/dom/DataTransfer.cpp +++ b/Source/WebCore/dom/DataTransfer.cpp @@ -510,6 +510,14 @@ Ref DataTransfer::createForDrag(const Document& document) @@ -2583,7 +2592,7 @@ index 9b8dbfc15ce078702321abcd6c0e636df7a60510..2956f7098e87af10ab8f5584b456ce9a ] partial interface mixin DocumentOrShadowRoot { readonly attribute Element? pointerLockElement; diff --git a/Source/WebCore/dom/Element+PointerLock.idl b/Source/WebCore/dom/Element+PointerLock.idl -index f27718c1e2b8cd0a8075e556d4cdba7d9ae8fc54..2b61721594e5435845f3151e0de345e90eafc9ea 100644 +index 9b344003de17b96d8b9ca8c7f32143a27543b1ea..2208a3f2b7d930bcd291e65b474d4c3023d2a7e4 100644 --- a/Source/WebCore/dom/Element+PointerLock.idl +++ b/Source/WebCore/dom/Element+PointerLock.idl @@ -24,6 +24,7 @@ @@ -2593,7 +2602,7 @@ index f27718c1e2b8cd0a8075e556d4cdba7d9ae8fc54..2b61721594e5435845f3151e0de345e9 + EnabledBySetting=PointerLockEnabled, Conditional=POINTER_LOCK ] partial interface Element { - undefined requestPointerLock(); + // Returns Promise if PointerLockOptionsEnabled Runtime Flag is set, otherwise returns undefined. diff --git a/Source/WebCore/dom/PointerEvent.cpp b/Source/WebCore/dom/PointerEvent.cpp index c35c7851f168954a0c5265ea218a2173b7b079a8..500b267351d2e4ac9864129650b6c00627a8ea6f 100644 --- a/Source/WebCore/dom/PointerEvent.cpp @@ -2756,10 +2765,10 @@ index dde92a4942d3f6679b6ef2455fa15d023544dfbc..c6ed18b40209195d1cf5c7785091d37f break; } diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp -index 284787f7db1051968ccaf7852bf0e71228ef2e99..d1977ec28b264e964264fe26155d84005e8099aa 100644 +index 3844ae7bab48f46b77cfd85530e4ab19392a71dd..8d705215457f89711e78e3bee9c983d131b08245 100644 --- a/Source/WebCore/inspector/InspectorController.cpp +++ b/Source/WebCore/inspector/InspectorController.cpp -@@ -288,6 +288,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel) +@@ -287,6 +287,8 @@ void InspectorController::disconnectFrontend(FrontendChannel& frontendChannel) // Unplug all instrumentations since they aren't needed now. InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get()); @@ -2768,7 +2777,7 @@ index 284787f7db1051968ccaf7852bf0e71228ef2e99..d1977ec28b264e964264fe26155d8400 } m_inspectorClient->frontendCountChanged(m_frontendRouter->frontendCount()); -@@ -307,6 +309,8 @@ void InspectorController::disconnectAllFrontends() +@@ -306,6 +308,8 @@ void InspectorController::disconnectAllFrontends() // The frontend should call setInspectorFrontendClient(nullptr) under closeWindow(). ASSERT(!m_inspectorFrontendClient); @@ -2777,7 +2786,7 @@ index 284787f7db1051968ccaf7852bf0e71228ef2e99..d1977ec28b264e964264fe26155d8400 if (!m_frontendRouter->hasFrontends()) return; -@@ -395,8 +399,8 @@ void InspectorController::inspect(Node* node) +@@ -394,8 +398,8 @@ void InspectorController::inspect(Node* node) if (!enabled()) return; @@ -2788,7 +2797,7 @@ index 284787f7db1051968ccaf7852bf0e71228ef2e99..d1977ec28b264e964264fe26155d8400 ensureDOMAgent().inspect(node); } -@@ -539,4 +543,24 @@ void InspectorController::didComposite(LocalFrame& frame) +@@ -538,4 +542,24 @@ void InspectorController::didComposite(LocalFrame& frame) InspectorInstrumentation::didComposite(frame); } @@ -3262,7 +3271,7 @@ index 7aa2d9e599359d9302cbdde8a7a0b9399e37d313..7b4ec6ee9adb5687e16eb0fe746a3114 { return context ? instrumentingAgents(*context) : nullptr; diff --git a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp -index 8922f4e9112436011f5ed028dfb12b0ce273576b..d3299f4fb14c1ef3c67caabd27cb2d8b5339b1da 100644 +index a5167242b6b1ee9d6ccfcd81ef86a5729882d3a4..d64c560f86db46786ba47fe55654c140efd1d31b 100644 --- a/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp +++ b/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp @@ -65,10 +65,14 @@ @@ -3564,8 +3573,8 @@ index 8922f4e9112436011f5ed028dfb12b0ce273576b..d3299f4fb14c1ef3c67caabd27cb2d8b } Node* InspectorDOMAgent::scriptValueAsNode(JSC::JSValue value) -@@ -3178,4 +3350,57 @@ Inspector::Protocol::ErrorStringOr> In - return stats; +@@ -3183,4 +3355,57 @@ Inspector::Protocol::ErrorStringOr> In + #endif } +Protocol::ErrorStringOr InspectorDOMAgent::setInputFiles(const String& objectId, RefPtr&& files, RefPtr&& paths) { @@ -3696,7 +3705,7 @@ index 5f1dba2bc4d5c2f113a88dcc9ba479679cb79233..5616c853a99b5fdb38306a804cc0e917 void discardBindings(); diff --git a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp -index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8d03165ca 100644 +index 00dba5735f2f682d00f7e17ef2abddf85a4c7f90..4c2ca023d6ad04a3ccda68d5f707df8065d50419 100644 --- a/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp +++ b/Source/WebCore/inspector/agents/InspectorNetworkAgent.cpp @@ -59,6 +59,7 @@ @@ -3707,18 +3716,18 @@ index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8 #include "Page.h" #include "PlatformStrategies.h" #include "ProgressTracker.h" -@@ -337,8 +338,8 @@ static Ref buildObjectForResourceRequest( +@@ -339,8 +340,8 @@ static Ref buildObjectForResourceRequest( .release(); if (request.httpBody() && !request.httpBody()->isEmpty()) { - auto bytes = request.httpBody()->flatten(); -- requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.data(), bytes.size())); +- requestObject->setPostData(String::fromUTF8WithLatin1Fallback(bytes.span())); + Vector bytes = request.httpBody()->flatten(); + requestObject->setPostData(base64EncodeToString(bytes)); } if (resourceLoader) { -@@ -391,6 +392,8 @@ RefPtr InspectorNetworkAgent::buildObjec +@@ -393,6 +394,8 @@ RefPtr InspectorNetworkAgent::buildObjec .setSource(responseSource(response.source())) .release(); @@ -3727,7 +3736,7 @@ index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8 if (resourceLoader) { auto* metrics = response.deprecatedNetworkLoadMetricsOrNull(); responseObject->setTiming(buildObjectForTiming(metrics ? *metrics : NetworkLoadMetrics::emptyMetrics(), *resourceLoader)); -@@ -958,6 +961,7 @@ void InspectorNetworkAgent::continuePendingResponses() +@@ -960,6 +963,7 @@ void InspectorNetworkAgent::continuePendingResponses() Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::setExtraHTTPHeaders(Ref&& headers) { @@ -3735,7 +3744,7 @@ index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8 for (auto& entry : headers.get()) { auto stringValue = entry.value->asString(); if (!!stringValue) -@@ -1236,6 +1240,9 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::interceptWithReq +@@ -1238,6 +1242,9 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::interceptWithReq return makeUnexpected("Missing pending intercept request for given requestId"_s); auto& loader = *pendingRequest->m_loader; @@ -3745,7 +3754,7 @@ index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8 ResourceRequest request = loader.request(); if (!!url) request.setURL(URL({ }, url)); -@@ -1335,14 +1342,23 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::interceptRequest +@@ -1333,14 +1340,23 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::interceptRequest response.setHTTPStatusCode(status); response.setHTTPStatusText(String { statusText }); HTTPHeaderMap explicitHeaders; @@ -3771,7 +3780,7 @@ index cf2145f9d95fb7e1639757b0b90d1e93fb6b6f14..93da4f3e31842777238ff26ea1cf7ce8 if (loader->reachedTerminalState()) return; -@@ -1405,6 +1421,12 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::setEmulatedCondi +@@ -1403,6 +1419,12 @@ Inspector::Protocol::ErrorStringOr InspectorNetworkAgent::setEmulatedCondi #endif // ENABLE(INSPECTOR_NETWORK_THROTTLING) @@ -3806,7 +3815,7 @@ index dc7e574ee6e9256a1f75ea838d20ca7f5e9190de..5dd4464256e0f5d652fa51fd611286dd // InspectorInstrumentation void willRecalculateStyle(); diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp -index 8fc922b0ab24e76458c959361551736c361bf390..4c3a462dbfacf1cdf9b16478ab579d8965221aa4 100644 +index 5329fd0a2c24031a74d05d7c6c342a5f8398eaae..a64e486220e4fc8e37c34856fce8c3d8dea87401 100644 --- a/Source/WebCore/inspector/agents/InspectorPageAgent.cpp +++ b/Source/WebCore/inspector/agents/InspectorPageAgent.cpp @@ -32,19 +32,26 @@ @@ -3884,9 +3893,9 @@ index 8fc922b0ab24e76458c959361551736c361bf390..4c3a462dbfacf1cdf9b16478ab579d89 + return nameToWorld; +} + - static bool decodeBuffer(const uint8_t* buffer, unsigned size, const String& textEncodingName, String* result) + static bool decodeBuffer(std::span buffer, const String& textEncodingName, String* result) { - if (buffer) { + if (buffer.data()) { @@ -334,6 +355,7 @@ InspectorPageAgent::InspectorPageAgent(PageAgentContext& context, InspectorClien , m_frontendDispatcher(makeUnique(context.frontendRouter)) , m_backendDispatcher(Inspector::PageBackendDispatcher::create(context.backendDispatcher, this)) @@ -4274,7 +4283,7 @@ index 8fc922b0ab24e76458c959361551736c361bf390..4c3a462dbfacf1cdf9b16478ab579d89 Inspector::Protocol::ErrorStringOr InspectorPageAgent::setScreenSizeOverride(std::optional&& width, std::optional&& height) { if (width.has_value() != height.has_value()) -@@ -1251,6 +1451,523 @@ Inspector::Protocol::ErrorStringOr InspectorPageAgent::setScreenSizeOverri +@@ -1251,6 +1451,519 @@ Inspector::Protocol::ErrorStringOr InspectorPageAgent::setScreenSizeOverri localMainFrame->setOverrideScreenSize(FloatSize(width.value_or(0), height.value_or(0))); return { }; } @@ -4310,16 +4319,12 @@ index 8fc922b0ab24e76458c959361551736c361bf390..4c3a462dbfacf1cdf9b16478ab579d89 + return "ApplicationAlertDialog"_s; + case AccessibilityRole::ApplicationDialog: + return "ApplicationDialog"_s; -+ case AccessibilityRole::ApplicationGroup: -+ return "ApplicationGroup"_s; + case AccessibilityRole::ApplicationLog: + return "ApplicationLog"_s; + case AccessibilityRole::ApplicationMarquee: + return "ApplicationMarquee"_s; + case AccessibilityRole::ApplicationStatus: + return "ApplicationStatus"_s; -+ case AccessibilityRole::ApplicationTextGroup: -+ return "ApplicationTextGroup"_s; + case AccessibilityRole::ApplicationTimer: + return "ApplicationTimer"_s; + case AccessibilityRole::Audio: @@ -4799,7 +4804,7 @@ index 8fc922b0ab24e76458c959361551736c361bf390..4c3a462dbfacf1cdf9b16478ab579d89 } // namespace WebCore diff --git a/Source/WebCore/inspector/agents/InspectorPageAgent.h b/Source/WebCore/inspector/agents/InspectorPageAgent.h -index f270cb7c3bcc1b5d7d646d9c6e6bda7063cf82e3..83d793622a71b441afe5962bd7c94ad85a12263f 100644 +index 371bcfcf1d0ae17471f8e69706d2f12356793418..6bc660d683a639f1d6f6a0dca8db5e058d32cd21 100644 --- a/Source/WebCore/inspector/agents/InspectorPageAgent.h +++ b/Source/WebCore/inspector/agents/InspectorPageAgent.h @@ -32,8 +32,10 @@ @@ -4923,7 +4928,7 @@ index f270cb7c3bcc1b5d7d646d9c6e6bda7063cf82e3..83d793622a71b441afe5962bd7c94ad8 + void ensureUserWorldsExistInAllFrames(const Vector&); static bool mainResourceContent(LocalFrame*, bool withBase64Encode, String* result); - static bool dataContent(const uint8_t* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result); + static bool dataContent(std::span data, const String& textEncodingName, bool withBase64Encode, String* result); @@ -169,17 +201,21 @@ private: RefPtr m_backendDispatcher; @@ -4949,7 +4954,7 @@ index f270cb7c3bcc1b5d7d646d9c6e6bda7063cf82e3..83d793622a71b441afe5962bd7c94ad8 } // namespace WebCore diff --git a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp -index 4e2613c5194137568d629dc809d6f062e9e2bc95..345876eb0eb72ffa75f5f7ea71bdcb7d71127d6f 100644 +index 61b797e08f5e6d90cc2724dd7a3b45c0f45af4f8..919a8b963d93742cc99c2739e472361deea84e4c 100644 --- a/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp +++ b/Source/WebCore/inspector/agents/page/PageRuntimeAgent.cpp @@ -34,6 +34,7 @@ @@ -4959,7 +4964,7 @@ index 4e2613c5194137568d629dc809d6f062e9e2bc95..345876eb0eb72ffa75f5f7ea71bdcb7d +#include "FrameLoader.h" #include "InspectorPageAgent.h" #include "InstrumentingAgents.h" - #include "JSExecState.h" + #include "JSDOMWindowCustom.h" @@ -42,6 +43,7 @@ #include "Page.h" #include "PageConsoleClient.h" @@ -5136,7 +5141,7 @@ index edfc601a36f006122f26946de5b3a60573a07968..794a6c389be8af23989a54696d573123 protected: static SameSiteInfo sameSiteInfo(const Document&, IsForDOMCookieAccess = IsForDOMCookieAccess::No); diff --git a/Source/WebCore/loader/DocumentLoader.cpp b/Source/WebCore/loader/DocumentLoader.cpp -index e85ff270c6f646f5f8f7e02ce5346a1f0b5cadaa..84214d0b81ad08f8039522b9a48ac8b34d933f38 100644 +index 90023ca4ebad0d8608b74434ca5d870ffeb00871..7360ea6857f98e60bdfa74ad4a0d595958cfc11f 100644 --- a/Source/WebCore/loader/DocumentLoader.cpp +++ b/Source/WebCore/loader/DocumentLoader.cpp @@ -763,8 +763,10 @@ void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const Resourc @@ -5171,7 +5176,7 @@ index e85ff270c6f646f5f8f7e02ce5346a1f0b5cadaa..84214d0b81ad08f8039522b9a48ac8b3 { ASSERT(navigationID); diff --git a/Source/WebCore/loader/DocumentLoader.h b/Source/WebCore/loader/DocumentLoader.h -index 875b1833d5c8a3c7402070de33587630114e1a93..b61fa5f72c3aab410b1d3a4b58dd268d996f5311 100644 +index aa98ba7e3eb896b65a156fe8f75ae3c0bc99f246..00531c35e1d5041d3bcc13c54308eb7eff387baf 100644 --- a/Source/WebCore/loader/DocumentLoader.h +++ b/Source/WebCore/loader/DocumentLoader.h @@ -191,6 +191,8 @@ public: @@ -5184,10 +5189,10 @@ index 875b1833d5c8a3c7402070de33587630114e1a93..b61fa5f72c3aab410b1d3a4b58dd268d CheckedPtr checkedFrameLoader() const; WEBCORE_EXPORT SubresourceLoader* mainResourceLoader() const; diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp -index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e82729a47911a 100644 +index 4882d1ded68a2e88595c1ce7e2a6891f066b3457..e630a3cd7022449e6eec9516f7bb5e63f3085b0e 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp -@@ -1310,6 +1310,7 @@ void FrameLoader::loadInSameDocument(URL url, RefPtr stat +@@ -1355,6 +1355,7 @@ void FrameLoader::loadInSameDocument(URL url, RefPtr stat } m_client->dispatchDidNavigateWithinPage(); @@ -5195,7 +5200,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 document->statePopped(stateObject ? stateObject.releaseNonNull() : SerializedScriptValue::nullValue()); m_client->dispatchDidPopStateWithinPage(); -@@ -1775,6 +1776,8 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t +@@ -1820,6 +1821,8 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t const String& httpMethod = loader->request().httpMethod(); if (shouldPerformFragmentNavigation(isFormSubmission, httpMethod, policyChecker().loadType(), newURL)) { @@ -5204,7 +5209,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 RefPtr oldDocumentLoader = m_documentLoader; NavigationAction action { frame->protectedDocument().releaseNonNull(), loader->request(), InitiatedByMainFrame::Unknown, loader->isRequestFromClientOrUserInput(), policyChecker().loadType(), isFormSubmission }; oldDocumentLoader->setTriggeringAction(WTFMove(action)); -@@ -1808,7 +1811,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t +@@ -1853,7 +1856,9 @@ void FrameLoader::loadWithDocumentLoader(DocumentLoader* loader, FrameLoadType t } RELEASE_ASSERT(!isBackForwardLoadType(policyChecker().loadType()) || history().provisionalItem()); @@ -5214,7 +5219,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 continueLoadAfterNavigationPolicy(request, RefPtr { weakFormState.get() }.get(), navigationPolicyDecision, allowNavigationToInvalidURL); completionHandler(); }, PolicyDecisionMode::Asynchronous); -@@ -3066,14 +3071,19 @@ String FrameLoader::userAgent(const URL& url) const +@@ -3115,14 +3120,19 @@ String FrameLoader::userAgent(const URL& url) const String FrameLoader::navigatorPlatform() const { @@ -5236,7 +5241,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 } void FrameLoader::dispatchOnloadEvents() -@@ -3514,6 +3524,8 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error) +@@ -3572,6 +3582,8 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error) checkCompleted(); if (frame->page()) checkLoadComplete(); @@ -5245,7 +5250,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 } void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, const SecurityOrigin* requesterOrigin, bool shouldContinue) -@@ -4367,9 +4379,6 @@ String FrameLoader::referrer() const +@@ -4425,9 +4437,6 @@ String FrameLoader::referrer() const void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() { @@ -5255,7 +5260,7 @@ index 504ef796ccbc570fc44b441c69a4ddc4b89fee75..9c3a168dd937dbd274ecd758398e8272 Vector> worlds; ScriptController::getAllWorlds(worlds); for (auto& world : worlds) -@@ -4379,13 +4388,12 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() +@@ -4437,13 +4446,12 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world) { Ref frame = m_frame.get(); @@ -5335,10 +5340,10 @@ index b74c5258454b0df9f74aa8a5297674b733925685..b6c3999745368c7f7e2e6176bfca6dc0 void ProgressTracker::incrementProgress(ResourceLoaderIdentifier identifier, const ResourceResponse& response) diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp -index a2220c148173e75ab575dbca17506243523a7f7e..1bd9e2d210c4b7c636666e7584c0d33f2102345b 100644 +index f0d0aeb93ca42f7178a9dc07beeba911a38c32fe..1f82595cbbbc4f32b5cc4330b4d71e05d51b27a0 100644 --- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp +++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp -@@ -1061,8 +1061,11 @@ ResourceErrorOr> CachedResourceLoader::requ +@@ -1054,8 +1054,11 @@ ResourceErrorOr> CachedResourceLoader::requ request.updateReferrerPolicy(document() ? document()->referrerPolicy() : ReferrerPolicy::Default); @@ -5352,7 +5357,7 @@ index a2220c148173e75ab575dbca17506243523a7f7e..1bd9e2d210c4b7c636666e7584c0d33f Ref page = *frame->page(); -@@ -1670,8 +1673,9 @@ Vector> CachedResourceLoader::allCachedSVGImages() const +@@ -1663,8 +1666,9 @@ Vector> CachedResourceLoader::allCachedSVGImages() const ResourceErrorOr> CachedResourceLoader::preload(CachedResource::Type type, CachedResourceRequest&& request) { @@ -5365,10 +5370,10 @@ index a2220c148173e75ab575dbca17506243523a7f7e..1bd9e2d210c4b7c636666e7584c0d33f ASSERT(m_document); if (request.charset().isEmpty() && m_document && (type == CachedResource::Type::Script || type == CachedResource::Type::CSSStyleSheet)) diff --git a/Source/WebCore/page/ChromeClient.h b/Source/WebCore/page/ChromeClient.h -index ba86781050d91cdc6b67f088bfd199b29bbc7a3f..b13a833c0712d8d2b6c8b3a0cee3fa5827d04de2 100644 +index 20666cc080e04b0fa12e654ac357531f18c7c1df..3cf1823363aacdc014326957f98f3435cf505beb 100644 --- a/Source/WebCore/page/ChromeClient.h +++ b/Source/WebCore/page/ChromeClient.h -@@ -334,7 +334,7 @@ public: +@@ -335,7 +335,7 @@ public: #endif #if ENABLE(ORIENTATION_EVENTS) @@ -5378,10 +5383,10 @@ index ba86781050d91cdc6b67f088bfd199b29bbc7a3f..b13a833c0712d8d2b6c8b3a0cee3fa58 #if ENABLE(INPUT_TYPE_COLOR) diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp -index ac9e55cc26b95ceb6b8a3bd62b984ccf4e96fbec..37edb3407986ba04a82c0d1acd1662e5e835fb6a 100644 +index 1171407b2f308431ba948ec477a56c90e66911e8..a96feb7fe5a299adaeb950a11512bdf26b1f2836 100644 --- a/Source/WebCore/page/EventHandler.cpp +++ b/Source/WebCore/page/EventHandler.cpp -@@ -4322,6 +4322,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr +@@ -4325,6 +4325,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr if (!document) return false; @@ -5394,7 +5399,7 @@ index ac9e55cc26b95ceb6b8a3bd62b984ccf4e96fbec..37edb3407986ba04a82c0d1acd1662e5 dragState().dataTransfer = DataTransfer::createForDrag(*document); auto hasNonDefaultPasteboardData = HasNonDefaultPasteboardData::No; -@@ -4948,7 +4954,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve +@@ -4951,7 +4957,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap. unsigned touchPointTargetKey = point.id() + 1; @@ -5403,7 +5408,7 @@ index ac9e55cc26b95ceb6b8a3bd62b984ccf4e96fbec..37edb3407986ba04a82c0d1acd1662e5 bool pointerCancelled = false; #endif RefPtr touchTarget; -@@ -4995,7 +5001,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve +@@ -4998,7 +5004,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve // we also remove it from the map. touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey); @@ -5412,7 +5417,7 @@ index ac9e55cc26b95ceb6b8a3bd62b984ccf4e96fbec..37edb3407986ba04a82c0d1acd1662e5 HitTestResult result = hitTestResultAtPoint(pagePoint, hitType | HitTestRequest::Type::AllowChildFrameContent); pointerTarget = result.targetElement(); pointerCancelled = (pointerTarget != touchTarget); -@@ -5018,7 +5024,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve +@@ -5021,7 +5027,7 @@ HandleUserInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEve if (!targetFrame) continue; @@ -5473,7 +5478,7 @@ index e4f52ca1cb3228868bc77a5498c87e1f2af59ce4..9ce6b102570cdcd2775ebf5adcd1650d struct SnapshotOptions { diff --git a/Source/WebCore/page/History.cpp b/Source/WebCore/page/History.cpp -index fc2312697a19a2dca1907f9ddaffef26a2918113..ab51a74df8ff444302c46f85f0bc8ab0f791d1dc 100644 +index 28dacedeebc77b2da6428cdbe166581c96348dfa..9c5bfaf9c81c2e5904f69071ee674363ee9decf8 100644 --- a/Source/WebCore/page/History.cpp +++ b/Source/WebCore/page/History.cpp @@ -32,6 +32,7 @@ @@ -5493,7 +5498,7 @@ index fc2312697a19a2dca1907f9ddaffef26a2918113..ab51a74df8ff444302c46f85f0bc8ab0 if (stateObjectType == StateObjectType::Push) { frame->loader().history().pushState(WTFMove(data), fullURL.string()); diff --git a/Source/WebCore/page/LocalFrame.cpp b/Source/WebCore/page/LocalFrame.cpp -index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b5785637341016eb2ff44 100644 +index 9f480cb9a6000333711f0e9630522ddc77534015..f2d62e42e926b0d1d53f3a9feb3ce4ea93507ca3 100644 --- a/Source/WebCore/page/LocalFrame.cpp +++ b/Source/WebCore/page/LocalFrame.cpp @@ -40,6 +40,7 @@ @@ -5512,7 +5517,7 @@ index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b578563734101 #include "HTMLAttachmentElement.h" #include "HTMLFormControlElement.h" #include "HTMLFormElement.h" -@@ -76,6 +78,7 @@ +@@ -77,6 +79,7 @@ #include "Logging.h" #include "Navigator.h" #include "NodeList.h" @@ -5520,7 +5525,7 @@ index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b578563734101 #include "NodeTraversal.h" #include "Page.h" #include "ProcessWarming.h" -@@ -186,6 +189,7 @@ LocalFrame::LocalFrame(Page& page, UniqueRef&& frameLoad +@@ -187,6 +190,7 @@ LocalFrame::LocalFrame(Page& page, UniqueRef&& frameLoad void LocalFrame::init() { @@ -5528,7 +5533,7 @@ index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b578563734101 checkedLoader()->init(); } -@@ -420,7 +424,7 @@ void LocalFrame::orientationChanged() +@@ -411,7 +415,7 @@ void LocalFrame::orientationChanged() IntDegrees LocalFrame::orientation() const { if (RefPtr page = this->page()) @@ -5537,7 +5542,7 @@ index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b578563734101 return 0; } #endif // ENABLE(ORIENTATION_EVENTS) -@@ -1341,6 +1345,362 @@ String LocalFrame::customUserAgentAsSiteSpecificQuirks() const +@@ -1340,6 +1344,362 @@ String LocalFrame::customUserAgentAsSiteSpecificQuirks() const return { }; } @@ -5901,7 +5906,7 @@ index 1261ef00be22e57714d52a718a1a463aff4b902e..1b6eaf61ebf7f3987b0b578563734101 #undef FRAME_RELEASE_LOG_ERROR diff --git a/Source/WebCore/page/LocalFrame.h b/Source/WebCore/page/LocalFrame.h -index 8664b164cf806585025da5d60ad1440ee4723482..8e0a986d16eb6cd6bb4cf381d18434b6acf1ab61 100644 +index 976a7e01a1a83902d2eddcdbe044c1ec1cd9a7b8..d548c31e6beffe704b8093669ee07d576941a50a 100644 --- a/Source/WebCore/page/LocalFrame.h +++ b/Source/WebCore/page/LocalFrame.h @@ -28,8 +28,10 @@ @@ -5980,10 +5985,10 @@ index 8664b164cf806585025da5d60ad1440ee4723482..8e0a986d16eb6cd6bb4cf381d18434b6 ViewportArguments m_viewportArguments; diff --git a/Source/WebCore/page/Page.cpp b/Source/WebCore/page/Page.cpp -index 2e0f4477ca7e4874b4b5b38fe1e8fefd2bc75cd8..c0e9358b9cdbb92c273832edbb560236af24e80c 100644 +index 2da22620311314dc67bec3563c7f1b6525bd7b28..e7c530d193fe0c318dfa89f5ae72e3598bdf44bd 100644 --- a/Source/WebCore/page/Page.cpp +++ b/Source/WebCore/page/Page.cpp -@@ -554,6 +554,45 @@ void Page::setOverrideViewportArguments(const std::optional& +@@ -569,6 +569,45 @@ void Page::setOverrideViewportArguments(const std::optional& document->updateViewportArguments(); } @@ -6029,7 +6034,7 @@ index 2e0f4477ca7e4874b4b5b38fe1e8fefd2bc75cd8..c0e9358b9cdbb92c273832edbb560236 ScrollingCoordinator* Page::scrollingCoordinator() { if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled()) { -@@ -3834,6 +3873,26 @@ void Page::setUseDarkAppearanceOverride(std::optional valueOverride) +@@ -3870,6 +3909,26 @@ void Page::setUseDarkAppearanceOverride(std::optional valueOverride) #endif } @@ -6057,10 +6062,10 @@ index 2e0f4477ca7e4874b4b5b38fe1e8fefd2bc75cd8..c0e9358b9cdbb92c273832edbb560236 { if (insets == m_fullscreenInsets) diff --git a/Source/WebCore/page/Page.h b/Source/WebCore/page/Page.h -index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456c11a0db8 100644 +index 551ffa245a63f05cd7d58a86048ed22c1feb6205..cd1ce84ec63f5ed8ae75178f79c35b9fd91b37f7 100644 --- a/Source/WebCore/page/Page.h +++ b/Source/WebCore/page/Page.h -@@ -312,6 +312,9 @@ public: +@@ -316,6 +316,9 @@ public: const std::optional& overrideViewportArguments() const { return m_overrideViewportArguments; } WEBCORE_EXPORT void setOverrideViewportArguments(const std::optional&); @@ -6070,7 +6075,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 static void refreshPlugins(bool reload); WEBCORE_EXPORT PluginData& pluginData(); void clearPluginData(); -@@ -375,6 +378,10 @@ public: +@@ -380,6 +383,10 @@ public: #if ENABLE(DRAG_SUPPORT) DragController& dragController() { return m_dragController.get(); } const DragController& dragController() const { return m_dragController.get(); } @@ -6081,7 +6086,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #endif FocusController& focusController() const { return *m_focusController; } WEBCORE_EXPORT CheckedRef checkedFocusController() const; -@@ -555,6 +562,10 @@ public: +@@ -563,6 +570,10 @@ public: WEBCORE_EXPORT void effectiveAppearanceDidChange(bool useDarkAppearance, bool useElevatedUserInterfaceLevel); bool defaultUseDarkAppearance() const { return m_useDarkAppearance; } void setUseDarkAppearanceOverride(std::optional); @@ -6092,7 +6097,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #if ENABLE(TEXT_AUTOSIZING) float textAutosizingWidth() const { return m_textAutosizingWidth; } -@@ -1003,6 +1014,11 @@ public: +@@ -1011,6 +1022,11 @@ public: WEBCORE_EXPORT void setInteractionRegionsEnabled(bool); #endif @@ -6104,7 +6109,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY) DeviceOrientationUpdateProvider* deviceOrientationUpdateProvider() const { return m_deviceOrientationUpdateProvider.get(); } #endif -@@ -1166,6 +1182,9 @@ private: +@@ -1181,6 +1197,9 @@ private: #if ENABLE(DRAG_SUPPORT) UniqueRef m_dragController; @@ -6114,7 +6119,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #endif std::unique_ptr m_focusController; #if ENABLE(CONTEXT_MENUS) -@@ -1241,6 +1260,8 @@ private: +@@ -1259,6 +1278,8 @@ private: bool m_useElevatedUserInterfaceLevel { false }; bool m_useDarkAppearance { false }; std::optional m_useDarkAppearanceOverride; @@ -6123,7 +6128,7 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #if ENABLE(TEXT_AUTOSIZING) float m_textAutosizingWidth { 0 }; -@@ -1419,6 +1440,11 @@ private: +@@ -1437,6 +1458,11 @@ private: #endif std::optional m_overrideViewportArguments; @@ -6136,10 +6141,10 @@ index 1941a2ed150ad039c4e7b02fa826a3be6c55a0bd..5c5610ef3410a55b8f1b684ff68be456 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS_FAMILY) RefPtr m_deviceOrientationUpdateProvider; diff --git a/Source/WebCore/page/PageConsoleClient.cpp b/Source/WebCore/page/PageConsoleClient.cpp -index 98f3da2b75dce250749bbf206d64d1acf7790c69..8d28363676fdc8f52139b6e326119a03379aac66 100644 +index 18e3cde7b9ae368de4b87c88c2f8324b77cbd7c8..1ebc51b6d81fc6ae17124e7be7da039609df03d0 100644 --- a/Source/WebCore/page/PageConsoleClient.cpp +++ b/Source/WebCore/page/PageConsoleClient.cpp -@@ -434,4 +434,9 @@ Ref PageConsoleClient::protectedPage() const +@@ -439,4 +439,9 @@ Ref PageConsoleClient::protectedPage() const return m_page.get(); } @@ -6150,10 +6155,10 @@ index 98f3da2b75dce250749bbf206d64d1acf7790c69..8d28363676fdc8f52139b6e326119a03 + } // namespace WebCore diff --git a/Source/WebCore/page/PageConsoleClient.h b/Source/WebCore/page/PageConsoleClient.h -index e9b4f0bca732d0448b3f5e439ca52625277cef64..cb21a4d14aaed660cf6a9398a6b5f3b6d1c0c23d 100644 +index 6ee10d6ca68ad8ea93ae45adb0876c80953d3278..d4e14d54af6cd21fc5649d18dbc6af2020fae4a2 100644 --- a/Source/WebCore/page/PageConsoleClient.h +++ b/Source/WebCore/page/PageConsoleClient.h -@@ -82,6 +82,7 @@ private: +@@ -85,6 +85,7 @@ private: void record(JSC::JSGlobalObject*, Ref&&) override; void recordEnd(JSC::JSGlobalObject*, Ref&&) override; void screenshot(JSC::JSGlobalObject*, Ref&&) override; @@ -6256,7 +6261,7 @@ index 4e4dfdebe954bf3f047d3a86a758dfd0913f732e..da2bcd0256cdfc2ba28fb07094abd0b6 } diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp -index ad0c3f33aa674454f270899400cc0e8e4421a874..6c68e218b27b117145324b10572393854d48ead0 100644 +index a35951b3150fe859450c5f781e44032078ca5f74..7fd0c71777a3fb451f3bd97b16911c01e5aa2203 100644 --- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp @@ -336,6 +336,8 @@ bool ContentSecurityPolicy::allowContentSecurityPolicySourceStarToMatchAnyProtoc @@ -6563,10 +6568,10 @@ index ae46341ba71c7f6df7c607bd852338cdb7f83fe1..b318c0771192344a6891c1f097cb0b93 +} // namespace WebCore +#endif diff --git a/Source/WebCore/platform/PlatformScreen.h b/Source/WebCore/platform/PlatformScreen.h -index 93b1d7907a2ec5ca59ffad0e3f5d562ea669473e..11debfb941710bc41fc8d222d7dca0d18239bcdd 100644 +index 6c64c7040eb190c3d67380070e884a8230029c26..d0f8341c538cbc2323ac0074a5ef3226d00a5fd6 100644 --- a/Source/WebCore/platform/PlatformScreen.h +++ b/Source/WebCore/platform/PlatformScreen.h -@@ -150,13 +150,18 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr); +@@ -151,13 +151,18 @@ WEBCORE_EXPORT float screenScaleFactor(UIScreen * = nullptr); #endif #if ENABLE(TOUCH_EVENTS) @@ -6628,7 +6633,7 @@ index e280025043b3c03c3974289e62ef7cc88ebfa2c7..077a4ab4aa5b688937ed4d5018745aa6 static const unsigned thumbBorderSize = 1; static const unsigned overlayThumbSize = 3; diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp -index a126eaa294ef640841f62a3f0d9364b733236e6b..f5b81118b2b430b87492f1c3669ffff2d563d721 100644 +index d137ffd1a8ed0b788bd28197c6d7e9f7d14e852f..dcf8bf3f7ee6b037a370712e2ac36b6e2e4bbebc 100644 --- a/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/ImageBufferUtilitiesCairo.cpp @@ -48,6 +48,13 @@ @@ -6703,7 +6708,7 @@ index a126eaa294ef640841f62a3f0d9364b733236e6b..f5b81118b2b430b87492f1c3669ffff2 + jpeg_destroy_compress(&info); + + Vector output; -+ output.append(bufferPtr, bufferSize); ++ output.append(std::span { bufferPtr, bufferSize }); + // Cannot use unique_ptr as bufferPtr changes during compression. GUniquePtr would work + // but it's under GLib and won't work on Windows. + free(bufferPtr); @@ -6723,7 +6728,7 @@ index a126eaa294ef640841f62a3f0d9364b733236e6b..f5b81118b2b430b87492f1c3669ffff2 if (!image || !encodeImage(image, mimeType, &encodedImage)) return { }; diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h -index 076b61642867584cc02cb7263026ff94555adf64..e56cd4cb92e51e48bfbb25f6c8bba6fbe404bac7 100644 +index a82b748682f984fcdd4f5413d0254e0f5573f043..2c3d4bba92c63235c124a400d89455499aa3a189 100644 --- a/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h +++ b/Source/WebCore/platform/graphics/cg/ImageBufferUtilitiesCG.h @@ -38,7 +38,7 @@ WEBCORE_EXPORT uint8_t verifyImageBufferIsBigEnough(const void* buffer, size_t b @@ -6733,7 +6738,7 @@ index 076b61642867584cc02cb7263026ff94555adf64..e56cd4cb92e51e48bfbb25f6c8bba6fb -Vector encodeData(CGImageRef, const String& mimeType, std::optional quality); +WEBCORE_EXPORT Vector encodeData(CGImageRef, const String& mimeType, std::optional quality); Vector encodeData(const PixelBuffer&, const String& mimeType, std::optional quality); - Vector encodeData(const std::span&, const String& mimeType, std::optional quality); + Vector encodeData(std::span, const String& mimeType, std::optional quality); diff --git a/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h b/Source/WebCore/platform/graphics/filters/software/FEComponentTransferSoftwareApplier.h index b60f9a64bacc8282860da6de299b75aeb295b9b5..55bd017c03c6478ca334bd5ef164160fef5d5302 100644 @@ -6748,7 +6753,7 @@ index b60f9a64bacc8282860da6de299b75aeb295b9b5..55bd017c03c6478ca334bd5ef164160f namespace WebCore { diff --git a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp -index 7b9d3c85fa1f76e2b53efc712f98866e6d892d4f..40e21fe75fd53d40e388a31eb10a1941347b7776 100644 +index 3f96ccee98a29188e4af376484ab6514b319ddf8..20d9ba661aa10adada5ef5688854b4bc3c0f0702 100644 --- a/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp +++ b/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp @@ -169,6 +169,33 @@ static Vector stringIndicesFromClusters(const Vector& clusters, @@ -6795,7 +6800,7 @@ index 7b9d3c85fa1f76e2b53efc712f98866e6d892d4f..40e21fe75fd53d40e388a31eb10a1941 // Determine the string for this item. const UChar* str = cp + items[i].iCharPos; diff --git a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp -index 62ff097c43f0fcf0ad4f25376da113de2f1754c6..49923d505d6d41c38520431a92dc905b2e608708 100644 +index 58f2ac6c28396289c55493c7a78b2b4709e5f129..cf9687900fdeeebe9d829907d121da2495722bae 100644 --- a/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp +++ b/Source/WebCore/platform/gtk/PlatformKeyboardEventGtk.cpp @@ -37,7 +37,9 @@ @@ -7056,10 +7061,10 @@ index 62ff097c43f0fcf0ad4f25376da113de2f1754c6..49923d505d6d41c38520431a92dc905b { switch (val) { diff --git a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp -index 9049189fde4e939feff4db303b0aa25eadeb7180..efa236e9b8330456889fb4c888ba5f3905d7e557 100644 +index ae1da37330aa06a8f660876ba415ff2821f59813..c358a925347187181fbe1b381428c7bd0018455c 100644 --- a/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp +++ b/Source/WebCore/platform/gtk/PlatformScreenGtk.cpp -@@ -117,7 +117,7 @@ bool screenSupportsExtendedColor(Widget*) +@@ -124,7 +124,7 @@ bool screenSupportsExtendedColor(Widget*) } #if ENABLE(TOUCH_EVENTS) @@ -7068,7 +7073,7 @@ index 9049189fde4e939feff4db303b0aa25eadeb7180..efa236e9b8330456889fb4c888ba5f39 { auto* display = gdk_display_get_default(); if (!display) -@@ -127,7 +127,7 @@ bool screenHasTouchDevice() +@@ -134,7 +134,7 @@ bool screenHasTouchDevice() return seat ? gdk_seat_get_capabilities(seat) & GDK_SEAT_CAPABILITY_TOUCH : true; } @@ -7547,7 +7552,7 @@ index e187936cbef017c080d1dfa14de439b3f5bc2cf8..270c237c8db2f6809719ecfd54a95306 { switch (val) { diff --git a/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp b/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp -index 93db57fd75b8fcac1a745f62294e27c97e040ab0..02411ac6bb361c2677c269945f665e0a92ccb902 100644 +index c62e88f8c3aa40f01618cdaf0c0e22a2404b17ad..02411ac6bb361c2677c269945f665e0a92ccb902 100644 --- a/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp +++ b/Source/WebCore/platform/libwpe/PlatformPasteboardLibWPE.cpp @@ -31,10 +31,18 @@ @@ -7578,7 +7583,7 @@ index 93db57fd75b8fcac1a745f62294e27c97e040ab0..02411ac6bb361c2677c269945f665e0a - - for (unsigned i = 0; i < pasteboardTypes.length; ++i) { - auto& typeString = pasteboardTypes.strings[i]; -- types.append(String(typeString.data, typeString.length)); +- types.append(String({ typeString.data, typeString.length })); - } - - wpe_pasteboard_string_vector_free(&pasteboardTypes); @@ -7593,7 +7598,7 @@ index 93db57fd75b8fcac1a745f62294e27c97e040ab0..02411ac6bb361c2677c269945f665e0a - if (!string.length) - return String(); - -- String returnValue(string.data, string.length); +- String returnValue({ string.data, string.length }); - - wpe_pasteboard_string_free(&string); - return returnValue; @@ -7664,7 +7669,7 @@ index 0552842dbe3f3a2c12a504178f5a8ca977e1c4db..2ef3b1b459d8a9b4e86b4556feeb4f07 class WEBCORE_EXPORT LibWebRTCProviderGStreamer : public LibWebRTCProvider { diff --git a/Source/WebCore/platform/network/HTTPHeaderMap.cpp b/Source/WebCore/platform/network/HTTPHeaderMap.cpp -index 35ade40b37f0c476815535541118f9246ed199cd..2bd1444f9a5e9a14ab3d6acbc020434e1f55ede1 100644 +index 34caadc74c1ad6b411e9043289fece53b9757f17..1e8ec2fe9f16ddd0a33e261172689a9d35ec5194 100644 --- a/Source/WebCore/platform/network/HTTPHeaderMap.cpp +++ b/Source/WebCore/platform/network/HTTPHeaderMap.cpp @@ -235,8 +235,11 @@ void HTTPHeaderMap::add(HTTPHeaderName name, const String& value) @@ -7681,7 +7686,7 @@ index 35ade40b37f0c476815535541118f9246ed199cd..2bd1444f9a5e9a14ab3d6acbc020434e m_commonHeaders.append(CommonHeader { name, value }); } diff --git a/Source/WebCore/platform/network/NetworkStorageSession.h b/Source/WebCore/platform/network/NetworkStorageSession.h -index d044695c67cc56999c6e0f71dcccf5ce65c7dd2f..3ca5d2ad1d8993958b198cc78eb40cfb6f6483dc 100644 +index e745131ddc12d23cd5e2429f565f910ad3520e82..dd23b06a3ceab1675e7e59d8642abc589c360d2a 100644 --- a/Source/WebCore/platform/network/NetworkStorageSession.h +++ b/Source/WebCore/platform/network/NetworkStorageSession.h @@ -167,6 +167,8 @@ public: @@ -7775,7 +7780,7 @@ index 203c591edc985e99ec7dc7a2bfaf69c92d3de99c..461b774d446528b7259ffc6ea3982d17 ResourceResponseBase::Source source; ResourceResponseBase::Type type; diff --git a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm -index 7103740892b1f4b49a713b02308932e088c9a646..ca4d8fd2c993c48743bccaa3e6dbf4a83b17e97b 100644 +index 305080a5c298eaa1ef4644bdc6d90e243bcd061d..e3cbec55b164a49b9ed92b66ff70134618ab53f5 100644 --- a/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm +++ b/Source/WebCore/platform/network/cocoa/NetworkStorageSessionCocoa.mm @@ -518,6 +518,22 @@ bool NetworkStorageSession::setCookieFromDOM(const URL& firstParty, const SameSi @@ -7858,7 +7863,7 @@ index bc9c731a0e69c4923bb8b4bdda088c2be30b3f1c..2088662fb2ce29b7ed843586460630fb void send(UniqueArray&&, size_t); diff --git a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp -index 2032a40640bd944ed7e3255c8d4f1af8889a1b02..1283c85ec2e431144168504fd9cc23e0d147fdfe 100644 +index 048cd352dd9b4cc952337308337a4bd9c31f00f1..de54623b601aea9fbd6a88f5c646b20524b8ee2b 100644 --- a/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp +++ b/Source/WebCore/platform/network/curl/CurlStreamScheduler.cpp @@ -40,7 +40,7 @@ CurlStreamScheduler::~CurlStreamScheduler() @@ -7912,7 +7917,7 @@ index f46f26a553e0634fd6a4d383c0821aadd504a399..738327163771952be91bc024e92070c0 { switch (cookieDatabase().acceptPolicy()) { diff --git a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp -index e5e324e7e616f16ca13e41cd0b618eb946063995..0827159dea1d162aa9e5db36ac252b475081312c 100644 +index 09ab1320beacc41ae92399f3320aaf805d9d81d1..4c63cb2a3f6fbf277227a88b92f206402bc12cd7 100644 --- a/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp +++ b/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp @@ -424,6 +424,30 @@ void NetworkStorageSession::replaceCookies(const Vector& cookies) @@ -7947,7 +7952,7 @@ index e5e324e7e616f16ca13e41cd0b618eb946063995..0827159dea1d162aa9e5db36ac252b47 { GUniquePtr targetCookie(cookie.toSoupCookie()); diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp -index 79648fbd61bff20a1496c3247219796fe713daed..fc4ca92aab0bd6fdf234a09d1d8b21c68bcea794 100644 +index 15f47d0d2a99bcb1a7b9dd9764a9766a20e97692..f623d165826485f58cef60c4b3551055f4352de6 100644 --- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp +++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp @@ -39,6 +39,7 @@ @@ -7958,20 +7963,20 @@ index 79648fbd61bff20a1496c3247219796fe713daed..fc4ca92aab0bd6fdf234a09d1d8b21c6 namespace WebCore { -@@ -690,7 +691,10 @@ template void getStringData(IDataObject* data, FORMATETC* format, Ve +@@ -689,7 +690,10 @@ template void getStringData(IDataObject* data, FORMATETC* format, Ve STGMEDIUM store; if (FAILED(data->GetData(format, &store))) return; -- dataStrings.append(String(static_cast(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T))); +- dataStrings.append(String({ static_cast(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T) })); + // The string here should be null terminated, but it could come from another app so lets lock it + // to the size to prevent an overflow. -+ String rawString = String(static_cast(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T)); ++ String rawString = String({ static_cast(GlobalLock(store.hGlobal)), ::GlobalSize(store.hGlobal) / sizeof(T) }); + dataStrings.append(String::fromUTF8(rawString.utf8().data())); GlobalUnlock(store.hGlobal); ReleaseStgMedium(&store); } diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h -index c50799b63e05adbe32bae3535d786c7d268f980f..9cf1cc7ec4eaae22947f80ba272dfae272167bd6 100644 +index c3ffc7392c0b7fa099a7dd4e4be977cdee1c803c..9570dbb0f2c42ca38598a8898183c9b310f858ab 100644 --- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.h +++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.h @@ -34,6 +34,7 @@ namespace WebCore { @@ -8013,7 +8018,7 @@ index 7bdb180c89bf3fe9d48098318d3b7503b8fd6279..296a3b2b82733b27272acb51ab4f883d if (!m_dragDataMap.isEmpty() || !m_platformDragData) return m_dragDataMap; diff --git a/Source/WebCore/platform/win/KeyEventWin.cpp b/Source/WebCore/platform/win/KeyEventWin.cpp -index f997a64f68deca632435450869c1abc9c3c35ac2..79da1d419799e359c60f2346e1d3ac8a8be4e654 100644 +index b9f728911d34163c1ca14d359741d44cc05ab755..1609197044eaa8e9036e6dae23d1c5270b53e08b 100644 --- a/Source/WebCore/platform/win/KeyEventWin.cpp +++ b/Source/WebCore/platform/win/KeyEventWin.cpp @@ -242,10 +242,16 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, @@ -8037,7 +8042,7 @@ index f997a64f68deca632435450869c1abc9c3c35ac2..79da1d419799e359c60f2346e1d3ac8a OptionSet PlatformKeyboardEvent::currentStateOfModifierKeys() diff --git a/Source/WebCore/platform/win/PasteboardWin.cpp b/Source/WebCore/platform/win/PasteboardWin.cpp -index 54e81c8974a68333027ec4ca26d63cd11d9873c0..80ae2fd4c97a502ffea49c937265bf7cabb18fca 100644 +index 5728033e25919cef5b81d08516964aa5445c5d6e..0e588ebd34299d56ace86806bdec6e9ce337b053 100644 --- a/Source/WebCore/platform/win/PasteboardWin.cpp +++ b/Source/WebCore/platform/win/PasteboardWin.cpp @@ -1130,7 +1130,21 @@ void Pasteboard::writeCustomData(const Vector& data) @@ -8183,7 +8188,7 @@ index 0000000000000000000000000000000000000000..f8fc3fa43bfe62a1c066689f48ddabaa +} diff --git a/Source/WebCore/platform/wpe/DragImageWPE.cpp b/Source/WebCore/platform/wpe/DragImageWPE.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..3aedd4bdfacd4d66552346bec8211efaeff1993c +index 0000000000000000000000000000000000000000..a2454253889d4c7d5129c2d7895c089f54bc2e3d --- /dev/null +++ b/Source/WebCore/platform/wpe/DragImageWPE.cpp @@ -0,0 +1,73 @@ @@ -8238,7 +8243,7 @@ index 0000000000000000000000000000000000000000..3aedd4bdfacd4d66552346bec8211efa + +DragImageRef createDragImageFromImage(Image* image, ImageOrientation) +{ -+ return image->nativeImageForCurrentFrame()->platformImage(); ++ return image->currentNativeImage()->platformImage(); +} + + @@ -8261,10 +8266,10 @@ index 0000000000000000000000000000000000000000..3aedd4bdfacd4d66552346bec8211efa + +} diff --git a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp -index b4b1421799ba24ff07842c3006afcff7948e6c83..64b3bfab8d80ce9a4aea931ed7e478300a3bc358 100644 +index 77bdff686770e56f5445fa12216c6bff93bb5cfb..e16583ea6298864df9c8b82cb0686b2afb18ce95 100644 --- a/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp +++ b/Source/WebCore/platform/wpe/PlatformScreenWPE.cpp -@@ -139,12 +139,12 @@ bool screenSupportsExtendedColor(Widget*) +@@ -151,12 +151,12 @@ bool screenSupportsExtendedColor(Widget*) } #if ENABLE(TOUCH_EVENTS) @@ -8508,7 +8513,7 @@ index 0000000000000000000000000000000000000000..cf2b51f6f02837a1106f4d999f2f130e + +} // namespace WebCore diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp -index 43d3b0ea8c3000a82999356aeca617e9ce0cc9bc..6e0557a1cd8b9d1d03f6dbc6f8b67df462d8a2a9 100644 +index 58574b4d9fb503918e2cac0993ffe778f256a953..23de6aecb4ea7f7a1a36af6a93611559f19cfc11 100644 --- a/Source/WebCore/rendering/RenderTextControl.cpp +++ b/Source/WebCore/rendering/RenderTextControl.cpp @@ -222,13 +222,13 @@ void RenderTextControl::layoutExcludedChildren(bool relayoutChildren) @@ -8527,10 +8532,10 @@ index 43d3b0ea8c3000a82999356aeca617e9ce0cc9bc..6e0557a1cd8b9d1d03f6dbc6f8b67df4 { auto innerText = innerTextElement(); diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h -index e064a7a15a416e593b68de15133c5528b1ce2ae0..2860c13fad04ea32e28142848e0583701263f45d 100644 +index 0c3b0f009ba9fca604f9bea904aae15142ee600e..b55788795cb550764d3de2e4dd0368773a14f290 100644 --- a/Source/WebCore/rendering/RenderTextControl.h +++ b/Source/WebCore/rendering/RenderTextControl.h -@@ -36,9 +36,9 @@ public: +@@ -37,9 +37,9 @@ public: WEBCORE_EXPORT HTMLTextFormControlElement& textFormControlElement() const; @@ -8565,7 +8570,7 @@ index 1d8488e0d36288e09cd5662bd7f770ade95dfee3..dee07f87b47d62d4ef8ede45824bdb2f WorkerOrWorkletGlobalScope& m_globalScope; }; diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp -index bf5894cb3065bcded234f5bb0c2384ffe8afeaf1..5bb922d3fb26790b337e39460dde88b736157126 100644 +index caf9b8fe4c94e56154fa70b4b09391dc1db5b4b6..e9c038a464ac0e30bce7c1e162911d12086c1082 100644 --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.cpp @@ -96,6 +96,8 @@ @@ -8577,7 +8582,7 @@ index bf5894cb3065bcded234f5bb0c2384ffe8afeaf1..5bb922d3fb26790b337e39460dde88b7 #endif #if ENABLE(APPLE_PAY_REMOTE_UI) -@@ -1077,6 +1079,14 @@ void NetworkConnectionToWebProcess::clearPageSpecificData(PageIdentifier pageID) +@@ -1093,6 +1095,14 @@ void NetworkConnectionToWebProcess::clearPageSpecificData(PageIdentifier pageID) storageSession->clearPageSpecificDataForResourceLoadStatistics(pageID); } @@ -8593,7 +8598,7 @@ index bf5894cb3065bcded234f5bb0c2384ffe8afeaf1..5bb922d3fb26790b337e39460dde88b7 { if (auto* storageSession = networkProcess().storageSession(m_sessionID)) diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h -index 2e75a2e5f36e4bf8572dde214007ef9112340147..da32d9a2159dde35b31ad6494b57ee002bc32230 100644 +index a9fd7f7625ca67043c8ed0dcd7979df49cd65266..8e7903e0c5acefb8c5381f8297b52d610b8e4a29 100644 --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.h @@ -343,6 +343,8 @@ private: @@ -8606,7 +8611,7 @@ index 2e75a2e5f36e4bf8572dde214007ef9112340147..da32d9a2159dde35b31ad6494b57ee00 void logUserInteraction(RegistrableDomain&&); diff --git a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in -index db2fd2aa2a4e2cc6f8e543a1238768a87a47b7b3..6fd98fff31ca2f07267c2f1e87e67585d356504b 100644 +index b90021dcc3e4d70cb7b42b538050c5a37653b3cd..acc42255c8d3fb08971f62e6771f022f544199b7 100644 --- a/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in +++ b/Source/WebKit/NetworkProcess/NetworkConnectionToWebProcess.messages.in @@ -74,6 +74,8 @@ messages -> NetworkConnectionToWebProcess LegacyReceiver { @@ -8619,10 +8624,10 @@ index db2fd2aa2a4e2cc6f8e543a1238768a87a47b7b3..6fd98fff31ca2f07267c2f1e87e67585 LogUserInteraction(WebCore::RegistrableDomain domain) ResourceLoadStatisticsUpdated(Vector statistics) -> () diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.cpp b/Source/WebKit/NetworkProcess/NetworkProcess.cpp -index a64ab0c971d231725f54b48f2dfce9b14f176413..edf339a771288a5779088f47dd140bbb1ac79d9f 100644 +index cd174626a10faea7348b568bcfc384d9aaa86f5a..72e66509f540301cedc64ac9ea69f50fb1044245 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.cpp +++ b/Source/WebKit/NetworkProcess/NetworkProcess.cpp -@@ -630,6 +630,12 @@ void NetworkProcess::registrableDomainsExemptFromWebsiteDataDeletion(PAL::Sessio +@@ -658,6 +658,12 @@ void NetworkProcess::registrableDomainsExemptFromWebsiteDataDeletion(PAL::Sessio completionHandler({ }); } @@ -8636,7 +8641,7 @@ index a64ab0c971d231725f54b48f2dfce9b14f176413..edf339a771288a5779088f47dd140bbb { if (auto* session = networkSession(sessionID)) { diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h -index a8e9afedc539d5be95b11d30a621d75b0a1e21ca..3a94e96c865c1e324571a31fba49fdeb7f524a58 100644 +index 6d41842684f3e0e8b1190359f87105b747cf9da9..279d5c033397afb120a082953c0112f34bf2878a 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.h +++ b/Source/WebKit/NetworkProcess/NetworkProcess.h @@ -33,6 +33,7 @@ @@ -8647,7 +8652,7 @@ index a8e9afedc539d5be95b11d30a621d75b0a1e21ca..3a94e96c865c1e324571a31fba49fdeb #include "WebPageProxyIdentifier.h" #include "WebResourceLoadStatisticsStore.h" #include "WebsiteData.h" -@@ -86,6 +87,7 @@ class SessionID; +@@ -82,6 +83,7 @@ class SessionID; namespace WebCore { class CertificateInfo; @@ -8655,7 +8660,7 @@ index a8e9afedc539d5be95b11d30a621d75b0a1e21ca..3a94e96c865c1e324571a31fba49fdeb class CurlProxySettings; class ProtectionSpace; class NetworkStorageSession; -@@ -214,6 +216,9 @@ public: +@@ -212,6 +214,9 @@ public: void registrableDomainsWithLastAccessedTime(PAL::SessionID, CompletionHandler>)>&&); void registrableDomainsExemptFromWebsiteDataDeletion(PAL::SessionID, CompletionHandler)>&&); @@ -8666,7 +8671,7 @@ index a8e9afedc539d5be95b11d30a621d75b0a1e21ca..3a94e96c865c1e324571a31fba49fdeb void clearUserInteraction(PAL::SessionID, RegistrableDomain&&, CompletionHandler&&); void deleteAndRestrictWebsiteDataForRegistrableDomains(PAL::SessionID, OptionSet, RegistrableDomainsToDeleteOrRestrictWebsiteDataFor&&, bool shouldNotifyPage, CompletionHandler&&)>&&); diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in -index 0a6ee4fa17b06a3983e083ccef42af134367a63b..0e386d5f16c60c185ebec1d3b974c6242fadd6bc 100644 +index 5e590b5a09f8bd5d040e2e68d54c545c52d4b179..c58bb6270ab75026187fdda6c94822f6aa47a35a 100644 --- a/Source/WebKit/NetworkProcess/NetworkProcess.messages.in +++ b/Source/WebKit/NetworkProcess/NetworkProcess.messages.in @@ -79,6 +79,8 @@ messages -> NetworkProcess LegacyReceiver { @@ -8679,10 +8684,10 @@ index 0a6ee4fa17b06a3983e083ccef42af134367a63b..0e386d5f16c60c185ebec1d3b974c624 ClearUserInteraction(PAL::SessionID sessionID, WebCore::RegistrableDomain resourceDomain) -> () DumpResourceLoadStatistics(PAL::SessionID sessionID) -> (String dumpedStatistics) diff --git a/Source/WebKit/NetworkProcess/NetworkSession.h b/Source/WebKit/NetworkProcess/NetworkSession.h -index e0abf3efc001aef58ecdc10e7b0066d5a0f0bc3f..0940c4918d6db0f22a350abde8089b300222505b 100644 +index b22ff912dba5b116a979119af6721bcfcc72ec5d..deb9a0b67adb51b190833354e7ea5d8e46aea56c 100644 --- a/Source/WebKit/NetworkProcess/NetworkSession.h +++ b/Source/WebKit/NetworkProcess/NetworkSession.h -@@ -198,6 +198,9 @@ public: +@@ -200,6 +200,9 @@ public: void lowMemoryHandler(WTF::Critical); @@ -8692,7 +8697,7 @@ index e0abf3efc001aef58ecdc10e7b0066d5a0f0bc3f..0940c4918d6db0f22a350abde8089b30 void removeSoftUpdateLoader(ServiceWorkerSoftUpdateLoader* loader) { m_softUpdateLoaders.remove(loader); } void addNavigationPreloaderTask(ServiceWorkerFetchTask&); ServiceWorkerFetchTask* navigationPreloaderTaskFromFetchIdentifier(WebCore::FetchIdentifier); -@@ -307,6 +310,7 @@ protected: +@@ -309,6 +312,7 @@ protected: bool m_privateClickMeasurementDebugModeEnabled { false }; std::optional m_ephemeralMeasurement; bool m_isRunningEphemeralMeasurementTest { false }; @@ -8701,7 +8706,7 @@ index e0abf3efc001aef58ecdc10e7b0066d5a0f0bc3f..0940c4918d6db0f22a350abde8089b30 HashSet> m_keptAliveLoads; diff --git a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm -index 95fd05820627eb2ec3ab61bbfe3c93011761464c..b1944ca937b09a942a42ce4e57311f8a5ff6aa51 100644 +index 95d84783fe56cc381e67113924780bf1e2d9320e..129e7ada7fa90665a80ccf79641d7fcaf9f085a0 100644 --- a/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm +++ b/Source/WebKit/NetworkProcess/cocoa/NetworkSessionCocoa.mm @@ -761,6 +761,8 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didRece @@ -8872,7 +8877,7 @@ index 486849ef6f550a0f3caab311abf5743c6d38e5af..afeaac63a18d9e71d3afead23b7da4fe void NetworkSessionCurl::didReceiveChallenge(WebSocketTask& webSocketTask, WebCore::AuthenticationChallenge&& challenge, CompletionHandler&& challengeCompletionHandler) diff --git a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp -index 34712a017c7a7f444f6e296681ad5d95db9df63c..d5fc1c0583df5548ca9ec3e8760d8f50a6be13e3 100644 +index 60106d6125f85d0cf848e828fd4ed7a50005f105..021d7b6d12baf4671a2968753969ca4675044313 100644 --- a/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp +++ b/Source/WebKit/NetworkProcess/curl/WebSocketTaskCurl.cpp @@ -36,11 +36,12 @@ @@ -8929,10 +8934,10 @@ index 5023a9be6554abc9ffe8fb37968978cb28c5b9a1..9cfdedd0411bf32843c2c9a7d7d722c5 WebCore::CurlStreamScheduler& m_scheduler; diff --git a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in -index 514d2ee0446c8316e9e27a302e32de73480aafdc..42584c972be820f6906da2e0f54c839908db111a 100644 +index 51f3fb7ae9a4e208bc11ac583b72e772eac5e4dc..386ec972eba86763b83407c322a971a30286f40f 100644 --- a/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in +++ b/Source/WebKit/NetworkProcess/mac/com.apple.WebKit.NetworkProcess.sb.in -@@ -444,9 +444,11 @@ +@@ -448,9 +448,11 @@ ;; FIXME: This should be removed when is fixed. ;; Restrict AppSandboxed processes from creating /Library/Keychains, but allow access to the contents of /Library/Keychains: @@ -8948,7 +8953,7 @@ index 514d2ee0446c8316e9e27a302e32de73480aafdc..42584c972be820f6906da2e0f54c8399 ;; Except deny access to new-style iOS Keychain folders which are UUIDs. (deny file-read* file-write* diff --git a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp -index e00ae629016df8bec8cdaf45a42b1ae891cc2e93..ab5cb955e0b1b97a4df9ac4c6baa391ec2ee1798 100644 +index 4295b59484942084404ff7b03669aba249667e97..73dea05ac933938a19bbd6ec5bbcbd6139f98c25 100644 --- a/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp +++ b/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp @@ -466,6 +466,8 @@ void NetworkDataTaskSoup::didSendRequest(GRefPtr&& inputStream) @@ -8970,10 +8975,10 @@ index e00ae629016df8bec8cdaf45a42b1ae891cc2e93..ab5cb955e0b1b97a4df9ac4c6baa391e if (!error) return true; diff --git a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp -index 3fa6072886e6d34d53c63fffb131d51a197540fd..72d919c0043fb524109aed043897195a78563198 100644 +index 60e79ff683e280591d686468c42decf1ac109ed2..ef74cb09e75c3e6f57d180487fa266b7a0f09af5 100644 --- a/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp +++ b/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp -@@ -99,6 +99,11 @@ void NetworkSessionSoup::clearCredentials(WallTime) +@@ -97,6 +97,11 @@ void NetworkSessionSoup::clearCredentials(WallTime) #endif } @@ -8985,7 +8990,7 @@ index 3fa6072886e6d34d53c63fffb131d51a197540fd..72d919c0043fb524109aed043897195a #if USE(SOUP2) static gboolean webSocketAcceptCertificateCallback(GTlsConnection* connection, GTlsCertificate* certificate, GTlsCertificateFlags errors, NetworkSessionSoup* session) { -@@ -119,6 +124,15 @@ static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSock +@@ -117,6 +122,15 @@ static void webSocketMessageNetworkEventCallback(SoupMessage* soupMessage, GSock } #endif @@ -9001,7 +9006,7 @@ index 3fa6072886e6d34d53c63fffb131d51a197540fd..72d919c0043fb524109aed043897195a std::unique_ptr NetworkSessionSoup::createWebSocketTask(WebPageProxyIdentifier, std::optional frameID, std::optional pageID, NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol, const ClientOrigin&, bool, bool, OptionSet, ShouldRelaxThirdPartyCookieBlocking shouldRelaxThirdPartyCookieBlocking, StoredCredentialsPolicy) { GRefPtr soupMessage = request.createSoupMessage(blobRegistry()); -@@ -127,14 +141,21 @@ std::unique_ptr NetworkSessionSoup::createWebSocketTask(WebPagePr +@@ -125,14 +139,21 @@ std::unique_ptr NetworkSessionSoup::createWebSocketTask(WebPagePr if (request.url().protocolIs("wss"_s)) { #if USE(SOUP2) @@ -9031,10 +9036,10 @@ index 3fa6072886e6d34d53c63fffb131d51a197540fd..72d919c0043fb524109aed043897195a } diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake -index a2d21b8fab2c038ed4d73dd9505b2e523084c219..84fa5c0fa497a55b3959e5c24a8ecde5acdbfc74 100644 +index bd8dab990c4c034059d21588921784f047bb6d6a..46a61dcef89e94a9a1a25e6ae352ec88f0aec5e7 100644 --- a/Source/WebKit/PlatformGTK.cmake +++ b/Source/WebKit/PlatformGTK.cmake -@@ -316,6 +316,9 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES +@@ -321,6 +321,9 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES ${GSTREAMER_PBUTILS_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS} ${LIBSOUP_INCLUDE_DIRS} @@ -9044,7 +9049,7 @@ index a2d21b8fab2c038ed4d73dd9505b2e523084c219..84fa5c0fa497a55b3959e5c24a8ecde5 ) list(APPEND WebKit_INTERFACE_INCLUDE_DIRECTORIES -@@ -355,6 +358,9 @@ if (USE_LIBWEBRTC) +@@ -351,6 +354,9 @@ if (USE_LIBWEBRTC) list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES "${THIRDPARTY_DIR}/libwebrtc/Source/" "${THIRDPARTY_DIR}/libwebrtc/Source/webrtc" @@ -9054,7 +9059,7 @@ index a2d21b8fab2c038ed4d73dd9505b2e523084c219..84fa5c0fa497a55b3959e5c24a8ecde5 ) endif () -@@ -406,6 +412,12 @@ else () +@@ -402,6 +408,12 @@ else () set(WebKitGTK_ENUM_HEADER_TEMPLATE ${WEBKIT_DIR}/UIProcess/API/gtk/WebKitEnumTypesGtk3.h.in) endif () @@ -9068,10 +9073,10 @@ index a2d21b8fab2c038ed4d73dd9505b2e523084c219..84fa5c0fa497a55b3959e5c24a8ecde5 set(WebKitGTK_ENUM_GENERATION_HEADERS ${WebKitGTK_INSTALLED_HEADERS}) list(REMOVE_ITEM WebKitGTK_ENUM_GENERATION_HEADERS ${WebKitGTK_DERIVED_SOURCES_DIR}/webkit/WebKitEnumTypes.h) diff --git a/Source/WebKit/PlatformWPE.cmake b/Source/WebKit/PlatformWPE.cmake -index be960eda81a449e654cc76f98998f6695e3be15b..61546c86ac76c565517e7a5c27f968c9e5cab4da 100644 +index 8f27536b690e863fcaf086c04d1b0fb21356a622..a0207624821b4179d7adc646adf06aae65f0ca33 100644 --- a/Source/WebKit/PlatformWPE.cmake +++ b/Source/WebKit/PlatformWPE.cmake -@@ -210,6 +210,7 @@ set(WPE_API_HEADER_TEMPLATES +@@ -212,6 +212,7 @@ set(WPE_API_HEADER_TEMPLATES ${WEBKIT_DIR}/UIProcess/API/glib/WebKitWindowProperties.h.in ${WEBKIT_DIR}/UIProcess/API/glib/WebKitWebsitePolicies.h.in ${WEBKIT_DIR}/UIProcess/API/glib/webkit.h.in @@ -9079,7 +9084,7 @@ index be960eda81a449e654cc76f98998f6695e3be15b..61546c86ac76c565517e7a5c27f968c9 ) if (ENABLE_2022_GLIB_API) -@@ -422,8 +423,17 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES +@@ -423,8 +424,17 @@ list(APPEND WebKit_SYSTEM_INCLUDE_DIRECTORIES ${GIO_UNIX_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS} ${LIBSOUP_INCLUDE_DIRS} @@ -9095,8 +9100,8 @@ index be960eda81a449e654cc76f98998f6695e3be15b..61546c86ac76c565517e7a5c27f968c9 +# Playwright end + list(APPEND WebKit_LIBRARIES - ATK::Bridge WPE::libwpe + ${GLIB_LIBRARIES} diff --git a/Source/WebKit/PlatformWin.cmake b/Source/WebKit/PlatformWin.cmake index 06a86d0cfd1ca90f383af2b079f60ce220f8eb02..9e21935463bf964ecb090be48e68b50ef29c049b 100644 --- a/Source/WebKit/PlatformWin.cmake @@ -9331,26 +9336,11 @@ index 72ad2880160a374e8fa663e561d59becf9d2f36d..372ae6953199245fe4fc55a49813c7ca String markup #endif }; -diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp -index 27289a1df966d9ce4964a21ed407cf694c8a4b84..4403ea531c85fd7c623e2c8793e71820d6043530 100644 ---- a/Source/WebKit/Shared/WebCoreArgumentCoders.cpp -+++ b/Source/WebKit/Shared/WebCoreArgumentCoders.cpp -@@ -182,6 +182,10 @@ - #include - #endif - -+#if PLATFORM(WPE) -+#include "ArgumentCodersWPE.h" -+#endif -+ - // FIXME: Seems like we could use std::tuple to cut down the code below a lot! - - namespace IPC { diff --git a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in -index 3c2e6946fe221f15889e98b46bdb82eab8055ad5..843a49d6ae1476ed83147d417015520e523f1e01 100644 +index 2a11967151ca0bebd14b6a64482a793e2a536333..f4fc1b8eab49eba96badf4151358325a0bb7072c 100644 --- a/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in +++ b/Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in -@@ -2609,6 +2609,9 @@ class WebCore::AuthenticationChallenge { +@@ -2658,6 +2658,9 @@ class WebCore::AuthenticationChallenge { class WebCore::DragData { #if PLATFORM(COCOA) String pasteboardName(); @@ -9360,7 +9350,7 @@ index 3c2e6946fe221f15889e98b46bdb82eab8055ad5..843a49d6ae1476ed83147d417015520e #endif WebCore::IntPoint clientPosition(); WebCore::IntPoint globalPosition(); -@@ -3170,6 +3173,7 @@ enum class WebCore::WasPrivateRelayed : bool; +@@ -3221,6 +3224,7 @@ enum class WebCore::WasPrivateRelayed : bool; String httpStatusText; String httpVersion; WebCore::HTTPHeaderMap httpHeaderFields; @@ -9451,7 +9441,7 @@ index b80bcb39473ecec86be5671f38698130bd9acbf3..d886cbac5f4c073e14e12f257fa92041 { } diff --git a/Source/WebKit/Shared/WebKeyboardEvent.h b/Source/WebKit/Shared/WebKeyboardEvent.h -index 2734461c33f7f9a57933afbc1098029d905522ec..1eb7f2cff4f5fe70aa576be4d4f9b0ea6ea5ddf4 100644 +index 8e4e2d6d5ebb08fba210fe0a328d45290348dd11..32a43192ec1e918c33b1b046b71d2ec571dc92ff 100644 --- a/Source/WebKit/Shared/WebKeyboardEvent.h +++ b/Source/WebKit/Shared/WebKeyboardEvent.h @@ -42,14 +42,18 @@ public: @@ -9474,7 +9464,7 @@ index 2734461c33f7f9a57933afbc1098029d905522ec..1eb7f2cff4f5fe70aa576be4d4f9b0ea const String& text() const { return m_text; } diff --git a/Source/WebKit/Shared/WebMouseEvent.h b/Source/WebKit/Shared/WebMouseEvent.h -index a38fc7fde1d5f1a1fd04ae1f84eb59c1501deec5..d3669c3d3bad91468fbbeeaa328c361082ecd408 100644 +index 5da1ed78e5a55bf63e9e52e33dfa9e704922589a..6630725885bbfe6123537ea799bf5b6885ea977f 100644 --- a/Source/WebKit/Shared/WebMouseEvent.h +++ b/Source/WebKit/Shared/WebMouseEvent.h @@ -70,6 +70,7 @@ public: @@ -9486,10 +9476,10 @@ index a38fc7fde1d5f1a1fd04ae1f84eb59c1501deec5..d3669c3d3bad91468fbbeeaa328c3610 void setPosition(const WebCore::IntPoint& position) { m_position = position; } const WebCore::IntPoint& globalPosition() const { return m_globalPosition; } diff --git a/Source/WebKit/Shared/WebPageCreationParameters.h b/Source/WebKit/Shared/WebPageCreationParameters.h -index 91be42f87923a08e8f19a35bbacc9cbc3781a550..b4de1b8170a28ec38556922967d849b05861468c 100644 +index e0f2fcf54bf77b41619a9b76a3f42cc17303029f..4f79a4a9e081bfbb6a05c2c8afcbdaae060f2229 100644 --- a/Source/WebKit/Shared/WebPageCreationParameters.h +++ b/Source/WebKit/Shared/WebPageCreationParameters.h -@@ -295,6 +295,8 @@ struct WebPageCreationParameters { +@@ -300,6 +300,8 @@ struct WebPageCreationParameters { bool httpsUpgradeEnabled { true }; @@ -9499,10 +9489,10 @@ index 91be42f87923a08e8f19a35bbacc9cbc3781a550..b4de1b8170a28ec38556922967d849b0 bool allowsDeprecatedSynchronousXMLHttpRequestDuringUnload { false }; #endif diff --git a/Source/WebKit/Shared/WebPageCreationParameters.serialization.in b/Source/WebKit/Shared/WebPageCreationParameters.serialization.in -index 4ea97727612b82724ed25a1a6f04d07dd6faa7b7..7eb2a40699258a5cad2bc09631f54993cdf1945e 100644 +index c7c3aac107d2b528d63a31645d84573ba4115a89..4e6932d22e24e2df15e045c0cbb177e8e0a8e880 100644 --- a/Source/WebKit/Shared/WebPageCreationParameters.serialization.in +++ b/Source/WebKit/Shared/WebPageCreationParameters.serialization.in -@@ -227,6 +227,8 @@ enum class WebCore::UserInterfaceLayoutDirection : bool; +@@ -228,6 +228,8 @@ enum class WebCore::UserInterfaceLayoutDirection : bool; bool httpsUpgradeEnabled; @@ -9767,7 +9757,7 @@ index 0000000000000000000000000000000000000000..789a0d7cf69704c8f665a9ed79348fbc + +} // namespace IPC diff --git a/Source/WebKit/Shared/win/WebEventFactory.cpp b/Source/WebKit/Shared/win/WebEventFactory.cpp -index 665b9d6a9de903ee9ad6dc53e15ab421b6cb769f..2b129963074d2ceec1c05f3a637c5e1c9e652008 100644 +index eae9e21a437c04cec91d1a4848038e11f4ee3e07..4fe63a9042d875555d9d1b934a9f53ea352e47aa 100644 --- a/Source/WebKit/Shared/win/WebEventFactory.cpp +++ b/Source/WebKit/Shared/win/WebEventFactory.cpp @@ -476,7 +476,7 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(HWND hwnd, UINT message @@ -9780,10 +9770,10 @@ index 665b9d6a9de903ee9ad6dc53e15ab421b6cb769f..2b129963074d2ceec1c05f3a637c5e1c #endif // ENABLE(TOUCH_EVENTS) diff --git a/Source/WebKit/Sources.txt b/Source/WebKit/Sources.txt -index e57ec3140eeed2a50f0465448a165de12abc09bb..d3509d47546a35c31f4ed053cf4fa4f5f78caa7f 100644 +index d3b9afee939c3ec362f48851865da60251a5700f..fe0c3cc89c0823ed145eb1c374edd13239f48ee7 100644 --- a/Source/WebKit/Sources.txt +++ b/Source/WebKit/Sources.txt -@@ -378,6 +378,7 @@ Shared/XR/XRDeviceProxy.cpp +@@ -379,6 +379,7 @@ Shared/XR/XRDeviceProxy.cpp UIProcess/AuxiliaryProcessProxy.cpp UIProcess/BackgroundProcessResponsivenessTimer.cpp UIProcess/BrowsingContextGroup.cpp @@ -9791,7 +9781,7 @@ index e57ec3140eeed2a50f0465448a165de12abc09bb..d3509d47546a35c31f4ed053cf4fa4f5 UIProcess/DeviceIdHashSaltStorage.cpp UIProcess/DisplayLink.cpp UIProcess/DisplayLinkProcessProxyClient.cpp -@@ -387,16 +388,20 @@ UIProcess/FrameLoadState.cpp +@@ -388,16 +389,20 @@ UIProcess/FrameLoadState.cpp UIProcess/FrameProcess.cpp UIProcess/GeolocationPermissionRequestManagerProxy.cpp UIProcess/GeolocationPermissionRequestProxy.cpp @@ -9812,7 +9802,7 @@ index e57ec3140eeed2a50f0465448a165de12abc09bb..d3509d47546a35c31f4ed053cf4fa4f5 UIProcess/RemotePageDrawingAreaProxy.cpp UIProcess/RemotePageProxy.cpp UIProcess/ResponsivenessTimer.cpp -@@ -440,6 +445,8 @@ UIProcess/WebOpenPanelResultListenerProxy.cpp +@@ -441,6 +446,8 @@ UIProcess/WebOpenPanelResultListenerProxy.cpp UIProcess/WebPageDiagnosticLoggingClient.cpp UIProcess/WebPageGroup.cpp UIProcess/WebPageInjectedBundleClient.cpp @@ -9821,7 +9811,7 @@ index e57ec3140eeed2a50f0465448a165de12abc09bb..d3509d47546a35c31f4ed053cf4fa4f5 UIProcess/WebPageProxy.cpp UIProcess/WebPageProxyMessageReceiverRegistration.cpp UIProcess/WebPasteboardProxy.cpp -@@ -574,7 +581,11 @@ UIProcess/Inspector/WebInspectorUtilities.cpp +@@ -576,7 +583,11 @@ UIProcess/Inspector/WebInspectorUtilities.cpp UIProcess/Inspector/WebPageDebuggable.cpp UIProcess/Inspector/WebPageInspectorController.cpp @@ -9834,10 +9824,10 @@ index e57ec3140eeed2a50f0465448a165de12abc09bb..d3509d47546a35c31f4ed053cf4fa4f5 UIProcess/Media/AudioSessionRoutingArbitratorProxy.cpp UIProcess/Media/MediaUsageManager.cpp diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt -index f23b74ff14d4c0bcf3ea58dc93c3582ae9d8ff54..0b615daef0d042deba914ad958a437c50cab926c 100644 +index 8dc390feda97fbe8e80e0bdfd62b682be36c81e5..9dee9867202c5e63e81dec992fa348fd16a557d8 100644 --- a/Source/WebKit/SourcesCocoa.txt +++ b/Source/WebKit/SourcesCocoa.txt -@@ -269,6 +269,7 @@ UIProcess/API/Cocoa/_WKArchiveExclusionRule.mm +@@ -271,6 +271,7 @@ UIProcess/API/Cocoa/_WKArchiveExclusionRule.mm UIProcess/API/Cocoa/_WKAttachment.mm UIProcess/API/Cocoa/_WKAutomationSession.mm UIProcess/API/Cocoa/_WKAutomationSessionConfiguration.mm @@ -9845,7 +9835,7 @@ index f23b74ff14d4c0bcf3ea58dc93c3582ae9d8ff54..0b615daef0d042deba914ad958a437c5 UIProcess/API/Cocoa/_WKContentRuleListAction.mm UIProcess/API/Cocoa/_WKContextMenuElementInfo.mm UIProcess/API/Cocoa/_WKCustomHeaderFields.mm @no-unify -@@ -447,6 +448,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm +@@ -455,6 +456,7 @@ UIProcess/Inspector/ios/WKInspectorHighlightView.mm UIProcess/Inspector/ios/WKInspectorNodeSearchGestureRecognizer.mm UIProcess/Inspector/mac/RemoteWebInspectorUIProxyMac.mm @@ -9854,7 +9844,7 @@ index f23b74ff14d4c0bcf3ea58dc93c3582ae9d8ff54..0b615daef0d042deba914ad958a437c5 UIProcess/Inspector/mac/WKInspectorResourceURLSchemeHandler.mm UIProcess/Inspector/mac/WKInspectorViewController.mm diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt -index 103182e1768930dbeecdbabe590e6491af0d92bf..96305b9bfafec6b70ec807a04c78f7e2002da0ea 100644 +index bec1e568f9ad00bfff883318692d9c404e012e2c..de45461d0851248f44973780b07d0ba7692fd578 100644 --- a/Source/WebKit/SourcesGTK.txt +++ b/Source/WebKit/SourcesGTK.txt @@ -134,6 +134,7 @@ UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify @@ -9891,7 +9881,7 @@ index 103182e1768930dbeecdbabe590e6491af0d92bf..96305b9bfafec6b70ec807a04c78f7e2 UIProcess/gtk/WebPasteboardProxyGtk.cpp UIProcess/gtk/WebPopupMenuProxyGtk.cpp diff --git a/Source/WebKit/SourcesWPE.txt b/Source/WebKit/SourcesWPE.txt -index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2ead031c3b 100644 +index 3eefd6cc3eb22329583901518442756d728378a1..45f2092be52d2d347660972a6723741176ff4b42 100644 --- a/Source/WebKit/SourcesWPE.txt +++ b/Source/WebKit/SourcesWPE.txt @@ -86,6 +86,7 @@ Shared/glib/ProcessExecutablePathGLib.cpp @@ -9902,7 +9892,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e Shared/libwpe/NativeWebKeyboardEventLibWPE.cpp Shared/libwpe/NativeWebMouseEventLibWPE.cpp Shared/libwpe/NativeWebTouchEventLibWPE.cpp -@@ -135,6 +136,7 @@ UIProcess/API/glib/WebKitAuthenticationRequest.cpp @no-unify +@@ -136,6 +137,7 @@ UIProcess/API/glib/WebKitAuthenticationRequest.cpp @no-unify UIProcess/API/glib/WebKitAutomationSession.cpp @no-unify UIProcess/API/glib/WebKitBackForwardList.cpp @no-unify UIProcess/API/glib/WebKitBackForwardListItem.cpp @no-unify @@ -9910,7 +9900,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e UIProcess/API/glib/WebKitContextMenuClient.cpp @no-unify UIProcess/API/glib/WebKitCookieManager.cpp @no-unify UIProcess/API/glib/WebKitCredential.cpp @no-unify -@@ -168,6 +170,7 @@ UIProcess/API/glib/WebKitOptionMenu.cpp @no-unify +@@ -169,6 +171,7 @@ UIProcess/API/glib/WebKitOptionMenu.cpp @no-unify UIProcess/API/glib/WebKitOptionMenuItem.cpp @no-unify UIProcess/API/glib/WebKitPermissionRequest.cpp @no-unify UIProcess/API/glib/WebKitPermissionStateQuery.cpp @no-unify @@ -9918,7 +9908,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e UIProcess/API/glib/WebKitPolicyDecision.cpp @no-unify UIProcess/API/glib/WebKitPrivate.cpp @no-unify UIProcess/API/glib/WebKitProtocolHandler.cpp @no-unify -@@ -204,6 +207,7 @@ UIProcess/API/soup/HTTPCookieStoreSoup.cpp +@@ -205,6 +208,7 @@ UIProcess/API/soup/HTTPCookieStoreSoup.cpp UIProcess/API/wpe/InputMethodFilterWPE.cpp @no-unify UIProcess/API/wpe/PageClientImpl.cpp @no-unify UIProcess/API/wpe/WebKitColor.cpp @no-unify @@ -9926,7 +9916,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e UIProcess/API/wpe/WebKitInputMethodContextWPE.cpp @no-unify UIProcess/API/wpe/WebKitPopupMenu.cpp @no-unify UIProcess/API/wpe/WebKitRectangle.cpp @no-unify -@@ -226,6 +230,7 @@ UIProcess/glib/DisplayLinkGLib.cpp +@@ -228,6 +232,7 @@ UIProcess/glib/DisplayLinkGLib.cpp UIProcess/glib/DisplayVBlankMonitor.cpp UIProcess/glib/DisplayVBlankMonitorDRM.cpp UIProcess/glib/DisplayVBlankMonitorTimer.cpp @@ -9934,7 +9924,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e UIProcess/glib/ScreenManager.cpp UIProcess/glib/WebPageProxyGLib.cpp UIProcess/glib/WebProcessPoolGLib.cpp -@@ -256,7 +261,12 @@ UIProcess/linux/MemoryPressureMonitor.cpp +@@ -258,7 +263,12 @@ UIProcess/linux/MemoryPressureMonitor.cpp UIProcess/soup/WebProcessPoolSoup.cpp UIProcess/wpe/AcceleratedBackingStoreDMABuf.cpp @@ -9947,7 +9937,7 @@ index 10b4c898beea0c4246e5329298dba514a6f68663..fb685e34364ab73bacaf8314336c2d2e UIProcess/wpe/WebPageProxyWPE.cpp UIProcess/wpe/WebPreferencesWPE.cpp -@@ -280,6 +290,8 @@ WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp +@@ -282,6 +292,8 @@ WebProcess/WebCoreSupport/glib/WebEditorClientGLib.cpp WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp @@ -10004,10 +9994,10 @@ index 32ef9bd308e520f5ac7173639c8b23ea91cde037..7a80553c2d91b9236f563fa1b76aa8a5 bool m_shouldTakeUIBackgroundAssertion { true }; bool m_shouldCaptureDisplayInUIProcess { DEFAULT_CAPTURE_DISPLAY_IN_UI_PROCESS }; diff --git a/Source/WebKit/UIProcess/API/APIUIClient.h b/Source/WebKit/UIProcess/API/APIUIClient.h -index 06b83708038f6d39aa841f941f9490f45d5e90ed..e2300ca79ed61c378cb2024e23ef83281ae8b7d0 100644 +index f8baf3b5cbd1613da54c001cbff573125742358d..be628650e5562978187f8cc1d0afed8849a083b2 100644 --- a/Source/WebKit/UIProcess/API/APIUIClient.h +++ b/Source/WebKit/UIProcess/API/APIUIClient.h -@@ -113,6 +113,7 @@ public: +@@ -114,6 +114,7 @@ public: virtual void runJavaScriptAlert(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function&& completionHandler) { completionHandler(); } virtual void runJavaScriptConfirm(WebKit::WebPageProxy&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function&& completionHandler) { completionHandler(false); } virtual void runJavaScriptPrompt(WebKit::WebPageProxy&, const WTF::String&, const WTF::String&, WebKit::WebFrameProxy*, WebKit::FrameInfoData&&, Function&& completionHandler) { completionHandler(WTF::String()); } @@ -10059,10 +10049,10 @@ index 026121d114c5fcad84c1396be8d692625beaa3bd..edd6e5cae033124c589959a42522fde0 } #endif diff --git a/Source/WebKit/UIProcess/API/C/WKPage.cpp b/Source/WebKit/UIProcess/API/C/WKPage.cpp -index 8db060fa2f15d58d8bbc9faed88cac4e51d0f3c1..22fcdf0790b7187fbf2978bf3079b3011929d23e 100644 +index 81d4f44bd1f4201cb0ddd9d4b8ef210862551cdb..6e750c6e1f4624b5cf54a642b831ab10d4448649 100644 --- a/Source/WebKit/UIProcess/API/C/WKPage.cpp +++ b/Source/WebKit/UIProcess/API/C/WKPage.cpp -@@ -1783,6 +1783,13 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient +@@ -1780,6 +1780,13 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient completionHandler(String()); } @@ -10076,7 +10066,7 @@ index 8db060fa2f15d58d8bbc9faed88cac4e51d0f3c1..22fcdf0790b7187fbf2978bf3079b301 void setStatusText(WebPageProxy* page, const String& text) final { if (!m_client.setStatusText) -@@ -1812,6 +1819,8 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient +@@ -1809,6 +1816,8 @@ void WKPageSetPageUIClient(WKPageRef pageRef, const WKPageUIClientBase* wkClient { if (!m_client.didNotHandleKeyEvent) return; @@ -10146,10 +10136,10 @@ index 1484f064ec89ee8c25c35df9f0a4462896699415..0622f4d5fc9144b9059395d9d0730a4a // Version 15. WKPageDecidePolicyForSpeechRecognitionPermissionRequestCallback decidePolicyForSpeechRecognitionPermissionRequest; diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm -index 9479d9025142e679533061397c93f750053efacb..01031cca01abb99eef44a054dc200922be6b782d 100644 +index 857afb1b892c2ee7327808f3dab0cff441c92c52..332bb2e687d6b97fd11f1366ade5b17841bcae58 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferences.mm -@@ -700,6 +700,16 @@ - (void)_setMediaCaptureRequiresSecureConnection:(BOOL)requiresSecureConnection +@@ -702,6 +702,16 @@ - (void)_setMediaCaptureRequiresSecureConnection:(BOOL)requiresSecureConnection _preferences->setMediaCaptureRequiresSecureConnection(requiresSecureConnection); } @@ -10167,10 +10157,10 @@ index 9479d9025142e679533061397c93f750053efacb..01031cca01abb99eef44a054dc200922 { return _preferences->inactiveMediaCaptureSteamRepromptIntervalInMinutes(); diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h -index 2d7258f213b74356c8ab3e47923016dd4554e672..0f8977d00655cd4c36ae280c8c27c52f8dd0c09f 100644 +index 48e4b28374b93173df1be63444aa5ca3abd626d6..194b2099be032c800a463891976364ab7cd74890 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h +++ b/Source/WebKit/UIProcess/API/Cocoa/WKPreferencesPrivate.h -@@ -118,6 +118,7 @@ typedef NS_ENUM(NSInteger, _WKPitchCorrectionAlgorithm) { +@@ -119,6 +119,7 @@ typedef NS_ENUM(NSInteger, _WKPitchCorrectionAlgorithm) { @property (nonatomic, setter=_setMockCaptureDevicesEnabled:) BOOL _mockCaptureDevicesEnabled WK_API_AVAILABLE(macos(10.13), ios(11.0)); @property (nonatomic, setter=_setMockCaptureDevicesPromptEnabled:) BOOL _mockCaptureDevicesPromptEnabled WK_API_AVAILABLE(macos(10.13.4), ios(11.3)); @property (nonatomic, setter=_setMediaCaptureRequiresSecureConnection:) BOOL _mediaCaptureRequiresSecureConnection WK_API_AVAILABLE(macos(10.13), ios(11.0)); @@ -10217,7 +10207,7 @@ index 4f5956098f0e83c2e9c421c97056b6718b124a3c..1eb51dd70dc6ef1b7e95a09118aa816b NS_ASSUME_NONNULL_END diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm -index 07a937bf57e682398c2befad11ad6a4d228e741e..189f4b3cbe358490f2779a1042f2e9fd240fa422 100644 +index 350914dd5352683024925bb820148ba2582cd0c7..ac9767ff4920e066b11da4556b2df77debd18a1f 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm @@ -51,6 +51,7 @@ @@ -10228,7 +10218,7 @@ index 07a937bf57e682398c2befad11ad6a4d228e741e..189f4b3cbe358490f2779a1042f2e9fd #import #import #import -@@ -444,6 +445,11 @@ - (void)removeDataOfTypes:(NSSet *)dataTypes modifiedSince:(NSDate *)date comple +@@ -446,6 +447,11 @@ - (void)removeDataOfTypes:(NSSet *)dataTypes modifiedSince:(NSDate *)date comple }); } @@ -10401,7 +10391,7 @@ index df71be1e30c4a13fe9565d309c7bbfb82e049d06..8424a471e7841d300174aa54143578f8 { _processPoolConfiguration->setIsAutomaticProcessWarmingEnabled(prewarms); diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm -index e5209134d490c226db6a122f4f0f3f38d26e20eb..47a41b11999d7927fbfbe033e3630eac86d61e99 100644 +index 500a748e78bdcd418b18fb4de416b95e9042d2c4..63d4ea68cbc711ba8f12e126d0f6b78aad5f5155 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm @@ -24,6 +24,7 @@ @@ -10425,7 +10415,7 @@ index 4974e14214e2bb3e982325b885bab33e54f83998..cacdf8c71fab248d38d2faf03f7affdc typedef NS_ENUM(NSInteger, _WKUserStyleLevel) { _WKUserStyleUserLevel, diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm -index 705a8483a04c8abe863bd788f5a4ea6a09414f27..c0e69429369155aa3974c508e755292c81c89e19 100644 +index 383bd33cc0b53ea049d2e6fb1bf338d584caeb18..e29ba10dceced9d115b09e014cc086c5453e33fe 100644 --- a/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm +++ b/Source/WebKit/UIProcess/API/Cocoa/_WKUserStyleSheet.mm @@ -35,6 +35,7 @@ @@ -10639,10 +10629,10 @@ index 0000000000000000000000000000000000000000..e0b1da48465c850f541532ed961d1b77 +WebKit::WebPageProxy* webkitBrowserInspectorCreateNewPageInContext(WebKitWebContext*); +void webkitBrowserInspectorQuitApplication(); diff --git a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp -index a13f808f23a97bd4eaf452fc57e0f1279e3a264b..e222833eeea5d4252189ba2755993e35c3190963 100644 +index d6b7f61b141870b4af00fdd0a104dc6cf382fc36..bacc29f875ec5dccb65f7653a772bb99ceee2129 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitUIClient.cpp -@@ -94,6 +94,10 @@ private: +@@ -95,6 +95,10 @@ private: page.makeViewBlankIfUnpaintedSinceLastLoadCommit(); webkitWebViewRunJavaScriptPrompt(m_webView, message.utf8(), defaultValue.utf8(), WTFMove(completionHandler)); } @@ -10654,7 +10644,7 @@ index a13f808f23a97bd4eaf452fc57e0f1279e3a264b..e222833eeea5d4252189ba2755993e35 bool canRunBeforeUnloadConfirmPanel() const final { return true; } diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp -index cdf57e32e9024051ed28eb57678662376b0aae6c..8647bf0e5beff4d5d92e02733548332abeb00c55 100644 +index 14c655bdd47bfb87d548e8c4ddd826e6bbb5d7c5..05440a65021ff70887fc88dc5fbfff71f4990957 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebContext.cpp @@ -415,10 +415,19 @@ static void webkitWebContextSetProperty(GObject* object, guint propID, const GVa @@ -10723,7 +10713,7 @@ index e994309b097c1b140abfa4373fd2fafee46c05ec..6e0cc677a3bf33683ae8c89d12a48191 #endif +int webkitWebContextExistingCount(); diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp -index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b4e8c4247 100644 +index 1e389f70c7b4722458cffbf4ac34b1d67efa4ba8..b9f5f22c8e866de1909240b72d23c06d7525d863 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp @@ -33,6 +33,7 @@ @@ -10750,7 +10740,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b #include "WebKitPrintOperationPrivate.h" #include "WebKitWebInspectorPrivate.h" #include "WebKitWebViewBasePrivate.h" -@@ -140,6 +141,7 @@ enum { +@@ -141,6 +142,7 @@ enum { CLOSE, SCRIPT_DIALOG, @@ -10758,7 +10748,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b DECIDE_POLICY, PERMISSION_REQUEST, -@@ -493,6 +495,9 @@ GRefPtr WebKitWebViewClient::showOptionMenu(WebKitPopupMenu& p +@@ -494,6 +496,9 @@ GRefPtr WebKitWebViewClient::showOptionMenu(WebKitPopupMenu& p void WebKitWebViewClient::frameDisplayed(WKWPE::View&) { @@ -10768,7 +10758,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b { SetForScope inFrameDisplayedGuard(m_webView->priv->inFrameDisplayed, true); for (const auto& callback : m_webView->priv->frameDisplayedCallbacks) { -@@ -509,6 +514,11 @@ void WebKitWebViewClient::frameDisplayed(WKWPE::View&) +@@ -510,6 +515,11 @@ void WebKitWebViewClient::frameDisplayed(WKWPE::View&) } } @@ -10780,7 +10770,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b void WebKitWebViewClient::willStartLoad(WKWPE::View&) { webkitWebViewWillStartLoad(m_webView); -@@ -595,7 +605,7 @@ static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* +@@ -596,7 +606,7 @@ static gboolean webkitWebViewDecidePolicy(WebKitWebView*, WebKitPolicyDecision* static gboolean webkitWebViewPermissionRequest(WebKitWebView*, WebKitPermissionRequest* request) { @@ -10789,7 +10779,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b if (WEBKIT_IS_POINTER_LOCK_PERMISSION_REQUEST(request)) { webkit_permission_request_allow(request); return TRUE; -@@ -1902,6 +1912,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) +@@ -1903,6 +1913,15 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_SCRIPT_DIALOG); @@ -10805,7 +10795,7 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b /** * WebKitWebView::decide-policy: * @web_view: the #WebKitWebView on which the signal is emitted -@@ -2701,6 +2720,23 @@ void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const +@@ -2702,6 +2721,23 @@ void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView* webView, const webkit_script_dialog_unref(webView->priv->currentScriptDialog); } @@ -10830,10 +10820,10 @@ index 4a15f81cbca7ab84ce25b6ccc96cd6ad720f6129..a1d6e0f4ccdceddff6c88563c480266b { if (!webView->priv->currentScriptDialog) diff --git a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h -index 8b5eb1ce720c9ad09b9de9e9f3d6b15564a86b54..89642048bad844aabdf1eec8486679bfc75e20c0 100644 +index 1a04ee05c3ddec0628ef5b8b8c181cbcc2b7d622..2a24f8f3fdc3f0eed13f8a79050258a4e4a489f0 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h +++ b/Source/WebKit/UIProcess/API/glib/WebKitWebViewPrivate.h -@@ -65,6 +65,7 @@ void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message, Fun +@@ -66,6 +66,7 @@ void webkitWebViewRunJavaScriptAlert(WebKitWebView*, const CString& message, Fun void webkitWebViewRunJavaScriptConfirm(WebKitWebView*, const CString& message, Function&& completionHandler); void webkitWebViewRunJavaScriptPrompt(WebKitWebView*, const CString& message, const CString& defaultText, Function&& completionHandler); void webkitWebViewRunJavaScriptBeforeUnloadConfirm(WebKitWebView*, const CString& message, Function&& completionHandler); @@ -10854,10 +10844,10 @@ index 805f9f638c1630b5e9310494ae2970262de001cc..add3e80896c2e82bdd12cee15c8014bf #include <@API_INCLUDE_PREFIX@/WebKitClipboardPermissionRequest.h> #include <@API_INCLUDE_PREFIX@/WebKitColorChooserRequest.h> diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp -index 1c4f884537edf50ed867378786f58ace47eabfaa..283fa58d2427cffc115e12a861ab9d6882004214 100644 +index cea5882f6c455898e1b5a231e1213e6b71ff21b6..d82b93d3c759b1184869b3504e1c3c07f53cc8ce 100644 --- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp +++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp -@@ -266,6 +266,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool +@@ -269,6 +269,8 @@ void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool { if (wasEventHandled || event.type() != WebEventType::KeyDown || !event.nativeEvent()) return; @@ -10866,7 +10856,7 @@ index 1c4f884537edf50ed867378786f58ace47eabfaa..283fa58d2427cffc115e12a861ab9d68 // Always consider arrow keys as handled, otherwise the GtkWindow key bindings will move the focus. guint keyval; -@@ -368,9 +370,9 @@ void PageClientImpl::selectionDidChange() +@@ -371,9 +373,9 @@ void PageClientImpl::selectionDidChange() webkitWebViewSelectionDidChange(WEBKIT_WEB_VIEW(m_viewWidget)); } @@ -10992,10 +10982,10 @@ index 496079da90993ac37689b060b69ecd4a67c2b6a8..af30181ca922f16c0f6e245c70e5ce7d G_BEGIN_DECLS diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp -index e1a7e687913826b5912ab1e735894a6e0a5b4da9..d75b97ebdd06e529e457266b2ee2bfa7debd3330 100644 +index 9ce95b0e5ec142f4067c99d4aeb388fa08ae3f89..0718c8d9764d100fc8f41348a9273020645f0825 100644 --- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp +++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp -@@ -2923,6 +2923,11 @@ void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase) +@@ -2908,6 +2908,11 @@ void webkitWebViewBaseResetClickCounter(WebKitWebViewBase* webkitWebViewBase) #endif } @@ -11007,7 +10997,7 @@ index e1a7e687913826b5912ab1e735894a6e0a5b4da9..d75b97ebdd06e529e457266b2ee2bfa7 void webkitWebViewBaseEnterAcceleratedCompositingMode(WebKitWebViewBase* webkitWebViewBase, const LayerTreeContext& layerTreeContext) { ASSERT(webkitWebViewBase->priv->acceleratedBackingStore); -@@ -2979,12 +2984,12 @@ void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase) +@@ -2964,12 +2969,12 @@ void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase) webkitWebViewBase->priv->acceleratedBackingStore->update({ }); } @@ -11023,7 +11013,7 @@ index e1a7e687913826b5912ab1e735894a6e0a5b4da9..d75b97ebdd06e529e457266b2ee2bfa7 #if !USE(GTK4) diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h -index 1e98b90627322094b58b60f06b9b2294b8e79d63..1fa990e53ce63e5f54d68928d0d8d3f7c64062b3 100644 +index a227380c1171e1e5824370b21c66440bb744c7f7..9b7bc68d01ef5d7c5d34720a6ab7c27f9e8c2156 100644 --- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h +++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h @@ -27,6 +27,7 @@ @@ -11033,8 +11023,8 @@ index 1e98b90627322094b58b60f06b9b2294b8e79d63..1fa990e53ce63e5f54d68928d0d8d3f7 +#include "AcceleratedBackingStore.h" #include "APIPageConfiguration.h" #include "InputMethodState.h" - #include "SameDocumentNavigationType.h" -@@ -106,7 +107,7 @@ void webkitWebViewBaseStartDrag(WebKitWebViewBase*, WebCore::SelectionData&&, Op + #include "RendererBufferFormat.h" +@@ -107,7 +108,7 @@ void webkitWebViewBaseStartDrag(WebKitWebViewBase*, WebCore::SelectionData&&, Op void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase*); #endif @@ -11043,10 +11033,10 @@ index 1e98b90627322094b58b60f06b9b2294b8e79d63..1fa990e53ce63e5f54d68928d0d8d3f7 void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase*, bool enabled); WebKit::ViewGestureController* webkitWebViewBaseViewGestureController(WebKitWebViewBase*); -@@ -145,3 +146,5 @@ void webkitWebViewBaseCallAfterNextPresentationUpdate(WebKitWebViewBase*, Comple - #if USE(GTK4) - void webkitWebViewBaseSetPlugID(WebKitWebViewBase*, const String&); +@@ -148,3 +149,5 @@ void webkitWebViewBaseSetPlugID(WebKitWebViewBase*, const String&); #endif + + WebKit::RendererBufferFormat webkitWebViewBaseGetRendererBufferFormat(WebKitWebViewBase*); + +WebKit::AcceleratedBackingStore* webkitWebViewBaseGetAcceleratedBackingStore(WebKitWebViewBase*); diff --git a/Source/WebKit/UIProcess/API/wpe/APIViewClient.h b/Source/WebKit/UIProcess/API/wpe/APIViewClient.h @@ -11072,7 +11062,7 @@ index 26d1790017e528f26ae04dac635678d5494bfd04..48dbe50eb05628307264a350350ac19f virtual void didChangePageID(WKWPE::View&) { } virtual void didReceiveUserMessage(WKWPE::View&, WebKit::UserMessage&&, CompletionHandler&& completionHandler) { completionHandler(WebKit::UserMessage()); } diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp -index ab920ef03db906e90613cdb4a4369169a2bf1cbe..d4deb4bad543ff8692b79ecbd3a6d74f8b53915e 100644 +index f498562d70a4652f6831ac6bc12ef86e537d3930..503a8875fed34fd7925646b61a1eed11d7c866b7 100644 --- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp +++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.cpp @@ -33,9 +33,13 @@ @@ -11089,7 +11079,7 @@ index ab920ef03db906e90613cdb4a4369169a2bf1cbe..d4deb4bad543ff8692b79ecbd3a6d74f #include #include #include -@@ -200,7 +204,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I +@@ -203,7 +207,7 @@ WebCore::IntPoint PageClientImpl::accessibilityScreenToRootView(const WebCore::I WebCore::IntRect PageClientImpl::rootViewToAccessibilityScreen(const WebCore::IntRect& rect) { @@ -11098,7 +11088,7 @@ index ab920ef03db906e90613cdb4a4369169a2bf1cbe..d4deb4bad543ff8692b79ecbd3a6d74f } void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent&, bool) -@@ -460,6 +464,33 @@ void PageClientImpl::selectionDidChange() +@@ -465,6 +469,33 @@ void PageClientImpl::selectionDidChange() m_view.selectionDidChange(); } @@ -11132,7 +11122,7 @@ index ab920ef03db906e90613cdb4a4369169a2bf1cbe..d4deb4bad543ff8692b79ecbd3a6d74f WebKitWebResourceLoadManager* PageClientImpl::webResourceLoadManager() { return m_view.webResourceLoadManager(); -@@ -470,4 +501,23 @@ void PageClientImpl::callAfterNextPresentationUpdate(CompletionHandler&& +@@ -475,4 +506,23 @@ void PageClientImpl::callAfterNextPresentationUpdate(CompletionHandler&& m_view.callAfterNextPresentationUpdate(WTFMove(callback)); } @@ -11157,10 +11147,10 @@ index ab920ef03db906e90613cdb4a4369169a2bf1cbe..d4deb4bad543ff8692b79ecbd3a6d74f + } // namespace WebKit diff --git a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h -index dbd9dd946fceebb49b70d6600b1e654e2f0cc0a6..22c6839e2e7c9aa435be04727c6218a88aa29dc1 100644 +index a7ece2c8dc3fd30bfb850de04c4fc10004444d5a..b5ee1a1877b3e748dea3ce195cd75cb0701a7034 100644 --- a/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h +++ b/Source/WebKit/UIProcess/API/wpe/PageClientImpl.h -@@ -164,9 +164,21 @@ private: +@@ -166,9 +166,21 @@ private: void didChangeWebPageID() const override; void selectionDidChange() override; @@ -11183,20 +11173,20 @@ index dbd9dd946fceebb49b70d6600b1e654e2f0cc0a6..22c6839e2e7c9aa435be04727c6218a8 }; diff --git a/Source/WebKit/UIProcess/API/wpe/WPEWebView.cpp b/Source/WebKit/UIProcess/API/wpe/WPEWebView.cpp -index 9a682ff7309e3a7290384d922579094e35ef0167..ec1cd8cb3b8518cb90c526f55f1ba9d482ddb097 100644 +index 8a9b8a7a853f2bdb6ae0b8bb389d3db1e1a53ac4..c22553b96c3e9afc126ce93c4e45e3af0fbd38f0 100644 --- a/Source/WebKit/UIProcess/API/wpe/WPEWebView.cpp +++ b/Source/WebKit/UIProcess/API/wpe/WPEWebView.cpp -@@ -103,7 +103,9 @@ View::View(struct wpe_view_backend* backend, WPEDisplay* display, const API::Pag - if (preferences) { - preferences->setAcceleratedCompositingEnabled(true); - preferences->setForceCompositingMode(true); -- preferences->setThreadedScrollingEnabled(true); -+ // Playwright override begin -+ preferences->setThreadedScrollingEnabled(false); -+ // Playwright override end - } +@@ -98,7 +98,9 @@ View::View(struct wpe_view_backend* backend, WPEDisplay* display, const API::Pag + auto& preferences = configuration->preferences(); + preferences.setAcceleratedCompositingEnabled(true); + preferences.setForceCompositingMode(true); +- preferences.setThreadedScrollingEnabled(true); ++ // Playwright override begin ++ preferences.setThreadedScrollingEnabled(false); ++ // Playwright override end - auto* pool = configuration->processPool(); + auto& pool = configuration->processPool(); + m_pageProxy = pool.createWebPage(*m_pageClient, WTFMove(configuration)); diff --git a/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h b/Source/WebKit/UIProcess/API/wpe/WebKitBrowserInspector.h new file mode 100644 index 0000000000000000000000000000000000000000..273c5105cdf1638955cea01128c9bbab3e64436c @@ -11491,10 +11481,10 @@ index 720c88818bdb4cde3cb58e95785454754f6c1396..7f702c0b922e13128522d2bb1ace6a23 void didChangePageID(WKWPE::View&) override; void didReceiveUserMessage(WKWPE::View&, WebKit::UserMessage&&, CompletionHandler&&) override; diff --git a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp -index 39e4660d5936fd8915cf0dcd7afa83aece092067..da3ef68451021c296b3ff12416ad3bf8440fa657 100644 +index 6f69cd9d4db8544a2c0c8b11fb557697f9b6a183..750a565d8a0c1208cd6950740b2beffa8c1d69d9 100644 --- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp +++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.cpp -@@ -157,7 +157,11 @@ void AuxiliaryProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& lau +@@ -158,7 +158,11 @@ void AuxiliaryProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& lau launchOptions.processCmdPrefix = String::fromUTF8(processCmdPrefix); #endif // ENABLE(DEVELOPER_MODE) && (PLATFORM(GTK) || PLATFORM(WPE)) @@ -11507,10 +11497,10 @@ index 39e4660d5936fd8915cf0dcd7afa83aece092067..da3ef68451021c296b3ff12416ad3bf8 platformGetLaunchOptions(launchOptions); } diff --git a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h -index a18630c193b4902b58f3880b038928c9518cb4d1..c3c9e54a8eb5c653be37a6be81336f4f7ac1e209 100644 +index e2d1e9dfbc77e3d520ce8d31c812a8482facae10..28238da43a4fc45466b43753bc5ad8aa07963f94 100644 --- a/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h +++ b/Source/WebKit/UIProcess/AuxiliaryProcessProxy.h -@@ -259,13 +259,16 @@ protected: +@@ -264,13 +264,16 @@ protected: static RefPtr fetchAudioComponentServerRegistrations(); #endif @@ -11673,7 +11663,7 @@ index 957f7f088087169668a9b4f1ba65d9f206a2a836..15e44c8d5b6a3eafb7f1148707366b0c class PopUpSOAuthorizationSession final : public SOAuthorizationSession { public: diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h -index b310d8ccd4ab217564ff72b1e9d02e1136eb7b89..052056e17d3e8c198a3148e8578905c08d34e7f6 100644 +index 20af8a02d6dee5af7328accca7cd88a06995c4bb..16e8fc676e4bd70f3f35414434963ccb9f277311 100644 --- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.h +++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.h @@ -96,6 +96,7 @@ private: @@ -11684,7 +11674,7 @@ index b310d8ccd4ab217564ff72b1e9d02e1136eb7b89..052056e17d3e8c198a3148e8578905c0 void presentStorageAccessConfirmDialog(const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler&&); void requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WebCore::RegistrableDomain& requestingDomain, const WebCore::RegistrableDomain& currentDomain, std::optional&&, CompletionHandler&&) final; void decidePolicyForGeolocationPermissionRequest(WebPageProxy&, WebFrameProxy&, const FrameInfoData&, Function&) final; -@@ -205,6 +206,7 @@ private: +@@ -207,6 +208,7 @@ private: bool webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler : 1; bool webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1; bool webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler : 1; @@ -11693,10 +11683,10 @@ index b310d8ccd4ab217564ff72b1e9d02e1136eb7b89..052056e17d3e8c198a3148e8578905c0 bool webViewRequestStorageAccessPanelForDomainUnderCurrentDomainForQuirkDomainsCompletionHandler : 1; bool webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler : 1; diff --git a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm -index eeaf81b4869c7d557e9547b0d1bd99ce1efe7aa1..136eef5fcc033fc37a046939f87625c8348b4544 100644 +index db0e7523899917cc9055ced3127a1e4eb493313d..c5a8a5a7da934deda55313465c26a38b1b33d2ac 100644 --- a/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm +++ b/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm -@@ -117,6 +117,7 @@ void UIDelegate::setDelegate(id delegate) +@@ -118,6 +118,7 @@ void UIDelegate::setDelegate(id delegate) m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)]; m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)]; m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)]; @@ -11704,7 +11694,7 @@ index eeaf81b4869c7d557e9547b0d1bd99ce1efe7aa1..136eef5fcc033fc37a046939f87625c8 m_delegateMethods.webViewRequestStorageAccessPanelUnderFirstPartyCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:)]; m_delegateMethods.webViewRequestStorageAccessPanelForDomainUnderCurrentDomainForQuirkDomainsCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:forQuirkDomains:completionHandler:)]; m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)]; -@@ -438,6 +439,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St +@@ -442,6 +443,15 @@ void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy& page, const WTF::St }).get()]; } @@ -11721,7 +11711,7 @@ index eeaf81b4869c7d557e9547b0d1bd99ce1efe7aa1..136eef5fcc033fc37a046939f87625c8 { if (!m_uiDelegate) diff --git a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm -index 1e5123cddd3d09b7bd1076f8e050979b3388757d..827edb9d65ad34f4b1372d884cce08aa7880346e 100644 +index b77d46b64193c5cf2017da8d81623e54d5f6f7a8..61a08b78ff3829995b54ce14c1752d4e073d5796 100644 --- a/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm +++ b/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm @@ -38,6 +38,7 @@ @@ -11732,7 +11722,7 @@ index 1e5123cddd3d09b7bd1076f8e050979b3388757d..827edb9d65ad34f4b1372d884cce08aa #import "PlaybackSessionManagerProxy.h" #import "QuickLookThumbnailLoader.h" #import "RemoteLayerTreeTransaction.h" -@@ -282,10 +283,87 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting() +@@ -283,10 +284,87 @@ bool WebPageProxy::scrollingUpdatesDisabledForTesting() void WebPageProxy::startDrag(const DragItem& dragItem, ShareableBitmap::Handle&& dragImageHandle) { @@ -11819,13 +11809,13 @@ index 1e5123cddd3d09b7bd1076f8e050979b3388757d..827edb9d65ad34f4b1372d884cce08aa + +#endif // ENABLE(DRAG_SUPPORT) - #if ENABLE(ATTACHMENT_ELEMENT) + #if ENABLE(UNIFIED_TEXT_REPLACEMENT) diff --git a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm -index 39e5b93f61600114b4229c53ca529aa2ea5357bd..b8c0f37272184c6847ed1ed1737464cbb0febe10 100644 +index ba0c5fe1678dc1055c7f495f5ff421438db7e082..bdf2dd23de87c114db52603b919f29188a2c4bed 100644 --- a/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm +++ b/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm -@@ -429,7 +429,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END +@@ -434,7 +434,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END auto screenProperties = WebCore::collectScreenProperties(); parameters.screenProperties = WTFMove(screenProperties); #if PLATFORM(MAC) @@ -11834,7 +11824,7 @@ index 39e5b93f61600114b4229c53ca529aa2ea5357bd..b8c0f37272184c6847ed1ed1737464cb #endif #if (PLATFORM(IOS) || PLATFORM(VISION)) && HAVE(AGX_COMPILER_SERVICE) -@@ -797,8 +797,8 @@ void WebProcessPool::registerNotificationObservers() +@@ -803,8 +803,8 @@ void WebProcessPool::registerNotificationObservers() }]; m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) { @@ -11846,7 +11836,7 @@ index 39e5b93f61600114b4229c53ca529aa2ea5357bd..b8c0f37272184c6847ed1ed1737464cb m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) { diff --git a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp -index 40ad458db34babad87d145c16244a678d4531941..55c32131029665071775a0c8881d0f171cbae89d 100644 +index 3796110b3f6ffb29bc1eae80505017dee9e779d1..1a181f4ac8ce8d15d5e65a9df6afc8fe5695e85c 100644 --- a/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp +++ b/Source/WebKit/UIProcess/CoordinatedGraphics/DrawingAreaProxyCoordinatedGraphics.cpp @@ -33,14 +33,17 @@ @@ -12004,7 +11994,7 @@ index d2ceeda76e90ab2041f238c240f81bf9e37f6072..faa338a2b4af13663bb63efc940b7efe } // namespace WebKit diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp -index f2d9013c71bc229498425de62c090323d6f7655b..0e26ccf1d2ad583b54b8a3c0f8829f12f1ce9853 100644 +index 0295a560194b82bf172bfe978c711bb8f280f8e4..e8584dc0133a6a57734c63f6020f3d27dbcd04d7 100644 --- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp +++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.cpp @@ -40,8 +40,10 @@ @@ -12043,7 +12033,7 @@ index f2d9013c71bc229498425de62c090323d6f7655b..0e26ccf1d2ad583b54b8a3c0f8829f12 m_downloadProxyMap.downloadFinished(*this); }); } else -@@ -162,6 +170,21 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour +@@ -164,6 +172,21 @@ void DownloadProxy::decideDestinationWithSuggestedFilename(const WebCore::Resour suggestedFilename = m_suggestedFilename; suggestedFilename = MIMETypeRegistry::appendFileExtensionIfNecessary(suggestedFilename, response.mimeType()); @@ -12065,7 +12055,7 @@ index f2d9013c71bc229498425de62c090323d6f7655b..0e26ccf1d2ad583b54b8a3c0f8829f12 m_client->decideDestinationWithSuggestedFilename(*this, response, ResourceResponseBase::sanitizeSuggestedFilename(suggestedFilename), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)] (AllowOverwrite allowOverwrite, String destination) mutable { SandboxExtension::Handle sandboxExtensionHandle; if (!destination.isNull()) { -@@ -210,6 +233,8 @@ void DownloadProxy::didFinish() +@@ -212,6 +235,8 @@ void DownloadProxy::didFinish() updateQuarantinePropertiesIfPossible(); #endif m_client->didFinish(*this); @@ -12074,7 +12064,7 @@ index f2d9013c71bc229498425de62c090323d6f7655b..0e26ccf1d2ad583b54b8a3c0f8829f12 // This can cause the DownloadProxy object to be deleted. m_downloadProxyMap.downloadFinished(*this); -@@ -220,6 +245,8 @@ void DownloadProxy::didFail(const ResourceError& error, std::span +@@ -222,6 +247,8 @@ void DownloadProxy::didFail(const ResourceError& error, std::span m_legacyResumeData = createData(resumeData); m_client->didFail(*this, error, m_legacyResumeData.get()); @@ -12420,7 +12410,7 @@ index 0000000000000000000000000000000000000000..4ec8b96bbbddf8a7b042f53a8068754a +cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsigned char **data, size_t *len, int quality); diff --git a/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..844f559af924de3fddce8cfcea8550261a8da95b +index 0000000000000000000000000000000000000000..91cf94cd292350afb3e3ed071ca44760acda1c14 --- /dev/null +++ b/Source/WebKit/UIProcess/Inspector/Agents/InspectorScreencastAgent.cpp @@ -0,0 +1,305 @@ @@ -12536,7 +12526,7 @@ index 0000000000000000000000000000000000000000..844f559af924de3fddce8cfcea855026 + int stride = cairo_image_surface_get_stride(surface); + int height = cairo_image_surface_get_height(surface); + auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1); -+ cryptoDigest->addBytes(data, stride * height); ++ cryptoDigest->addBytes(std::span(data, stride * height)); + auto digest = cryptoDigest->computeHash(); + if (m_lastFrameDigest == digest) + return; @@ -12703,7 +12693,7 @@ index 0000000000000000000000000000000000000000..844f559af924de3fddce8cfcea855026 + + // Do not send the same frame over and over. + auto cryptoDigest = PAL::CryptoDigest::create(PAL::CryptoDigest::Algorithm::SHA_1); -+ cryptoDigest->addBytes(data.data(), data.size()); ++ cryptoDigest->addBytes(std::span(data.data(), data.size())); + auto digest = cryptoDigest->computeHash(); + if (m_lastFrameDigest != digest) { + String base64Data = base64EncodeToString(data); @@ -12834,7 +12824,7 @@ index 0000000000000000000000000000000000000000..d28dde452275f18739e3b1c8d709185c +} // namespace WebKit diff --git a/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..5f82314ec035268b1a90568935d427e0909eae05 +index 0000000000000000000000000000000000000000..90080e92c8278e73355c1fd4c571ea12f0bca9c5 --- /dev/null +++ b/Source/WebKit/UIProcess/Inspector/Agents/ScreencastEncoder.cpp @@ -0,0 +1,391 @@ @@ -13022,7 +13012,7 @@ index 0000000000000000000000000000000000000000..5f82314ec035268b1a90568935d427e0 +class ScreencastEncoder::VPXCodec { +public: + VPXCodec(ScopedVpxCodec codec, vpx_codec_enc_cfg_t cfg, FILE* file) -+ : m_encoderQueue(WorkQueue::create("Screencast encoder")) ++ : m_encoderQueue(WorkQueue::create("Screencast encoder"_s)) + , m_codec(WTFMove(codec)) + , m_cfg(cfg) + , m_file(file) @@ -15535,23 +15525,11 @@ index 3fe0abcfe36bef7ca45bed5661a737ed2bfe56d0..510656948af01ec65d4543c805e9667a #include "RemoteMediaSessionCoordinatorMessages.h" #include "RemoteMediaSessionCoordinatorProxyMessages.h" #include "WebPageProxy.h" -diff --git a/Source/WebKit/UIProcess/Notifications/glib/NotificationService.cpp b/Source/WebKit/UIProcess/Notifications/glib/NotificationService.cpp -index 6f2b716f4445008123e96f9db494aea307520636..8f0235a699c91d966a4de9fd03aff57712e80675 100644 ---- a/Source/WebKit/UIProcess/Notifications/glib/NotificationService.cpp -+++ b/Source/WebKit/UIProcess/Notifications/glib/NotificationService.cpp -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/Source/WebKit/UIProcess/PageClient.h b/Source/WebKit/UIProcess/PageClient.h -index 42eee66ab16a2194f63b01a9f26c20aeb728a872..c66aca2950f5cc8823194c4f6cfd60275f5f00a2 100644 +index 46f725b53f67ed41ff3312d106a23174d6a16363..369ee3539762a6286977d94a7958b25291f11ed6 100644 --- a/Source/WebKit/UIProcess/PageClient.h +++ b/Source/WebKit/UIProcess/PageClient.h -@@ -91,6 +91,10 @@ OBJC_CLASS WKView; +@@ -92,6 +92,10 @@ OBJC_CLASS WKView; #endif #endif @@ -15562,7 +15540,7 @@ index 42eee66ab16a2194f63b01a9f26c20aeb728a872..c66aca2950f5cc8823194c4f6cfd6027 namespace API { class Attachment; class HitTestResult; -@@ -342,7 +346,16 @@ public: +@@ -347,7 +351,16 @@ public: virtual void selectionDidChange() = 0; #endif @@ -15706,7 +15684,7 @@ index 0000000000000000000000000000000000000000..3c8fd0549f1847515d35092f0f49b060 + +#endif // ENABLE(FULLSCREEN_API) diff --git a/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp b/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp -index a2dabe84360ef09ea687ded6234d4a742fcc8e56..c411e95dc6549be2e8ed65f025f154bbc9f1ef2c 100644 +index b2dc99d6ca28e7f1140122a259d9fbcf3b4eeabf..4f182cd32458d19b775f79deb1f6da22a4077ba6 100644 --- a/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp +++ b/Source/WebKit/UIProcess/ProvisionalFrameProxy.cpp @@ -25,6 +25,7 @@ @@ -15719,7 +15697,7 @@ index a2dabe84360ef09ea687ded6234d4a742fcc8e56..c411e95dc6549be2e8ed65f025f154bb #include "VisitedLinkStore.h" diff --git a/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp new file mode 100644 -index 0000000000000000000000000000000000000000..967d6e05836be7e46c8aecfd4c3243bb9f422b96 +index 0000000000000000000000000000000000000000..1a824be7d9fcb225d018b4a821fa895e844d7805 --- /dev/null +++ b/Source/WebKit/UIProcess/RemoteInspectorPipe.cpp @@ -0,0 +1,225 @@ @@ -15838,7 +15816,7 @@ index 0000000000000000000000000000000000000000..967d6e05836be7e46c8aecfd4c3243bb + +public: + RemoteFrontendChannel() -+ : m_senderQueue(WorkQueue::create("Inspector pipe writer")) ++ : m_senderQueue(WorkQueue::create("Inspector pipe writer"_s)) + { + } + @@ -15886,7 +15864,7 @@ index 0000000000000000000000000000000000000000..967d6e05836be7e46c8aecfd4c3243bb + + m_playwrightAgent.connectFrontend(*m_remoteFrontendChannel); + m_terminated = false; -+ m_receiverThread = Thread::create("Inspector pipe reader", [this] { ++ m_receiverThread = Thread::create("Inspector pipe reader"_s, [this] { + workerRun(); + }); + return true; @@ -15920,7 +15898,7 @@ index 0000000000000000000000000000000000000000..967d6e05836be7e46c8aecfd4c3243bb + } + size_t start = 0; + size_t end = line.size(); -+ line.append(buffer.get(), size); ++ line.append(std::span { buffer.get(), size }); + while (true) { + for (; end < line.size(); ++end) { + if (line[end] == '\0') @@ -15930,7 +15908,7 @@ index 0000000000000000000000000000000000000000..967d6e05836be7e46c8aecfd4c3243bb + break; + + if (end > start) { -+ String message = String::fromUTF8(line.data() + start, end - start); ++ String message = String::fromUTF8({ line.data() + start, end - start }); + RunLoop::main().dispatch([this, message = WTFMove(message)] { + if (!m_terminated) + m_playwrightAgent.dispatchMessageFromFrontend(message); @@ -16044,10 +16022,10 @@ index d499ee31f32b9dcdb456ba0b476d211fba115673..43b349887d18e21162b59fa8174df32c namespace WebCore { class PlatformWheelEvent; diff --git a/Source/WebKit/UIProcess/RemotePageProxy.cpp b/Source/WebKit/UIProcess/RemotePageProxy.cpp -index 7ba86bc321d138d96705bfb979088a327cd14944..41ce842abf547f173672ff220f2256f89f4aae47 100644 +index 1db0914af03203844ccbda63b50f8486dc823586..3bf331ae9866aaea83e3bea6ca5bb196d4039110 100644 --- a/Source/WebKit/UIProcess/RemotePageProxy.cpp +++ b/Source/WebKit/UIProcess/RemotePageProxy.cpp -@@ -42,6 +42,7 @@ +@@ -43,6 +43,7 @@ #include "WebPageProxyMessages.h" #include "WebProcessMessages.h" #include "WebProcessProxy.h" @@ -16068,7 +16046,7 @@ index 5ecfa03204724d8e5696149dd45e4d35877993f0..fc8262fb617aef3eb68cf13117747dc4 class RemotePageProxy : public IPC::MessageReceiver { WTF_MAKE_FAST_ALLOCATED; diff --git a/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp b/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp -index b2d3197c7a4428171d97a8dff2054e0eebd965fe..2cc258a0343cdeffa1d3c7afd89985b9388f715a 100644 +index 4d8a16e02d2d3c1d11df5df2c84197da76539324..5de382d79c2dd8f7884eb27ef454ba0b99f3fab8 100644 --- a/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp +++ b/Source/WebKit/UIProcess/WebAuthentication/fido/U2fAuthenticator.cpp @@ -37,6 +37,7 @@ @@ -16104,7 +16082,7 @@ index e7d6621532fcc73212cc9130a7cafbb13f458d1d..ec931c8f19d2a61c0fa7d78b52df7f3f WebPageProxy* page() const { return m_page.get(); } diff --git a/Source/WebKit/UIProcess/WebFrameProxy.cpp b/Source/WebKit/UIProcess/WebFrameProxy.cpp -index 049738f4f0db8071eb2dce0d3187fb50da0214af..30ee4aff100cfcb6aa90d730bceea6bb3b9f3b0d 100644 +index 6e6560e17721ed182ab27277759488c410ae130e..207bda7e3c53118344536568ef18ccc043104ba1 100644 --- a/Source/WebKit/UIProcess/WebFrameProxy.cpp +++ b/Source/WebKit/UIProcess/WebFrameProxy.cpp @@ -31,6 +31,7 @@ @@ -16810,10 +16788,10 @@ index 0000000000000000000000000000000000000000..3e87bf40ced2301f4fb145c6cb31f2cf + +} // namespace WebKit diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp -index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8aee698d86a 100644 +index 365c5e2c7925347531f2e488d720973612f25d39..585c51dd017a628f08d443c863fd1453d4592996 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit/UIProcess/WebPageProxy.cpp -@@ -183,12 +183,14 @@ +@@ -185,12 +185,14 @@ #include #include #include @@ -16828,7 +16806,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #include #include #include -@@ -209,6 +211,7 @@ +@@ -211,6 +213,7 @@ #include #include #include @@ -16836,8 +16814,8 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #include #include #include -@@ -216,11 +219,13 @@ - #include +@@ -218,11 +221,13 @@ + #include #include #include +#include @@ -16850,7 +16828,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #include #include #include -@@ -296,6 +301,9 @@ +@@ -298,6 +303,9 @@ #include "AcceleratedBackingStoreDMABuf.h" #endif #include "GtkSettingsManager.h" @@ -16860,7 +16838,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #include #endif -@@ -409,6 +417,8 @@ static constexpr Seconds tryCloseTimeoutDelay = 50_ms; +@@ -419,6 +427,8 @@ static constexpr Seconds tryCloseTimeoutDelay = 50_ms; static constexpr Seconds audibleActivityClearDelay = 10_s; #endif @@ -16869,7 +16847,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy")); #if PLATFORM(COCOA) -@@ -813,6 +823,10 @@ WebPageProxy::~WebPageProxy() +@@ -823,6 +833,10 @@ WebPageProxy::~WebPageProxy() if (preferences->mediaSessionCoordinatorEnabled()) GroupActivitiesSessionNotifier::sharedNotifier().removeWebPage(*this); #endif @@ -16880,7 +16858,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::addAllMessageReceivers() -@@ -1341,6 +1355,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason) +@@ -1361,6 +1375,7 @@ void WebPageProxy::finishAttachingToWebProcess(ProcessLaunchReason reason) protectedPageClient()->didRelaunchProcess(); internals().pageLoadState.didSwapWebProcesses(); @@ -16888,7 +16866,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::didAttachToRunningProcess() -@@ -1349,7 +1364,7 @@ void WebPageProxy::didAttachToRunningProcess() +@@ -1369,7 +1384,7 @@ void WebPageProxy::didAttachToRunningProcess() #if ENABLE(FULLSCREEN_API) ASSERT(!m_fullScreenManager); @@ -16897,7 +16875,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #endif #if ENABLE(VIDEO_PRESENTATION_MODE) ASSERT(!m_playbackSessionManager); -@@ -1747,6 +1762,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess() +@@ -1764,6 +1779,21 @@ WebProcessProxy& WebPageProxy::ensureRunningProcess() return m_process; } @@ -16919,7 +16897,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae RefPtr WebPageProxy::loadRequest(ResourceRequest&& request, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy, API::Object* userData) { if (m_isClosed) -@@ -2321,6 +2351,42 @@ void WebPageProxy::setControlledByAutomation(bool controlled) +@@ -2336,6 +2366,42 @@ void WebPageProxy::setControlledByAutomation(bool controlled) websiteDataStore().protectedNetworkProcess()->send(Messages::NetworkProcess::SetSessionIsControlledByAutomation(m_websiteDataStore->sessionID(), m_controlledByAutomation), 0); } @@ -16962,7 +16940,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae void WebPageProxy::createInspectorTarget(const String& targetId, Inspector::InspectorTargetType type) { MESSAGE_CHECK(m_process, !targetId.isEmpty()); -@@ -2562,6 +2628,24 @@ void WebPageProxy::updateActivityState(OptionSet flagsToUpdate) +@@ -2577,6 +2643,24 @@ void WebPageProxy::updateActivityState(OptionSet flagsToUpdate) bool wasVisible = isViewVisible(); Ref pageClient = this->pageClient(); internals().activityState.remove(flagsToUpdate); @@ -16987,7 +16965,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae if (flagsToUpdate & ActivityState::IsFocused && pageClient->isViewFocused()) internals().activityState.add(ActivityState::IsFocused); if (flagsToUpdate & ActivityState::WindowIsActive && pageClient->isViewWindowActive()) -@@ -3273,7 +3357,7 @@ void WebPageProxy::performDragOperation(DragData& dragData, const String& dragSt +@@ -3302,7 +3386,7 @@ void WebPageProxy::performDragOperation(DragData& dragData, const String& dragSt grantAccessToCurrentPasteboardData(dragStorageName); #endif @@ -16996,7 +16974,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae performDragControllerAction(DragControllerAction::PerformDragOperation, dragData); #else if (!hasRunningProcess()) -@@ -3290,6 +3374,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag +@@ -3319,6 +3403,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag if (!hasRunningProcess()) return; @@ -17005,7 +16983,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae auto completionHandler = [this, protectedThis = Ref { *this }, action, dragData] (std::optional dragOperation, WebCore::DragHandlingMethod dragHandlingMethod, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, const IntRect& insertionRect, const IntRect& editableElementRect, std::optional remoteUserInputEventData) mutable { if (!remoteUserInputEventData) { didPerformDragControllerAction(dragOperation, dragHandlingMethod, mouseIsOverFileInput, numberOfItemsToBeAccepted, insertionRect, editableElementRect); -@@ -3306,6 +3392,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag +@@ -3335,6 +3421,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag protectedProcess()->assumeReadAccessToBaseURL(*this, url); ASSERT(dragData.platformData()); @@ -17014,7 +16992,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae sendWithAsyncReply(Messages::WebPage::PerformDragControllerAction(action, dragData.clientPosition(), dragData.globalPosition(), dragData.draggingSourceOperationMask(), *dragData.platformData(), dragData.flags()), WTFMove(completionHandler)); #else sendToProcessContainingFrame(frameID, Messages::WebPage::PerformDragControllerAction(frameID, action, dragData), WTFMove(completionHandler)); -@@ -3321,14 +3409,34 @@ void WebPageProxy::didPerformDragControllerAction(std::optionaldidPerformDragControllerAction(); @@ -17052,7 +17030,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae didStartDrag(); } #endif -@@ -3349,6 +3457,24 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo +@@ -3378,6 +3486,24 @@ void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& glo setDragCaretRect({ }); } @@ -17077,7 +17055,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae void WebPageProxy::didStartDrag() { if (!hasRunningProcess()) -@@ -3356,6 +3482,16 @@ void WebPageProxy::didStartDrag() +@@ -3385,6 +3511,16 @@ void WebPageProxy::didStartDrag() discardQueuedMouseEvents(); send(Messages::WebPage::DidStartDrag()); @@ -17094,7 +17072,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::dragCancelled() -@@ -3508,16 +3644,37 @@ void WebPageProxy::processNextQueuedMouseEvent() +@@ -3540,16 +3676,37 @@ void WebPageProxy::processNextQueuedMouseEvent() process->startResponsivenessTimer(); } @@ -17138,7 +17116,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::doAfterProcessingAllPendingMouseEvents(WTF::Function&& action) -@@ -3683,6 +3840,8 @@ void WebPageProxy::wheelEventHandlingCompleted(bool wasHandled) +@@ -3715,6 +3872,8 @@ void WebPageProxy::wheelEventHandlingCompleted(bool wasHandled) if (RefPtr automationSession = process().processPool().automationSession()) automationSession->wheelEventsFlushedForPage(*this); @@ -17147,7 +17125,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::cacheWheelEventScrollingAccelerationCurve(const NativeWebWheelEvent& nativeWheelEvent) -@@ -3829,7 +3988,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b) +@@ -3863,7 +4022,7 @@ static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b) void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent) { @@ -17156,7 +17134,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae for (auto& touchPoint : touchStartEvent.touchPoints()) { auto location = touchPoint.location(); auto update = [this, location](TrackingType& trackingType, EventTrackingRegions::EventType eventType) { -@@ -4420,6 +4579,7 @@ void WebPageProxy::receivedNavigationActionPolicyDecision(WebProcessProxy& proce +@@ -4460,6 +4619,7 @@ void WebPageProxy::receivedNavigationActionPolicyDecision(WebProcessProxy& proce void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr&& websitePolicies, Ref&& navigationAction, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional sandboxExtensionHandle, std::optional&& consoleMessage, CompletionHandler&& completionHandler) { @@ -17164,7 +17142,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae if (!hasRunningProcess()) return completionHandler(PolicyDecision { }); -@@ -5342,6 +5502,11 @@ void WebPageProxy::pageScaleFactorDidChange(double scaleFactor) +@@ -5382,6 +5542,11 @@ void WebPageProxy::pageScaleFactorDidChange(double scaleFactor) m_pageScaleFactor = scaleFactor; } @@ -17176,7 +17154,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae void WebPageProxy::pluginScaleFactorDidChange(double pluginScaleFactor) { MESSAGE_CHECK(m_process, scaleFactorIsValid(pluginScaleFactor)); -@@ -5872,6 +6037,7 @@ void WebPageProxy::didDestroyNavigationShared(Ref&& process, ui +@@ -5935,6 +6100,7 @@ void WebPageProxy::didDestroyNavigationShared(Ref&& process, ui Ref protectedPageClient { pageClient() }; m_navigationState->didDestroyNavigation(process->coreProcessIdentifier(), navigationID); @@ -17184,7 +17162,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::didStartProvisionalLoadForFrame(FrameIdentifier frameID, FrameInfoData&& frameInfo, ResourceRequest&& request, uint64_t navigationID, URL&& url, URL&& unreachableURL, const UserData& userData) -@@ -6126,6 +6292,8 @@ void WebPageProxy::didFailProvisionalLoadForFrameShared(Ref&& p +@@ -6189,6 +6355,8 @@ void WebPageProxy::didFailProvisionalLoadForFrameShared(Ref&& p m_failingProvisionalLoadURL = { }; @@ -17193,7 +17171,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae // If the provisional page's load fails then we destroy the provisional page. if (m_provisionalPage && m_provisionalPage->mainFrame() == &frame && willContinueLoading == WillContinueLoading::No) m_provisionalPage = nullptr; -@@ -6767,7 +6935,14 @@ void WebPageProxy::beginSafeBrowsingCheck(const URL&, bool, WebFramePolicyListen +@@ -6834,7 +7002,14 @@ void WebPageProxy::beginSafeBrowsingCheck(const URL&, bool, WebFramePolicyListen void WebPageProxy::decidePolicyForNavigationActionAsync(NavigationActionData&& data, CompletionHandler&& completionHandler) { @@ -17209,7 +17187,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } void WebPageProxy::decidePolicyForNavigationActionAsyncShared(Ref&& process, NavigationActionData&& data, CompletionHandler&& completionHandler) -@@ -7404,6 +7579,7 @@ void WebPageProxy::createNewPage(WindowFeatures&& windowFeatures, NavigationActi +@@ -7474,6 +7649,7 @@ void WebPageProxy::createNewPage(WindowFeatures&& windowFeatures, NavigationActi if (RefPtr page = originatingFrameInfo->page()) openerAppInitiatedState = page->lastNavigationWasAppInitiated(); @@ -17217,7 +17195,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae auto completionHandler = [ this, protectedThis = Ref { *this }, -@@ -7462,6 +7638,7 @@ void WebPageProxy::createNewPage(WindowFeatures&& windowFeatures, NavigationActi +@@ -7540,6 +7716,7 @@ void WebPageProxy::createNewPage(WindowFeatures&& windowFeatures, NavigationActi void WebPageProxy::showPage() { m_uiClient->showPage(this); @@ -17225,7 +17203,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } bool WebPageProxy::hasOpenedPage() const -@@ -7541,6 +7718,10 @@ void WebPageProxy::closePage() +@@ -7621,6 +7798,10 @@ void WebPageProxy::closePage() if (isClosed()) return; @@ -17236,7 +17214,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae WEBPAGEPROXY_RELEASE_LOG(Process, "closePage:"); protectedPageClient()->clearAllEditCommands(); m_uiClient->close(this); -@@ -7577,6 +7758,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f +@@ -7657,6 +7838,8 @@ void WebPageProxy::runJavaScriptAlert(FrameIdentifier frameID, FrameInfoData&& f } runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler&& completion) mutable { @@ -17245,7 +17223,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae page.m_uiClient->runJavaScriptAlert(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)]() mutable { reply(); completion(); -@@ -7598,6 +7781,8 @@ void WebPageProxy::runJavaScriptConfirm(FrameIdentifier frameID, FrameInfoData&& +@@ -7678,6 +7861,8 @@ void WebPageProxy::runJavaScriptConfirm(FrameIdentifier frameID, FrameInfoData&& if (RefPtr automationSession = process().processPool().automationSession()) automationSession->willShowJavaScriptDialog(*this); } @@ -17254,7 +17232,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply)](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler&& completion) mutable { page.m_uiClient->runJavaScriptConfirm(page, message, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](bool result) mutable { -@@ -7621,6 +7806,8 @@ void WebPageProxy::runJavaScriptPrompt(FrameIdentifier frameID, FrameInfoData&& +@@ -7701,6 +7886,8 @@ void WebPageProxy::runJavaScriptPrompt(FrameIdentifier frameID, FrameInfoData&& if (RefPtr automationSession = process().processPool().automationSession()) automationSession->willShowJavaScriptDialog(*this); } @@ -17263,7 +17241,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae runModalJavaScriptDialog(WTFMove(frame), WTFMove(frameInfo), message, [reply = WTFMove(reply), defaultValue](WebPageProxy& page, WebFrameProxy* frame, FrameInfoData&& frameInfo, const String& message, CompletionHandler&& completion) mutable { page.m_uiClient->runJavaScriptPrompt(page, message, defaultValue, frame, WTFMove(frameInfo), [reply = WTFMove(reply), completion = WTFMove(completion)](auto& result) mutable { -@@ -7737,6 +7924,8 @@ void WebPageProxy::runBeforeUnloadConfirmPanel(FrameIdentifier frameID, FrameInf +@@ -7817,6 +8004,8 @@ void WebPageProxy::runBeforeUnloadConfirmPanel(FrameIdentifier frameID, FrameInf return; } } @@ -17272,7 +17250,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer and the tryClose timer. protectedProcess()->stopResponsivenessTimer(); -@@ -8220,6 +8409,11 @@ void WebPageProxy::resourceLoadDidCompleteWithError(ResourceLoadInfo&& loadInfo, +@@ -8307,6 +8496,11 @@ void WebPageProxy::resourceLoadDidCompleteWithError(ResourceLoadInfo&& loadInfo, } #if ENABLE(FULLSCREEN_API) @@ -17284,7 +17262,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae WebFullScreenManagerProxy* WebPageProxy::fullScreenManager() { return m_fullScreenManager.get(); -@@ -8296,6 +8490,17 @@ void WebPageProxy::requestDOMPasteAccess(WebCore::DOMPasteAccessCategory pasteAc +@@ -8383,6 +8577,17 @@ void WebPageProxy::requestDOMPasteAccess(WebCore::DOMPasteAccessCategory pasteAc { MESSAGE_CHECK_COMPLETION(m_process, !originIdentifier.isEmpty(), completionHandler(DOMPasteAccessResponse::DeniedForGesture)); @@ -17302,7 +17280,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae m_pageClient->requestDOMPasteAccess(pasteAccessCategory, elementRect, originIdentifier, WTFMove(completionHandler)); } -@@ -9121,6 +9326,8 @@ void WebPageProxy::mouseEventHandlingCompleted(std::optional event +@@ -9232,6 +9437,8 @@ void WebPageProxy::mouseEventHandlingCompleted(std::optional event if (RefPtr automationSession = process().processPool().automationSession()) automationSession->mouseEventsFlushedForPage(*this); didFinishProcessingAllPendingMouseEvents(); @@ -17311,7 +17289,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } } -@@ -9155,6 +9362,7 @@ void WebPageProxy::keyEventHandlingCompleted(std::optional eventTy +@@ -9266,6 +9473,7 @@ void WebPageProxy::keyEventHandlingCompleted(std::optional eventTy if (!canProcessMoreKeyEvents) { if (RefPtr automationSession = process().processPool().automationSession()) automationSession->keyboardEventsFlushedForPage(*this); @@ -17319,9 +17297,9 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae } } -@@ -9560,7 +9768,10 @@ void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason) +@@ -9671,7 +9879,10 @@ void WebPageProxy::dispatchProcessDidTerminate(ProcessTerminationReason reason) { - WEBPAGEPROXY_RELEASE_LOG_ERROR(Loading, "dispatchProcessDidTerminate: reason=%" PUBLIC_LOG_STRING, processTerminationReasonToString(reason)); + WEBPAGEPROXY_RELEASE_LOG_ERROR(Loading, "dispatchProcessDidTerminate: reason=%" PUBLIC_LOG_STRING, processTerminationReasonToString(reason).characters()); - bool handledByClient = false; + bool handledByClient = m_inspectorController->pageCrashed(reason); @@ -17331,15 +17309,15 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae if (m_loaderClient) handledByClient = reason != ProcessTerminationReason::RequestedByClient && m_loaderClient->processDidCrash(*this); else -@@ -9927,6 +10138,7 @@ bool WebPageProxy::useGPUProcessForDOMRenderingEnabled() const +@@ -10041,6 +10252,7 @@ bool WebPageProxy::useGPUProcessForDOMRenderingEnabled() const - WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea, bool isProcessSwap, RefPtr&& websitePolicies, std::optional&& mainFrameIdentifier, SubframeProcessPageParameters* subframeProcessPageParameters, std::optional topContentInset) + WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& process, DrawingAreaProxy& drawingArea, std::optional&& subframeProcessPageParameters, bool isProcessSwap, RefPtr&& websitePolicies, std::optional&& mainFrameIdentifier, std::optional topContentInset) { + WebPageCreationParameters parameters; parameters.processDisplayName = configuration().processDisplayName(); -@@ -10151,6 +10363,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc +@@ -10267,6 +10479,8 @@ WebPageCreationParameters WebPageProxy::creationParameters(WebProcessProxy& proc parameters.httpsUpgradeEnabled = preferences().upgradeKnownHostsToHTTPSEnabled() ? m_configuration->httpsUpgradeEnabled() : false; @@ -17348,7 +17326,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae #if PLATFORM(IOS) || PLATFORM(VISION) // FIXME: This is also being passed over the to WebProcess via the PreferencesStore. parameters.allowsDeprecatedSynchronousXMLHttpRequestDuringUnload = allowsDeprecatedSynchronousXMLHttpRequestDuringUnload(); -@@ -10257,8 +10471,42 @@ void WebPageProxy::gamepadActivity(const Vector>& gam +@@ -10373,8 +10587,42 @@ void WebPageProxy::gamepadActivity(const Vector>& gam #endif @@ -17391,7 +17369,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae if (negotiatedLegacyTLS == NegotiatedLegacyTLS::Yes) { m_navigationClient->shouldAllowLegacyTLS(*this, authenticationChallenge.get(), [this, protectedThis = Ref { *this }, authenticationChallenge] (bool shouldAllowLegacyTLS) { if (shouldAllowLegacyTLS) -@@ -10353,6 +10601,12 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge +@@ -10469,6 +10717,12 @@ void WebPageProxy::requestGeolocationPermissionForFrame(GeolocationIdentifier ge request->deny(); }; @@ -17404,7 +17382,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae // FIXME: Once iOS migrates to the new WKUIDelegate SPI, clean this up // and make it one UIClient call that calls the completionHandler with false // if there is no delegate instead of returning the completionHandler -@@ -10415,6 +10669,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi +@@ -10531,6 +10785,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi shouldChangeDeniedToPrompt = false; if (sessionID().isEphemeral()) { @@ -17417,7 +17395,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae completionHandler(shouldChangeDeniedToPrompt ? PermissionState::Prompt : PermissionState::Denied); return; } -@@ -10429,6 +10689,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi +@@ -10545,6 +10805,12 @@ void WebPageProxy::queryPermission(const ClientOrigin& clientOrigin, const Permi return; } @@ -17431,7 +17409,7 @@ index df4dd0b19148e6c1ec29ca080209bca624f9bdd1..f64fd97f7d82209da372c102cd6ca8ae completionHandler(shouldChangeDeniedToPrompt ? PermissionState::Prompt : PermissionState::Denied); return; diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h -index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07ba620d7be 100644 +index 2e40bbb43a05c10eee30296c5a7febdcdb74c157..4deb131a7c531d9035833f22062cf9e8f0aa3a6c 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.h +++ b/Source/WebKit/UIProcess/WebPageProxy.h @@ -26,6 +26,7 @@ @@ -17442,7 +17420,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #include "MessageReceiver.h" #include "MessageSender.h" #include -@@ -35,6 +36,24 @@ +@@ -36,6 +37,24 @@ #include #include #include @@ -17467,7 +17445,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #if USE(DICTATION_ALTERNATIVES) #include -@@ -104,6 +123,7 @@ class DestinationColorSpace; +@@ -106,6 +125,7 @@ class DestinationColorSpace; class DragData; class FloatPoint; class FloatQuad; @@ -17475,7 +17453,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b class FloatRect; class FloatSize; class FontAttributeChanges; -@@ -418,6 +438,7 @@ class WebExtensionController; +@@ -421,6 +441,7 @@ class WebExtensionController; class WebFramePolicyListenerProxy; class WebFrameProxy; class WebFullScreenManagerProxy; @@ -17483,7 +17461,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b class WebInspectorUIProxy; class WebKeyboardEvent; class WebMouseEvent; -@@ -645,6 +666,8 @@ public: +@@ -649,6 +670,8 @@ public: void setControlledByAutomation(bool); WebPageInspectorController& inspectorController() { return *m_inspectorController; } @@ -17492,7 +17470,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #if PLATFORM(IOS_FAMILY) void showInspectorIndication(); -@@ -678,6 +701,7 @@ public: +@@ -682,6 +705,7 @@ public: bool hasSleepDisabler() const; #if ENABLE(FULLSCREEN_API) @@ -17500,7 +17478,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b WebFullScreenManagerProxy* fullScreenManager(); API::FullscreenClient& fullscreenClient() const { return *m_fullscreenClient; } -@@ -766,6 +790,11 @@ public: +@@ -770,6 +794,11 @@ public: void setPageLoadStateObserver(std::unique_ptr&&); @@ -17512,7 +17490,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b void initializeWebPage(); void setDrawingArea(std::unique_ptr&&); -@@ -792,6 +821,7 @@ public: +@@ -796,6 +825,7 @@ public: void addPlatformLoadParameters(WebProcessProxy&, LoadParameters&); RefPtr loadRequest(WebCore::ResourceRequest&&); RefPtr loadRequest(WebCore::ResourceRequest&&, WebCore::ShouldOpenExternalURLsPolicy, API::Object* userData = nullptr); @@ -17520,7 +17498,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b RefPtr loadFile(const String& fileURL, const String& resourceDirectoryURL, bool isAppInitiated = true, API::Object* userData = nullptr); RefPtr loadData(std::span, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData = nullptr); RefPtr loadData(std::span, const String& MIMEType, const String& encoding, const String& baseURL, API::Object* userData, WebCore::ShouldOpenExternalURLsPolicy); -@@ -856,6 +886,7 @@ public: +@@ -862,6 +892,7 @@ public: PageClient& pageClient() const; Ref protectedPageClient() const; @@ -17528,7 +17506,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b void setViewNeedsDisplay(const WebCore::Region&); void requestScroll(const WebCore::FloatPoint& scrollPosition, const WebCore::IntPoint& scrollOrigin, WebCore::ScrollIsAnimated); -@@ -1376,6 +1407,7 @@ public: +@@ -1389,6 +1420,7 @@ public: #endif void pageScaleFactorDidChange(double); @@ -17536,7 +17514,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b void pluginScaleFactorDidChange(double); void pluginZoomFactorDidChange(double); -@@ -1460,14 +1492,20 @@ public: +@@ -1473,14 +1505,20 @@ public: void didStartDrag(); void dragCancelled(); void setDragCaretRect(const WebCore::IntRect&); @@ -17558,7 +17536,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #endif void processDidBecomeUnresponsive(); -@@ -1700,6 +1738,7 @@ public: +@@ -1713,6 +1751,7 @@ public: void setViewportSizeForCSSViewportUnits(const WebCore::FloatSize&); WebCore::FloatSize viewportSizeForCSSViewportUnits() const; @@ -17566,7 +17544,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b void didReceiveAuthenticationChallengeProxy(Ref&&, NegotiatedLegacyTLS); void negotiatedLegacyTLS(); void didNegotiateModernTLS(const URL&); -@@ -1734,6 +1773,8 @@ public: +@@ -1747,6 +1786,8 @@ public: #if PLATFORM(COCOA) || PLATFORM(GTK) RefPtr takeViewSnapshot(std::optional&&); @@ -17575,7 +17553,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #endif void wrapCryptoKey(const Vector&, CompletionHandler>&&)>&&); -@@ -2596,6 +2637,7 @@ private: +@@ -2639,6 +2680,7 @@ private: RefPtr launchProcessForReload(); void requestNotificationPermission(const String& originString, CompletionHandler&&); @@ -17583,7 +17561,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b void didChangeContentSize(const WebCore::IntSize&); void didChangeIntrinsicContentSize(const WebCore::IntSize&); -@@ -3103,8 +3145,10 @@ private: +@@ -3145,8 +3187,10 @@ private: String m_overrideContentSecurityPolicy; RefPtr m_inspector; @@ -17594,7 +17572,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b std::unique_ptr m_fullScreenManager; std::unique_ptr m_fullscreenClient; #endif -@@ -3294,6 +3338,22 @@ private: +@@ -3336,6 +3380,22 @@ private: std::optional m_currentDragOperation; bool m_currentDragIsOverFileInput { false }; unsigned m_currentDragNumberOfFilesToBeAccepted { 0 }; @@ -17617,7 +17595,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #endif bool m_mainFrameHasHorizontalScrollbar { false }; -@@ -3465,6 +3525,10 @@ private: +@@ -3507,6 +3567,10 @@ private: RefPtr messageBody; }; Vector m_pendingInjectedBundleMessages; @@ -17629,7 +17607,7 @@ index d02f8aff91035baa83a6465152c8d62d824a2829..074bb4572f078ee140375f60c5fca07b #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION) std::unique_ptr m_webDeviceOrientationUpdateProviderProxy; diff --git a/Source/WebKit/UIProcess/WebPageProxy.messages.in b/Source/WebKit/UIProcess/WebPageProxy.messages.in -index 3b1f8c7613d9ebc836bb173b49187bb5cc53247e..91a86a693e99950efb90c406199dcb9769c1e401 100644 +index 3907e52e0136c24b8cdc24cb6e178b201e3e482a..03ef59a3032b12f91dcdd4a1160c7c8ef12cc0e3 100644 --- a/Source/WebKit/UIProcess/WebPageProxy.messages.in +++ b/Source/WebKit/UIProcess/WebPageProxy.messages.in @@ -29,6 +29,7 @@ messages -> WebPageProxy { @@ -17648,7 +17626,7 @@ index 3b1f8c7613d9ebc836bb173b49187bb5cc53247e..91a86a693e99950efb90c406199dcb97 PluginScaleFactorDidChange(double zoomFactor) PluginZoomFactorDidChange(double zoomFactor) -@@ -303,10 +305,14 @@ messages -> WebPageProxy { +@@ -309,10 +311,14 @@ messages -> WebPageProxy { StartDrag(struct WebCore::DragItem dragItem, WebCore::ShareableBitmapHandle dragImage) SetPromisedDataForImage(String pasteboardName, WebCore::SharedMemory::Handle imageHandle, String filename, String extension, String title, String url, String visibleURL, WebCore::SharedMemory::Handle archiveHandle, String originIdentifier) #endif @@ -17680,10 +17658,10 @@ index c909cd634d6acd72695de8372866691269ad6a04..ff5b37e3b4a17eab4bd3f8e9a2a6ef84 } diff --git a/Source/WebKit/UIProcess/WebProcessPool.cpp b/Source/WebKit/UIProcess/WebProcessPool.cpp -index 8d176f2829f0c11fbb5c2d052a3036bcae981c78..5416b923ad7f36d6676120b640ca258905176aa2 100644 +index f997e69f867ecaa6ec60a94a21ac89d51de413a4..78008ea36f1d08948c671fdfeeef08b30c7fc7fa 100644 --- a/Source/WebKit/UIProcess/WebProcessPool.cpp +++ b/Source/WebKit/UIProcess/WebProcessPool.cpp -@@ -429,10 +429,10 @@ void WebProcessPool::setAutomationClient(std::unique_ptr& +@@ -430,10 +430,10 @@ void WebProcessPool::setAutomationClient(std::unique_ptr& void WebProcessPool::setOverrideLanguages(Vector&& languages) { @@ -17696,7 +17674,7 @@ index 8d176f2829f0c11fbb5c2d052a3036bcae981c78..5416b923ad7f36d6676120b640ca2589 #if ENABLE(GPU_PROCESS) if (RefPtr gpuProcess = GPUProcessProxy::singletonIfCreated()) -@@ -440,9 +440,10 @@ void WebProcessPool::setOverrideLanguages(Vector&& languages) +@@ -441,9 +441,10 @@ void WebProcessPool::setOverrideLanguages(Vector&& languages) #endif #if USE(SOUP) for (Ref networkProcess : NetworkProcessProxy::allNetworkProcesses()) @@ -17708,7 +17686,7 @@ index 8d176f2829f0c11fbb5c2d052a3036bcae981c78..5416b923ad7f36d6676120b640ca2589 void WebProcessPool::fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled) { -@@ -934,7 +935,7 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa +@@ -936,7 +937,7 @@ void WebProcessPool::initializeNewWebProcess(WebProcessProxy& process, WebsiteDa #endif parameters.cacheModel = LegacyGlobalSettings::singleton().cacheModel(); @@ -17718,10 +17696,10 @@ index 8d176f2829f0c11fbb5c2d052a3036bcae981c78..5416b923ad7f36d6676120b640ca2589 parameters.urlSchemesRegisteredAsEmptyDocument = copyToVector(m_schemesToRegisterAsEmptyDocument); diff --git a/Source/WebKit/UIProcess/WebProcessProxy.cpp b/Source/WebKit/UIProcess/WebProcessProxy.cpp -index c10fcb327b2d8ddf2393a7acda99c84531cab4e2..ab03eb619003f7202ccefed2d030f5cd6c7251c3 100644 +index b8305771145ecb6b92e28de1bcb370dc8ccbba0d..d3b591bc81ccd07367223270c545056fbdb51f49 100644 --- a/Source/WebKit/UIProcess/WebProcessProxy.cpp +++ b/Source/WebKit/UIProcess/WebProcessProxy.cpp -@@ -184,6 +184,11 @@ Vector> WebProcessProxy::allProcesses() +@@ -188,6 +188,11 @@ Vector> WebProcessProxy::allProcesses() }); } @@ -17733,7 +17711,7 @@ index c10fcb327b2d8ddf2393a7acda99c84531cab4e2..ab03eb619003f7202ccefed2d030f5cd RefPtr WebProcessProxy::processForIdentifier(ProcessIdentifier identifier) { return allProcessMap().get(identifier); -@@ -541,6 +546,26 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt +@@ -555,6 +560,26 @@ void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOpt if (WebKit::isInspectorProcessPool(processPool())) launchOptions.extraInitializationData.add("inspector-process"_s, "1"_s); @@ -17761,10 +17739,10 @@ index c10fcb327b2d8ddf2393a7acda99c84531cab4e2..ab03eb619003f7202ccefed2d030f5cd if (isPrewarmed()) diff --git a/Source/WebKit/UIProcess/WebProcessProxy.h b/Source/WebKit/UIProcess/WebProcessProxy.h -index bb3e329ad02085273cbc7f00c514acfb3c8f9c35..be6d0e7e0d8023f3c6a84af9535db6b786855993 100644 +index 92ebcbaf5abecd997e8bfd3cb5cb41b02191b7c5..bec4da91324e832f1dd027ad9e064a3336b3e047 100644 --- a/Source/WebKit/UIProcess/WebProcessProxy.h +++ b/Source/WebKit/UIProcess/WebProcessProxy.h -@@ -164,6 +164,7 @@ public: +@@ -166,6 +166,7 @@ public: static void forWebPagesWithOrigin(PAL::SessionID, const WebCore::SecurityOriginData&, const Function&); static Vector> allowedFirstPartiesForCookies(); @@ -17773,7 +17751,7 @@ index bb3e329ad02085273cbc7f00c514acfb3c8f9c35..be6d0e7e0d8023f3c6a84af9535db6b7 WebConnection* webConnection() const { return m_webConnection.get(); } RefPtr protectedWebConnection() const { return m_webConnection; } diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp -index d6ab1fddd24467a01e748a6ec94fbbd2a806454c..14486b0c5e1f80f0825ebc6cec337283732e5fd2 100644 +index 9729698017cabce150921532f0dd40e10634f0ce..9bb75eda6f3e5e0633d6ef55b3980f8ce35b2f2f 100644 --- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp +++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp @@ -305,7 +305,8 @@ SOAuthorizationCoordinator& WebsiteDataStore::soAuthorizationCoordinator(const W @@ -17786,7 +17764,7 @@ index d6ab1fddd24467a01e748a6ec94fbbd2a806454c..14486b0c5e1f80f0825ebc6cec337283 if (sessionID.isEphemeral()) { // Reuse a previous persistent session network process for ephemeral sessions. for (auto& dataStore : allDataStores().values()) { -@@ -2266,6 +2267,12 @@ void WebsiteDataStore::originDirectoryForTesting(WebCore::ClientOrigin&& origin, +@@ -2278,6 +2279,12 @@ void WebsiteDataStore::originDirectoryForTesting(WebCore::ClientOrigin&& origin, protectedNetworkProcess()->websiteDataOriginDirectoryForTesting(m_sessionID, WTFMove(origin), type, WTFMove(completionHandler)); } @@ -17800,7 +17778,7 @@ index d6ab1fddd24467a01e748a6ec94fbbd2a806454c..14486b0c5e1f80f0825ebc6cec337283 void WebsiteDataStore::hasAppBoundSession(CompletionHandler&& completionHandler) const { diff --git a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h -index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34bad93c053 100644 +index 165885137ca032390c6b55baacc30a8c4c423eb5..930ceeca56587636993f9a0c0e0a21d0ebab3835 100644 --- a/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h +++ b/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h @@ -97,6 +97,7 @@ class DeviceIdHashSaltStorage; @@ -17833,7 +17811,7 @@ index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34b class WebsiteDataStore : public API::ObjectImpl, public CanMakeWeakPtr { public: static Ref defaultDataStore(); -@@ -302,11 +312,13 @@ public: +@@ -305,11 +315,13 @@ public: const WebCore::CurlProxySettings& networkProxySettings() const { return m_proxySettings; } #endif @@ -17848,7 +17826,7 @@ index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34b void setNetworkProxySettings(WebCore::SoupNetworkProxySettings&&); const WebCore::SoupNetworkProxySettings& networkProxySettings() const { return m_networkProxySettings; } void setCookiePersistentStorage(const String&, SoupCookiePersistentStorageType); -@@ -391,6 +403,12 @@ public: +@@ -394,6 +406,12 @@ public: static const String& defaultBaseDataDirectory(); #endif @@ -17861,7 +17839,7 @@ index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34b void resetQuota(CompletionHandler&&); void resetStoragePersistedState(CompletionHandler&&); #if PLATFORM(IOS_FAMILY) -@@ -561,9 +579,11 @@ private: +@@ -564,9 +582,11 @@ private: WebCore::CurlProxySettings m_proxySettings; #endif @@ -17874,7 +17852,7 @@ index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34b WebCore::SoupNetworkProxySettings m_networkProxySettings; String m_cookiePersistentStoragePath; SoupCookiePersistentStorageType m_cookiePersistentStorageType { SoupCookiePersistentStorageType::SQLite }; -@@ -590,6 +610,10 @@ private: +@@ -593,6 +613,10 @@ private: RefPtr m_cookieStore; RefPtr m_networkProcess; @@ -17886,10 +17864,10 @@ index f89889023ac34839a249145b37540cf34e9a6e9e..25418e0cba99a7d82ee2cd758f25e34b std::unique_ptr m_soAuthorizationCoordinator; #endif diff --git a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp -index 8cf57bf6b4370d7c19d0a624e852a8bec4f9aba3..cc9047c17a10863a9ea8bdda903af9367018c3cc 100644 +index d02a8ad4cd66f7f277eee16d21e9ffb0e1a961db..ef35d46977b9b6a866b665e3a01eac94a648cc97 100644 --- a/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp +++ b/Source/WebKit/UIProcess/geoclue/GeoclueGeolocationProvider.cpp -@@ -100,6 +100,14 @@ void GeoclueGeolocationProvider::stop() +@@ -101,6 +101,14 @@ void GeoclueGeolocationProvider::stop() } m_sourceType = LocationProviderSource::Unknown; @@ -17904,7 +17882,7 @@ index 8cf57bf6b4370d7c19d0a624e852a8bec4f9aba3..cc9047c17a10863a9ea8bdda903af936 } void GeoclueGeolocationProvider::setEnableHighAccuracy(bool enabled) -@@ -372,6 +380,8 @@ void GeoclueGeolocationProvider::createGeoclueClient(const char* clientPath) +@@ -373,6 +381,8 @@ void GeoclueGeolocationProvider::createGeoclueClient(const char* clientPath) return; } @@ -18185,10 +18163,10 @@ index 0000000000000000000000000000000000000000..394f07e1754be52b7d503d5720cba5d3 + +#endif // ENABLE(REMOTE_INSPECTOR) diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h -index 71fb4cbd4338bcbda3a61019cbf4a914bf74953e..6f56e4afb345c23b4d8b91ee77f1991c72e58383 100644 +index b02c70d85fe1a93899640a8b909b0cf734d28b18..b1dc8e89eb265be81e083bf337109561e08cbf45 100644 --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStore.h -@@ -28,6 +28,7 @@ +@@ -29,6 +29,7 @@ #include typedef struct _cairo cairo_t; @@ -18196,7 +18174,7 @@ index 71fb4cbd4338bcbda3a61019cbf4a914bf74953e..6f56e4afb345c23b4d8b91ee77f1991c #if USE(GTK4) typedef struct _GdkSnapshot GdkSnapshot; -@@ -56,6 +57,8 @@ public: +@@ -57,6 +58,8 @@ public: #else virtual bool paint(cairo_t*, const WebCore::IntRect&) = 0; #endif @@ -18206,12 +18184,12 @@ index 71fb4cbd4338bcbda3a61019cbf4a914bf74953e..6f56e4afb345c23b4d8b91ee77f1991c virtual void unrealize() { }; virtual int renderHostFileDescriptor() { return -1; } diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp -index a02443e27fe05c1ad14337b676c365a7ff63aaa6..d0772d4ac275dd8298dbf24d4ecc6d3ae101f2e1 100644 +index bef1f57ad45eaef04640991d4afd34138b8d7b76..a37024640fbf6eb79838c039001ee1cf4907042e 100644 --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp -@@ -618,6 +618,32 @@ bool AcceleratedBackingStoreDMABuf::paint(cairo_t* cr, const WebCore::IntRect& c +@@ -659,4 +659,30 @@ RendererBufferFormat AcceleratedBackingStoreDMABuf::bufferFormat() const + return buffer ? buffer->format() : RendererBufferFormat { }; } - #endif +// Playwright begin +cairo_surface_t* AcceleratedBackingStoreDMABuf::surface() @@ -18240,10 +18218,8 @@ index a02443e27fe05c1ad14337b676c365a7ff63aaa6..d0772d4ac275dd8298dbf24d4ecc6d3a +// Playwright end + } // namespace WebKit - - #endif // USE(EGL) diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h -index 8bfba047f41fa3f805d93771c648ca2045411ed6..f32e795be4d60cd35e3a704cd3975065146cdb06 100644 +index cd95ceb063fc776b5d68ff45262c4d84e572c509..041c562551cd467c320b8f566264885d00d1434b 100644 --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.h @@ -88,6 +88,7 @@ private: @@ -18253,8 +18229,8 @@ index 8bfba047f41fa3f805d93771c648ca2045411ed6..f32e795be4d60cd35e3a704cd3975065 + cairo_surface_t* surface() override; void unrealize() override; void update(const LayerTreeContext&) override; - -@@ -233,6 +234,9 @@ private: + RendererBufferFormat bufferFormat() const override; +@@ -243,6 +244,9 @@ private: RefPtr m_pendingBuffer; RefPtr m_committedBuffer; HashMap> m_buffers; @@ -18531,10 +18507,10 @@ index d18b3e777203ef5d0f33884f909bc598d3526831..aef80b47359d7a2e4805a006dc59cd60 m_primarySelectionOwner = frame; } diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm -index b5adddce23fd14eab99f55739a3e18bccbcdf5ec..e7dd2d5daafb870e524bcd8f7cf6779e97ae08ba 100644 +index 286877d14b4eb6ac45092fa1cce5ce530558f8af..85240554255d69a30269e764214a139743de521b 100644 --- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm +++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm -@@ -494,6 +494,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect) +@@ -504,6 +504,8 @@ IntRect PageClientImpl::rootViewToAccessibilityScreen(const IntRect& rect) void PageClientImpl::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool eventWasHandled) { @@ -18753,7 +18729,7 @@ index 0000000000000000000000000000000000000000..721826c8c98fc85b68a4f45deaee69c1 + +#endif diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.h b/Source/WebKit/UIProcess/mac/PageClientImplMac.h -index bf8da430d8a48128879eb2033ceb1a4e6aae3fd3..8c048aa6055aa2ec7e74d96f99dbd58594cb01fc 100644 +index 1647891b55a718f66ee2f4a084439edd655c623a..2099b9166e2cac062d4161d704050a0795a26c93 100644 --- a/Source/WebKit/UIProcess/mac/PageClientImplMac.h +++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.h @@ -54,6 +54,8 @@ class PageClientImpl final : public PageClientImplCocoa @@ -18787,7 +18763,7 @@ index bf8da430d8a48128879eb2033ceb1a4e6aae3fd3..8c048aa6055aa2ec7e74d96f99dbd585 void navigationGestureWillEnd(bool willNavigate, WebBackForwardListItem&) override; void navigationGestureDidEnd(bool willNavigate, WebBackForwardListItem&) override; diff --git a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm -index 0150ec4512cb5a8d405c045f6b6464b374849d04..8ff52a96708296f4933b5f43a106396c4943adb0 100644 +index 3fe2a9487a96b31f476bb17e45374f880e80da9a..b72433e5981f298d4d1ca93274df51cd830855c0 100644 --- a/Source/WebKit/UIProcess/mac/PageClientImplMac.mm +++ b/Source/WebKit/UIProcess/mac/PageClientImplMac.mm @@ -80,6 +80,7 @@ @@ -18938,7 +18914,7 @@ index 6ab7aacaebfda818e3010bb06db72c8552ac598a..3e19cba50d73084392f62f176ad4c315 bool showAfterPostProcessingContextData(); diff --git a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm -index 5edd66a5259b64217d338ac041c8dd0dafafed9b..c786a8205ddd8f9e40c1da3d2c4a67732d2d2499 100644 +index 6da27ca16f9f4d359118053049caa5033b6789d7..254e582066fbc774fc02c69dddbc1ae589efdc7a 100644 --- a/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm +++ b/Source/WebKit/UIProcess/mac/WebContextMenuProxyMac.mm @@ -481,6 +481,12 @@ void WebContextMenuProxyMac::getShareMenuItem(CompletionHandlersizeInBytes(); - auto stride = bitmap->bytesPerRow(); - GRefPtr bytes = adoptGRef(g_bytes_new_with_free_func(data, dataSize, [](gpointer userData) { -- delete static_cast(userData); -+ delete static_cast(userData); - }, bitmap.leakRef())); - - GRefPtr buffer = adoptGRef(WPE_BUFFER(wpe_buffer_shm_new(m_wpeView.get(), size.width(), size.height(), WPE_PIXEL_FORMAT_ARGB8888, bytes.get(), stride))); diff --git a/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/InspectorTargetProxyWPE.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7453194ca6f032ba86a4c67f5bf12688ab6ec1be @@ -19974,7 +19925,7 @@ index 0000000000000000000000000000000000000000..a7d88f8c745f95af21db71dcfce368ba + +} // namespace WebKit diff --git a/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp b/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp -index 057b6c7a43cbde35cfaac266dfc9fce5bc3c6a31..1605888e79ccb9416719eff486d8151a6845fe98 100644 +index b6536b74452c26a4d661bcf6039af54824f258d0..ade7c4ad1cef7bc69c452bef404eb38437c93088 100644 --- a/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp +++ b/Source/WebKit/UIProcess/wpe/WebPageProxyWPE.cpp @@ -29,6 +29,7 @@ @@ -19983,10 +19934,10 @@ index 057b6c7a43cbde35cfaac266dfc9fce5bc3c6a31..1605888e79ccb9416719eff486d8151a #include "PageClientImpl.h" +#include #include - #include + #if USE(ATK) diff --git a/Source/WebKit/WPEPlatform/CMakeLists.txt b/Source/WebKit/WPEPlatform/CMakeLists.txt -index 4dc0d0990d9ab5f89efa44bd404b95264c2bbfa8..0cb39461386cfe0e34bcf33cc07bcb03e3826a05 100644 +index 9319cacf6dff2c3ffdd469927c91a880978a80aa..17a829b23ae6941b184d32e8701f0fd774639449 100644 --- a/Source/WebKit/WPEPlatform/CMakeLists.txt +++ b/Source/WebKit/WPEPlatform/CMakeLists.txt @@ -82,6 +82,7 @@ set(WPEPlatform_SYSTEM_INCLUDE_DIRECTORIES @@ -19998,10 +19949,10 @@ index 4dc0d0990d9ab5f89efa44bd404b95264c2bbfa8..0cb39461386cfe0e34bcf33cc07bcb03 ${GLIB_GIO_LIBRARIES} ${GLIB_GOBJECT_LIBRARIES} diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj -index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51337a21b8 100644 +index 5638e7e7ca660b2bb7c9b3f21dde5f5dfb68dad0..d4c7e4081d7b4c80423e2a406f8471c3ffb292f7 100644 --- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj +++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj -@@ -1535,6 +1535,7 @@ +@@ -1542,6 +1542,7 @@ 5CABDC8722C40FED001EDE8E /* APIMessageListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CABDC8322C40FA7001EDE8E /* APIMessageListener.h */; }; 5CADDE05215046BD0067D309 /* WKWebProcess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C74300E21500492004BFA17 /* WKWebProcess.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5CAECB6627465AE400AB78D0 /* UnifiedSource115.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */; }; @@ -20009,7 +19960,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5CAF7AA726F93AB00003F19E /* adattributiond.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5CAF7AA526F93A950003F19E /* adattributiond.cpp */; }; 5CAFDE452130846300B1F7E1 /* _WKInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE422130843500B1F7E1 /* _WKInspector.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5CAFDE472130846A00B1F7E1 /* _WKInspectorInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CAFDE442130843600B1F7E1 /* _WKInspectorInternal.h */; }; -@@ -2369,6 +2370,18 @@ +@@ -2381,6 +2382,18 @@ DF0C5F28252ECB8E00D921DB /* WKDownload.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F24252ECB8D00D921DB /* WKDownload.h */; settings = {ATTRIBUTES = (Public, ); }; }; DF0C5F2A252ECB8E00D921DB /* WKDownloadDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; DF0C5F2B252ED44000D921DB /* WKDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */; }; @@ -20028,7 +19979,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 DF462E0F23F22F5500EFF35F /* WKHTTPCookieStorePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; DF462E1223F338BE00EFF35F /* WKContentWorldPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; DF7A231C291B088D00B98DF3 /* WKSnapshotConfigurationPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DF7A231B291B088D00B98DF3 /* WKSnapshotConfigurationPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; -@@ -2453,6 +2466,8 @@ +@@ -2468,6 +2481,8 @@ E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; }; E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; }; E5CBA76427A318E100DF7858 /* UnifiedSource120.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA75F27A3187800DF7858 /* UnifiedSource120.cpp */; }; @@ -20037,7 +19988,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 E5CBA76527A318E100DF7858 /* UnifiedSource118.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */; }; E5CBA76627A318E100DF7858 /* UnifiedSource116.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */; }; E5CBA76727A318E100DF7858 /* UnifiedSource119.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CBA76027A3187900DF7858 /* UnifiedSource119.cpp */; }; -@@ -2473,6 +2488,9 @@ +@@ -2488,6 +2503,9 @@ EBA8D3B627A5E33F00CB7900 /* MockPushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B027A5E33F00CB7900 /* MockPushServiceConnection.mm */; }; EBA8D3B727A5E33F00CB7900 /* PushServiceConnection.mm in Sources */ = {isa = PBXBuildFile; fileRef = EBA8D3B127A5E33F00CB7900 /* PushServiceConnection.mm */; }; ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -20047,7 +19998,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; }; F40C3B712AB401C5007A3567 /* WKDatePickerPopoverController.h in Headers */ = {isa = PBXBuildFile; fileRef = F40C3B6F2AB40167007A3567 /* WKDatePickerPopoverController.h */; }; F41795A62AC61B78007F5F12 /* CompactContextMenuPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = F41795A42AC619A2007F5F12 /* CompactContextMenuPresenter.h */; }; -@@ -6192,6 +6210,7 @@ +@@ -6218,6 +6236,7 @@ 5CABDC8522C40FCC001EDE8E /* WKMessageListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKMessageListener.h; sourceTree = ""; }; 5CABE07A28F60E8A00D83FD9 /* WebPushMessage.serialization.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebPushMessage.serialization.in; sourceTree = ""; }; 5CADDE0D2151AA010067D309 /* AuthenticationChallengeDisposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthenticationChallengeDisposition.h; sourceTree = ""; }; @@ -20055,7 +20006,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5CAECB5E27465AE300AB78D0 /* UnifiedSource115.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource115.cpp; sourceTree = ""; }; 5CAF7AA426F93A750003F19E /* adattributiond */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = adattributiond; sourceTree = BUILT_PRODUCTS_DIR; }; 5CAF7AA526F93A950003F19E /* adattributiond.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = adattributiond.cpp; sourceTree = ""; }; -@@ -7894,6 +7913,19 @@ +@@ -7930,6 +7949,19 @@ DF0C5F24252ECB8D00D921DB /* WKDownload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownload.h; sourceTree = ""; }; DF0C5F25252ECB8E00D921DB /* WKDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadInternal.h; sourceTree = ""; }; DF0C5F26252ECB8E00D921DB /* WKDownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDownloadDelegate.h; sourceTree = ""; }; @@ -20075,7 +20026,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 DF462E0E23F22F5300EFF35F /* WKHTTPCookieStorePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKHTTPCookieStorePrivate.h; sourceTree = ""; }; DF462E1123F338AD00EFF35F /* WKContentWorldPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKContentWorldPrivate.h; sourceTree = ""; }; DF58C6311371AC5800F9A37C /* NativeWebWheelEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeWebWheelEvent.h; sourceTree = ""; }; -@@ -8040,6 +8072,8 @@ +@@ -8082,6 +8114,8 @@ E5CBA76127A3187900DF7858 /* UnifiedSource118.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource118.cpp; sourceTree = ""; }; E5CBA76227A3187900DF7858 /* UnifiedSource117.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource117.cpp; sourceTree = ""; }; E5CBA76327A3187B00DF7858 /* UnifiedSource116.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnifiedSource116.cpp; sourceTree = ""; }; @@ -20084,7 +20035,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 E5DEFA6726F8F42600AB68DB /* PhotosUISPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PhotosUISPI.h; sourceTree = ""; }; EB0D312D275AE13300863D8F /* com.apple.webkit.webpushd.mac.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.mac.plist; sourceTree = ""; }; EB0D312E275AE13300863D8F /* com.apple.webkit.webpushd.ios.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.webkit.webpushd.ios.plist; sourceTree = ""; }; -@@ -8064,6 +8098,14 @@ +@@ -8106,6 +8140,14 @@ ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = ""; }; ECBFC1DB1E6A4D66000300C7 /* ExtraPublicSymbolsForTAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtraPublicSymbolsForTAPI.h; sourceTree = ""; }; F036978715F4BF0500C3A80E /* WebColorPicker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebColorPicker.cpp; sourceTree = ""; }; @@ -20099,7 +20050,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDragDestinationAction.h; sourceTree = ""; }; F40C3B6F2AB40167007A3567 /* WKDatePickerPopoverController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKDatePickerPopoverController.h; path = ios/forms/WKDatePickerPopoverController.h; sourceTree = ""; }; F40C3B702AB40167007A3567 /* WKDatePickerPopoverController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKDatePickerPopoverController.mm; path = ios/forms/WKDatePickerPopoverController.mm; sourceTree = ""; }; -@@ -8351,6 +8393,7 @@ +@@ -8404,6 +8446,7 @@ 3766F9EE189A1241003CF19B /* JavaScriptCore.framework in Frameworks */, 3766F9F1189A1254003CF19B /* libicucore.dylib in Frameworks */, 7B9FC5BB28A5233B007570E7 /* libWebKitPlatform.a in Frameworks */, @@ -20107,7 +20058,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 3766F9EF189A1244003CF19B /* QuartzCore.framework in Frameworks */, 37694525184FC6B600CDE21F /* Security.framework in Frameworks */, 37BEC4DD1948FC6A008B4286 /* WebCore.framework in Frameworks */, -@@ -11211,6 +11254,7 @@ +@@ -11278,6 +11321,7 @@ 99788ACA1F421DCA00C08000 /* _WKAutomationSessionConfiguration.mm */, 990D28A81C6404B000986977 /* _WKAutomationSessionDelegate.h */, 990D28AF1C65203900986977 /* _WKAutomationSessionInternal.h */, @@ -20115,7 +20066,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5C4609E222430E4C009943C2 /* _WKContentRuleListAction.h */, 5C4609E322430E4D009943C2 /* _WKContentRuleListAction.mm */, 5C4609E422430E4D009943C2 /* _WKContentRuleListActionInternal.h */, -@@ -12503,6 +12547,7 @@ +@@ -12589,6 +12633,7 @@ E34B110C27C46BC6006D2F2E /* libWebCoreTestShim.dylib */, E34B110F27C46D09006D2F2E /* libWebCoreTestSupport.dylib */, DDE992F4278D06D900F60D26 /* libWebKitAdditions.a */, @@ -20123,7 +20074,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 57A9FF15252C6AEF006A2040 /* libWTF.a */, 5750F32A2032D4E500389347 /* LocalAuthentication.framework */, 570DAAB0230273D200E8FC04 /* NearField.framework */, -@@ -13073,6 +13118,12 @@ +@@ -13159,6 +13204,12 @@ children = ( 9197940423DBC4BB00257892 /* InspectorBrowserAgent.cpp */, 9197940323DBC4BB00257892 /* InspectorBrowserAgent.h */, @@ -20136,7 +20087,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 ); path = Agents; sourceTree = ""; -@@ -13081,6 +13132,7 @@ +@@ -13167,6 +13218,7 @@ isa = PBXGroup; children = ( A5D3504D1D78F0D2005124A9 /* RemoteWebInspectorUIProxyMac.mm */, @@ -20144,7 +20095,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 1CA8B935127C774E00576C2B /* WebInspectorUIProxyMac.mm */, 99A7ACE326012919006D57FD /* WKInspectorResourceURLSchemeHandler.h */, 99A7ACE42601291A006D57FD /* WKInspectorResourceURLSchemeHandler.mm */, -@@ -13794,6 +13846,7 @@ +@@ -13884,6 +13936,7 @@ E1513C65166EABB200149FCB /* AuxiliaryProcessProxy.h */, 46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */, 46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */, @@ -20152,7 +20103,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5C6D69352AC3935D0099BDAF /* BrowsingContextGroup.cpp */, 5C6D69362AC3935D0099BDAF /* BrowsingContextGroup.h */, 07297F9C1C1711EA003F0735 /* DeviceIdHashSaltStorage.cpp */, -@@ -13817,6 +13870,8 @@ +@@ -13907,6 +13960,8 @@ BC06F43912DBCCFB002D78DE /* GeolocationPermissionRequestProxy.cpp */, BC06F43812DBCCFB002D78DE /* GeolocationPermissionRequestProxy.h */, 2DD5A72A1EBF09A7009BA597 /* HiddenPageThrottlingAutoIncreasesCounter.h */, @@ -20161,7 +20112,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5CEABA2B2333251400797797 /* LegacyGlobalSettings.cpp */, 5CEABA2A2333247700797797 /* LegacyGlobalSettings.h */, 31607F3819627002009B87DA /* LegacySessionStateCoding.h */, -@@ -13850,6 +13905,7 @@ +@@ -13940,6 +13995,7 @@ 1A0C227D2451130A00ED614D /* QuickLookThumbnailingSoftLink.mm */, 1AEE57232409F142002005D6 /* QuickLookThumbnailLoader.h */, 1AEE57242409F142002005D6 /* QuickLookThumbnailLoader.mm */, @@ -20169,7 +20120,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5CCB54DC2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.cpp */, 5CCB54DB2A4FEA6A0005FAA8 /* RemotePageDrawingAreaProxy.h */, 5C907E9A294D507100B3402D /* RemotePageProxy.cpp */, -@@ -13955,6 +14011,8 @@ +@@ -14045,6 +14101,8 @@ BC7B6204129A0A6700D174A4 /* WebPageGroup.h */, 2D9EA3101A96D9EB002D2807 /* WebPageInjectedBundleClient.cpp */, 2D9EA30E1A96CBFF002D2807 /* WebPageInjectedBundleClient.h */, @@ -20178,7 +20129,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 BC111B0B112F5E4F00337BAB /* WebPageProxy.cpp */, BC032DCB10F4389F0058C15A /* WebPageProxy.h */, BCBD38FA125BAB9A00D2C29F /* WebPageProxy.messages.in */, -@@ -14117,6 +14175,7 @@ +@@ -14209,6 +14267,7 @@ BC646C1911DD399F006455B0 /* WKBackForwardListItemRef.h */, BC646C1611DD399F006455B0 /* WKBackForwardListRef.cpp */, BC646C1711DD399F006455B0 /* WKBackForwardListRef.h */, @@ -20186,7 +20137,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 BCB9E24A1120E15C00A137E0 /* WKContext.cpp */, BCB9E2491120E15C00A137E0 /* WKContext.h */, 1AE52F9319201F6B00A1FA37 /* WKContextConfigurationRef.cpp */, -@@ -14700,6 +14759,9 @@ +@@ -14792,6 +14851,9 @@ 7AFA6F682A9F57C50055322A /* DisplayLinkMac.cpp */, 31ABA79C215AF9E000C90E31 /* HighPerformanceGPUManager.h */, 31ABA79D215AF9E000C90E31 /* HighPerformanceGPUManager.mm */, @@ -20196,7 +20147,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 1AFDE65B1954E8D500C48FFA /* LegacySessionStateCoding.cpp */, 0FCB4E5818BBE3D9000FCFC9 /* PageClientImplMac.h */, 0FCB4E5918BBE3D9000FCFC9 /* PageClientImplMac.mm */, -@@ -14723,6 +14785,8 @@ +@@ -14815,6 +14877,8 @@ E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */, E55CD20124D09F1F0042DB9C /* WebDateTimePickerMac.h */, E55CD20224D09F1F0042DB9C /* WebDateTimePickerMac.mm */, @@ -20205,7 +20156,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 BC857E8512B71EBB00EDEB2E /* WebPageProxyMac.mm */, BC5750951268F3C6006F0F12 /* WebPopupMenuProxyMac.h */, BC5750961268F3C6006F0F12 /* WebPopupMenuProxyMac.mm */, -@@ -15726,6 +15790,7 @@ +@@ -15820,6 +15884,7 @@ 99788ACB1F421DDA00C08000 /* _WKAutomationSessionConfiguration.h in Headers */, 990D28AC1C6420CF00986977 /* _WKAutomationSessionDelegate.h in Headers */, 990D28B11C65208D00986977 /* _WKAutomationSessionInternal.h in Headers */, @@ -20213,7 +20164,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 5C4609E7224317B4009943C2 /* _WKContentRuleListAction.h in Headers */, 5C4609E8224317BB009943C2 /* _WKContentRuleListActionInternal.h in Headers */, 1A5704F81BE01FF400874AF1 /* _WKContextMenuElementInfo.h in Headers */, -@@ -16029,6 +16094,7 @@ +@@ -16129,6 +16194,7 @@ E170876C16D6CA6900F99226 /* BlobRegistryProxy.h in Headers */, 4F601432155C5AA2001FBDE0 /* BlockingResponseMap.h in Headers */, 1A5705111BE410E600874AF1 /* BlockSPI.h in Headers */, @@ -20221,7 +20172,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 A7E69BCC2B2117A100D43D3F /* BufferAndBackendInfo.h in Headers */, BC3065FA1259344E00E71278 /* CacheModel.h in Headers */, 935BF7FC2936BF1A00B41326 /* CacheStorageCache.h in Headers */, -@@ -16208,7 +16274,11 @@ +@@ -16309,7 +16375,11 @@ BC14DF77120B5B7900826C0C /* InjectedBundleScriptWorld.h in Headers */, CE550E152283752200D28791 /* InsertTextOptions.h in Headers */, 9197940523DBC4BB00257892 /* InspectorBrowserAgent.h in Headers */, @@ -20233,7 +20184,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 A5E391FD2183C1F800C8FB31 /* InspectorTargetProxy.h in Headers */, C5BCE5DF1C50766A00CDE3FA /* InteractionInformationAtPosition.h in Headers */, 2D4D2C811DF60BF3002EB10C /* InteractionInformationRequest.h in Headers */, -@@ -16464,6 +16534,7 @@ +@@ -16567,6 +16637,7 @@ CDAC20C923FC2F750021DEE3 /* RemoteCDMInstanceSessionIdentifier.h in Headers */, F451C0FE2703B263002BA03B /* RemoteDisplayListRecorderProxy.h in Headers */, A78A5FE42B0EB39E005036D3 /* RemoteImageBufferSetIdentifier.h in Headers */, @@ -20241,7 +20192,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 2D47B56D1810714E003A3AEE /* RemoteLayerBackingStore.h in Headers */, 2DDF731518E95060004F5A66 /* RemoteLayerBackingStoreCollection.h in Headers */, 1AB16AEA164B3A8800290D62 /* RemoteLayerTreeContext.h in Headers */, -@@ -16519,6 +16590,7 @@ +@@ -16622,6 +16693,7 @@ E1E552C516AE065F004ED653 /* SandboxInitializationParameters.h in Headers */, E36FF00327F36FBD004BE21A /* SandboxStateVariables.h in Headers */, 7BAB111025DD02B3008FC479 /* ScopedActiveMessageReceiveQueue.h in Headers */, @@ -20249,7 +20200,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 463BB93A2B9D08D80098C5C3 /* ScriptMessageHandlerIdentifier.h in Headers */, E4D54D0421F1D72D007E3C36 /* ScrollingTreeFrameScrollingNodeRemoteIOS.h in Headers */, 0F931C1C18C5711900DBA7C3 /* ScrollingTreeOverflowScrollingNodeIOS.h in Headers */, -@@ -16868,6 +16940,8 @@ +@@ -16972,6 +17044,8 @@ 939EF87029D112EE00F23AEE /* WebPageInlines.h in Headers */, 9197940823DBC4CB00257892 /* WebPageInspectorAgentBase.h in Headers */, A513F5402154A5D700662841 /* WebPageInspectorController.h in Headers */, @@ -20258,7 +20209,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 A543E30C215C8A8D00279CD9 /* WebPageInspectorTarget.h in Headers */, A543E30D215C8A9000279CD9 /* WebPageInspectorTargetController.h in Headers */, A543E307215AD13700279CD9 /* WebPageInspectorTargetFrontendChannel.h in Headers */, -@@ -19161,6 +19235,8 @@ +@@ -19367,6 +19441,8 @@ 522F792928D50EBB0069B45B /* HidService.mm in Sources */, 2749F6442146561B008380BF /* InjectedBundleNodeHandle.cpp in Sources */, 2749F6452146561E008380BF /* InjectedBundleRangeHandle.cpp in Sources */, @@ -20267,7 +20218,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 1CC94E532AC92F190045F269 /* JSWebExtensionAPIAction.mm in Sources */, 1C2B4D4B2A819D0D00C528A1 /* JSWebExtensionAPIAlarms.mm in Sources */, 1C8ECFEA2AFC7DCB007BAA62 /* JSWebExtensionAPICommands.mm in Sources */, -@@ -19600,6 +19676,8 @@ +@@ -19807,6 +19883,8 @@ E3816B3D27E2463A005EAFC0 /* WebMockContentFilterManager.cpp in Sources */, 31BA924D148831260062EDB5 /* WebNotificationManagerMessageReceiver.cpp in Sources */, 2DF6FE52212E110900469030 /* WebPage.cpp in Sources */, @@ -20277,7 +20228,7 @@ index 399ee15035d02439fd905dcfef995b15c367cbc0..3119ffb671cb9518ec080b3b78a08f51 BCBD3914125BB1A800D2C29F /* WebPageProxyMessageReceiver.cpp in Sources */, 7CE9CE101FA0767A000177DE /* WebPageUpdatePreferences.cpp in Sources */, diff --git a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp -index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35995a4b59 100644 +index 0ab7a191b4d1b35579666f381f87d8a3995e3501..bfd50e5c4f82ad02d9a96afb9a297450257bd2fb 100644 --- a/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp +++ b/Source/WebKit/WebProcess/Network/WebLoaderStrategy.cpp @@ -229,6 +229,11 @@ void WebLoaderStrategy::scheduleLoad(ResourceLoader& resourceLoader, CachedResou @@ -20337,7 +20288,7 @@ index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35 loadParameters.isMainFrameNavigation = isMainFrameNavigation; if (loadParameters.isMainFrameNavigation && document) -@@ -525,12 +527,24 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL +@@ -525,6 +527,17 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL } ASSERT((loadParameters.webPageID && loadParameters.webFrameID) || loadParameters.clientCredentialPolicy == ClientCredentialPolicy::CannotAskClientForCredentials); @@ -20355,14 +20306,7 @@ index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35 std::optional existingNetworkResourceLoadIdentifierToResume; if (loadParameters.isMainFrameNavigation) - existingNetworkResourceLoadIdentifierToResume = std::exchange(m_existingNetworkResourceLoadIdentifierToResume, std::nullopt); - WEBLOADERSTRATEGY_RELEASE_LOG("scheduleLoad: Resource is being scheduled with the NetworkProcess (priority=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64 ")", static_cast(resourceLoader.request().priority()), valueOrDefault(existingNetworkResourceLoadIdentifierToResume).toUInt64()); - -+ auto* frame = resourceLoader.frame(); - if (frame && !frame->settings().siteIsolationEnabled() && !WebProcess::singleton().allowsFirstPartyForCookies(loadParameters.request.firstPartyForCookies())) - RELEASE_LOG_FAULT(IPC, "scheduleLoad: Process will terminate due to failed allowsFirstPartyForCookies check"); - -@@ -543,7 +557,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL +@@ -540,7 +553,7 @@ void WebLoaderStrategy::scheduleLoadFromNetworkProcess(ResourceLoader& resourceL } auto loader = WebResourceLoader::create(resourceLoader, trackingParameters); @@ -20371,7 +20315,7 @@ index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35 } void WebLoaderStrategy::scheduleInternallyFailedLoad(WebCore::ResourceLoader& resourceLoader) -@@ -953,7 +967,7 @@ void WebLoaderStrategy::didFinishPreconnection(WebCore::ResourceLoaderIdentifier +@@ -950,7 +963,7 @@ void WebLoaderStrategy::didFinishPreconnection(WebCore::ResourceLoaderIdentifier bool WebLoaderStrategy::isOnLine() const { @@ -20380,7 +20324,7 @@ index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35 } void WebLoaderStrategy::addOnlineStateChangeListener(Function&& listener) -@@ -980,6 +994,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet +@@ -977,6 +990,11 @@ void WebLoaderStrategy::isResourceLoadFinished(CachedResource& resource, Complet void WebLoaderStrategy::setOnLineState(bool isOnLine) { @@ -20392,7 +20336,7 @@ index 610dc831f72e672abd8ebd1ad9dfdf77ca94a727..e297bd173390d9ae50fded54d3ff9b35 if (m_isOnLine == isOnLine) return; -@@ -988,6 +1007,12 @@ void WebLoaderStrategy::setOnLineState(bool isOnLine) +@@ -985,6 +1003,12 @@ void WebLoaderStrategy::setOnLineState(bool isOnLine) listener(isOnLine); } @@ -20436,10 +20380,10 @@ index 3ef86cc236b8acee2fbe5d0b9c3fd755fcc9f06f..75951fc0fc5e4ef566582c0a49482793 } // namespace WebKit diff --git a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp -index e9bd84cf730f46d9e18a4f39e7050f7cc7343b5f..9998a2e3647373429ed1af6d97b5cd3e5ff59fe2 100644 +index ee6ed68f57ac7205087c7f0abe59fb56ee0fa012..9d81ae6dff0ab154a0665d6430be58affae6d820 100644 --- a/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp +++ b/Source/WebKit/WebProcess/Network/WebResourceLoader.cpp -@@ -200,9 +200,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR +@@ -189,9 +189,6 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR } m_coreLoader->didReceiveResponse(inspectorResponse, [this, protectedThis = WTFMove(protectedThis), interceptedRequestIdentifier, policyDecisionCompletionHandler = WTFMove(policyDecisionCompletionHandler), overrideData = WTFMove(overrideData)]() mutable { @@ -20449,7 +20393,7 @@ index e9bd84cf730f46d9e18a4f39e7050f7cc7343b5f..9998a2e3647373429ed1af6d97b5cd3e if (!m_coreLoader || !m_coreLoader->identifier()) { m_interceptController.continueResponse(interceptedRequestIdentifier); return; -@@ -220,6 +217,8 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR +@@ -209,6 +206,8 @@ void WebResourceLoader::didReceiveResponse(ResourceResponse&& response, PrivateR } }); }); @@ -20472,7 +20416,7 @@ index ee9c3c4f48c328daaa015e2122235e51349bd999..5b3a4d3e742147195e0ff9e88176759d auto permissionHandlers = m_requestsPerOrigin.take(securityOrigin); diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp -index 14a6547ae278cd186805daf5f812d1070582aaf1..83a809d9a2ff7987ce8ecb4f2aed7f27009bf4d6 100644 +index 3fa53c3e4977dcc0b83d48091490c2261ed785e0..bef114c5988a88eaca305287471c55515fc22ff6 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp @@ -468,6 +468,8 @@ void WebChromeClient::addMessageToConsole(MessageSource source, MessageLevel lev @@ -20512,13 +20456,13 @@ index 2eb0886f13ed035a53b8eaa60605de4dfe53fbe3..0f6a539f00a42149c0f2b2237a9cbdd8 { } diff --git a/Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.cpp b/Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.cpp -index 991213d7cb5c4790f563a8c09add8413a7f48b3c..275629aaff71d44397b58685b4c9ff0baf759f09 100644 +index 7b9b0348c1a3b606ad31b3fe2df3eedcb64cf233..97a6a56cc8427bd3eadfacc8fd5c4f15d5bfcdf7 100644 --- a/Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.cpp +++ b/Source/WebKit/WebProcess/WebCoreSupport/WebLocalFrameLoaderClient.cpp -@@ -1588,14 +1588,6 @@ void WebLocalFrameLoaderClient::transitionToCommittedForNewPage() +@@ -1592,14 +1592,6 @@ void WebLocalFrameLoaderClient::transitionToCommittedForNewPage(InitializingIfra - if (webPage->scrollPinningBehavior() != ScrollPinningBehavior::DoNotPin) - view->setScrollPinningBehavior(webPage->scrollPinningBehavior()); + if (initializingIframe == InitializingIframe::No) + webPage->scheduleFullEditorStateUpdate(); - -#if USE(COORDINATED_GRAPHICS) - if (shouldUseFixedLayout) { @@ -20725,10 +20669,10 @@ index 6780fb04b94241977df3396ffb77585f10faf035..db015c88e2b3413c9fde348779b62c90 void DrawingAreaCoordinatedGraphics::scheduleDisplay() diff --git a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp -index 33fe769ad9c94388e4038e5848b4c50087bf9cd3..9cff157e96cd005a43e9c64dcd83ddc35d5c1518 100644 +index d453fc33b2a366e4944b48c47bbe056d508124e7..4b58d67c55ebcde8598a1045cbc99202bf6f8feb 100644 --- a/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp +++ b/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/LayerTreeHost.cpp -@@ -194,8 +194,16 @@ void LayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer) +@@ -193,8 +193,16 @@ void LayerTreeHost::setViewOverlayRootLayer(GraphicsLayer* viewOverlayRootLayer) void LayerTreeHost::scrollNonCompositedContents(const IntRect& rect) { auto* frameView = m_webPage.localMainFrameView(); @@ -20745,7 +20689,7 @@ index 33fe769ad9c94388e4038e5848b4c50087bf9cd3..9cff157e96cd005a43e9c64dcd83ddc3 m_viewportController.didScroll(rect.location()); didChangeViewport(); -@@ -274,6 +282,7 @@ GraphicsLayerFactory* LayerTreeHost::graphicsLayerFactory() +@@ -273,6 +281,7 @@ GraphicsLayerFactory* LayerTreeHost::graphicsLayerFactory() void LayerTreeHost::contentsSizeChanged(const IntSize& newSize) { m_viewportController.didChangeContentsSize(newSize); @@ -20753,7 +20697,7 @@ index 33fe769ad9c94388e4038e5848b4c50087bf9cd3..9cff157e96cd005a43e9c64dcd83ddc3 } void LayerTreeHost::didChangeViewportAttributes(ViewportAttributes&& attr) -@@ -313,6 +322,10 @@ void LayerTreeHost::didChangeViewport() +@@ -312,6 +321,10 @@ void LayerTreeHost::didChangeViewport() if (!view->useFixedLayout()) view->notifyScrollPositionChanged(m_lastScrollPosition); @@ -20861,10 +20805,10 @@ index b6e5283f51db82b60091320df44ef0bbf20c33c6..0d82fbb98b93e760cecf5fa7a41327d0 WebCookieJar(); diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp -index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c20996a5049e 100644 +index 36ca16c66c74db2f7d4b2a4938e7714b5ef49ca1..821029c298841fc1408f80579d43ec7c8d54faad 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp +++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp -@@ -1024,6 +1024,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters) +@@ -1034,6 +1034,9 @@ WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters) #endif #endif // HAVE(SANDBOX_STATE_FLAGS) @@ -20874,7 +20818,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 updateThrottleState(); #if ENABLE(ACCESSIBILITY_ANIMATION_CONTROL) updateImageAnimationEnabled(); -@@ -1991,6 +1994,22 @@ void WebPage::transitionFrameToLocal(LocalFrameCreationParameters&& creationPara +@@ -2007,6 +2010,22 @@ void WebPage::transitionFrameToLocal(LocalFrameCreationParameters&& creationPara frame->transitionToLocal(creationParameters.layerHostingContextIdentifier); } @@ -20897,7 +20841,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 void WebPage::loadRequest(LoadParameters&& loadParameters) { WEBPAGE_RELEASE_LOG(Loading, "loadRequest: navigationID=%" PRIu64 ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64, loadParameters.navigationID, static_cast(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), valueOrDefault(loadParameters.existingNetworkResourceLoadIdentifierToResume).toUInt64()); -@@ -2270,17 +2289,14 @@ void WebPage::setSize(const WebCore::IntSize& viewSize) +@@ -2283,17 +2302,14 @@ void WebPage::setSize(const WebCore::IntSize& viewSize) view->resize(viewSize); m_drawingArea->setNeedsDisplay(); @@ -20915,7 +20859,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments) { RefPtr localMainFrame = dynamicDowncast(m_page->mainFrame()); -@@ -2305,20 +2321,18 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg +@@ -2318,20 +2334,18 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize); @@ -20943,7 +20887,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 #if USE(COORDINATED_GRAPHICS) m_drawingArea->didChangeViewportAttributes(WTFMove(attr)); -@@ -2326,7 +2340,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg +@@ -2339,7 +2353,6 @@ void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArg send(Messages::WebPageProxy::DidChangeViewportProperties(attr)); #endif } @@ -20951,7 +20895,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset) { -@@ -2619,6 +2632,7 @@ void WebPage::scaleView(double scale) +@@ -2640,6 +2653,7 @@ void WebPage::scaleView(double scale) } m_page->setViewScaleFactor(scale); @@ -20959,7 +20903,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 scalePage(pageScale, scrollPositionAtNewScale); } -@@ -2798,18 +2812,14 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum +@@ -2819,18 +2833,14 @@ void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArgum viewportConfigurationChanged(); #endif @@ -20979,7 +20923,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 } #if !PLATFORM(IOS_FAMILY) -@@ -3809,6 +3819,97 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent, CompletionHandlersendMessageToTargetBackend(targetId, message); } @@ -21089,7 +21033,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 void WebPage::insertNewlineInQuotedContent() { RefPtr frame = m_page->checkedFocusController()->focusedOrMainFrame(); -@@ -4129,6 +4235,7 @@ void WebPage::didCompletePageTransition() +@@ -4150,6 +4256,7 @@ void WebPage::didCompletePageTransition() void WebPage::show() { send(Messages::WebPageProxy::ShowPage()); @@ -21097,7 +21041,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 } void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension) -@@ -5224,7 +5331,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana +@@ -5249,7 +5356,7 @@ NotificationPermissionRequestManager* WebPage::notificationPermissionRequestMana #if ENABLE(DRAG_SUPPORT) @@ -21106,7 +21050,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet draggingSourceOperationMask, SelectionData&& selectionData, OptionSet flags, CompletionHandler, DragHandlingMethod, bool, unsigned, IntRect, IntRect, std::optional)>&& completionHandler) { if (!m_page) -@@ -7552,6 +7659,10 @@ void WebPage::didCommitLoad(WebFrame* frame) +@@ -7586,6 +7693,10 @@ void WebPage::didCommitLoad(WebFrame* frame) #endif flushDeferredDidReceiveMouseEvent(); @@ -21117,7 +21061,7 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 } void WebPage::didFinishDocumentLoad(WebFrame& frame) -@@ -7792,6 +7903,9 @@ Ref WebPage::createDocumentLoader(LocalFrame& frame, const Resou +@@ -7850,6 +7961,9 @@ Ref WebPage::createDocumentLoader(LocalFrame& frame, const Resou WebsitePoliciesData::applyToDocumentLoader(WTFMove(*m_pendingWebsitePolicies), documentLoader); m_pendingWebsitePolicies = std::nullopt; } @@ -21128,18 +21072,18 @@ index da971ba778c6e8c0397c255b60a33c76d4124056..ebfb82b8ec31cb78a9f13b6da929c209 return documentLoader; diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.h b/Source/WebKit/WebProcess/WebPage/WebPage.h -index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e2261b5b7 100644 +index a8d232fda1bf1dc7a9b3e866b3cbfb2952b26eef..b048960902cdd660209be177b4ecbe7719c74f8d 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.h +++ b/Source/WebKit/WebProcess/WebPage/WebPage.h -@@ -69,6 +69,7 @@ - #include +@@ -70,6 +70,7 @@ #include #include + #include +#include #include #include #include -@@ -110,6 +111,10 @@ +@@ -112,6 +113,10 @@ #include "WebPrintOperationGtk.h" #endif @@ -21150,7 +21094,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e #if PLATFORM(GTK) || PLATFORM(WPE) #include "InputMethodState.h" #endif -@@ -1135,11 +1140,11 @@ public: +@@ -1145,11 +1150,11 @@ public: void clearSelection(); void restoreSelectionInFocusedEditableElement(); @@ -21164,7 +21108,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e void performDragControllerAction(std::optional, DragControllerAction, WebCore::DragData&&, CompletionHandler, WebCore::DragHandlingMethod, bool, unsigned, WebCore::IntRect, WebCore::IntRect, std::optional)>&&); void performDragOperation(WebCore::DragData&&, SandboxExtension::Handle&&, Vector&&, CompletionHandler&&); #endif -@@ -1154,6 +1159,9 @@ public: +@@ -1164,6 +1169,9 @@ public: void didStartDrag(); void dragCancelled(); OptionSet allowedDragSourceActions() const { return m_allowedDragSourceActions; } @@ -21174,7 +21118,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e #endif void beginPrinting(WebCore::FrameIdentifier, const PrintInfo&); -@@ -1377,6 +1385,7 @@ public: +@@ -1387,6 +1395,7 @@ public: void connectInspector(const String& targetId, Inspector::FrontendChannel::ConnectionType); void disconnectInspector(const String& targetId); void sendMessageToTargetBackend(const String& targetId, const String& message); @@ -21182,7 +21126,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e void insertNewlineInQuotedContent(); -@@ -1834,6 +1843,7 @@ private: +@@ -1863,6 +1872,7 @@ private: void tryClose(CompletionHandler&&); void platformDidReceiveLoadParameters(const LoadParameters&); void transitionFrameToLocal(LocalFrameCreationParameters&&, WebCore::FrameIdentifier); @@ -21190,7 +21134,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e void loadRequest(LoadParameters&&); [[noreturn]] void loadRequestWaitingForProcessLaunch(LoadParameters&&, URL&&, WebPageProxyIdentifier, bool); void loadData(LoadParameters&&); -@@ -1873,6 +1883,7 @@ private: +@@ -1902,6 +1912,7 @@ private: void updatePotentialTapSecurityOrigin(const WebTouchEvent&, bool wasHandled); #elif ENABLE(TOUCH_EVENTS) void touchEvent(const WebTouchEvent&, CompletionHandler, bool)>&&); @@ -21198,7 +21142,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e #endif void cancelPointer(WebCore::PointerID, const WebCore::IntPoint&); -@@ -2017,9 +2028,7 @@ private: +@@ -2046,9 +2057,7 @@ private: void addLayerForFindOverlay(CompletionHandler&&); void removeLayerForFindOverlay(CompletionHandler&&); @@ -21208,7 +21152,7 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e void didChangeSelectedIndexForActivePopupMenu(int32_t newIndex); void setTextForActivePopupMenu(int32_t index); -@@ -2603,6 +2612,7 @@ private: +@@ -2649,6 +2658,7 @@ private: UserActivity m_userActivity; uint64_t m_pendingNavigationID { 0 }; @@ -21217,10 +21161,10 @@ index d122b26429823b3dfc9a215977174a1348a19fd0..6b154a312bedd764f78d32aba8c4452e bool m_mainFrameProgressCompleted { false }; diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in -index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21a899b942 100644 +index b67b771976b46970925529207e0153bc5637c533..7fc087a6d9769664347d62776d744287ec39c3a3 100644 --- a/Source/WebKit/WebProcess/WebPage/WebPage.messages.in +++ b/Source/WebKit/WebProcess/WebPage/WebPage.messages.in -@@ -149,6 +149,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType +@@ -147,6 +147,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType ConnectInspector(String targetId, Inspector::FrontendChannel::ConnectionType connectionType) DisconnectInspector(String targetId) SendMessageToTargetBackend(String targetId, String message) @@ -21228,7 +21172,7 @@ index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21 #if ENABLE(REMOTE_INSPECTOR) SetIndicating(bool indicating); -@@ -159,6 +160,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType +@@ -157,6 +158,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType #endif #if !ENABLE(IOS_TOUCH_EVENTS) && ENABLE(TOUCH_EVENTS) TouchEvent(WebKit::WebTouchEvent event) -> (std::optional eventType, bool handled) @@ -21236,7 +21180,7 @@ index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21 #endif CancelPointer(WebCore::PointerID pointerId, WebCore::IntPoint documentPoint) -@@ -190,6 +192,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType +@@ -188,6 +190,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType LoadDataInFrame(std::span data, String MIMEType, String encodingName, URL baseURL, WebCore::FrameIdentifier frameID) LoadRequest(struct WebKit::LoadParameters loadParameters) TransitionFrameToLocal(struct WebKit::LocalFrameCreationParameters creationParameters, WebCore::FrameIdentifier frameID) @@ -21244,8 +21188,8 @@ index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21 LoadRequestWaitingForProcessLaunch(struct WebKit::LoadParameters loadParameters, URL resourceDirectoryURL, WebKit::WebPageProxyIdentifier pageID, bool checkAssumedReadAccessToResourceURL) LoadData(struct WebKit::LoadParameters loadParameters) LoadSimulatedRequestAndResponse(struct WebKit::LoadParameters loadParameters, WebCore::ResourceResponse simulatedResponse) -@@ -357,10 +360,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType - AddMIMETypeWithCustomContentProvider(String mimeType) +@@ -353,10 +356,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType + RemoveLayerForFindOverlay() -> () # Drag and drop. -#if PLATFORM(GTK) && ENABLE(DRAG_SUPPORT) @@ -21257,7 +21201,7 @@ index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21 PerformDragControllerAction(std::optional frameID, enum:uint8_t WebKit::DragControllerAction action, WebCore::DragData dragData) -> (std::optional dragOperation, enum:uint8_t WebCore::DragHandlingMethod dragHandlingMethod, bool mouseIsOverFileInput, unsigned numberOfItemsToBeAccepted, WebCore::IntRect insertionRect, WebCore::IntRect editableElementRect, struct std::optional remoteUserInputEventData) PerformDragOperation(WebCore::DragData dragData, WebKit::SandboxExtensionHandle sandboxExtensionHandle, Vector sandboxExtensionsForUpload) -> (bool handled) #endif -@@ -370,6 +373,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType +@@ -366,6 +369,10 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType DragCancelled() #endif @@ -21269,7 +21213,7 @@ index 3b1d4404bd28adadb01c27d39a335cf5519b83f3..7fcdf4d0ac653c249938974105707a21 RequestDragStart(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet allowedActionsMask) RequestAdditionalItemsForDragSession(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, OptionSet allowedActionsMask) diff --git a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm -index fbc94ccff0a00b9b827c5f6fd22735ee3ff3eab7..380bafd4d7decd8dbefe14dd1780a4f1bf664ba3 100644 +index 46b5327ff8777f3dce83ecf37219ad08321e8462..364d1010f0356a37d3f3b07d7fde187973028857 100644 --- a/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm +++ b/Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm @@ -800,21 +800,37 @@ String WebPage::platformUserAgent(const URL&) const @@ -21361,7 +21305,7 @@ index f17f5d719d892309ed9c7093384945866b5117b9..1dba47bbf0dbd0362548423a74b38034 } diff --git a/Source/WebKit/WebProcess/WebProcess.cpp b/Source/WebKit/WebProcess/WebProcess.cpp -index 3ad4794de88f16fb0b90c004654782e80b1d0b1e..ef49378d65ea56b10f30ecf8d6817dffc35acb01 100644 +index 4b52cd3a81eceb55531d48d4e4a54dc7d62b4d32..e3427d76d44a9bf148f4f9dca7ed7d7b58319b53 100644 --- a/Source/WebKit/WebProcess/WebProcess.cpp +++ b/Source/WebKit/WebProcess/WebProcess.cpp @@ -88,6 +88,7 @@ @@ -21372,7 +21316,7 @@ index 3ad4794de88f16fb0b90c004654782e80b1d0b1e..ef49378d65ea56b10f30ecf8d6817dff #include #include #include -@@ -373,6 +374,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter +@@ -365,6 +366,8 @@ void WebProcess::initializeProcess(const AuxiliaryProcessInitializationParameter platformInitializeProcess(parameters); updateCPULimit(); @@ -21397,7 +21341,7 @@ index 8987c3964a9308f2454759de7f8972215a3ae416..bcac0afeb94ed8123d1f9fb0b932c849 SetProcessDPIAware(); return true; diff --git a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm -index 79b45534f7468cddc04a9021623799bf1052a7f9..d8efaabf72c725ca3a7247bc8475d90a9cecdd50 100644 +index 1ef662de86f8b92a7a5c6414df2dac6dbb3882f0..793785e12f96fe52193e8c27ec8b015521e06390 100644 --- a/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm +++ b/Source/WebKitLegacy/mac/WebView/WebHTMLView.mm @@ -4214,7 +4214,7 @@ ALLOW_DEPRECATED_DECLARATIONS_END @@ -21410,10 +21354,10 @@ index 79b45534f7468cddc04a9021623799bf1052a7f9..d8efaabf72c725ca3a7247bc8475d90a - (void)touch:(WebEvent *)event { diff --git a/Source/WebKitLegacy/mac/WebView/WebView.mm b/Source/WebKitLegacy/mac/WebView/WebView.mm -index 1e9502677b2434c8f0e7c8ae395d4c1e148cf9d7..0da8e737d05031413b12803eb62041a7f571d26b 100644 +index c892fdcdb2834ab3d93a4a0575b712c848b662c0..0e817f6ac6cf4e0bc04e1acd178ef976105d9b16 100644 --- a/Source/WebKitLegacy/mac/WebView/WebView.mm +++ b/Source/WebKitLegacy/mac/WebView/WebView.mm -@@ -3974,7 +3974,7 @@ + (void)_doNotStartObservingNetworkReachability +@@ -3979,7 +3979,7 @@ + (void)_doNotStartObservingNetworkReachability } #endif // PLATFORM(IOS_FAMILY) @@ -21422,7 +21366,7 @@ index 1e9502677b2434c8f0e7c8ae395d4c1e148cf9d7..0da8e737d05031413b12803eb62041a7 - (NSArray *)_touchEventRegions { -@@ -4016,7 +4016,7 @@ - (NSArray *)_touchEventRegions +@@ -4021,7 +4021,7 @@ - (NSArray *)_touchEventRegions }).autorelease(); } @@ -21463,7 +21407,7 @@ index 0000000000000000000000000000000000000000..dd6a53e2d57318489b7e49dd7373706d + LIBVPX_LIBRARIES +) diff --git a/Source/cmake/OptionsGTK.cmake b/Source/cmake/OptionsGTK.cmake -index 6bf415090c55f84b887319aff5316e3538e78ca8..2aaba526ca8ccb39b7457821e7332cc775f8b715 100644 +index 31085c5a7f8d4e1680887ff9f20de2d421256a62..d1374f5f68f26d166d9a6e4f1ae9a23dd9151e13 100644 --- a/Source/cmake/OptionsGTK.cmake +++ b/Source/cmake/OptionsGTK.cmake @@ -11,8 +11,13 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni @@ -21489,9 +21433,9 @@ index 6bf415090c55f84b887319aff5316e3538e78ca8..2aaba526ca8ccb39b7457821e7332cc7 +# Playwright end + include(GStreamerDefinitions) + include(FindGLibCompileResources) - SET_AND_EXPOSE_TO_BUILD(USE_GCRYPT TRUE) -@@ -87,14 +96,14 @@ endif () +@@ -88,14 +97,14 @@ endif () # without approval from a GTK reviewer. There must be strong reason to support # changing the value of the option. WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DRAG_SUPPORT PUBLIC ON) @@ -21509,16 +21453,16 @@ index 6bf415090c55f84b887319aff5316e3538e78ca8..2aaba526ca8ccb39b7457821e7332cc7 WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_LCMS PUBLIC ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_JPEGXL PUBLIC ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_WOFF2 PUBLIC ON) -@@ -120,7 +129,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_MONTH PRIVATE ON) +@@ -119,7 +128,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_DATETIMELOCAL PRIVATE ON) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_MONTH PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_TIME PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_INPUT_TYPE_WEEK PRIVATE ON) - WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON) -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF) - WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON) -@@ -132,7 +141,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION P +@@ -131,7 +140,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION P WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_NETWORK_CACHE_STALE_WHILE_REVALIDATE PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) @@ -21527,7 +21471,7 @@ index 6bf415090c55f84b887319aff5316e3538e78ca8..2aaba526ca8ccb39b7457821e7332cc7 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_POINTER_LOCK PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON) -@@ -142,6 +151,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON) +@@ -141,6 +150,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_API_STATISTICS PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CODECS PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_RTC PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) @@ -21543,7 +21487,7 @@ index 6bf415090c55f84b887319aff5316e3538e78ca8..2aaba526ca8ccb39b7457821e7332cc7 # Finalize the value for all options. Do not attempt to use an option before diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake -index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb48492d7ca37 100644 +index e0c8dc92717c31173b6848b9f04856276125fb9d..24bbbae0654cded5197e6a4ce13246f71f5d5590 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -9,6 +9,8 @@ if (${CMAKE_VERSION} VERSION_LESS "3.20" AND NOT ${CMAKE_GENERATOR} STREQUAL "Ni @@ -21554,8 +21498,8 @@ index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb484 + set(USER_AGENT_BRANDING "" CACHE STRING "Branding to add to user agent string") - find_package(ATK 2.16.0 REQUIRED) -@@ -29,6 +31,9 @@ find_package(WebP REQUIRED COMPONENTS demux) + find_package(HarfBuzz 1.4.2 REQUIRED COMPONENTS ICU) +@@ -27,6 +29,9 @@ find_package(WebP REQUIRED COMPONENTS demux) find_package(WPE REQUIRED) find_package(ZLIB REQUIRED) @@ -21565,7 +21509,7 @@ index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb484 WEBKIT_OPTION_BEGIN() SET_AND_EXPOSE_TO_BUILD(ENABLE_DEVELOPER_MODE ${DEVELOPER_MODE}) -@@ -39,11 +44,11 @@ include(GStreamerDefinitions) +@@ -38,11 +43,11 @@ include(FindGLibCompileResources) # without approval from a WPE reviewer. There must be strong reason to support # changing the value of the option. WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ENCRYPTED_MEDIA PUBLIC ${ENABLE_EXPERIMENTAL_FEATURES}) @@ -21579,16 +21523,16 @@ index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb484 WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_LCMS PUBLIC ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_JPEGXL PUBLIC ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(USE_WOFF2 PUBLIC ON) -@@ -61,7 +66,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF) +@@ -58,7 +63,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GPU_PROCESS PRIVATE OFF) - WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_LAYER_BASED_SVG_ENGINE PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_CONTROLS_CONTEXT_MENUS PRIVATE ON) -WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE ON) +WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_RECORDER PRIVATE OFF) - WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) + WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_SESSION_PLAYLIST PRIVATE OFF) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_MEDIA_STREAM PRIVATE ON) -@@ -75,7 +80,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${EN +@@ -72,7 +77,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_OFFSCREEN_CANVAS_IN_WORKERS PRIVATE ${EN WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_PERIODIC_MEMORY_MONITOR PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHAREABLE_RESOURCE PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPEECH_SYNTHESIS PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES}) @@ -21597,7 +21541,7 @@ index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb484 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VARIATION_FONTS PRIVATE ON) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_WEB_CODECS PRIVATE ON) -@@ -86,6 +91,23 @@ if (WPE_VERSION VERSION_GREATER_EQUAL 1.13.90) +@@ -83,6 +88,23 @@ if (WPE_VERSION VERSION_GREATER_EQUAL 1.13.90) WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_GAMEPAD PUBLIC ON) endif () @@ -21621,17 +21565,17 @@ index 7ca4dbcaa45ad799539f96a19377ca2b7023a921..770d7fbc68bec3112c530f47edabb484 # Public options specific to the WPE port. Do not add any options here unless # there is a strong reason we should support changing the value of the option, # and the option is not relevant to other WebKit ports. -@@ -95,7 +117,7 @@ WEBKIT_OPTION_DEFINE(ENABLE_JOURNALD_LOG "Whether to enable journald logging" PU +@@ -92,7 +114,7 @@ WEBKIT_OPTION_DEFINE(ENABLE_JOURNALD_LOG "Whether to enable journald logging" PU WEBKIT_OPTION_DEFINE(ENABLE_WPE_PLATFORM_DRM "Whether to enable support for DRM platform" PUBLIC ON) WEBKIT_OPTION_DEFINE(ENABLE_WPE_PLATFORM_HEADLESS "Whether to enable support for headless platform" PUBLIC ON) WEBKIT_OPTION_DEFINE(ENABLE_WPE_PLATFORM_WAYLAND "Whether to enable support for Wayland platform" PUBLIC ON) -WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC ${ENABLE_DEVELOPER_MODE}) +WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC OFF) WEBKIT_OPTION_DEFINE(ENABLE_WPE_1_1_API "Whether to build WPE 1.1 instead of WPE 2.0" PUBLIC OFF) + WEBKIT_OPTION_DEFINE(USE_ATK "Whether to enable usage of ATK." PUBLIC ON) WEBKIT_OPTION_DEFINE(USE_GBM "Whether to enable usage of GBM." PUBLIC ON) - WEBKIT_OPTION_DEFINE(USE_LIBBACKTRACE "Whether to enable usage of libbacktrace." PUBLIC ON) diff --git a/Source/cmake/OptionsWin.cmake b/Source/cmake/OptionsWin.cmake -index e60d013125f60b32b7b9bca1847eb118cfb72406..5fca8f7c0a78e36144e28e1b1388dc1380f1bcf9 100644 +index 2ed9985c35980ba0fca09c2fc9ea5ab300b19b00..a5f773d071cb67025b16614a998bd09355061572 100644 --- a/Source/cmake/OptionsWin.cmake +++ b/Source/cmake/OptionsWin.cmake @@ -86,6 +86,29 @@ find_package(ZLIB 1.2.11 REQUIRED) @@ -21664,7 +21608,7 @@ index e60d013125f60b32b7b9bca1847eb118cfb72406..5fca8f7c0a78e36144e28e1b1388dc13 WEBKIT_OPTION_BEGIN() # FIXME: Most of these options should not be public. -@@ -163,6 +186,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF) +@@ -159,6 +182,14 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF) SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_KEYBOARD_INTERACTIONS ON) SET_AND_EXPOSE_TO_BUILD(ENABLE_WEBDRIVER_MOUSE_INTERACTIONS ON) @@ -22008,10 +21952,10 @@ index 451e0333dd4e8f5d6313fa80c5027ef2661a61ac..7398af4772ed9a479b1632e38af2d4ee return exitAfterLoad && webProcessCrashed ? 1 : 0; diff --git a/Tools/MiniBrowser/wpe/main.cpp b/Tools/MiniBrowser/wpe/main.cpp -index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8ae9e35f4a 100644 +index 3c2476471ef67299da6312d0f995fc0738aa96c9..b13ab78bfe62c8c2cdd052e24255a780bbc2afa3 100644 --- a/Tools/MiniBrowser/wpe/main.cpp +++ b/Tools/MiniBrowser/wpe/main.cpp -@@ -42,6 +42,9 @@ static gboolean headlessMode; +@@ -45,6 +45,9 @@ static gboolean headlessMode; static gboolean privateMode; static gboolean automationMode; static gboolean ignoreTLSErrors; @@ -22021,7 +21965,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a static const char* contentFilter; static const char* cookiesFile; static const char* cookiesPolicy; -@@ -75,6 +78,9 @@ static const GOptionEntry commandLineOptions[] = +@@ -78,6 +81,9 @@ static const GOptionEntry commandLineOptions[] = { "use-wpe-platform-api", 0, 0, G_OPTION_ARG_NONE, &useWPEPlatformAPI, "Use the WPE platform API", nullptr }, #endif { "version", 'v', 0, G_OPTION_ARG_NONE, &printVersion, "Print the WPE version", nullptr }, @@ -22031,7 +21975,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uriArguments, nullptr, "[URL]" }, { nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr } }; -@@ -210,15 +216,38 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul +@@ -220,15 +226,38 @@ static void filterSavedCallback(WebKitUserContentFilterStore *store, GAsyncResul g_main_loop_quit(data->mainLoop); } @@ -22072,7 +22016,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a { auto backend = createViewBackend(1280, 720); -@@ -234,18 +263,37 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi +@@ -244,18 +273,37 @@ static WebKitWebView* createWebView(WebKitWebView* webView, WebKitNavigationActi }, backend.release()); } @@ -22116,7 +22060,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a return newWebView; } -@@ -259,13 +307,89 @@ static WebKitFeature* findFeature(WebKitFeatureList* featureList, const char* id +@@ -269,13 +317,89 @@ static WebKitFeature* findFeature(WebKitFeatureList* featureList, const char* id return nullptr; } @@ -22207,7 +22151,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a webkit_network_session_set_itp_enabled(networkSession, enableITP); if (proxy) { -@@ -292,10 +416,18 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* +@@ -302,10 +426,18 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* webkit_cookie_manager_set_persistent_storage(cookieManager, cookiesFile, storageType); } } @@ -22228,7 +22172,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a webkit_website_data_manager_set_itp_enabled(manager, enableITP); if (proxy) { -@@ -326,6 +458,7 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* +@@ -336,6 +468,7 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* } #endif @@ -22236,7 +22180,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a WebKitUserContentManager* userContentManager = nullptr; if (contentFilter) { GFile* contentFilterFile = g_file_new_for_commandline_arg(contentFilter); -@@ -398,6 +531,15 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* +@@ -408,6 +541,15 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* "autoplay", WEBKIT_AUTOPLAY_ALLOW, nullptr); @@ -22252,7 +22196,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a auto* webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, "backend", viewBackend, "web-context", webContext, -@@ -424,8 +566,6 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* +@@ -436,8 +578,6 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* g_signal_connect(wpeView, "event", G_CALLBACK(wpeViewEventCallback), webView); #endif @@ -22261,7 +22205,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a webkit_web_context_set_automation_allowed(webContext, automationMode); g_signal_connect(webContext, "automation-started", G_CALLBACK(automationStartedCallback), webView); g_signal_connect(webView, "permission-request", G_CALLBACK(decidePermissionRequest), nullptr); -@@ -438,16 +578,9 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* +@@ -450,16 +590,9 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend* webkit_web_view_set_background_color(webView, &color); if (uriArguments) { @@ -22281,7 +22225,7 @@ index 630d96d01ca6175ef114ec07fbf9396af0a85b26..75d31fcf0507fcc1fc27696c956a3f8a webkit_web_view_load_uri(webView, "about:blank"); else webkit_web_view_load_uri(webView, "https://wpewebkit.org"); -@@ -521,8 +654,14 @@ int main(int argc, char *argv[]) +@@ -533,8 +666,14 @@ int main(int argc, char *argv[]) } } @@ -22309,7 +22253,7 @@ index 1067b31bc989748dfcc5502209d36d001b9b239e..7629263fb8bc93dca6dfc01c75eed8d2 + add_subdirectory(Playwright/win) +endif () diff --git a/Tools/Scripts/build-webkit b/Tools/Scripts/build-webkit -index 9d2c490729c07369eac8372885c7ff98bb3e5707..21cb415200240028360eb7492a64522c5913aec6 100755 +index 39c351abbdd7b1b7f7016c5fd071ec2ae59b4a42..dc804e1d5284b15da6fa0679932d6cca8ece499a 100755 --- a/Tools/Scripts/build-webkit +++ b/Tools/Scripts/build-webkit @@ -273,7 +273,7 @@ if (isAppleCocoaWebKit()) { @@ -22337,10 +22281,10 @@ index 9e53f459e444b9c10fc5248f0e8059df6c1e0041..c17c875a7dd3ca05c4489578ab32378b "${WebKitTestRunner_DIR}/InjectedBundle/Bindings/AccessibilityController.idl" "${WebKitTestRunner_DIR}/InjectedBundle/Bindings/AccessibilityTextMarker.idl" diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp -index 4278aa9844a3a6bade0e3ea0ba5fc19792992afa..e27a870a70bbde031240f33ff6f29e01d9fcff1c 100644 +index 244cfc247fa50bf073ba523913543cab0c6f1b3b..d1cd4657f513d1be167f8d1176dc1217f57acbbd 100644 --- a/Tools/WebKitTestRunner/TestController.cpp +++ b/Tools/WebKitTestRunner/TestController.cpp -@@ -963,6 +963,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options) +@@ -964,6 +964,7 @@ void TestController::createWebViewWithOptions(const TestOptions& options) 0, // requestStorageAccessConfirm shouldAllowDeviceOrientationAndMotionAccess, runWebAuthenticationPanel, @@ -22450,7 +22394,7 @@ index 1e2a9202f88c63afa6525d97d0f945438f5f2032..e6cdee08aff723eb5c6b16491051ca39 # These are dependencies necessary for running tests. cups-daemon diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules -index 0bd2f996ba2641cbe4f4864b6fd8ce59204bae0a..b211f1bad06fab907de2bb592de843683c8af0fb 100644 +index 5453eb855928744d58e459f8a986535825dc29a0..b7d9568aef262d8e2825569b021ea0f5d0923ba0 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -252,10 +252,10 @@ @@ -22468,19 +22412,18 @@ index 0bd2f996ba2641cbe4f4864b6fd8ce59204bae0a..b211f1bad06fab907de2bb592de84368 diff --git a/Tools/jhbuild/jhbuild-minimal.modules b/Tools/jhbuild/jhbuild-minimal.modules -index 6c9e52c5c872d81e6e50ee44af9a3abae7750029..34b30f388341865a94f3fe26bf7feea9a17e2678 100644 +index fe58a444522de94d8f2a57c538a8e7bca93e5c74..78fd69a2a98cb0a826cba13f95c3f419b4376045 100644 --- a/Tools/jhbuild/jhbuild-minimal.modules +++ b/Tools/jhbuild/jhbuild-minimal.modules -@@ -24,7 +24,7 @@ - - - -- -+ +@@ -32,7 +32,6 @@ + - -@@ -120,10 +120,10 @@ +- + + + +@@ -132,10 +131,10 @@ @@ -22494,7 +22437,7 @@ index 6c9e52c5c872d81e6e50ee44af9a3abae7750029..34b30f388341865a94f3fe26bf7feea9 -@@ -219,6 +219,16 @@ +@@ -231,6 +230,16 @@ @@ -22512,10 +22455,10 @@ index 6c9e52c5c872d81e6e50ee44af9a3abae7750029..34b30f388341865a94f3fe26bf7feea9 + + - -@@ -101,10 +102,10 @@ +@@ -102,10 +103,10 @@ @@ -22599,7 +22542,7 @@ index 191d23b445c58ddbf0fb0eb416deea938f28e2aa..9f4e4897676b06e28925b0003bd1c6d2 -@@ -323,6 +324,16 @@ +@@ -334,6 +335,16 @@ hash="sha256:c625a83b4838befc8cafcd54e3619946515d9e44d63d61c4adf7f5513ddfbebf"/> diff --git a/docs/src/api/class-apirequestcontext.md b/docs/src/api/class-apirequestcontext.md index 7101d1996d..dab99bec2b 100644 --- a/docs/src/api/class-apirequestcontext.md +++ b/docs/src/api/class-apirequestcontext.md @@ -344,6 +344,9 @@ If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/ ### option: APIRequestContext.fetch.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.fetch.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.get * since: v1.16 - returns: <[APIResponse]> @@ -433,6 +436,9 @@ await request.GetAsync("https://example.com/api/getText", new() { Params = query ### option: APIRequestContext.get.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.get.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.head * since: v1.16 - returns: <[APIResponse]> @@ -486,6 +492,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.head.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.head.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.patch * since: v1.16 - returns: <[APIResponse]> @@ -539,6 +548,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.patch.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.patch.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.post * since: v1.16 - returns: <[APIResponse]> @@ -713,6 +725,9 @@ await request.PostAsync("https://example.com/api/uploadScript", new() { Multipar ### option: APIRequestContext.post.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.post.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.put * since: v1.16 - returns: <[APIResponse]> @@ -766,6 +781,9 @@ context cookies from the response. The method will automatically follow redirect ### option: APIRequestContext.put.maxRedirects = %%-js-python-csharp-fetch-option-maxredirects-%% * since: v1.26 +### option: APIRequestContext.put.maxRetries = %%-js-python-csharp-fetch-option-maxretries-%% +* since: v1.46 + ## async method: APIRequestContext.storageState * since: v1.16 - returns: <[Object]> diff --git a/docs/src/api/class-browsercontext.md b/docs/src/api/class-browsercontext.md index 3ea2180873..48542a2603 100644 --- a/docs/src/api/class-browsercontext.md +++ b/docs/src/api/class-browsercontext.md @@ -357,18 +357,14 @@ await context.AddCookiesAsync(new[] { cookie1, cookie2 }); - `cookies` <[Array]<[Object]>> - `name` <[string]> - `value` <[string]> - - `url` ?<[string]> either url or domain / path are required. Optional. - - `domain` ?<[string]> either url or domain / path are required Optional. - - `path` ?<[string]> either url or domain / path are required Optional. + - `url` ?<[string]> Either url or domain / path are required. Optional. + - `domain` ?<[string]> For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". Either url or domain / path are required. Optional. + - `path` ?<[string]> Either url or domain / path are required Optional. - `expires` ?<[float]> Unix time in seconds. Optional. - `httpOnly` ?<[boolean]> Optional. - `secure` ?<[boolean]> Optional. - `sameSite` ?<[SameSiteAttribute]<"Strict"|"Lax"|"None">> Optional. -Adds cookies to the browser context. - -For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". - ## async method: BrowserContext.addInitScript * since: v1.8 @@ -748,83 +744,6 @@ await page.SetContentAsync(" -
Click me
-
Or click me
-`); -``` - -```java -context.exposeBinding("clicked", (source, args) -> { - ElementHandle element = (ElementHandle) args[0]; - System.out.println(element.textContent()); - return null; -}, new BrowserContext.ExposeBindingOptions().setHandle(true)); -page.setContent("" + - "\n" + - "
Click me
\n" + - "
Or click me
\n"); -``` - -```python async -async def print(source, element): - print(await element.text_content()) - -await context.expose_binding("clicked", print, handle=true) -await page.set_content(""" - -
Click me
-
Or click me
-""") -``` - -```python sync -def print(source, element): - print(element.text_content()) - -context.expose_binding("clicked", print, handle=true) -page.set_content(""" - -
Click me
-
Or click me
-""") -``` - -```csharp -var result = new TaskCompletionSource(); -var page = await Context.NewPageAsync(); -await Context.ExposeBindingAsync("clicked", async (BindingSource _, IJSHandle t) => -{ - return result.TrySetResult(await t.AsElement().TextContentAsync()); -}); - -await page.SetContentAsync("\n" + - "
Click me
\n" + - "
Or click me
\n"); - -await page.ClickAsync("div"); -// Note: it makes sense to await the result here, because otherwise, the context -// gets closed and the binding function will throw an exception. -Assert.AreEqual("Click me", await result.Task); -``` - ### param: BrowserContext.exposeBinding.name * since: v1.8 - `name` <[string]> @@ -839,6 +758,7 @@ Callback function that will be called in the Playwright's context. ### option: BrowserContext.exposeBinding.handle * since: v1.8 +* deprecated: This option will be removed in the future. - `handle` <[boolean]> Whether to pass the argument as a handle, instead of passing by value. When passing a handle, only one argument is diff --git a/docs/src/api/class-clock.md b/docs/src/api/class-clock.md index 9099d33a4f..6f70e72a02 100644 --- a/docs/src/api/class-clock.md +++ b/docs/src/api/class-clock.md @@ -41,7 +41,7 @@ await page.Clock.FastForwardAsync("30:00"); ### param: Clock.fastForward.ticks * since: v1.45 -- `ticks` <[int]|[string]> +- `ticks` <[long]|[string]> Time may be the number of milliseconds to advance the clock by or a human-readable string. Valid string formats are "08" for eight seconds, "01:00" for one minute and "02:34:10" for two hours, 34 minutes and ten seconds. @@ -65,7 +65,7 @@ Fake timers are used to manually control the flow of time in tests. They allow y ### option: Clock.install.time * since: v1.45 -- `time` <[int]|[string]|[Date]> +- `time` <[long]|[string]|[Date]> Time to initialize with, current system time by default. @@ -103,7 +103,7 @@ await page.Clock.RunForAsync("30:00"); ### param: Clock.runFor.ticks * since: v1.45 -- `ticks` <[int]|[string]> +- `ticks` <[long]|[string]> Time may be the number of milliseconds to advance the clock by or a human-readable string. Valid string formats are "08" for eight seconds, "01:00" for one minute and "02:34:10" for two hours, 34 minutes and ten seconds. @@ -136,7 +136,8 @@ page.clock.pause_at("2020-02-02") ``` ```java -page.clock().pauseAt(Instant.parse("2020-02-02")); +SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd"); +page.clock().pauseAt(format.parse("2020-02-02")); page.clock().pauseAt("2020-02-02"); ``` @@ -147,7 +148,7 @@ await page.Clock.PauseAtAsync("2020-02-02"); ### param: Clock.pauseAt.time * since: v1.45 -- `time` <[int]|[string]|[Date]> +- `time` <[long]|[string]|[Date]> ## async method: Clock.resume @@ -182,8 +183,8 @@ page.clock.set_fixed_time("2020-02-02") ``` ```java -page.clock().setFixedTime(Instant.now()); -page.clock().setFixedTime(Instant.parse("2020-02-02")); +page.clock().setFixedTime(new Date()); +page.clock().setFixedTime(new SimpleDateFormat("yyy-MM-dd").parse("2020-02-02")); page.clock().setFixedTime("2020-02-02"); ``` @@ -195,7 +196,7 @@ await page.Clock.SetFixedTimeAsync("2020-02-02"); ### param: Clock.setFixedTime.time * since: v1.45 -- `time` <[int]|[string]|[Date]> +- `time` <[long]|[string]|[Date]> Time to be set. @@ -225,8 +226,8 @@ page.clock.set_system_time("2020-02-02") ``` ```java -page.clock().setSystemTime(Instant.now()); -page.clock().setSystemTime(Instant.parse("2020-02-02")); +page.clock().setSystemTime(new Date()); +page.clock().setSystemTime(new SimpleDateFormat("yyy-MM-dd").parse("2020-02-02")); page.clock().setSystemTime("2020-02-02"); ``` @@ -238,4 +239,4 @@ await page.Clock.SetSystemTimeAsync("2020-02-02"); ### param: Clock.setSystemTime.time * since: v1.45 -- `time` <[int]|[string]|[Date]> +- `time` <[long]|[string]|[Date]> diff --git a/docs/src/api/class-page.md b/docs/src/api/class-page.md index d087b78c9f..3d667bb186 100644 --- a/docs/src/api/class-page.md +++ b/docs/src/api/class-page.md @@ -1817,80 +1817,6 @@ class PageExamples } ``` -An example of passing an element handle: - -```js -await page.exposeBinding('clicked', async (source, element) => { - console.log(await element.textContent()); -}, { handle: true }); -await page.setContent(` - -
Click me
-
Or click me
-`); -``` - -```java -page.exposeBinding("clicked", (source, args) -> { - ElementHandle element = (ElementHandle) args[0]; - System.out.println(element.textContent()); - return null; -}, new Page.ExposeBindingOptions().setHandle(true)); -page.setContent("" + - "\n" + - "
Click me
\n" + - "
Or click me
\n"); -``` - -```python async -async def print(source, element): - print(await element.text_content()) - -await page.expose_binding("clicked", print, handle=true) -await page.set_content(""" - -
Click me
-
Or click me
-""") -``` - -```python sync -def print(source, element): - print(element.text_content()) - -page.expose_binding("clicked", print, handle=true) -page.set_content(""" - -
Click me
-
Or click me
-""") -``` - -```csharp -var result = new TaskCompletionSource(); -await page.ExposeBindingAsync("clicked", async (BindingSource _, IJSHandle t) => -{ - return result.TrySetResult(await t.AsElement().TextContentAsync()); -}); - -await page.SetContentAsync("\n" + - "
Click me
\n" + - "
Or click me
\n"); - -await page.ClickAsync("div"); -Console.WriteLine(await result.Task); -``` - ### param: Page.exposeBinding.name * since: v1.8 - `name` <[string]> @@ -1905,6 +1831,7 @@ Callback function that will be called in the Playwright's context. ### option: Page.exposeBinding.handle * since: v1.8 +* deprecated: This option will be removed in the future. - `handle` <[boolean]> Whether to pass the argument as a handle, instead of passing by value. When passing a handle, only one argument is diff --git a/docs/src/api/class-requestoptions.md b/docs/src/api/class-requestoptions.md index b6eeb8970a..401e13d944 100644 --- a/docs/src/api/class-requestoptions.md +++ b/docs/src/api/class-requestoptions.md @@ -126,6 +126,16 @@ Whether to ignore HTTPS errors when sending network requests. Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is exceeded. Defaults to `20`. Pass `0` to not follow redirects. +## method: RequestOptions.setMaxRetries +* since: v1.46 +- returns: <[RequestOptions]> + +### param: RequestOptions.setMaxRetries.maxRetries +* since: v1.46 +- `maxRetries` <[int]> + +Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + ## method: RequestOptions.setMethod * since: v1.18 - returns: <[RequestOptions]> diff --git a/docs/src/api/class-touchscreen.md b/docs/src/api/class-touchscreen.md index 90ea8cd759..79fd134dca 100644 --- a/docs/src/api/class-touchscreen.md +++ b/docs/src/api/class-touchscreen.md @@ -20,3 +20,23 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi ### param: Touchscreen.tap.y * since: v1.8 - `y` <[float]> + +## async method: Touchscreen.touch +* since: v1.46 + +Synthesizes a touch event. + +### param: Touchscreen.touch.type +* since: v1.46 +- `type` <[TouchType]<"touchstart"|"touchend"|"touchmove"|"touchcancel">> + +Type of the touch event. + +### param: Touchscreen.touch.touches +* since: v1.46 +- `touchPoints` <[Array]<[Object]>> + - `x` <[float]> x coordinate of the event in CSS pixels. + - `y` <[float]> y coordinate of the event in CSS pixels. + - `id` ?<[int]> Identifier used to track the touch point between events, must be unique within an event. Optional. + +List of touch points for this event. `id` is a unique identifier of a touch point that helps identify it between touch events for the duration of its movement around the surface. \ No newline at end of file diff --git a/docs/src/api/params.md b/docs/src/api/params.md index a1dd84c4ef..253ca3a1fd 100644 --- a/docs/src/api/params.md +++ b/docs/src/api/params.md @@ -458,6 +458,12 @@ Whether to ignore HTTPS errors when sending network requests. Defaults to `false Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is exceeded. Defaults to `20`. Pass `0` to not follow redirects. +## js-python-csharp-fetch-option-maxretries +* langs: js, python, csharp +- `maxRetries` <[int]> + +Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error will be thrown if the limit is exceeded. Defaults to `0` - no retries. + ## evaluate-expression - `expression` <[string]> diff --git a/docs/src/ci.md b/docs/src/ci.md index 2556cbf241..69a59a70dc 100644 --- a/docs/src/ci.md +++ b/docs/src/ci.md @@ -601,6 +601,23 @@ steps: - 'CI=true' ``` +### Drone +* langs: js + +To run Playwright tests on Drone, use our public Docker image ([see Dockerfile](./docker.md)). + +```yml +kind: pipeline +name: default +type: docker + +steps: + - name: test + image: mcr.microsoft.com/playwright:v%%VERSION%%-jammy + commands: + - npx playwright test +``` + ## Caching browsers Caching browser binaries is not recommended, since the amount of time it takes to restore the cache is comparable to the time it takes to download the binaries. Especially under Linux, [operating system dependencies](./browsers.md#install-system-dependencies) need to be installed, which are not cacheable. @@ -633,7 +650,7 @@ By default, Playwright launches browsers in headless mode. See in our [Running t On Linux agents, headed execution requires [Xvfb](https://en.wikipedia.org/wiki/Xvfb) to be installed. Our [Docker image](./docker.md) and GitHub Action have Xvfb pre-installed. To run browsers in headed mode with Xvfb, add `xvfb-run` before the actual command. ```bash js -xvfb-run npx playwrght test +xvfb-run npx playwright test ``` ```bash python xvfb-run pytest diff --git a/docs/src/clock.md b/docs/src/clock.md index b89dfd93d6..ec3aaf8bd5 100644 --- a/docs/src/clock.md +++ b/docs/src/clock.md @@ -2,11 +2,24 @@ id: clock title: "Clock" --- +import LiteYouTube from '@site/src/components/LiteYouTube'; ## Introduction Accurately simulating time-dependent behavior is essential for verifying the correctness of applications. Utilizing [Clock] functionality allows developers to manipulate and control time within tests, enabling the precise validation of features such as rendering time, timeouts, scheduled tasks without the delays and variability of real-time execution. +The [Clock] API provides the following methods to control time: +- `setFixedTime`: Sets the fixed time for `Date.now()` and `new Date()`. +- `install`: initializes the clock and allows you to: + - `pauseAt`: Pauses the time at a specific time. + - `fastForward`: Fast forwards the time. + - `runFor`: Runs the time for a specific duration. + - `resume`: Resumes the time. +- `setSystemTime`: Sets the current system time. + +The recommended approach is to use `setFixedTime` to set the time to a specific value. If that doesn't work for your use case, you can use `install` which allows you to pause time later on, fast forward it, tick it, etc. `setSystemTime` is only recommended for advanced use cases. + +:::note [`property: Page.clock`] overrides native global classes and functions related to time allowing them to be manually controlled: - `Date` - `setTimeout` @@ -18,6 +31,7 @@ Accurately simulating time-dependent behavior is essential for verifying the cor - `requestIdleCallback` - `cancelIdleCallback` - `performance` +::: ## Test with predefined time @@ -118,13 +132,14 @@ expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:30:00 AM" ```java // Initialize clock with some time before the test time and let the page load // naturally. `Date.now` will progress as the timers fire. -page.clock().install(new Clock.InstallOptions().setTime(Instant.parse("2024-02-02T08:00:00"))); +SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss"); +page.clock().install(new Clock.InstallOptions().setTime(format.parse("2024-02-02T08:00:00"))); page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); // Pretend that the user closed the laptop lid and opened it again at 10am. // Pause the time once reached that point. -page.clock().pauseAt(Instant.parse("2024-02-02T10:00:00")); +page.clock().pauseAt(format.parse("2024-02-02T10:00:00")); // Assert the page state. assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); @@ -315,15 +330,16 @@ expect(locator).to_have_text("2/2/2024, 10:00:02 AM") ``` ```java +SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss"); // Initialize clock with a specific time, let the page load naturally. page.clock().install(new Clock.InstallOptions() - .setTime(Instant.parse("2024-02-02T08:00:00"))); + .setTime(format.parse("2024-02-02T08:00:00"))); page.navigate("http://localhost:3333"); Locator locator = page.getByTestId("current-time"); // Pause the time flow, stop the timers, you now have manual control // over the page time. -page.clock().pauseAt(Instant.parse("2024-02-02T10:00:00")); +page.clock().pauseAt(format.parse("2024-02-02T10:00:00")); assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); // Tick through time manually, firing all timers in the process. @@ -351,3 +367,10 @@ await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:00 AM"); await Page.Clock.RunForAsync(2000); await Expect(locator).ToHaveTextAsync("2/2/2024, 10:00:02 AM"); ``` + +## Related Videos + + diff --git a/docs/src/dialogs.md b/docs/src/dialogs.md index 1d8938778c..20037245ee 100644 --- a/docs/src/dialogs.md +++ b/docs/src/dialogs.md @@ -5,7 +5,7 @@ title: "Dialogs" ## Introduction -Playwright can interact with the web page dialogs such as [`alert`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert), [`confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm), [`prompt`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) as well as [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) confirmation. +Playwright can interact with the web page dialogs such as [`alert`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert), [`confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm), [`prompt`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) as well as [`beforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event) confirmation. For print dialogs, see [Print](#print-dialogs). ## alert(), confirm(), prompt() dialogs @@ -126,3 +126,55 @@ Page.Dialog += async (_, dialog) => }; await Page.CloseAsync(new() { RunBeforeUnload = true }); ``` + +## Print dialogs + +In order to assert that a print dialog via [`window.print`](https://developer.mozilla.org/en-US/docs/Web/API/Window/print) was triggered, you can use the following snippet: + +```js +await page.goto(''); + +await page.evaluate('(() => {window.waitForPrintDialog = new Promise(f => window.print = f);})()'); +await page.getByText('Print it!').click(); + +await page.waitForFunction('window.waitForPrintDialog'); +``` + +```java +page.navigate(""); + +page.evaluate("(() => {window.waitForPrintDialog = new Promise(f => window.print = f);})()"); +page.getByText("Print it!").click(); + +page.waitForFunction("window.waitForPrintDialog"); +``` + +```python async +await page.goto("") + +await page.evaluate("(() => {window.waitForPrintDialog = new Promise(f => window.print = f);})()") +await page.get_by_text("Print it!").click() + +await page.wait_for_function("window.waitForPrintDialog") +``` + +```python sync +page.goto("") + +page.evaluate("(() => {window.waitForPrintDialog = new Promise(f => window.print = f);})()") +page.get_by_text("Print it!").click() + +page.wait_for_function("window.waitForPrintDialog") +``` + +```csharp +await Page.GotoAsync(""); + +await Page.EvaluateAsync("(() => {window.waitForPrintDialog = new Promise(f => window.print = f);})()"); +await Page.GetByText("Print it!").ClickAsync(); + +await Page.WaitForFunctionAsync("window.waitForPrintDialog"); +``` + +This will wait for the print dialog to be opened after the button is clicked. +Make sure to evaluate the script before clicking the button / after the page is loaded. diff --git a/docs/src/docker.md b/docs/src/docker.md index 11553a578a..0946c2f68b 100644 --- a/docs/src/docker.md +++ b/docs/src/docker.md @@ -5,7 +5,7 @@ title: "Docker" ## Introduction -[Dockerfile.jammy] can be used to run Playwright scripts in Docker environment. These image includes the [Playwright browsers](./browsers.md#install-browsers) and [browser system dependencies](./browsers.md#install-system-dependencies). The Playwright package/dependency is not included in the image and should be installed separately. +[Dockerfile.jammy] can be used to run Playwright scripts in Docker environment. This image includes the [Playwright browsers](./browsers.md#install-browsers) and [browser system dependencies](./browsers.md#install-system-dependencies). The Playwright package/dependency is not included in the image and should be installed separately. ## Usage diff --git a/docs/src/input.md b/docs/src/input.md index 87f92099a7..b6fab7d005 100644 --- a/docs/src/input.md +++ b/docs/src/input.md @@ -397,17 +397,17 @@ page.locator("#area").pressSequentially("Hello World!"); ```python async # Press keys one by one -await page.locator('#area').pressSequentially('Hello World!') +await page.locator('#area').press_sequentially('Hello World!') ``` ```python sync # Press keys one by one -page.locator('#area').pressSequentially('Hello World!') +page.locator('#area').press_sequentially('Hello World!') ``` ```csharp // Press keys one by one -await page.Locator("#area").TypeAsync("Hello World!"); +await Page.Locator("#area").PressSequentiallyAsync("Hello World!"); ``` This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior. diff --git a/docs/src/locators.md b/docs/src/locators.md index 6d5926b579..052894a172 100644 --- a/docs/src/locators.md +++ b/docs/src/locators.md @@ -1444,14 +1444,6 @@ page.getByText("orange").click(); await page.GetByText("orange").ClickAsync(); ``` -```html card -
    -
  • apple
  • -
  • banana
  • -
  • orange
  • -
-``` - #### Filter by text Use the [`method: Locator.filter`] to locate a specific item in a list. diff --git a/docs/src/release-notes-csharp.md b/docs/src/release-notes-csharp.md index 9a3301a764..9172478402 100644 --- a/docs/src/release-notes-csharp.md +++ b/docs/src/release-notes-csharp.md @@ -4,6 +4,69 @@ title: "Release notes" toc_max_heading_level: 2 --- +## Version 1.45 + +### Clock + +Utilizing the new [Clock] API allows to manipulate and control time within tests to verify time-related behavior. This API covers many common scenarios, including: +* testing with predefined time; +* keeping consistent time and timers; +* monitoring inactivity; +* ticking through time manually. + +```csharp +// Initialize clock with some time before the test time and let the page load naturally. +// `Date.now` will progress as the timers fire. +await Page.Clock.InstallAsync(new() +{ + TimeDate = new DateTime(2024, 2, 2, 8, 0, 0) +}); +await Page.GotoAsync("http://localhost:3333"); + +// Pretend that the user closed the laptop lid and opened it again at 10am. +// Pause the time once reached that point. +await Page.Clock.PauseAtAsync(new DateTime(2024, 2, 2, 10, 0, 0)); + +// Assert the page state. +await Expect(Page.GetByTestId("current-time")).ToHaveTextAsync("2/2/2024, 10:00:00 AM"); + +// Close the laptop lid again and open it at 10:30am. +await Page.Clock.FastForwardAsync("30:00"); +await Expect(Page.GetByTestId("current-time")).ToHaveTextAsync("2/2/2024, 10:30:00 AM"); +``` + +See [the clock guide](./clock.md) for more details. + +### Miscellaneous + +- Method [`method: Locator.setInputFiles`] now supports uploading a directory for `` elements. + ```csharp + await page.GetByLabel("Upload directory").SetInputFilesAsync("mydir"); + ``` + +- Multiple methods like [`method: Locator.click`] or [`method: Locator.press`] now support a `ControlOrMeta` modifier key. This key maps to `Meta` on macOS and maps to `Control` on Windows and Linux. + ```csharp + // Press the common keyboard shortcut Control+S or Meta+S to trigger a "Save" operation. + await page.Keyboard.PressAsync("ControlOrMeta+S"); + ``` + +- New property `httpCredentials.send` in [`method: APIRequest.newContext`] that allows to either always send the `Authorization` header or only send it in response to `401 Unauthorized`. + +- Playwright now supports Chromium, Firefox and WebKit on Ubuntu 24.04. + +- v1.45 is the last release to receive WebKit update for macOS 12 Monterey. Please update macOS to keep using the latest WebKit. + +### Browser Versions + +* Chromium 127.0.6533.5 +* Mozilla Firefox 127.0 +* WebKit 17.4 + +This version was also tested against the following stable channels: + +* Google Chrome 126 +* Microsoft Edge 126 + ## Version 1.44 ### New APIs @@ -129,7 +192,7 @@ This version was also tested against the following stable channels: ### New Locator Handler New method [`method: Page.addLocatorHandler`] registers a callback that will be invoked when specified element becomes visible and may block Playwright actions. The callback can get rid of the overlay. Here is an example that closes a cookie dialog when it appears. - + ```csharp // Setup the handler. await Page.AddLocatorHandlerAsync( diff --git a/docs/src/release-notes-java.md b/docs/src/release-notes-java.md index 4a46556f68..6dce675b8f 100644 --- a/docs/src/release-notes-java.md +++ b/docs/src/release-notes-java.md @@ -4,6 +4,67 @@ title: "Release notes" toc_max_heading_level: 2 --- +## Version 1.45 + +### Clock + +Utilizing the new [Clock] API allows to manipulate and control time within tests to verify time-related behavior. This API covers many common scenarios, including: +* testing with predefined time; +* keeping consistent time and timers; +* monitoring inactivity; +* ticking through time manually. + +```java +// Initialize clock with some time before the test time and let the page load +// naturally. `Date.now` will progress as the timers fire. +page.clock().install(new Clock.InstallOptions().setTime("2024-02-02T08:00:00")); +page.navigate("http://localhost:3333"); +Locator locator = page.getByTestId("current-time"); + +// Pretend that the user closed the laptop lid and opened it again at 10am. +// Pause the time once reached that point. +page.clock().pauseAt("2024-02-02T10:00:00"); + +// Assert the page state. +assertThat(locator).hasText("2/2/2024, 10:00:00 AM"); + +// Close the laptop lid again and open it at 10:30am. +page.clock().fastForward("30:00"); +assertThat(locator).hasText("2/2/2024, 10:30:00 AM"); +``` + +See [the clock guide](./clock.md) for more details. + +### Miscellaneous + +- Method [`method: Locator.setInputFiles`] now supports uploading a directory for `` elements. + ```java + page.getByLabel("Upload directory").setInputFiles(Paths.get("mydir")); + ``` + +- Multiple methods like [`method: Locator.click`] or [`method: Locator.press`] now support a `ControlOrMeta` modifier key. This key maps to `Meta` on macOS and maps to `Control` on Windows and Linux. + ```java + // Press the common keyboard shortcut Control+S or Meta+S to trigger a "Save" operation. + page.keyboard.press("ControlOrMeta+S"); + ``` + +- New property `httpCredentials.send` in [`method: APIRequest.newContext`] that allows to either always send the `Authorization` header or only send it in response to `401 Unauthorized`. + +- Playwright now supports Chromium, Firefox and WebKit on Ubuntu 24.04. + +- v1.45 is the last release to receive WebKit update for macOS 12 Monterey. Please update macOS to keep using the latest WebKit. + +### Browser Versions + +* Chromium 127.0.6533.5 +* Mozilla Firefox 127.0 +* WebKit 17.4 + +This version was also tested against the following stable channels: + +* Google Chrome 126 +* Microsoft Edge 126 + ## Version 1.44 ### New APIs @@ -201,7 +262,7 @@ Learn more about the fixtures in our [JUnit guide](./junit.md). ### New Locator Handler New method [`method: Page.addLocatorHandler`] registers a callback that will be invoked when specified element becomes visible and may block Playwright actions. The callback can get rid of the overlay. Here is an example that closes a cookie dialog when it appears. - + ```java // Setup the handler. page.addLocatorHandler( diff --git a/docs/src/release-notes-js.md b/docs/src/release-notes-js.md index ce2250f470..5bcea8962b 100644 --- a/docs/src/release-notes-js.md +++ b/docs/src/release-notes-js.md @@ -6,6 +6,103 @@ toc_max_heading_level: 2 import LiteYouTube from '@site/src/components/LiteYouTube'; +## Version 1.45 + + + +### Clock + +Utilizing the new [Clock] API allows to manipulate and control time within tests to verify time-related behavior. This API covers many common scenarios, including: +* testing with predefined time; +* keeping consistent time and timers; +* monitoring inactivity; +* ticking through time manually. + +```js +// Initialize clock and let the page load naturally. +await page.clock.install({ time: new Date('2024-02-02T08:00:00') }); +await page.goto('http://localhost:3333'); + +// Pretend that the user closed the laptop lid and opened it again at 10am, +// Pause the time once reached that point. +await page.clock.pauseAt(new Date('2024-02-02T10:00:00')); + +// Assert the page state. +await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:00:00 AM'); + +// Close the laptop lid again and open it at 10:30am. +await page.clock.fastForward('30:00'); +await expect(page.getByTestId('current-time')).toHaveText('2/2/2024, 10:30:00 AM'); +``` + +See [the clock guide](./clock.md) for more details. + +### Test runner + +- New CLI option `--fail-on-flaky-tests` that sets exit code to `1` upon any flaky tests. Note that by default, the test runner exits with code `0` when all failed tests recovered upon a retry. With this option, the test run will fail in such case. + +- New enviroment variable `PLAYWRIGHT_FORCE_TTY` controls whether built-in `list`, `line` and `dot` reporters assume a live terminal. For example, this could be useful to disable tty behavior when your CI environment does not handle ANSI control sequences well. Alternatively, you can enable tty behavior even when to live terminal is present, if you plan to post-process the output and handle control sequences. + + ```sh + # Avoid TTY features that output ANSI control sequences + PLAYWRIGHT_FORCE_TTY=0 npx playwright test + + # Enable TTY features, assuming a terminal width 80 + PLAYWRIGHT_FORCE_TTY=80 npx playwright test + ``` + +- New options [`property: TestConfig.respectGitIgnore`] and [`property: TestProject.respectGitIgnore`] control whether files matching `.gitignore` patterns are excluded when searching for tests. + +- New property `timeout` is now available for custom expect matchers. This property takes into account `playwright.config.ts` and `expect.configure()`. + ```ts + import { expect as baseExpect } from '@playwright/test'; + + export const expect = baseExpect.extend({ + async toHaveAmount(locator: Locator, expected: number, options?: { timeout?: number }) { + // When no timeout option is specified, use the config timeout. + const timeout = options?.timeout ?? this.timeout; + // ... implement the assertion ... + }, + }); + ``` + +### Miscellaneous + +- Method [`method: Locator.setInputFiles`] now supports uploading a directory for `` elements. + ```ts + await page.getByLabel('Upload directory').setInputFiles(path.join(__dirname, 'mydir')); + ``` + +- Multiple methods like [`method: Locator.click`] or [`method: Locator.press`] now support a `ControlOrMeta` modifier key. This key maps to `Meta` on macOS and maps to `Control` on Windows and Linux. + ```ts + // Press the common keyboard shortcut Control+S or Meta+S to trigger a "Save" operation. + await page.keyboard.press('ControlOrMeta+S'); + ``` + +- New property `httpCredentials.send` in [`method: APIRequest.newContext`] that allows to either always send the `Authorization` header or only send it in response to `401 Unauthorized`. + +- New option `reason` in [`method: APIRequestContext.dispose`] that will be included in the error message of ongoing operations interrupted by the context disposal. + +- New option `host` in [`method: BrowserType.launchServer`] allows to accept websocket connections on a specific address instead of unspecified `0.0.0.0`. + +- Playwright now supports Chromium, Firefox and WebKit on Ubuntu 24.04. + +- v1.45 is the last release to receive WebKit update for macOS 12 Monterey. Please update macOS to keep using the latest WebKit. + +### Browser Versions + +* Chromium 127.0.6533.5 +* Mozilla Firefox 127.0 +* WebKit 17.4 + +This version was also tested against the following stable channels: + +* Google Chrome 126 +* Microsoft Edge 126 + ## Version 1.44 ` elements. + ```python + page.get_by_label("Upload directory").set_input_files('mydir') + ``` + +- Multiple methods like [`method: Locator.click`] or [`method: Locator.press`] now support a `ControlOrMeta` modifier key. This key maps to `Meta` on macOS and maps to `Control` on Windows and Linux. + ```python + # Press the common keyboard shortcut Control+S or Meta+S to trigger a "Save" operation. + page.keyboard.press("ControlOrMeta+S") + ``` + +- New property `httpCredentials.send` in [`method: APIRequest.newContext`] that allows to either always send the `Authorization` header or only send it in response to `401 Unauthorized`. + +- Playwright now supports Chromium, Firefox and WebKit on Ubuntu 24.04. + +- v1.45 is the last release to receive WebKit update for macOS 12 Monterey. Please update macOS to keep using the latest WebKit. + +### Browser Versions + +* Chromium 127.0.6533.5 +* Mozilla Firefox 127.0 +* WebKit 17.4 + +This version was also tested against the following stable channels: + +* Google Chrome 126 +* Microsoft Edge 126 + ## Version 1.44 ### New APIs @@ -109,7 +169,7 @@ This version was also tested against the following stable channels: ### New Locator Handler New method [`method: Page.addLocatorHandler`] registers a callback that will be invoked when specified element becomes visible and may block Playwright actions. The callback can get rid of the overlay. Here is an example that closes a cookie dialog when it appears. - + ```python # Setup the handler. page.add_locator_handler( diff --git a/docs/src/test-components-js.md b/docs/src/test-components-js.md index cdb065347e..7d733230e8 100644 --- a/docs/src/test-components-js.md +++ b/docs/src/test-components-js.md @@ -232,12 +232,14 @@ Let's say you'd like to test following component: ```js title="input-media.tsx" import React from 'react'; -export const InputMedia: React.FC<{ +type InputMediaProps = { // Media is a complex browser object we can't send to Node while testing. - onChange: (media: Media) => void, -}> = ({ onChange }) => { - return <> as any; + onChange(media: Media): void; }; + +export function InputMedia(props: InputMediaProps) { + return <> as any; +} ``` Create a story file for your component: @@ -246,12 +248,14 @@ Create a story file for your component: import React from 'react'; import InputMedia from './import-media'; -export const InputMediaForTest: React.FC<{ - onMediaChange: (mediaName: string) => void, -}> = ({ onMediaChange }) => { - // Instead of sending a complex `media` object to the test, send the media name. - return onMediaChange(media.name)} />; +type InputMediaForTestProps = { + onMediaChange(mediaName: string): void; }; + +export function InputMediaForTest(props: InputMediaForTestProps) { + // Instead of sending a complex `media` object to the test, send the media name. + return props.onMediaChange(media.name)} />; +} // Export more stories here. ``` @@ -265,7 +269,6 @@ test('changes the image', async ({ mount }) => { { mediaSelected = mediaName; - console.log({ mediaName }); }} /> ); diff --git a/docs/src/test-fixtures-js.md b/docs/src/test-fixtures-js.md index 0971922d35..57334aa2ef 100644 --- a/docs/src/test-fixtures-js.md +++ b/docs/src/test-fixtures-js.md @@ -43,48 +43,7 @@ Here is how typical test environment setup differs between traditional test styl Click to expand the code for the TodoPage
-```js tab=js-js title="todo-page.js" -export class TodoPage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - this.page = page; - this.inputBox = this.page.locator('input.new-todo'); - this.todoItems = this.page.getByTestId('todo-item'); - } - - async goto() { - await this.page.goto('https://demo.playwright.dev/todomvc/'); - } - - /** - * @param {string} text - */ - async addToDo(text) { - await this.inputBox.fill(text); - await this.inputBox.press('Enter'); - } - - /** - * @param {string} text - */ - async remove(text) { - const todo = this.todoItems.filter({ hasText: text }); - await todo.hover(); - await todo.getByLabel('Delete').click(); - } - - async removeAll() { - while ((await this.todoItems.count()) > 0) { - await this.todoItems.first().hover(); - await this.todoItems.getByLabel('Delete').first().click(); - } - } -} -``` - -```js tab=js-ts title="todo-page.ts" +```js title="todo-page.ts" import type { Page, Locator } from '@playwright/test'; export class TodoPage { @@ -167,48 +126,7 @@ Fixtures have a number of advantages over before/after hooks: Click to expand the code for the TodoPage
-```js tab=js-js title="todo-page.js" -export class TodoPage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - this.page = page; - this.inputBox = this.page.locator('input.new-todo'); - this.todoItems = this.page.getByTestId('todo-item'); - } - - async goto() { - await this.page.goto('https://demo.playwright.dev/todomvc/'); - } - - /** - * @param {string} text - */ - async addToDo(text) { - await this.inputBox.fill(text); - await this.inputBox.press('Enter'); - } - - /** - * @param {string} text - */ - async remove(text) { - const todo = this.todoItems.filter({ hasText: text }); - await todo.hover(); - await todo.getByLabel('Delete').click(); - } - - async removeAll() { - while ((await this.todoItems.count()) > 0) { - await this.todoItems.first().hover(); - await this.todoItems.getByLabel('Delete').first().click(); - } - } -} -``` - -```js tab=js-ts title="todo-page.ts" +```js title="todo-page.ts" import type { Page, Locator } from '@playwright/test'; export class TodoPage { @@ -246,34 +164,7 @@ export class TodoPage {
-```js tab=js-js title="todo.spec.js" -const base = require('@playwright/test'); -const { TodoPage } = require('./todo-page'); - -// Extend basic test by providing a "todoPage" fixture. -const test = base.test.extend({ - todoPage: async ({ page }, use) => { - const todoPage = new TodoPage(page); - await todoPage.goto(); - await todoPage.addToDo('item1'); - await todoPage.addToDo('item2'); - await use(todoPage); - await todoPage.removeAll(); - }, -}); - -test('should add an item', async ({ todoPage }) => { - await todoPage.addToDo('my item'); - // ... -}); - -test('should remove an item', async ({ todoPage }) => { - await todoPage.remove('item1'); - // ... -}); -``` - -```js tab=js-ts title="example.spec.ts" +```js title="example.spec.ts" import { test as base } from '@playwright/test'; import { TodoPage } from './todo-page'; @@ -309,48 +200,8 @@ Below we create two fixtures `todoPage` and `settingsPage` that follow the [Page
Click to expand the code for the TodoPage and SettingsPage
-```js tab=js-js title="todo-page.js" -export class TodoPage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - this.page = page; - this.inputBox = this.page.locator('input.new-todo'); - this.todoItems = this.page.getByTestId('todo-item'); - } - async goto() { - await this.page.goto('https://demo.playwright.dev/todomvc/'); - } - - /** - * @param {string} text - */ - async addToDo(text) { - await this.inputBox.fill(text); - await this.inputBox.press('Enter'); - } - - /** - * @param {string} text - */ - async remove(text) { - const todo = this.todoItems.filter({ hasText: text }); - await todo.hover(); - await todo.getByLabel('Delete').click(); - } - - async removeAll() { - while ((await this.todoItems.count()) > 0) { - await this.todoItems.first().hover(); - await this.todoItems.getByLabel('Delete').first().click(); - } - } -} -``` - -```js tab=js-ts title="todo-page.ts" +```js title="todo-page.ts" import type { Page, Locator } from '@playwright/test'; export class TodoPage { @@ -388,22 +239,7 @@ export class TodoPage { SettingsPage is similar: -```js tab=js-js title="settings-page.js" -export class SettingsPage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - this.page = page; - } - - async switchToDarkMode() { - // ... - } -} -``` - -```js tab=js-ts title="settings-page.ts" +```js title="settings-page.ts" import type { Page } from '@playwright/test'; export class SettingsPage { @@ -419,36 +255,7 @@ export class SettingsPage {
-```js tab=js-js title="my-test.js" -const base = require('@playwright/test'); -const { TodoPage } = require('./todo-page'); -const { SettingsPage } = require('./settings-page'); - -// Extend base test by providing "todoPage" and "settingsPage". -// This new "test" can be used in multiple test files, and each of them will get the fixtures. -exports.test = base.test.extend({ - todoPage: async ({ page }, use) => { - // Set up the fixture. - const todoPage = new TodoPage(page); - await todoPage.goto(); - await todoPage.addToDo('item1'); - await todoPage.addToDo('item2'); - - // Use the fixture value in the test. - await use(todoPage); - - // Clean up the fixture. - await todoPage.removeAll(); - }, - - settingsPage: async ({ page }, use) => { - await use(new SettingsPage(page)); - }, -}); -exports.expect = base.expect; -``` - -```js tab=js-ts title="my-test.ts" +```js title="my-test.ts" import { test as base } from '@playwright/test'; import { TodoPage } from './todo-page'; import { SettingsPage } from './settings-page'; @@ -493,20 +300,7 @@ Just mention fixture in your test function argument, and test runner will take c Below we use the `todoPage` and `settingsPage` fixtures defined above. -```js tab=js-js -const { test, expect } = require('./my-test'); - -test.beforeEach(async ({ settingsPage }) => { - await settingsPage.switchToDarkMode(); -}); - -test('basic test', async ({ todoPage, page }) => { - await todoPage.addToDo('something nice'); - await expect(page.getByTestId('todo-title')).toContainText(['something nice']); -}); -``` - -```js tab=js-ts +```js import { test, expect } from './my-test'; test.beforeEach(async ({ settingsPage }) => { @@ -560,47 +354,7 @@ Playwright Test uses [worker processes](./test-parallel.md) to run test files. S Below we'll create an `account` fixture that will be shared by all tests in the same worker, and override the `page` fixture to login into this account for each test. To generate unique accounts, we'll use the [`property: WorkerInfo.workerIndex`] that is available to any test or fixture. Note the tuple-like syntax for the worker fixture - we have to pass `{scope: 'worker'}` so that test runner sets up this fixture once per worker. -```js tab=js-js title="my-test.js" -const base = require('@playwright/test'); - -exports.test = base.test.extend({ - account: [async ({ browser }, use, workerInfo) => { - // Unique username. - const username = 'user' + workerInfo.workerIndex; - const password = 'verysecure'; - - // Create the account with Playwright. - const page = await browser.newPage(); - await page.goto('/signup'); - await page.getByLabel('User Name').fill(username); - await page.getByLabel('Password').fill(password); - await page.getByText('Sign up').click(); - // Make sure everything is ok. - await expect(page.locator('#result')).toHaveText('Success'); - // Do not forget to cleanup. - await page.close(); - - // Use the account value. - await use({ username, password }); - }, { scope: 'worker' }], - - page: async ({ page, account }, use) => { - // Sign in with our account. - const { username, password } = account; - await page.goto('/signin'); - await page.getByLabel('User Name').fill(username); - await page.getByLabel('Password').fill(password); - await page.getByText('Sign in').click(); - await expect(page.getByTestId('userinfo')).toHaveText(username); - - // Use signed-in page in the test. - await use(page); - }, -}); -exports.expect = base.expect; -``` - -```js tab=js-ts title="my-test.ts" +```js title="my-test.ts" import { test as base } from '@playwright/test'; type Account = { @@ -652,32 +406,7 @@ Automatic fixtures are set up for each test/worker, even when the test does not Here is an example fixture that automatically attaches debug logs when the test fails, so we can later review the logs in the reporter. Note how it uses [TestInfo] object that is available in each test/fixture to retrieve metadata about the test being run. -```js tab=js-js title="my-test.js" -const debug = require('debug'); -const fs = require('fs'); -const base = require('@playwright/test'); - -exports.test = base.test.extend({ - saveLogs: [async ({}, use, testInfo) => { - // Collecting logs during the test. - const logs = []; - debug.log = (...args) => logs.push(args.map(String).join('')); - debug.enable('myserver'); - - await use(); - - // After the test we can check whether the test passed or failed. - if (testInfo.status !== testInfo.expectedStatus) { - // outputPath() API guarantees a unique file name. - const logFile = testInfo.outputPath('logs.txt'); - await fs.promises.writeFile(logFile, logs.join('\n'), 'utf8'); - testInfo.attachments.push({ name: 'logs', contentType: 'text/plain', path: logFile }); - } - }, { auto: true }], -}); -``` - -```js tab=js-ts title="my-test.ts" +```js title="my-test.ts" import * as debug from 'debug'; import * as fs from 'fs'; import { test as base } from '@playwright/test'; @@ -707,22 +436,7 @@ export { expect } from '@playwright/test'; By default, fixture shares timeout with the test. However, for slow fixtures, especially [worker-scoped](#worker-scoped-fixtures) ones, it is convenient to have a separate timeout. This way you can keep the overall test timeout small, and give the slow fixture more time. -```js tab=js-js -const { test: base, expect } = require('@playwright/test'); - -const test = base.extend({ - slowFixture: [async ({}, use) => { - // ... perform a slow operation ... - await use('hello'); - }, { timeout: 60000 }] -}); - -test('example test', async ({ slowFixture }) => { - // ... -}); -``` - -```js tab=js-ts +```js import { test as base, expect } from '@playwright/test'; const test = base.extend<{ slowFixture: string }>({ @@ -752,48 +466,7 @@ Below we'll create a `defaultItem` option in addition to the `todoPage` fixture Click to expand the code for the TodoPage
-```js tab=js-js title="todo-page.js" -export class TodoPage { - /** - * @param {import('@playwright/test').Page} page - */ - constructor(page) { - this.page = page; - this.inputBox = this.page.locator('input.new-todo'); - this.todoItems = this.page.getByTestId('todo-item'); - } - - async goto() { - await this.page.goto('https://demo.playwright.dev/todomvc/'); - } - - /** - * @param {string} text - */ - async addToDo(text) { - await this.inputBox.fill(text); - await this.inputBox.press('Enter'); - } - - /** - * @param {string} text - */ - async remove(text) { - const todo = this.todoItems.filter({ hasText: text }); - await todo.hover(); - await todo.getByLabel('Delete').click(); - } - - async removeAll() { - while ((await this.todoItems.count()) > 0) { - await this.todoItems.first().hover(); - await this.todoItems.getByLabel('Delete').first().click(); - } - } -} -``` - -```js tab=js-ts title="todo-page.ts" +```js title="todo-page.ts" import type { Page, Locator } from '@playwright/test'; export class TodoPage { @@ -832,28 +505,7 @@ export class TodoPage {
-```js tab=js-js title="my-test.js" -const base = require('@playwright/test'); -const { TodoPage } = require('./todo-page'); - -exports.test = base.test.extend({ - // Define an option and provide a default value. - // We can later override it in the config. - defaultItem: ['Something nice', { option: true }], - - // Our "todoPage" fixture depends on the option. - todoPage: async ({ page, defaultItem }, use) => { - const todoPage = new TodoPage(page); - await todoPage.goto(); - await todoPage.addToDo(defaultItem); - await use(todoPage); - await todoPage.removeAll(); - }, -}); -exports.expect = base.expect; -``` - -```js tab=js-ts title="my-test.ts" +```js title="my-test.ts" import { test as base } from '@playwright/test'; import { TodoPage } from './todo-page'; @@ -885,25 +537,7 @@ export { expect } from '@playwright/test'; We can now use `todoPage` fixture as usual, and set the `defaultItem` option in the config file. -```js tab=js-js title="playwright.config.ts" -// @ts-check - -const { defineConfig } = require('@playwright/test'); -module.exports = defineConfig({ - projects: [ - { - name: 'shopping', - use: { defaultItem: 'Buy milk' }, - }, - { - name: 'wellbeing', - use: { defaultItem: 'Exercise!' }, - }, - ] -}); -``` - -```js tab=js-ts title="playwright.config.ts" +```js title="playwright.config.ts" import { defineConfig } from '@playwright/test'; import type { MyOptions } from './my-test'; @@ -932,50 +566,7 @@ Fixtures follow these rules to determine the execution order: Consider the following example: -```js tab=js-js -const { test: base } = require('@playwright/test'); - -const test = base.extend({ - workerFixture: [async ({ browser }) => { - // workerFixture setup... - await use('workerFixture'); - // workerFixture teardown... - }, { scope: 'worker' }], - - autoWorkerFixture: [async ({ browser }) => { - // autoWorkerFixture setup... - await use('autoWorkerFixture'); - // autoWorkerFixture teardown... - }, { scope: 'worker', auto: true }], - - testFixture: [async ({ page, workerFixture }) => { - // testFixture setup... - await use('testFixture'); - // testFixture teardown... - }, { scope: 'test' }], - - autoTestFixture: [async () => { - // autoTestFixture setup... - await use('autoTestFixture'); - // autoTestFixture teardown... - }, { scope: 'test', auto: true }], - - unusedFixture: [async ({ page }) => { - // unusedFixture setup... - await use('unusedFixture'); - // unusedFixture teardown... - }, { scope: 'test' }], -}); - -test.beforeAll(async () => { /* ... */ }); -test.beforeEach(async ({ page }) => { /* ... */ }); -test('first test', async ({ page }) => { /* ... */ }); -test('second test', async ({ testFixture }) => { /* ... */ }); -test.afterEach(async () => { /* ... */ }); -test.afterAll(async () => { /* ... */ }); -``` - -```js tab=js-ts +```js import { test as base } from '@playwright/test'; const test = base.extend<{ @@ -1081,3 +672,30 @@ test('passes', async ({ database, page, a11y }) => { // use database and a11y fixtures. }); ``` + +## Box fixtures + +You can minimize the fixture exposure to the reporters UI and error messages via boxing it: + +```js +import { test as base } from '@playwright/test'; + +export const test = base.extend({ + _helperFixture: [async ({}, use, testInfo) => { + }, { box: true }], +}); +``` + +## Custom fixture title + +You can assign a custom title to a fixture to be used in error messages and in the +reporters UI: + +```js +import { test as base } from '@playwright/test'; + +export const test = base.extend({ + _innerFixture: [async ({}, use, testInfo) => { + }, { title: 'my fixture' }], +}); +``` diff --git a/docs/src/test-parameterize-js.md b/docs/src/test-parameterize-js.md index e6cc791207..8be8009549 100644 --- a/docs/src/test-parameterize-js.md +++ b/docs/src/test-parameterize-js.md @@ -9,13 +9,61 @@ You can either parameterize tests on a test level or on a project level. ## Parameterized Tests ```js title="example.spec.ts" -const people = ['Alice', 'Bob']; -for (const name of people) { - test(`testing with ${name}`, async () => { - // ... - }); +[ + { name: 'Alice', expected: 'Hello, Alice!' }, + { name: 'Bob', expected: 'Hello, Bob!' }, + { name: 'Charlie', expected: 'Hello, Charlie!' }, +].forEach(({ name, expected }) => { // You can also do it with test.describe() or with multiple tests as long the test name is unique. -} + test(`testing with ${name}`, async ({ page }) => { + await page.goto(`https://example.com/greet?name=${name}`); + await expect(page.getByRole('heading')).toHaveText(expected); + }); +}); +``` + +### Before and after hooks + +Most of the time you should put `beforeEach`, `beforeAll`, `afterEach` and `afterAll` hooks outside of `forEach`, so that hooks are executed just once: + +```js title="example.spec.ts" +test.beforeEach(async ({ page }) => { + // ... +}); + +test.afterEach(async ({ page }) => { + // ... +}); + +[ + { name: 'Alice', expected: 'Hello, Alice!' }, + { name: 'Bob', expected: 'Hello, Bob!' }, + { name: 'Charlie', expected: 'Hello, Charlie!' }, +].forEach(({ name, expected }) => { + test(`testing with ${name}`, async ({ page }) => { + await page.goto(`https://example.com/greet?name=${name}`); + await expect(page.getByRole('heading')).toHaveText(expected); + }); +}); +``` + +If you want to have hooks for each test, you can put them inside a `describe()` - so they are executed for each iteration / each invidual test: + +```js title="example.spec.ts" +[ + { name: 'Alice', expected: 'Hello, Alice!' }, + { name: 'Bob', expected: 'Hello, Bob!' }, + { name: 'Charlie', expected: 'Hello, Charlie!' }, +].forEach(({ name, expected }) => { + test.describe(() => { + test.beforeEach(async ({ page }) => { + await page.goto(`https://example.com/greet?name=${name}`); + }); + test(`testing with ${expected}`, async ({ page }) => { + await expect(page.getByRole('heading')).toHaveText(expected); + }); + }); +}); ``` ## Parameterized Projects diff --git a/docs/src/test-sharding-js.md b/docs/src/test-sharding-js.md index 068b7172d0..d0312db811 100644 --- a/docs/src/test-sharding-js.md +++ b/docs/src/test-sharding-js.md @@ -5,7 +5,11 @@ title: "Sharding" ## Introduction -By default, Playwright runs test files in [parallel](./test-parallel.md) and strives for optimal utilization of CPU cores on your machine. In order to achieve even greater parallelisation, you can further scale Playwright test execution by running tests on multiple machines simultaneously. We call this mode of operation "sharding". +By default, Playwright runs test files in [parallel](./test-parallel.md) and strives for optimal utilization of CPU cores on your machine. In order to achieve even greater parallelisation, you can further scale Playwright test execution by running tests on multiple machines simultaneously. We call this mode of operation "sharding". Sharding in Playwright means splitting your tests into smaller parts called "shards". Each shard is like a separate job that can run independently. The whole purpose is to divide your tests to speed up test runtime. + +When you shard your tests, each shard can run on its own, utilizing the available CPU cores. This helps speed up the testing process by doing tasks simultaneously. + +In a CI pipeline, each shard can run as a separate job, making use of the hardware resources available in your CI pipeline, like CPU cores, to run tests faster. ## Sharding tests between multiple machines @@ -18,7 +22,7 @@ npx playwright test --shard=3/4 npx playwright test --shard=4/4 ``` -Now, if you run these shards in parallel on different computers, your test suite completes four times faster. +Now, if you run these shards in parallel on different jobs, your test suite completes four times faster. Note that Playwright can only shard tests that can be run in parallel. By default, this means Playwright will shard test files. Learn about other options in the [parallelism guide](./test-parallel.md). diff --git a/package-lock.json b/package-lock.json index 34f246a8b3..b0941fafc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "playwright-internal", - "version": "1.45.0-next", + "version": "1.46.0-next", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "playwright-internal", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "workspaces": [ "packages/*" @@ -45,7 +45,7 @@ "concurrently": "^6.2.1", "cross-env": "^7.0.3", "dotenv": "^16.0.0", - "electron": "19.0.11", + "electron": "^30.1.2", "enquirer": "^2.3.6", "esbuild": "^0.18.11", "eslint": "^8.55.0", @@ -63,7 +63,7 @@ "ssim.js": "^3.5.0", "typescript": "^5.3.2", "vite": "^5.0.13", - "ws": "^8.5.0", + "ws": "^8.17.1", "xml2js": "^0.5.0", "yaml": "^2.2.2" }, @@ -832,25 +832,24 @@ } }, "node_modules/@electron/get": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", - "integrity": "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", "dev": true, "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", - "got": "^9.6.0", + "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "engines": { - "node": ">=8.6" + "node": ">=12" }, "optionalDependencies": { - "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1" + "global-agent": "^3.0.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -1699,12 +1698,15 @@ ] }, "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@sveltejs/vite-plugin-svelte": { @@ -1745,15 +1747,15 @@ } }, "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "dependencies": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/@types/babel__core": { @@ -1793,6 +1795,18 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/codemirror": { "version": "5.60.15", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", @@ -1816,12 +1830,27 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "18.19.8", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.8.tgz", @@ -1863,6 +1892,15 @@ "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", "dev": true }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", @@ -1902,6 +1940,16 @@ "@types/node": "*" } }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.19.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz", @@ -2723,12 +2771,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2774,69 +2822,33 @@ "node": "*" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } }, "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", - "dev": true - }, - "node_modules/cacheable-request/node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", @@ -3049,21 +3061,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "node_modules/concurrently": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-6.5.1.tgz", @@ -3171,28 +3168,11 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "optional": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -3294,15 +3274,30 @@ } }, "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "dependencies": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-is": { @@ -3320,10 +3315,13 @@ } }, "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } }, "node_modules/define-data-property": { "version": "1.1.1", @@ -3417,28 +3415,22 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "dev": true - }, "node_modules/electron": { - "version": "19.0.11", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.0.11.tgz", - "integrity": "sha512-GPM6C1Ze17/gR4koTE171MxrI5unYfFRgXQdkMdpWM2Cd55LMUrVa0QHCsfKpsaloufv9T65lsOn0uZuzCw5UA==", + "version": "30.1.2", + "resolved": "https://registry.npmjs.org/electron/-/electron-30.1.2.tgz", + "integrity": "sha512-A5CFGwbA+HSXnzwjc8fP2GIezBcAb0uN/VbNGLOW8DHOYn07rvJ/1bAJECHUUzt5zbfohveG3hpMQiYpbktuDw==", "dev": true, "hasInstallScript": true, "dependencies": { - "@electron/get": "^1.14.1", - "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" }, "engines": { - "node": ">= 8.6" + "node": ">= 12.20.55" } }, "node_modules/electron-to-chromium": { @@ -3447,10 +3439,13 @@ "integrity": "sha512-CkKf3ZUVZchr+zDpAlNLEEy2NJJ9T64ULWaDgy3THXXlPVPkLu3VOs9Bac44nebVtdwl2geSj6AxTtGDOxoXhg==" }, "node_modules/electron/node_modules/@types/node": { - "version": "16.18.71", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.71.tgz", - "integrity": "sha512-ARO+458bNJQeNEFuPyT6W+q9ULotmsQzhV3XABsFSxEvRMUYENcBsNAHWYPlahU+UHa5gCVwyKT1Z3f1Wwr26Q==", - "dev": true + "version": "20.12.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz", + "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -3458,16 +3453,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -4068,35 +4053,25 @@ } }, "node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/eyes": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", @@ -4171,9 +4146,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -4356,15 +4331,18 @@ } }, "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { "pump": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-symbol-description": { @@ -4469,9 +4447,9 @@ } }, "node_modules/global-agent/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "optional": true, "dependencies": { @@ -4491,22 +4469,6 @@ "dev": true, "optional": true }, - "node_modules/global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "dev": true, - "optional": true, - "dependencies": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -4572,25 +4534,28 @@ } }, "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "dev": true, "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, "node_modules/graceful-fs": { @@ -4715,6 +4680,19 @@ "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/ignore": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", @@ -4765,13 +4743,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "optional": true - }, "node_modules/internal-slot": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", @@ -5140,12 +5111,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5379,12 +5344,12 @@ } }, "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/lru-cache": { @@ -5671,36 +5636,15 @@ } }, "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "optional": true, - "dependencies": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" + "node": ">=10" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-conf/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm-normalize-package-bin": { @@ -5870,12 +5814,12 @@ } }, "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/p-limit": { @@ -6069,15 +6013,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/prettier": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", @@ -6093,12 +6028,6 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -6119,13 +6048,6 @@ "react-is": "^16.13.1" } }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true, - "optional": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -6180,6 +6102,18 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -6257,21 +6191,6 @@ "npm-normalize-package-bin": "^1.0.0" } }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "node_modules/readdir-scoped-modules": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", @@ -6370,6 +6289,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -6380,12 +6305,15 @@ } }, "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "dev": true, "dependencies": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/reusify": { @@ -6523,12 +6451,6 @@ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, "node_modules/safe-regex-test": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", @@ -6862,15 +6784,6 @@ "node": "*" } }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7064,15 +6977,6 @@ "node": ">=4" } }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7224,12 +7128,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -7323,24 +7221,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dev": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, "node_modules/util-extend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", @@ -8029,9 +7909,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8163,10 +8043,10 @@ } }, "packages/playwright": { - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "bin": { "playwright": "cli.js" @@ -8180,11 +8060,11 @@ }, "packages/playwright-browser-chromium": { "name": "@playwright/browser-chromium", - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "engines": { "node": ">=18" @@ -8192,11 +8072,11 @@ }, "packages/playwright-browser-firefox": { "name": "@playwright/browser-firefox", - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "engines": { "node": ">=18" @@ -8204,22 +8084,22 @@ }, "packages/playwright-browser-webkit": { "name": "@playwright/browser-webkit", - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "engines": { "node": ">=18" } }, "packages/playwright-chromium": { - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "bin": { "playwright": "cli.js" @@ -8229,7 +8109,7 @@ } }, "packages/playwright-core": { - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" @@ -8240,11 +8120,11 @@ }, "packages/playwright-ct-core": { "name": "@playwright/experimental-ct-core", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "playwright": "1.45.0-next", - "playwright-core": "1.45.0-next", + "playwright": "1.46.0-next", + "playwright-core": "1.46.0-next", "vite": "^5.2.8" }, "engines": { @@ -8253,10 +8133,10 @@ }, "packages/playwright-ct-react": { "name": "@playwright/experimental-ct-react", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-react": "^4.2.1" }, "bin": { @@ -8268,10 +8148,10 @@ }, "packages/playwright-ct-react17": { "name": "@playwright/experimental-ct-react17", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-react": "^4.2.1" }, "bin": { @@ -8283,10 +8163,10 @@ }, "packages/playwright-ct-solid": { "name": "@playwright/experimental-ct-solid", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "vite-plugin-solid": "^2.7.0" }, "bin": { @@ -8301,10 +8181,10 @@ }, "packages/playwright-ct-svelte": { "name": "@playwright/experimental-ct-svelte", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@sveltejs/vite-plugin-svelte": "^3.0.1" }, "bin": { @@ -8319,10 +8199,10 @@ }, "packages/playwright-ct-vue": { "name": "@playwright/experimental-ct-vue", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-vue": "^4.2.1" }, "bin": { @@ -8334,10 +8214,10 @@ }, "packages/playwright-ct-vue2": { "name": "@playwright/experimental-ct-vue2", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-vue2": "^2.2.0" }, "bin": { @@ -8386,11 +8266,11 @@ } }, "packages/playwright-firefox": { - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "bin": { "playwright": "cli.js" @@ -8401,10 +8281,10 @@ }, "packages/playwright-test": { "name": "@playwright/test", - "version": "1.45.0-next", + "version": "1.46.0-next", "license": "Apache-2.0", "dependencies": { - "playwright": "1.45.0-next" + "playwright": "1.46.0-next" }, "bin": { "playwright": "cli.js" @@ -8414,11 +8294,11 @@ } }, "packages/playwright-webkit": { - "version": "1.45.0-next", + "version": "1.46.0-next", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "bin": { "playwright": "cli.js" diff --git a/package.json b/package.json index 107aeaa8b1..16e94bc305 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "playwright-internal", "private": true, - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate web browsers", "repository": { "type": "git", @@ -83,7 +83,7 @@ "concurrently": "^6.2.1", "cross-env": "^7.0.3", "dotenv": "^16.0.0", - "electron": "19.0.11", + "electron": "^30.1.2", "enquirer": "^2.3.6", "esbuild": "^0.18.11", "eslint": "^8.55.0", @@ -101,7 +101,7 @@ "ssim.js": "^3.5.0", "typescript": "^5.3.2", "vite": "^5.0.13", - "ws": "^8.5.0", + "ws": "^8.17.1", "xml2js": "^0.5.0", "yaml": "^2.2.2" } diff --git a/packages/playwright-browser-chromium/package.json b/packages/playwright-browser-chromium/package.json index ff8b0ca2c1..c179a56841 100644 --- a/packages/playwright-browser-chromium/package.json +++ b/packages/playwright-browser-chromium/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/browser-chromium", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright package that automatically installs Chromium", "repository": { "type": "git", @@ -27,6 +27,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright-browser-firefox/package.json b/packages/playwright-browser-firefox/package.json index bc01cf5302..4da69d3c80 100644 --- a/packages/playwright-browser-firefox/package.json +++ b/packages/playwright-browser-firefox/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/browser-firefox", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright package that automatically installs Firefox", "repository": { "type": "git", @@ -27,6 +27,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright-browser-webkit/package.json b/packages/playwright-browser-webkit/package.json index f07053171d..3f0bfd168b 100644 --- a/packages/playwright-browser-webkit/package.json +++ b/packages/playwright-browser-webkit/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/browser-webkit", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright package that automatically installs WebKit", "repository": { "type": "git", @@ -27,6 +27,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright-chromium/package.json b/packages/playwright-chromium/package.json index 1305294a70..bb2ec01efc 100644 --- a/packages/playwright-chromium/package.json +++ b/packages/playwright-chromium/package.json @@ -1,6 +1,6 @@ { "name": "playwright-chromium", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate Chromium", "repository": { "type": "git", @@ -30,6 +30,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright-core/ThirdPartyNotices.txt b/packages/playwright-core/ThirdPartyNotices.txt index f0b678af04..3c5a71e20f 100644 --- a/packages/playwright-core/ThirdPartyNotices.txt +++ b/packages/playwright-core/ThirdPartyNotices.txt @@ -46,7 +46,7 @@ This project incorporates components from the projects listed below. The origina - sprintf-js@1.1.3 (https://github.com/alexei/sprintf.js) - stack-utils@2.0.5 (https://github.com/tapjs/stack-utils) - wrappy@1.0.2 (https://github.com/npm/wrappy) -- ws@8.4.2 (https://github.com/websockets/ws) +- ws@8.17.1 (https://github.com/websockets/ws) - yauzl@2.10.0 (https://github.com/thejoshwolfe/yauzl) - yazl@2.5.1 (https://github.com/thejoshwolfe/yazl) @@ -1435,29 +1435,30 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ========================================= END OF wrappy@1.0.2 AND INFORMATION -%% ws@8.4.2 NOTICES AND INFORMATION BEGIN HERE +%% ws@8.17.1 NOTICES AND INFORMATION BEGIN HERE ========================================= Copyright (c) 2011 Einar Otto Stangvik +Copyright (c) 2013 Arnout Kazemier and contributors +Copyright (c) 2016 Luigi Pinca and contributors -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= -END OF ws@8.4.2 AND INFORMATION +END OF ws@8.17.1 AND INFORMATION %% yauzl@2.10.0 NOTICES AND INFORMATION BEGIN HERE ========================================= diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 2a16962304..8dff6bf676 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -3,31 +3,31 @@ "browsers": [ { "name": "chromium", - "revision": "1123", + "revision": "1125", "installByDefault": true, - "browserVersion": "127.0.6533.5" + "browserVersion": "127.0.6533.26" }, { "name": "chromium-tip-of-tree", - "revision": "1231", + "revision": "1236", "installByDefault": false, - "browserVersion": "128.0.6536.0" + "browserVersion": "128.0.6561.0" }, { "name": "firefox", - "revision": "1454", + "revision": "1456", "installByDefault": true, "browserVersion": "127.0" }, { "name": "firefox-beta", - "revision": "1453", + "revision": "1456", "installByDefault": false, - "browserVersion": "127.0b3" + "browserVersion": "128.0b3" }, { "name": "webkit", - "revision": "2035", + "revision": "2041", "installByDefault": true, "revisionOverrides": { "mac10.14": "1446", @@ -46,7 +46,7 @@ }, { "name": "android", - "revision": "1000", + "revision": "1001", "installByDefault": false } ] diff --git a/packages/playwright-core/bundles/utils/package-lock.json b/packages/playwright-core/bundles/utils/package-lock.json index df01638322..66c4cdae12 100644 --- a/packages/playwright-core/bundles/utils/package-lock.json +++ b/packages/playwright-core/bundles/utils/package-lock.json @@ -24,7 +24,7 @@ "signal-exit": "3.0.7", "socks-proxy-agent": "6.1.1", "stack-utils": "2.0.5", - "ws": "8.4.2" + "ws": "8.17.1" }, "devDependencies": { "@types/debug": "^4.1.7", @@ -399,15 +399,15 @@ } }, "node_modules/ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -702,9 +702,9 @@ } }, "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "requires": {} } } diff --git a/packages/playwright-core/bundles/utils/package.json b/packages/playwright-core/bundles/utils/package.json index 786b544a97..8ac0c112fe 100644 --- a/packages/playwright-core/bundles/utils/package.json +++ b/packages/playwright-core/bundles/utils/package.json @@ -25,7 +25,7 @@ "signal-exit": "3.0.7", "socks-proxy-agent": "6.1.1", "stack-utils": "2.0.5", - "ws": "8.4.2" + "ws": "8.17.1" }, "devDependencies": { "@types/debug": "^4.1.7", diff --git a/packages/playwright-core/package.json b/packages/playwright-core/package.json index e057f472b4..c003463218 100644 --- a/packages/playwright-core/package.json +++ b/packages/playwright-core/package.json @@ -1,6 +1,6 @@ { "name": "playwright-core", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate web browsers", "repository": { "type": "git", diff --git a/packages/playwright-core/src/client/browser.ts b/packages/playwright-core/src/client/browser.ts index b6f55e3b29..be47ddeb51 100644 --- a/packages/playwright-core/src/client/browser.ts +++ b/packages/playwright-core/src/client/browser.ts @@ -85,12 +85,6 @@ export class Browser extends ChannelOwner implements ap const response = forReuse ? await this._channel.newContextForReuse(contextOptions) : await this._channel.newContext(contextOptions); const context = BrowserContext.from(response.context); await this._browserType._didCreateContext(context, contextOptions, this._options, options.logger || this._logger); - if (!forReuse && !!process.env.PW_FREEZE_TIME) { - await this._wrapApiCall(async () => { - await context.clock.install({ time: 0 }); - await context.clock.pauseAt(1000); - }, true); - } return context; } diff --git a/packages/playwright-core/src/client/clock.ts b/packages/playwright-core/src/client/clock.ts index 32faa7a4d4..73eb538c26 100644 --- a/packages/playwright-core/src/client/clock.ts +++ b/packages/playwright-core/src/client/clock.ts @@ -58,6 +58,8 @@ function parseTime(time: string | number | Date): { timeNumber?: number, timeStr return { timeNumber: time }; if (typeof time === 'string') return { timeString: time }; + if (!isFinite(time.getTime())) + throw new Error(`Invalid date: ${time}`); return { timeNumber: time.getTime() }; } diff --git a/packages/playwright-core/src/client/electron.ts b/packages/playwright-core/src/client/electron.ts index a9e90b77f2..fcabfa494f 100644 --- a/packages/playwright-core/src/client/electron.ts +++ b/packages/playwright-core/src/client/electron.ts @@ -29,7 +29,7 @@ import type { Page } from './page'; import { ConsoleMessage } from './consoleMessage'; import type { Env, WaitForEventOptions, Headers, BrowserContextOptions } from './types'; import { Waiter } from './waiter'; -import { TargetClosedError } from './errors'; +import { TargetClosedError, isTargetClosedError } from './errors'; type ElectronOptions = Omit & { env?: Env, @@ -116,7 +116,13 @@ export class ElectronApplication extends ChannelOwner {}); + try { + await this._context.close(); + } catch (e) { + if (isTargetClosedError(e)) + return; + throw e; + } } async waitForEvent(event: string, optionsOrPredicate: WaitForEventOptions = {}): Promise { diff --git a/packages/playwright-core/src/client/fetch.ts b/packages/playwright-core/src/client/fetch.ts index 4598ac2418..44314c6fa3 100644 --- a/packages/playwright-core/src/client/fetch.ts +++ b/packages/playwright-core/src/client/fetch.ts @@ -41,6 +41,7 @@ export type FetchOptions = { failOnStatusCode?: boolean, ignoreHTTPSErrors?: boolean, maxRedirects?: number, + maxRetries?: number, }; type NewContextOptions = Omit & { @@ -168,11 +169,11 @@ export class APIRequestContext extends ChannelOwner= 0, `'maxRedirects' should be greater than or equal to '0'`); + assert(options.maxRedirects === undefined || options.maxRedirects >= 0, `'maxRedirects' must be greater than or equal to '0'`); + assert(options.maxRetries === undefined || options.maxRetries >= 0, `'maxRetries' must be greater than or equal to '0'`); const url = options.url !== undefined ? options.url : options.request!.url(); const params = objectToArray(options.params); const method = options.method || options.request?.method(); - const maxRedirects = options.maxRedirects; // Cannot call allHeaders() here as the request may be paused inside route handler. const headersObj = options.headers || options.request?.headers() ; const headers = headersObj ? headersObjectToArray(headersObj) : undefined; @@ -234,7 +235,8 @@ export class APIRequestContext extends ChannelOwner implements api.Ro }); } - async fetch(options: FallbackOverrides & { maxRedirects?: number, timeout?: number } = {}): Promise { + async fetch(options: FallbackOverrides & { maxRedirects?: number, maxRetries?: number, timeout?: number } = {}): Promise { return await this._wrapApiCall(async () => { return await this._context.request._innerFetch({ request: this.request(), data: options.postData, ...options }); }); diff --git a/packages/playwright-core/src/protocol/debug.ts b/packages/playwright-core/src/protocol/debug.ts index 4f44f5941e..f8e1f6c4b2 100644 --- a/packages/playwright-core/src/protocol/debug.ts +++ b/packages/playwright-core/src/protocol/debug.ts @@ -31,6 +31,7 @@ export const slowMoActions = new Set([ 'Page.mouseClick', 'Page.mouseWheel', 'Page.touchscreenTap', + 'Page.touchscreenTouch', 'Frame.blur', 'Frame.check', 'Frame.click', @@ -89,6 +90,7 @@ export const commandsWithTracingSnapshots = new Set([ 'Page.mouseClick', 'Page.mouseWheel', 'Page.touchscreenTap', + 'Page.touchscreenTouch', 'Frame.evalOnSelector', 'Frame.evalOnSelectorAll', 'Frame.addScriptTag', diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 5727192b59..63679d1993 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -182,6 +182,7 @@ scheme.APIRequestContextFetchParams = tObject({ failOnStatusCode: tOptional(tBoolean), ignoreHTTPSErrors: tOptional(tBoolean), maxRedirects: tOptional(tNumber), + maxRetries: tOptional(tNumber), }); scheme.APIRequestContextFetchResult = tObject({ response: tType('APIResponse'), @@ -1236,6 +1237,15 @@ scheme.PageTouchscreenTapParams = tObject({ y: tNumber, }); scheme.PageTouchscreenTapResult = tOptional(tObject({})); +scheme.PageTouchscreenTouchParams = tObject({ + type: tEnum(['touchstart', 'touchend', 'touchmove', 'touchcancel']), + touchPoints: tArray(tObject({ + x: tNumber, + y: tNumber, + id: tOptional(tNumber), + })), +}); +scheme.PageTouchscreenTouchResult = tOptional(tObject({})); scheme.PageAccessibilitySnapshotParams = tObject({ interestingOnly: tOptional(tBoolean), root: tOptional(tChannel(['ElementHandle'])), diff --git a/packages/playwright-core/src/server/android/driver/.gitignore b/packages/playwright-core/src/server/android/driver/.gitignore index aa724b7707..a30139fcbb 100644 --- a/packages/playwright-core/src/server/android/driver/.gitignore +++ b/packages/playwright-core/src/server/android/driver/.gitignore @@ -13,3 +13,4 @@ .externalNativeBuild .cxx local.properties +build/ diff --git a/packages/playwright-core/src/server/android/driver/app/.gitignore b/packages/playwright-core/src/server/android/driver/app/.gitignore deleted file mode 100644 index 42afabfd2a..0000000000 --- a/packages/playwright-core/src/server/android/driver/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build \ No newline at end of file diff --git a/packages/playwright-core/src/server/android/driver/app/build.gradle b/packages/playwright-core/src/server/android/driver/app/build.gradle index d9fe9dffea..9571ac2bf1 100644 --- a/packages/playwright-core/src/server/android/driver/app/build.gradle +++ b/packages/playwright-core/src/server/android/driver/app/build.gradle @@ -8,6 +8,7 @@ android { defaultConfig { applicationId "com.microsoft.playwright.androiddriver" minSdkVersion 21 + // noinspection ExpiredTargetSdkVersion targetSdkVersion 29 versionCode 1 versionName "1.0" @@ -25,10 +26,11 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } + namespace 'com.microsoft.playwright.androiddriver' } dependencies { - androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' } diff --git a/packages/playwright-core/src/server/android/driver/app/src/main/AndroidManifest.xml b/packages/playwright-core/src/server/android/driver/app/src/main/AndroidManifest.xml index ef59bebe4e..3b7aea3023 100644 --- a/packages/playwright-core/src/server/android/driver/app/src/main/AndroidManifest.xml +++ b/packages/playwright-core/src/server/android/driver/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - + - \ No newline at end of file + diff --git a/packages/playwright-core/src/server/android/driver/build.gradle b/packages/playwright-core/src/server/android/driver/build.gradle index c8d7712154..90d35914f6 100644 --- a/packages/playwright-core/src/server/android/driver/build.gradle +++ b/packages/playwright-core/src/server/android/driver/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.1.0" + classpath 'com.android.tools.build:gradle:8.5.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -21,4 +21,4 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +} diff --git a/packages/playwright-core/src/server/android/driver/gradle.properties b/packages/playwright-core/src/server/android/driver/gradle.properties index 52f5917cb0..b08c9fb95d 100644 --- a/packages/playwright-core/src/server/android/driver/gradle.properties +++ b/packages/playwright-core/src/server/android/driver/gradle.properties @@ -16,4 +16,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.jar b/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.jar index f6b961fd5a..249e5832f0 100644 Binary files a/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.jar and b/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.jar differ diff --git a/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.properties b/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.properties index 3ea48480c4..48c0a02ca4 100644 --- a/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.properties +++ b/packages/playwright-core/src/server/android/driver/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Dec 08 09:38:33 PST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/packages/playwright-core/src/server/android/driver/gradlew b/packages/playwright-core/src/server/android/driver/gradlew index cccdd3d517..a69d9cb6c2 100755 --- a/packages/playwright-core/src/server/android/driver/gradlew +++ b/packages/playwright-core/src/server/android/driver/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,101 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done fi +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/packages/playwright-core/src/server/android/driver/gradlew.bat b/packages/playwright-core/src/server/android/driver/gradlew.bat index e95643d6a2..53a6b238d4 100644 --- a/packages/playwright-core/src/server/android/driver/gradlew.bat +++ b/packages/playwright-core/src/server/android/driver/gradlew.bat @@ -1,4 +1,20 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -9,19 +25,22 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,38 +64,26 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/packages/playwright-core/src/server/browserContext.ts b/packages/playwright-core/src/server/browserContext.ts index c1d70372a2..92f3f8a20b 100644 --- a/packages/playwright-core/src/server/browserContext.ts +++ b/packages/playwright-core/src/server/browserContext.ts @@ -24,6 +24,7 @@ import type { Download } from './download'; import type * as frames from './frames'; import { helper } from './helper'; import * as network from './network'; +import { InitScript } from './page'; import type { PageDelegate } from './page'; import { Page, PageBinding } from './page'; import type { Progress, ProgressController } from './progress'; @@ -84,7 +85,7 @@ export abstract class BrowserContext extends SdkObject { private _customCloseHandler?: () => Promise; readonly _tempDirs: string[] = []; private _settingStorageState = false; - readonly initScripts: string[] = []; + readonly initScripts: InitScript[] = []; private _routesInFlight = new Set(); private _debugger!: Debugger; _closeReason: string | undefined; @@ -216,6 +217,7 @@ export abstract class BrowserContext extends SdkObject { await this._resetStorage(); await this._removeExposedBindings(); await this._removeInitScripts(); + this.clock.markAsUninstalled(); // TODO: following can be optimized to not perform noops. if (this._options.permissions) await this.grantPermissions(this._options.permissions); @@ -265,7 +267,7 @@ export abstract class BrowserContext extends SdkObject { protected abstract doGrantPermissions(origin: string, permissions: string[]): Promise; protected abstract doClearPermissions(): Promise; protected abstract doSetHTTPCredentials(httpCredentials?: types.Credentials): Promise; - protected abstract doAddInitScript(expression: string): Promise; + protected abstract doAddInitScript(initScript: InitScript): Promise; protected abstract doRemoveInitScripts(): Promise; protected abstract doExposeBinding(binding: PageBinding): Promise; protected abstract doRemoveExposedBindings(): Promise; @@ -402,9 +404,10 @@ export abstract class BrowserContext extends SdkObject { this._options.httpCredentials = { username, password: password || '' }; } - async addInitScript(script: string) { - this.initScripts.push(script); - await this.doAddInitScript(script); + async addInitScript(source: string) { + const initScript = new InitScript(source); + this.initScripts.push(initScript); + await this.doAddInitScript(initScript); } async _removeInitScripts(): Promise { @@ -653,8 +656,13 @@ export function validateBrowserContextOptions(options: channels.BrowserNewContex throw new Error(`"deviceScaleFactor" option is not supported with null "viewport"`); if (options.noDefaultViewport && !!options.isMobile) throw new Error(`"isMobile" option is not supported with null "viewport"`); - if (options.acceptDownloads === undefined) + if (options.acceptDownloads === undefined && browserOptions.name !== 'electron') options.acceptDownloads = 'accept'; + // Electron requires explicit acceptDownloads: true since we wait for + // https://github.com/electron/electron/pull/41718 to be widely shipped. + // In 6-12 months, we can remove this check. + else if (options.acceptDownloads === undefined && browserOptions.name === 'electron') + options.acceptDownloads = 'internal-browser-default'; if (!options.viewport && !options.noDefaultViewport) options.viewport = { width: 1280, height: 720 }; if (options.recordVideo) { diff --git a/packages/playwright-core/src/server/chromium/chromium.ts b/packages/playwright-core/src/server/chromium/chromium.ts index 6200977473..6a369c918d 100644 --- a/packages/playwright-core/src/server/chromium/chromium.ts +++ b/packages/playwright-core/src/server/chromium/chromium.ts @@ -319,7 +319,7 @@ export class Chromium extends BrowserType { if (process.env.PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW) chromeArguments.push('--headless=new'); else - chromeArguments.push('--headless'); + chromeArguments.push('--headless=old'); chromeArguments.push( '--hide-scrollbars', diff --git a/packages/playwright-core/src/server/chromium/crBrowser.ts b/packages/playwright-core/src/server/chromium/crBrowser.ts index 09a24c1d1b..777ff2eee8 100644 --- a/packages/playwright-core/src/server/chromium/crBrowser.ts +++ b/packages/playwright-core/src/server/chromium/crBrowser.ts @@ -21,7 +21,7 @@ import { Browser } from '../browser'; import { assertBrowserContextIsNotOwned, BrowserContext, verifyGeolocation } from '../browserContext'; import { assert, createGuid } from '../../utils'; import * as network from '../network'; -import type { PageBinding, PageDelegate, Worker } from '../page'; +import type { InitScript, PageBinding, PageDelegate, Worker } from '../page'; import { Page } from '../page'; import { Frame } from '../frames'; import type { Dialog } from '../dialog'; @@ -348,7 +348,7 @@ export class CRBrowserContext extends BrowserContext { override async _initialize() { assert(!Array.from(this._browser._crPages.values()).some(page => page._browserContext === this)); const promises: Promise[] = [super._initialize()]; - if (this._browser.options.name !== 'electron' && this._browser.options.name !== 'clank' && this._options.acceptDownloads !== 'internal-browser-default') { + if (this._browser.options.name !== 'clank' && this._options.acceptDownloads !== 'internal-browser-default') { promises.push(this._browser._session.send('Browser.setDownloadBehavior', { behavior: this._options.acceptDownloads === 'accept' ? 'allowAndName' : 'deny', browserContextId: this._browserContextId, @@ -486,9 +486,9 @@ export class CRBrowserContext extends BrowserContext { await (sw as CRServiceWorker).updateHttpCredentials(); } - async doAddInitScript(source: string) { + async doAddInitScript(initScript: InitScript) { for (const page of this.pages()) - await (page._delegate as CRPage).addInitScript(source); + await (page._delegate as CRPage).addInitScript(initScript); } async doRemoveInitScripts() { diff --git a/packages/playwright-core/src/server/chromium/crInput.ts b/packages/playwright-core/src/server/chromium/crInput.ts index bbfd973d10..47e7cc53e9 100644 --- a/packages/playwright-core/src/server/chromium/crInput.ts +++ b/packages/playwright-core/src/server/chromium/crInput.ts @@ -179,4 +179,19 @@ export class RawTouchscreenImpl implements input.RawTouchscreen { }), ]); } + async touch(eventType: 'touchstart'|'touchmove'|'touchend'|'touchcancel', touchPoints: { x: number, y: number, id?: number }[], modifiers: Set) { + let type: 'touchStart' | 'touchMove' | 'touchEnd' | 'touchCancel'; + switch (eventType) { + case 'touchstart': type = 'touchStart'; break; + case 'touchmove': type = 'touchMove'; break; + case 'touchend': type = 'touchEnd'; break; + case 'touchcancel': type = 'touchCancel'; break; + default: throw new Error('Invalid eventType: ' + eventType); + } + await this._client.send('Input.dispatchTouchEvent', { + type, + touchPoints, + modifiers: toModifiersMask(modifiers) + }); + } } diff --git a/packages/playwright-core/src/server/chromium/crNetworkManager.ts b/packages/playwright-core/src/server/chromium/crNetworkManager.ts index 3752a5c06f..850f466afa 100644 --- a/packages/playwright-core/src/server/chromium/crNetworkManager.ts +++ b/packages/playwright-core/src/server/chromium/crNetworkManager.ts @@ -332,12 +332,13 @@ export class CRNetworkManager { } let route = null; + let headersOverride: types.HeadersArray | undefined; if (requestPausedEvent) { // We do not support intercepting redirects. if (redirectedFrom || (!this._userRequestInterceptionEnabled && this._protocolRequestInterceptionEnabled)) { // Chromium does not preserve header overrides between redirects, so we have to do it ourselves. - const headers = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers; - requestPausedSessionInfo!.session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId, headers }); + headersOverride = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers; + requestPausedSessionInfo!.session._sendMayFail('Fetch.continueRequest', { requestId: requestPausedEvent.requestId, headers: headersOverride }); } else { route = new RouteImpl(requestPausedSessionInfo!.session, requestPausedEvent.requestId); } @@ -353,15 +354,16 @@ export class CRNetworkManager { route, requestWillBeSentEvent, requestPausedEvent, - redirectedFrom + redirectedFrom, + headersOverride: headersOverride || null, }); this._requestIdToRequest.set(requestWillBeSentEvent.requestId, request); - if (requestPausedEvent) { - // We will not receive extra info when intercepting the request. + if (route) { + // We may not receive extra info when intercepting the request. // Use the headers from the Fetch.requestPausedPayload and release the allHeaders() // right away, so that client can call it from the route handler. - request.request.setRawRequestHeaders(headersObjectToArray(requestPausedEvent.request.headers, '\n')); + request.request.setRawRequestHeaders(headersObjectToArray(requestPausedEvent!.request.headers, '\n')); } (this._page?._frameManager || this._serviceWorker)!.requestStarted(request.request, route || undefined); } @@ -568,8 +570,9 @@ class InterceptableRequest { requestWillBeSentEvent: Protocol.Network.requestWillBeSentPayload; requestPausedEvent: Protocol.Fetch.requestPausedPayload | undefined; redirectedFrom: InterceptableRequest | null; + headersOverride: types.HeadersArray | null; }) { - const { session, context, frame, documentId, route, requestWillBeSentEvent, requestPausedEvent, redirectedFrom, serviceWorker } = options; + const { session, context, frame, documentId, route, requestWillBeSentEvent, requestPausedEvent, redirectedFrom, serviceWorker, headersOverride } = options; this.session = session; this._timestamp = requestWillBeSentEvent.timestamp; this._wallTime = requestWillBeSentEvent.wallTime; @@ -591,7 +594,7 @@ class InterceptableRequest { if (entries && entries.length) postDataBuffer = Buffer.concat(entries.map(entry => Buffer.from(entry.bytes!, 'base64'))); - this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersObjectToArray(headers)); + this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersOverride || headersObjectToArray(headers)); } } diff --git a/packages/playwright-core/src/server/chromium/crPage.ts b/packages/playwright-core/src/server/chromium/crPage.ts index 34d1c53cd4..53b96ad403 100644 --- a/packages/playwright-core/src/server/chromium/crPage.ts +++ b/packages/playwright-core/src/server/chromium/crPage.ts @@ -26,7 +26,7 @@ import * as dom from '../dom'; import * as frames from '../frames'; import { helper } from '../helper'; import * as network from '../network'; -import type { PageBinding, PageDelegate } from '../page'; +import type { InitScript, PageBinding, PageDelegate } from '../page'; import { Page, Worker } from '../page'; import type { Progress } from '../progress'; import type * as types from '../types'; @@ -256,8 +256,8 @@ export class CRPage implements PageDelegate { return this._go(+1); } - async addInitScript(source: string, world: types.World = 'main'): Promise { - await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(source, world)); + async addInitScript(initScript: InitScript, world: types.World = 'main'): Promise { + await this._forAllFrameSessions(frame => frame._evaluateOnNewDocument(initScript, world)); } async removeInitScripts() { @@ -511,6 +511,20 @@ class FrameSession { this._addRendererListeners(); } + const localFrames = this._isMainFrame() ? this._page.frames() : [this._page._frameManager.frame(this._targetId)!]; + for (const frame of localFrames) { + // Note: frames might be removed before we send these. + this._client._sendMayFail('Page.createIsolatedWorld', { + frameId: frame._id, + grantUniveralAccess: true, + worldName: UTILITY_WORLD_NAME, + }); + for (const binding of this._crPage._browserContext._pageBindings.values()) + frame.evaluateExpression(binding.source).catch(e => {}); + for (const initScript of this._crPage._browserContext.initScripts) + frame.evaluateExpression(initScript.source).catch(e => {}); + } + const isInitialEmptyPage = this._isMainFrame() && this._page.mainFrame().url() === ':'; if (isInitialEmptyPage) { // Ignore lifecycle events, worlds and bindings for the initial empty page. It is never the final page @@ -520,20 +534,6 @@ class FrameSession { this._eventListeners.push(eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event))); }); } else { - const localFrames = this._isMainFrame() ? this._page.frames() : [this._page._frameManager.frame(this._targetId)!]; - for (const frame of localFrames) { - // Note: frames might be removed before we send these. - this._client._sendMayFail('Page.createIsolatedWorld', { - frameId: frame._id, - grantUniveralAccess: true, - worldName: UTILITY_WORLD_NAME, - }); - for (const binding of this._crPage._browserContext._pageBindings.values()) - frame.evaluateExpression(binding.source).catch(e => {}); - for (const source of this._crPage._browserContext.initScripts) - frame.evaluateExpression(source).catch(e => {}); - } - this._firstNonInitialNavigationCommittedFulfill(); this._eventListeners.push(eventsHelper.addEventListener(this._client, 'Page.lifecycleEvent', event => this._onLifecycleEvent(event))); } @@ -575,10 +575,10 @@ class FrameSession { promises.push(this._updateFileChooserInterception(true)); for (const binding of this._crPage._page.allBindings()) promises.push(this._initBinding(binding)); - for (const source of this._crPage._browserContext.initScripts) - promises.push(this._evaluateOnNewDocument(source, 'main')); - for (const source of this._crPage._page.initScripts) - promises.push(this._evaluateOnNewDocument(source, 'main')); + for (const initScript of this._crPage._browserContext.initScripts) + promises.push(this._evaluateOnNewDocument(initScript, 'main')); + for (const initScript of this._crPage._page.initScripts) + promises.push(this._evaluateOnNewDocument(initScript, 'main')); if (screencastOptions) promises.push(this._startVideoRecording(screencastOptions)); } @@ -1099,9 +1099,9 @@ class FrameSession { await this._client.send('Page.setInterceptFileChooserDialog', { enabled }).catch(() => {}); // target can be closed. } - async _evaluateOnNewDocument(source: string, world: types.World): Promise { + async _evaluateOnNewDocument(initScript: InitScript, world: types.World): Promise { const worldName = world === 'utility' ? UTILITY_WORLD_NAME : undefined; - const { identifier } = await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source, worldName }); + const { identifier } = await this._client.send('Page.addScriptToEvaluateOnNewDocument', { source: initScript.source, worldName }); this._evaluateOnNewDocumentIdentifiers.push(identifier); } diff --git a/packages/playwright-core/src/server/chromium/crProtocolHelper.ts b/packages/playwright-core/src/server/chromium/crProtocolHelper.ts index 36bc712aa6..9458bed124 100644 --- a/packages/playwright-core/src/server/chromium/crProtocolHelper.ts +++ b/packages/playwright-core/src/server/chromium/crProtocolHelper.ts @@ -37,7 +37,7 @@ export function getExceptionMessage(exceptionDetails: Protocol.Runtime.Exception } export async function releaseObject(client: CRSession, objectId: string) { - await client.send('Runtime.releaseObject', { objectId }).catch(error => {}); + await client.send('Runtime.releaseObject', { objectId }).catch(error => { }); } export async function saveProtocolStream(client: CRSession, handle: string, path: string) { @@ -91,7 +91,8 @@ export function exceptionToError(exceptionDetails: Protocol.Runtime.ExceptionDet const err = new Error(message); err.stack = stack; - err.name = name; + const nameOverride = exceptionDetails.exception?.preview?.properties.find(o => o.name === 'name'); + err.name = nameOverride ? nameOverride.value ?? 'Error' : name; return err; } diff --git a/packages/playwright-core/src/server/clock.ts b/packages/playwright-core/src/server/clock.ts index 58a1f72720..5049e4766d 100644 --- a/packages/playwright-core/src/server/clock.ts +++ b/packages/playwright-core/src/server/clock.ts @@ -26,6 +26,10 @@ export class Clock { this._browserContext = browserContext; } + markAsUninstalled() { + this._scriptInstalled = false; + } + async fastForward(ticks: number | string) { await this._installIfNeeded(); const ticksMillis = parseTicks(ticks); @@ -144,5 +148,8 @@ function parseTime(epoch: string | number | undefined): number { return 0; if (typeof epoch === 'number') return epoch; - return new Date(epoch).getTime(); + const parsed = new Date(epoch); + if (!isFinite(parsed.getTime())) + throw new Error(`Invalid date: ${epoch}`); + return parsed.getTime(); } diff --git a/packages/playwright-core/src/server/deviceDescriptorsSource.json b/packages/playwright-core/src/server/deviceDescriptorsSource.json index db818f07e7..ee4e655e5a 100644 --- a/packages/playwright-core/src/server/deviceDescriptorsSource.json +++ b/packages/playwright-core/src/server/deviceDescriptorsSource.json @@ -110,7 +110,7 @@ "defaultBrowserType": "webkit" }, "Galaxy S5": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -121,7 +121,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -132,7 +132,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 360, "height": 740 @@ -143,7 +143,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 740, "height": 360 @@ -154,7 +154,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 320, "height": 658 @@ -165,7 +165,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+ landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 658, "height": 320 @@ -176,7 +176,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 712, "height": 1138 @@ -187,7 +187,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 1138, "height": 712 @@ -978,7 +978,7 @@ "defaultBrowserType": "webkit" }, "LG Optimus L70": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -989,7 +989,7 @@ "defaultBrowserType": "chromium" }, "LG Optimus L70 landscape": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1000,7 +1000,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1011,7 +1011,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1022,7 +1022,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1033,7 +1033,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1044,7 +1044,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 800, "height": 1280 @@ -1055,7 +1055,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 1280, "height": 800 @@ -1066,7 +1066,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -1077,7 +1077,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1088,7 +1088,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1099,7 +1099,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1110,7 +1110,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1121,7 +1121,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1132,7 +1132,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1143,7 +1143,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1154,7 +1154,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1165,7 +1165,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1176,7 +1176,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 600, "height": 960 @@ -1187,7 +1187,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "viewport": { "width": 960, "height": 600 @@ -1242,7 +1242,7 @@ "defaultBrowserType": "webkit" }, "Pixel 2": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 411, "height": 731 @@ -1253,7 +1253,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 731, "height": 411 @@ -1264,7 +1264,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 411, "height": 823 @@ -1275,7 +1275,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 823, "height": 411 @@ -1286,7 +1286,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 393, "height": 786 @@ -1297,7 +1297,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 786, "height": 393 @@ -1308,7 +1308,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 353, "height": 745 @@ -1319,7 +1319,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 745, "height": 353 @@ -1330,7 +1330,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G)": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "width": 412, "height": 892 @@ -1345,7 +1345,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G) landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "height": 892, "width": 412 @@ -1360,7 +1360,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "width": 393, "height": 851 @@ -1375,7 +1375,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "width": 851, "height": 393 @@ -1390,7 +1390,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "width": 412, "height": 915 @@ -1405,7 +1405,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "screen": { "width": 915, "height": 412 @@ -1420,7 +1420,7 @@ "defaultBrowserType": "chromium" }, "Moto G4": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1431,7 +1431,7 @@ "defaultBrowserType": "chromium" }, "Moto G4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1442,7 +1442,7 @@ "defaultBrowserType": "chromium" }, "Desktop Chrome HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "screen": { "width": 1792, "height": 1120 @@ -1457,7 +1457,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36 Edg/127.0.6533.5", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36 Edg/127.0.6533.26", "screen": { "width": 1792, "height": 1120 @@ -1502,7 +1502,7 @@ "defaultBrowserType": "webkit" }, "Desktop Chrome": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36", "screen": { "width": 1920, "height": 1080 @@ -1517,7 +1517,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.5 Safari/537.36 Edg/127.0.6533.5", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.26 Safari/537.36 Edg/127.0.6533.26", "screen": { "width": 1920, "height": 1080 diff --git a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts index 3101cd051d..9acc7378b2 100644 --- a/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts +++ b/packages/playwright-core/src/server/dispatchers/pageDispatcher.ts @@ -265,6 +265,10 @@ export class PageDispatcher extends Dispatcher { const rootAXNode = await this._page.accessibility.snapshot({ interestingOnly: params.interestingOnly, diff --git a/packages/playwright-core/src/server/fetch.ts b/packages/playwright-core/src/server/fetch.ts index 0f87e0046b..c02781f748 100644 --- a/packages/playwright-core/src/server/fetch.ts +++ b/packages/playwright-core/src/server/fetch.ts @@ -201,7 +201,7 @@ export abstract class APIRequestContext extends SdkObject { setHeader(headers, 'content-length', String(postData.byteLength)); const controller = new ProgressController(metadata, this); const fetchResponse = await controller.run(progress => { - return this._sendRequest(progress, requestUrl, options, postData); + return this._sendRequestWithRetries(progress, requestUrl, options, postData, params.maxRetries); }); const fetchUid = this._storeResponseBody(fetchResponse.body); this.fetchLog.set(fetchUid, controller.metadata.log); @@ -247,6 +247,28 @@ export abstract class APIRequestContext extends SdkObject { } } + private async _sendRequestWithRetries(progress: Progress, url: URL, options: SendRequestOptions, postData?: Buffer, maxRetries?: number): Promise & { body: Buffer }>{ + maxRetries ??= 0; + let backoff = 250; + for (let i = 0; i <= maxRetries; i++) { + try { + return await this._sendRequest(progress, url, options, postData); + } catch (e) { + if (maxRetries === 0) + throw e; + if (i === maxRetries || (options.deadline && monotonicTime() + backoff > options.deadline)) + throw new Error(`Failed after ${i + 1} attempt(s): ${e}`); + // Retry on connection reset only. + if (e.code !== 'ECONNRESET') + throw e; + progress.log(` Received ECONNRESET, will retry after ${backoff}ms.`); + await new Promise(f => setTimeout(f, backoff)); + backoff *= 2; + } + } + throw new Error('Unreachable'); + } + private async _sendRequest(progress: Progress, url: URL, options: SendRequestOptions, postData?: Buffer): Promise & { body: Buffer }>{ await this._updateRequestCookieHeader(url, options.headers); diff --git a/packages/playwright-core/src/server/firefox/ffBrowser.ts b/packages/playwright-core/src/server/firefox/ffBrowser.ts index ae26d0994a..7ed2d8cb2f 100644 --- a/packages/playwright-core/src/server/firefox/ffBrowser.ts +++ b/packages/playwright-core/src/server/firefox/ffBrowser.ts @@ -21,7 +21,7 @@ import type { BrowserOptions } from '../browser'; import { Browser } from '../browser'; import { assertBrowserContextIsNotOwned, BrowserContext, verifyGeolocation } from '../browserContext'; import * as network from '../network'; -import type { Page, PageBinding, PageDelegate } from '../page'; +import type { InitScript, Page, PageBinding, PageDelegate } from '../page'; import type { ConnectionTransport } from '../transport'; import type * as types from '../types'; import type * as channels from '@protocol/channels'; @@ -352,8 +352,8 @@ export class FFBrowserContext extends BrowserContext { await this._browser.session.send('Browser.setHTTPCredentials', { browserContextId: this._browserContextId, credentials }); } - async doAddInitScript(source: string) { - await this._browser.session.send('Browser.setInitScripts', { browserContextId: this._browserContextId, scripts: this.initScripts.map(script => ({ script })) }); + async doAddInitScript(initScript: InitScript) { + await this._browser.session.send('Browser.setInitScripts', { browserContextId: this._browserContextId, scripts: this.initScripts.map(script => ({ script: script.source })) }); } async doRemoveInitScripts() { diff --git a/packages/playwright-core/src/server/firefox/ffInput.ts b/packages/playwright-core/src/server/firefox/ffInput.ts index 66f35399a5..fcf53ee9fc 100644 --- a/packages/playwright-core/src/server/firefox/ffInput.ts +++ b/packages/playwright-core/src/server/firefox/ffInput.ts @@ -166,4 +166,8 @@ export class RawTouchscreenImpl implements input.RawTouchscreen { modifiers: toModifiersMask(modifiers), }); } + + async touch(eventType: 'touchstart'|'touchmove'|'touchend'|'touchcancel', touchPoints: { x: number, y: number, id?: number }[], modifiers: Set) { + throw new Error('Not implemented yet.'); + } } diff --git a/packages/playwright-core/src/server/firefox/ffPage.ts b/packages/playwright-core/src/server/firefox/ffPage.ts index 77fcd480bb..aac22d5e50 100644 --- a/packages/playwright-core/src/server/firefox/ffPage.ts +++ b/packages/playwright-core/src/server/firefox/ffPage.ts @@ -21,6 +21,7 @@ import type * as frames from '../frames'; import type { RegisteredListener } from '../../utils/eventsHelper'; import { eventsHelper } from '../../utils/eventsHelper'; import type { PageBinding, PageDelegate } from '../page'; +import { InitScript } from '../page'; import { Page, Worker } from '../page'; import type * as types from '../types'; import { getAccessibilityTree } from './ffAccessibility'; @@ -56,7 +57,7 @@ export class FFPage implements PageDelegate { private _eventListeners: RegisteredListener[]; private _workers = new Map(); private _screencastId: string | undefined; - private _initScripts: { script: string, worldName?: string }[] = []; + private _initScripts: { initScript: InitScript, worldName?: string }[] = []; constructor(session: FFSession, browserContext: FFBrowserContext, opener: FFPage | null) { this._session = session; @@ -113,7 +114,7 @@ export class FFPage implements PageDelegate { }); // Ideally, we somehow ensure that utility world is created before Page.ready arrives, but currently it is racy. // Therefore, we can end up with an initialized page without utility world, although very unlikely. - this.addInitScript('', UTILITY_WORLD_NAME).catch(e => this._markAsError(e)); + this.addInitScript(new InitScript(''), UTILITY_WORLD_NAME).catch(e => this._markAsError(e)); } potentiallyUninitializedPage(): Page { @@ -406,9 +407,9 @@ export class FFPage implements PageDelegate { return success; } - async addInitScript(script: string, worldName?: string): Promise { - this._initScripts.push({ script, worldName }); - await this._session.send('Page.setInitScripts', { scripts: this._initScripts }); + async addInitScript(initScript: InitScript, worldName?: string): Promise { + this._initScripts.push({ initScript, worldName }); + await this._session.send('Page.setInitScripts', { scripts: this._initScripts.map(s => ({ script: s.initScript.source, worldName: s.worldName })) }); } async removeInitScripts() { diff --git a/packages/playwright-core/src/server/har/harTracer.ts b/packages/playwright-core/src/server/har/harTracer.ts index 289a4f6d87..268da9e84d 100644 --- a/packages/playwright-core/src/server/har/harTracer.ts +++ b/packages/playwright-core/src/server/har/harTracer.ts @@ -434,12 +434,6 @@ export class HarTracer { const pageEntry = this._createPageEntryIfNeeded(page); const request = response.request(); - // Prefer "response received" time over "request sent" time - // for the purpose of matching requests that were used in a particular snapshot. - // Note that both snapshot time and request time are taken here in the Node process. - if (this._options.includeTraceInfo) - harEntry._monotonicTime = monotonicTime(); - harEntry.response = { status: response.status(), statusText: response.statusText(), diff --git a/packages/playwright-core/src/server/injected/clock.ts b/packages/playwright-core/src/server/injected/clock.ts index e566597e8d..26342f0223 100644 --- a/packages/playwright-core/src/server/injected/clock.ts +++ b/packages/playwright-core/src/server/injected/clock.ts @@ -705,11 +705,12 @@ export function install(globalObject: WindowOrWorkerGlobalScope, config: Install } export function inject(globalObject: WindowOrWorkerGlobalScope) { + const builtin = platformOriginals(globalObject).bound; const { clock: controller } = install(globalObject); controller.resume(); return { controller, - builtin: platformOriginals(globalObject).bound, + builtin, }; } diff --git a/packages/playwright-core/src/server/injected/injectedScript.ts b/packages/playwright-core/src/server/injected/injectedScript.ts index b7a395cfed..2323648bae 100644 --- a/packages/playwright-core/src/server/injected/injectedScript.ts +++ b/packages/playwright-core/src/server/injected/injectedScript.ts @@ -33,7 +33,7 @@ import { getChecked, getAriaDisabled, getAriaRole, getElementAccessibleName, get import { kLayoutSelectorNames, type LayoutSelectorName, layoutSelectorScore } from './layoutSelectorUtils'; import { asLocator } from '../../utils/isomorphic/locatorGenerators'; import type { Language } from '../../utils/isomorphic/locatorGenerators'; -import { normalizeWhiteSpace, trimStringWithEllipsis } from '../../utils/isomorphic/stringUtils'; +import { cacheNormalizedWhitespaces, normalizeWhiteSpace, trimStringWithEllipsis } from '../../utils/isomorphic/stringUtils'; export type FrameExpectParams = Omit & { expectedValue?: any }; @@ -66,7 +66,7 @@ export class InjectedScript { // eslint-disable-next-line no-restricted-globals readonly window: Window & typeof globalThis; readonly document: Document; - readonly utils = { isInsideScope, elementText, asLocator, normalizeWhiteSpace }; + readonly utils = { isInsideScope, elementText, asLocator, normalizeWhiteSpace, cacheNormalizedWhitespaces }; // eslint-disable-next-line no-restricted-globals constructor(window: Window & typeof globalThis, isUnderTest: boolean, sdkLanguage: Language, testIdAttributeNameForStrictErrorAndConsoleCodegen: string, stableRafCount: number, browserName: string, customEngines: { name: string, engine: SelectorEngine }[]) { @@ -478,7 +478,7 @@ export class InjectedScript { element = element.closest('button, [role=button], [role=checkbox], [role=radio]') || element; } if (behavior === 'follow-label') { - if (!element.matches('input, textarea, button, select, [role=button], [role=checkbox], [role=radio]') && + if (!element.matches('a, input, textarea, button, select, [role=link], [role=button], [role=checkbox], [role=radio]') && !(element as any).isContentEditable) { // Go up to the label that might be connected to the input/textarea. element = element.closest('label') || element; diff --git a/packages/playwright-core/src/server/injected/recorder/recorder.ts b/packages/playwright-core/src/server/injected/recorder/recorder.ts index 3977d69aef..4cfa512a4f 100644 --- a/packages/playwright-core/src/server/injected/recorder/recorder.ts +++ b/packages/playwright-core/src/server/injected/recorder/recorder.ts @@ -356,7 +356,7 @@ class RecordActionTool implements RecorderTool { return; this._performAction({ name: 'select', - selector: this._hoveredModel!.selector, + selector: this._activeModel!.selector, options: [...selectElement.selectedOptions].map(option => option.value), signals: [] }); @@ -578,8 +578,8 @@ class TextAssertionTool implements RecorderTool { onPointerUp(event: PointerEvent) { const target = this._hoverHighlight?.elements[0]; - if (this._kind === 'value' && target && target.nodeName === 'INPUT' && (target as HTMLInputElement).disabled) { - // Click on a disabled input does not produce a "click" event, but we still want + if (this._kind === 'value' && target && (target.nodeName === 'INPUT' || target.nodeName === 'SELECT') && (target as HTMLInputElement).disabled) { + // Click on a disabled input (or select) does not produce a "click" event, but we still want // to assert the value. this._commitAssertValue(); } @@ -973,7 +973,7 @@ export class Recorder { body[data-pw-cursor=text] *, body[data-pw-cursor=text] *::after { cursor: text !important; } `); this.installListeners(); - + injectedScript.utils.cacheNormalizedWhitespaces(); if (injectedScript.isUnderTest) console.error('Recorder script ready for test'); // eslint-disable-line no-console } diff --git a/packages/playwright-core/src/server/injected/selectorGenerator.ts b/packages/playwright-core/src/server/injected/selectorGenerator.ts index 7e4f51b1b2..eaa330a0e5 100644 --- a/packages/playwright-core/src/server/injected/selectorGenerator.ts +++ b/packages/playwright-core/src/server/injected/selectorGenerator.ts @@ -528,7 +528,7 @@ function suitableTextAlternatives(text: string) { const match = text.match(/^([\d.,]+)[^.,\w]/); const leadingNumberLength = match ? match[1].length : 0; if (leadingNumberLength) { - const alt = text.substring(leadingNumberLength).trimStart(); + const alt = trimWordBoundary(text.substring(leadingNumberLength).trimStart(), 80); result.push({ text: alt, scoreBouns: alt.length <= 30 ? 2 : 1 }); } } @@ -537,7 +537,7 @@ function suitableTextAlternatives(text: string) { const match = text.match(/[^.,\w]([\d.,]+)$/); const trailingNumberLength = match ? match[1].length : 0; if (trailingNumberLength) { - const alt = text.substring(0, text.length - trailingNumberLength).trimEnd(); + const alt = trimWordBoundary(text.substring(0, text.length - trailingNumberLength).trimEnd(), 80); result.push({ text: alt, scoreBouns: alt.length <= 30 ? 2 : 1 }); } } diff --git a/packages/playwright-core/src/server/input.ts b/packages/playwright-core/src/server/input.ts index f09f91b86f..501874322c 100644 --- a/packages/playwright-core/src/server/input.ts +++ b/packages/playwright-core/src/server/input.ts @@ -308,6 +308,7 @@ function buildLayoutClosure(layout: keyboardLayout.KeyboardLayout): Map): Promise; + touch(type: 'touchstart'|'touchmove'|'touchend'|'touchcancel', touchPoints: { x: number, y: number, id?: number }[], modifiers: Set): Promise; } export class Touchscreen { @@ -326,4 +327,19 @@ export class Touchscreen { throw new Error('hasTouch must be enabled on the browser context before using the touchscreen.'); await this._raw.tap(x, y, this._page.keyboard._modifiers()); } + async touch(type: 'touchstart'|'touchmove'|'touchend'|'touchcancel', touchPoints: { x: number, y: number, id?: number }[], metadata?: CallMetadata) { + if (metadata && touchPoints.length === 1) + metadata.point = { x: touchPoints[0].x, y: touchPoints[0].y }; + if (!this._page._browserContext._options.hasTouch) + throw new Error('hasTouch must be enabled on the browser context before using the touchscreen.'); + const ids = new Set(); + for (const point of touchPoints) { + if (point.id !== undefined) { + if (ids.has(point.id)) + throw new Error(`Duplicate touch point id: ${point.id}`); + ids.add(point.id); + } + } + await this._raw.touch(type, touchPoints, this._page.keyboard._modifiers()); + } } diff --git a/packages/playwright-core/src/server/page.ts b/packages/playwright-core/src/server/page.ts index 28ff203a3c..da9063821c 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, isError } from '../utils'; +import { LongStandingScope, assert, createGuid, isError } from '../utils'; import { ManualPromise } from '../utils/manualPromise'; import { debugLogger } from '../utils/debugLogger'; import type { ImageComparatorOptions } from '../utils/comparators'; @@ -56,7 +56,7 @@ export interface PageDelegate { goForward(): Promise; exposeBinding(binding: PageBinding): Promise; removeExposedBindings(): Promise; - addInitScript(source: string): Promise; + addInitScript(initScript: InitScript): Promise; removeInitScripts(): Promise; closePage(runBeforeUnload: boolean): Promise; potentiallyUninitializedPage(): Page; @@ -154,7 +154,7 @@ export class Page extends SdkObject { private _emulatedMedia: Partial = {}; private _interceptFileChooser = false; private readonly _pageBindings = new Map(); - readonly initScripts: string[] = []; + readonly initScripts: InitScript[] = []; readonly _screenshotter: Screenshotter; readonly _frameManager: frames.FrameManager; readonly accessibility: accessibility.Accessibility; @@ -527,8 +527,9 @@ export class Page extends SdkObject { } async addInitScript(source: string) { - this.initScripts.push(source); - await this._delegate.addInitScript(source); + const initScript = new InitScript(source); + this.initScripts.push(initScript); + await this._delegate.addInitScript(initScript); } async _removeInitScripts() { @@ -905,6 +906,22 @@ function addPageBinding(bindingName: string, needsHandle: boolean, utilityScript (globalThis as any)[bindingName].__installed = true; } +export class InitScript { + readonly source: string; + + constructor(source: string) { + const guid = createGuid(); + this.source = `(() => { + globalThis.__pwInitScripts = globalThis.__pwInitScripts || {}; + const hasInitScript = globalThis.__pwInitScripts[${JSON.stringify(guid)}]; + if (hasInitScript) + return; + globalThis.__pwInitScripts[${JSON.stringify(guid)}] = true; + ${source} + })();`; + } +} + class FrameThrottler { private _acks: (() => void)[] = []; private _defaultInterval: number; diff --git a/packages/playwright-core/src/server/webkit/protocol.d.ts b/packages/playwright-core/src/server/webkit/protocol.d.ts index 389ce6b7ac..9e71534a17 100644 --- a/packages/playwright-core/src/server/webkit/protocol.d.ts +++ b/packages/playwright-core/src/server/webkit/protocol.d.ts @@ -2122,6 +2122,10 @@ export module Protocol { * Array of DOMNode ids of any children marked as selected. */ selectedChildNodeIds?: NodeId[]; + /** + * On / off state of switch form controls. + */ + switchState?: "off"|"on"; } /** * A structure holding an RGBA color. @@ -5009,6 +5013,23 @@ might return multiple quads for inline nodes. * UTC time in seconds, counted from January 1, 1970. */ export type TimeSinceEpoch = number; + /** + * Touch point. + */ + export interface TouchPoint { + /** + * X coordinate of the event relative to the main frame's viewport in CSS pixels. + */ + x: number; + /** + * Y coordinate of the event relative to the main frame's viewport in CSS pixels. + */ + y: number; + /** + * Identifier used to track touch sources between events, must be unique within an event. + */ + id: number; + } /** @@ -5165,6 +5186,26 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the } export type dispatchTapEventReturnValue = { } + /** + * Dispatches a touch event to the page. + */ + export type dispatchTouchEventParameters = { + /** + * Type of the touch event. + */ + type: "touchStart"|"touchMove"|"touchEnd"|"touchCancel"; + /** + * Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 +(default: 0). + */ + modifiers?: number; + /** + * List of touch points + */ + touchPoints?: TouchPoint[]; + } + export type dispatchTouchEventReturnValue = { + } } export module Inspector { @@ -9528,6 +9569,7 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the "Input.dispatchMouseEvent": Input.dispatchMouseEventParameters; "Input.dispatchWheelEvent": Input.dispatchWheelEventParameters; "Input.dispatchTapEvent": Input.dispatchTapEventParameters; + "Input.dispatchTouchEvent": Input.dispatchTouchEventParameters; "Inspector.enable": Inspector.enableParameters; "Inspector.disable": Inspector.disableParameters; "Inspector.initialized": Inspector.initializedParameters; @@ -9839,6 +9881,7 @@ the top of the viewport and Y increases as it proceeds towards the bottom of the "Input.dispatchMouseEvent": Input.dispatchMouseEventReturnValue; "Input.dispatchWheelEvent": Input.dispatchWheelEventReturnValue; "Input.dispatchTapEvent": Input.dispatchTapEventReturnValue; + "Input.dispatchTouchEvent": Input.dispatchTouchEventReturnValue; "Inspector.enable": Inspector.enableReturnValue; "Inspector.disable": Inspector.disableReturnValue; "Inspector.initialized": Inspector.initializedReturnValue; diff --git a/packages/playwright-core/src/server/webkit/wkBrowser.ts b/packages/playwright-core/src/server/webkit/wkBrowser.ts index a8541e73cf..9eedec410b 100644 --- a/packages/playwright-core/src/server/webkit/wkBrowser.ts +++ b/packages/playwright-core/src/server/webkit/wkBrowser.ts @@ -22,7 +22,7 @@ import type { RegisteredListener } from '../../utils/eventsHelper'; import { assert } from '../../utils'; import { eventsHelper } from '../../utils/eventsHelper'; import * as network from '../network'; -import type { Page, PageBinding, PageDelegate } from '../page'; +import type { InitScript, Page, PageBinding, PageDelegate } from '../page'; import type { ConnectionTransport } from '../transport'; import type * as types from '../types'; import type * as channels from '@protocol/channels'; @@ -315,7 +315,7 @@ export class WKBrowserContext extends BrowserContext { await (page._delegate as WKPage).updateHttpCredentials(); } - async doAddInitScript(source: string) { + async doAddInitScript(initScript: InitScript) { for (const page of this.pages()) await (page._delegate as WKPage)._updateBootstrapScript(); } diff --git a/packages/playwright-core/src/server/webkit/wkInput.ts b/packages/playwright-core/src/server/webkit/wkInput.ts index 0732f246d1..88afa774c8 100644 --- a/packages/playwright-core/src/server/webkit/wkInput.ts +++ b/packages/playwright-core/src/server/webkit/wkInput.ts @@ -182,4 +182,20 @@ export class RawTouchscreenImpl implements input.RawTouchscreen { modifiers: toModifiersMask(modifiers), }); } + + async touch(eventType: 'touchstart'|'touchmove'|'touchend'|'touchcancel', touchPoints: { x: number, y: number, id?: number }[], modifiers: Set) { + let type: 'touchStart' | 'touchMove' | 'touchEnd' | 'touchCancel'; + switch (eventType) { + case 'touchstart': type = 'touchStart'; break; + case 'touchmove': type = 'touchMove'; break; + case 'touchend': type = 'touchEnd'; break; + case 'touchcancel': type = 'touchCancel'; break; + default: throw new Error('Invalid eventType: ' + eventType); + } + await this._pageProxySession.send('Input.dispatchTouchEvent', { + type, + touchPoints: touchPoints.map(p => ({ ...p, id: p.id || 0 })), + modifiers: toModifiersMask(modifiers) + }); + } } diff --git a/packages/playwright-core/src/server/webkit/wkPage.ts b/packages/playwright-core/src/server/webkit/wkPage.ts index 9507f187e5..adfd06c05e 100644 --- a/packages/playwright-core/src/server/webkit/wkPage.ts +++ b/packages/playwright-core/src/server/webkit/wkPage.ts @@ -30,7 +30,7 @@ import { eventsHelper } from '../../utils/eventsHelper'; import { helper } from '../helper'; import type { JSHandle } from '../javascript'; import * as network from '../network'; -import type { PageBinding, PageDelegate } from '../page'; +import type { InitScript, PageBinding, PageDelegate } from '../page'; import { Page } from '../page'; import type { Progress } from '../progress'; import type * as types from '../types'; @@ -777,7 +777,7 @@ export class WKPage implements PageDelegate { await this._updateBootstrapScript(); } - async addInitScript(script: string): Promise { + async addInitScript(initScript: InitScript): Promise { await this._updateBootstrapScript(); } @@ -797,8 +797,8 @@ export class WKPage implements PageDelegate { for (const binding of this._page.allBindings()) scripts.push(binding.source); - scripts.push(...this._browserContext.initScripts); - scripts.push(...this._page.initScripts); + scripts.push(...this._browserContext.initScripts.map(s => s.source)); + scripts.push(...this._page.initScripts.map(s => s.source)); return scripts.join(';\n'); } diff --git a/packages/playwright-core/src/utils/happy-eyeballs.ts b/packages/playwright-core/src/utils/happy-eyeballs.ts index 4576da7899..37d5c1b271 100644 --- a/packages/playwright-core/src/utils/happy-eyeballs.ts +++ b/packages/playwright-core/src/utils/happy-eyeballs.ts @@ -45,8 +45,9 @@ class HttpsHappyEyeballsAgent extends https.Agent { } } -export const httpsHappyEyeballsAgent = new HttpsHappyEyeballsAgent(); -export const httpHappyEyeballsAgent = new HttpHappyEyeballsAgent(); +// These options are aligned with the default Node.js globalAgent options. +export const httpsHappyEyeballsAgent = new HttpsHappyEyeballsAgent({ keepAlive: true }); +export const httpHappyEyeballsAgent = new HttpHappyEyeballsAgent({ keepAlive: true }); export async function createSocket(host: string, port: number): Promise { return new Promise((resolve, reject) => { diff --git a/packages/playwright-core/src/utils/isomorphic/stringUtils.ts b/packages/playwright-core/src/utils/isomorphic/stringUtils.ts index 19953ef5bb..df213a1085 100644 --- a/packages/playwright-core/src/utils/isomorphic/stringUtils.ts +++ b/packages/playwright-core/src/utils/isomorphic/stringUtils.ts @@ -67,8 +67,19 @@ function cssEscapeOne(s: string, i: number): string { return '\\' + s.charAt(i); } +let normalizedWhitespaceCache: Map | undefined; + +export function cacheNormalizedWhitespaces() { + normalizedWhitespaceCache = new Map(); +} + export function normalizeWhiteSpace(text: string): string { - return text.replace(/\u200b/g, '').trim().replace(/\s+/g, ' '); + let result = normalizedWhitespaceCache?.get(text); + if (result === undefined) { + result = text.replace(/\u200b/g, '').trim().replace(/\s+/g, ' '); + normalizedWhitespaceCache?.set(text, result); + } + return result; } export function normalizeEscapedRegexQuotes(source: string) { diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index 28250cb271..3152c067a3 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -814,21 +814,6 @@ export interface Page { * })(); * ``` * - * An example of passing an element handle: - * - * ```js - * await page.exposeBinding('clicked', async (source, element) => { - * console.log(await element.textContent()); - * }, { handle: true }); - * await page.setContent(` - * - *
Click me
- *
Or click me
- * `); - * ``` - * * @param name Name of the function on the window object. * @param callback Callback function that will be called in the Playwright's context. * @param options @@ -875,21 +860,6 @@ export interface Page { * })(); * ``` * - * An example of passing an element handle: - * - * ```js - * await page.exposeBinding('clicked', async (source, element) => { - * console.log(await element.textContent()); - * }, { handle: true }); - * await page.setContent(` - * - *
Click me
- *
Or click me
- * `); - * ``` - * * @param name Name of the function on the window object. * @param callback Callback function that will be called in the Playwright's context. * @param options @@ -7637,21 +7607,6 @@ export interface BrowserContext { * })(); * ``` * - * An example of passing an element handle: - * - * ```js - * await context.exposeBinding('clicked', async (source, element) => { - * console.log(await element.textContent()); - * }, { handle: true }); - * await page.setContent(` - * - *
Click me
- *
Or click me
- * `); - * ``` - * * @param name Name of the function on the window object. * @param callback Callback function that will be called in the Playwright's context. * @param options @@ -7693,21 +7648,6 @@ export interface BrowserContext { * })(); * ``` * - * An example of passing an element handle: - * - * ```js - * await context.exposeBinding('clicked', async (source, element) => { - * console.log(await element.textContent()); - * }, { handle: true }); - * await page.setContent(` - * - *
Click me
- *
Or click me
- * `); - * ``` - * * @param name Name of the function on the window object. * @param callback Callback function that will be called in the Playwright's context. * @param options @@ -8346,9 +8286,7 @@ export interface BrowserContext { * await browserContext.addCookies([cookieObject1, cookieObject2]); * ``` * - * @param cookies Adds cookies to the browser context. - * - * For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". + * @param cookies */ addCookies(cookies: ReadonlyArray<{ name: string; @@ -8356,17 +8294,18 @@ export interface BrowserContext { value: string; /** - * either url or domain / path are required. Optional. + * Either url or domain / path are required. Optional. */ url?: string; /** - * either url or domain / path are required Optional. + * For the cookie to apply to all subdomains as well, prefix domain with a dot, like this: ".example.com". Either url + * or domain / path are required. Optional. */ domain?: string; /** - * either url or domain / path are required Optional. + * Either url or domain / path are required Optional. */ path?: string; @@ -15963,6 +15902,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * If set changes the fetch method (e.g. [PUT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT) or * [POST](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST)). If not specified, GET method is used. @@ -16063,6 +16008,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless @@ -16143,6 +16094,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless @@ -16223,6 +16180,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless @@ -16345,6 +16308,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless @@ -16425,6 +16394,12 @@ export interface APIRequestContext { */ maxRedirects?: number; + /** + * Maximum number of times socket errors should be retried. Currently only `ECONNRESET` error is retried. An error + * will be thrown if the limit is exceeded. Defaults to `0` - no retries. + */ + maxRetries?: number; + /** * Provides an object that will be serialized as html form using `multipart/form-data` encoding and sent as this * request body. If this parameter is specified `content-type` header will be set to `multipart/form-data` unless @@ -19707,6 +19682,29 @@ export interface Touchscreen { * @param y */ tap(x: number, y: number): Promise; + + /** + * Synthesizes a touch event. + * @param type Type of the touch event. + * @param touchPoints List of touch points for this event. `id` is a unique identifier of a touch point that helps identify it between + * touch events for the duration of its movement around the surface. + */ + touch(type: "touchstart"|"touchend"|"touchmove"|"touchcancel", touchPoints: ReadonlyArray<{ + /** + * x coordinate of the event in CSS pixels. + */ + x: number; + + /** + * y coordinate of the event in CSS pixels. + */ + y: number; + + /** + * Identifier used to track the touch point between events, must be unique within an event. Optional. + */ + id?: number; + }>): Promise; } /** diff --git a/packages/playwright-ct-core/package.json b/packages/playwright-ct-core/package.json index 764795ef35..bb6d1ae01e 100644 --- a/packages/playwright-ct-core/package.json +++ b/packages/playwright-ct-core/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-core", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing Helpers", "repository": { "type": "git", @@ -26,8 +26,8 @@ } }, "dependencies": { - "playwright-core": "1.45.0-next", + "playwright-core": "1.46.0-next", "vite": "^5.2.8", - "playwright": "1.45.0-next" + "playwright": "1.46.0-next" } } diff --git a/packages/playwright-ct-react/package.json b/packages/playwright-ct-react/package.json index b9ce7892c4..295af3f34a 100644 --- a/packages/playwright-ct-react/package.json +++ b/packages/playwright-ct-react/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-react", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for React", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-react": "^4.2.1" }, "bin": { diff --git a/packages/playwright-ct-react17/package.json b/packages/playwright-ct-react17/package.json index 7cfc0a6262..8d0fee1168 100644 --- a/packages/playwright-ct-react17/package.json +++ b/packages/playwright-ct-react17/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-react17", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for React", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-react": "^4.2.1" }, "bin": { diff --git a/packages/playwright-ct-solid/package.json b/packages/playwright-ct-solid/package.json index f91b2fc24f..ed46930149 100644 --- a/packages/playwright-ct-solid/package.json +++ b/packages/playwright-ct-solid/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-solid", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for Solid", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "vite-plugin-solid": "^2.7.0" }, "devDependencies": { diff --git a/packages/playwright-ct-svelte/package.json b/packages/playwright-ct-svelte/package.json index a7f4c9ae51..2b35018c03 100644 --- a/packages/playwright-ct-svelte/package.json +++ b/packages/playwright-ct-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-svelte", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for Svelte", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@sveltejs/vite-plugin-svelte": "^3.0.1" }, "devDependencies": { diff --git a/packages/playwright-ct-vue/package.json b/packages/playwright-ct-vue/package.json index 660509458d..fdda54207a 100644 --- a/packages/playwright-ct-vue/package.json +++ b/packages/playwright-ct-vue/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-vue", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for Vue", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-vue": "^4.2.1" }, "bin": { diff --git a/packages/playwright-ct-vue2/package.json b/packages/playwright-ct-vue2/package.json index ddd61c3fc1..70981c4f9b 100644 --- a/packages/playwright-ct-vue2/package.json +++ b/packages/playwright-ct-vue2/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/experimental-ct-vue2", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "Playwright Component Testing for Vue2", "repository": { "type": "git", @@ -26,10 +26,11 @@ "./hooks": { "types": "./hooks.d.ts", "default": "./hooks.mjs" - } + }, + "./package.json": "./package.json" }, "dependencies": { - "@playwright/experimental-ct-core": "1.45.0-next", + "@playwright/experimental-ct-core": "1.46.0-next", "@vitejs/plugin-vue2": "^2.2.0" }, "devDependencies": { diff --git a/packages/playwright-firefox/package.json b/packages/playwright-firefox/package.json index 4b727de450..4f8d5ce8b1 100644 --- a/packages/playwright-firefox/package.json +++ b/packages/playwright-firefox/package.json @@ -1,6 +1,6 @@ { "name": "playwright-firefox", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate Firefox", "repository": { "type": "git", @@ -30,6 +30,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright-test/package.json b/packages/playwright-test/package.json index 1cbe67525b..6865e972ae 100644 --- a/packages/playwright-test/package.json +++ b/packages/playwright-test/package.json @@ -1,6 +1,6 @@ { "name": "@playwright/test", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate web browsers", "repository": { "type": "git", @@ -30,6 +30,6 @@ }, "scripts": {}, "dependencies": { - "playwright": "1.45.0-next" + "playwright": "1.46.0-next" } } diff --git a/packages/playwright-webkit/package.json b/packages/playwright-webkit/package.json index 227cf32eb6..c8d70d5277 100644 --- a/packages/playwright-webkit/package.json +++ b/packages/playwright-webkit/package.json @@ -1,6 +1,6 @@ { "name": "playwright-webkit", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate WebKit", "repository": { "type": "git", @@ -30,6 +30,6 @@ "install": "node install.js" }, "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" } } diff --git a/packages/playwright/package.json b/packages/playwright/package.json index b47d2fd766..cc705e24a2 100644 --- a/packages/playwright/package.json +++ b/packages/playwright/package.json @@ -1,6 +1,6 @@ { "name": "playwright", - "version": "1.45.0-next", + "version": "1.46.0-next", "description": "A high-level API to automate web browsers", "repository": { "type": "git", @@ -58,7 +58,7 @@ }, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0-next" + "playwright-core": "1.46.0-next" }, "optionalDependencies": { "fsevents": "2.3.2" diff --git a/packages/playwright/src/common/fixtures.ts b/packages/playwright/src/common/fixtures.ts index aa3886718c..6b50947ab5 100644 --- a/packages/playwright/src/common/fixtures.ts +++ b/packages/playwright/src/common/fixtures.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { formatLocation } from '../util'; +import { filterStackFile, formatLocation } from '../util'; import * as crypto from 'crypto'; import type { Fixtures } from '../../types/test'; import type { Location } from '../../types/testReporter'; @@ -23,7 +23,7 @@ import type { FixturesWithLocation } from './config'; export type FixtureScope = 'test' | 'worker'; type FixtureAuto = boolean | 'all-hooks-included'; const kScopeOrder: FixtureScope[] = ['test', 'worker']; -type FixtureOptions = { auto?: FixtureAuto, scope?: FixtureScope, option?: boolean, timeout?: number | undefined }; +type FixtureOptions = { auto?: FixtureAuto, scope?: FixtureScope, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }; type FixtureTuple = [ value: any, options: FixtureOptions ]; export type FixtureRegistration = { // Fixture registration location. @@ -49,8 +49,8 @@ export type FixtureRegistration = { super?: FixtureRegistration; // Whether this fixture is an option override value set from the config. optionOverride?: boolean; - // Do not generate the step for this fixture. - hideStep?: boolean; + // Do not generate the step for this fixture, consider it internal. + box?: boolean; }; export type LoadError = { message: string; @@ -63,7 +63,7 @@ type OptionOverrides = { }; function isFixtureTuple(value: any): value is FixtureTuple { - return Array.isArray(value) && typeof value[1] === 'object' && ('scope' in value[1] || 'auto' in value[1] || 'option' in value[1] || 'timeout' in value[1]); + return Array.isArray(value) && typeof value[1] === 'object'; } function isFixtureOption(value: any): value is FixtureTuple { @@ -103,15 +103,15 @@ export class FixturePool { for (const entry of Object.entries(fixtures)) { const name = entry[0]; let value = entry[1]; - let options: { auto: FixtureAuto, scope: FixtureScope, option: boolean, timeout: number | undefined, customTitle: string | undefined, hideStep: boolean | undefined } | undefined; + let options: { auto: FixtureAuto, scope: FixtureScope, option: boolean, timeout: number | undefined, customTitle?: string, box?: boolean } | undefined; if (isFixtureTuple(value)) { options = { auto: value[1].auto ?? false, scope: value[1].scope || 'test', option: !!value[1].option, timeout: value[1].timeout, - customTitle: (value[1] as any)._title, - hideStep: (value[1] as any)._hideStep, + customTitle: value[1].title, + box: value[1].box, }; value = value[0]; } @@ -128,9 +128,9 @@ export class FixturePool { continue; } } else if (previous) { - options = { auto: previous.auto, scope: previous.scope, option: previous.option, timeout: previous.timeout, customTitle: previous.customTitle, hideStep: undefined }; + options = { auto: previous.auto, scope: previous.scope, option: previous.option, timeout: previous.timeout, customTitle: previous.customTitle, box: previous.box }; } else if (!options) { - options = { auto: false, scope: 'test', option: false, timeout: undefined, customTitle: undefined, hideStep: undefined }; + options = { auto: false, scope: 'test', option: false, timeout: undefined }; } if (!kScopeOrder.includes(options.scope)) { @@ -152,7 +152,7 @@ export class FixturePool { } const deps = fixtureParameterNames(fn, location, e => this._onLoadError(e)); - const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, hideStep: options.hideStep, deps, super: previous, optionOverride: isOptionsOverride }; + const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, box: options.box, deps, super: previous, optionOverride: isOptionsOverride }; registrationId(registration); this._registrations.set(name, registration); } @@ -161,29 +161,36 @@ export class FixturePool { private validate() { const markers = new Map(); const stack: FixtureRegistration[] = []; - const visit = (registration: FixtureRegistration) => { + let hasDependencyErrors = false; + const addDependencyError = (message: string, location: Location) => { + hasDependencyErrors = true; + this._addLoadError(message, location); + }; + const visit = (registration: FixtureRegistration, boxedOnly: boolean) => { markers.set(registration, 'visiting'); stack.push(registration); for (const name of registration.deps) { const dep = this.resolve(name, registration); if (!dep) { if (name === registration.name) - this._addLoadError(`Fixture "${registration.name}" references itself, but does not have a base implementation.`, registration.location); + addDependencyError(`Fixture "${registration.name}" references itself, but does not have a base implementation.`, registration.location); else - this._addLoadError(`Fixture "${registration.name}" has unknown parameter "${name}".`, registration.location); + addDependencyError(`Fixture "${registration.name}" has unknown parameter "${name}".`, registration.location); continue; } if (kScopeOrder.indexOf(registration.scope) > kScopeOrder.indexOf(dep.scope)) { - this._addLoadError(`${registration.scope} fixture "${registration.name}" cannot depend on a ${dep.scope} fixture "${name}" defined in ${formatLocation(dep.location)}.`, registration.location); + addDependencyError(`${registration.scope} fixture "${registration.name}" cannot depend on a ${dep.scope} fixture "${name}" defined in ${formatPotentiallyInternalLocation(dep.location)}.`, registration.location); continue; } if (!markers.has(dep)) { - visit(dep); + visit(dep, boxedOnly); } else if (markers.get(dep) === 'visiting') { const index = stack.indexOf(dep); - const regs = stack.slice(index, stack.length); + const allRegs = stack.slice(index, stack.length); + const filteredRegs = allRegs.filter(r => !r.box); + const regs = boxedOnly ? filteredRegs : allRegs; const names = regs.map(r => `"${r.name}"`); - this._addLoadError(`Fixtures ${names.join(' -> ')} -> "${dep.name}" form a dependency cycle: ${regs.map(r => formatLocation(r.location)).join(' -> ')}`, dep.location); + addDependencyError(`Fixtures ${names.join(' -> ')} -> "${dep.name}" form a dependency cycle: ${regs.map(r => formatPotentiallyInternalLocation(r.location)).join(' -> ')} -> ${formatPotentiallyInternalLocation(dep.location)}`, dep.location); continue; } } @@ -191,11 +198,27 @@ export class FixturePool { stack.pop(); }; - const hash = crypto.createHash('sha1'); const names = Array.from(this._registrations.keys()).sort(); + + // First iterate over non-boxed fixtures to provide clear error messages. + for (const name of names) { + const registration = this._registrations.get(name)!; + if (!registration.box) + visit(registration, true); + } + + // If no errors found, iterate over boxed fixtures + if (!hasDependencyErrors) { + for (const name of names) { + const registration = this._registrations.get(name)!; + if (registration.box) + visit(registration, false); + } + } + + const hash = crypto.createHash('sha1'); for (const name of names) { const registration = this._registrations.get(name)!; - visit(registration); if (registration.scope === 'worker') hash.update(registration.id + ';'); } @@ -227,6 +250,11 @@ export class FixturePool { const signatureSymbol = Symbol('signature'); +export function formatPotentiallyInternalLocation(location: Location): string { + const isUserFixture = location && filterStackFile(location.file); + return isUserFixture ? formatLocation(location) : ''; +} + export function fixtureParameterNames(fn: Function | any, location: Location, onError: LoadErrorSink): string[] { if (typeof fn !== 'function') return []; diff --git a/packages/playwright/src/fsWatcher.ts b/packages/playwright/src/fsWatcher.ts index c0d4e4d04e..a1c09c343d 100644 --- a/packages/playwright/src/fsWatcher.ts +++ b/packages/playwright/src/fsWatcher.ts @@ -16,7 +16,6 @@ import { chokidar } from './utilsBundle'; import type { FSWatcher } from 'chokidar'; -import path from 'path'; export type FSEvent = { event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', file: string }; @@ -52,7 +51,7 @@ export class Watcher { if (!this._watchedFiles.length) return; - const ignored = [...this._ignoredFolders, (name: string) => name.includes(path.sep + 'node_modules' + path.sep)]; + const ignored = [...this._ignoredFolders, '**/node_modules/**']; this._fsWatcher = chokidar.watch(watchedFiles, { ignoreInitial: true, ignored }).on('all', async (event, file) => { if (this._throttleTimer) clearTimeout(this._throttleTimer); diff --git a/packages/playwright/src/index.ts b/packages/playwright/src/index.ts index 3fbaf33585..79184cc135 100644 --- a/packages/playwright/src/index.ts +++ b/packages/playwright/src/index.ts @@ -59,13 +59,13 @@ type WorkerFixtures = PlaywrightWorkerArgs & PlaywrightWorkerOptions & { const playwrightFixtures: Fixtures = ({ defaultBrowserType: ['chromium', { scope: 'worker', option: true }], browserName: [({ defaultBrowserType }, use) => use(defaultBrowserType), { scope: 'worker', option: true }], - _playwrightImpl: [({}, use) => use(require('playwright-core')), { scope: 'worker' }], + _playwrightImpl: [({}, use) => use(require('playwright-core')), { scope: 'worker', box: true }], playwright: [async ({ _playwrightImpl, screenshot }, use) => { await connector.setPlaywright(_playwrightImpl, screenshot); await use(_playwrightImpl); await connector.setPlaywright(undefined, screenshot); - }, { scope: 'worker', _hideStep: true } as any], + }, { scope: 'worker', box: true }], headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: 'worker', option: true }], channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }], @@ -93,7 +93,7 @@ const playwrightFixtures: Fixtures = ({ await use(options); for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) (browserType as any)._defaultLaunchOptions = undefined; - }, { scope: 'worker', auto: true }], + }, { scope: 'worker', auto: true, box: true }], browser: [async ({ playwright, browserName, _browserOptions, connectOptions, _reuseContext }, use, testInfo) => { if (!['chromium', 'firefox', 'webkit'].includes(browserName)) @@ -152,7 +152,7 @@ const playwrightFixtures: Fixtures = ({ serviceWorkers: [({ contextOptions }, use) => use(contextOptions.serviceWorkers ?? 'allow'), { option: true }], contextOptions: [{}, { option: true }], - _combinedContextOptions: async ({ + _combinedContextOptions: [async ({ acceptDownloads, bypassCSP, colorScheme, @@ -223,7 +223,7 @@ const playwrightFixtures: Fixtures = ({ ...contextOptions, ...options, }); - }, + }, { box: true }], _setupContextOptions: [async ({ playwright, _combinedContextOptions, actionTimeout, navigationTimeout, testIdAttribute }, use, testInfo) => { if (testIdAttribute) @@ -246,9 +246,9 @@ const playwrightFixtures: Fixtures = ({ (browserType as any)._defaultContextTimeout = undefined; (browserType as any)._defaultContextNavigationTimeout = undefined; } - }, { auto: 'all-hooks-included', _title: 'context configuration' } as any], + }, { auto: 'all-hooks-included', title: 'context configuration', box: true } as any], - _contextFactory: [async ({ browser, video, _reuseContext }, use, testInfo) => { + _contextFactory: [async ({ browser, video, _reuseContext, _combinedContextOptions /** mitigate dep-via-auto lack of traceability */ }, use, testInfo) => { const testInfoImpl = testInfo as TestInfoImpl; const videoMode = normalizeVideoMode(video); const captureVideo = shouldCaptureVideo(videoMode, testInfo) && !_reuseContext; @@ -274,6 +274,18 @@ const playwrightFixtures: Fixtures = ({ contexts.set(context, contextData); if (captureVideo) context.on('page', page => contextData.pagesWithVideo.push(page)); + + if (process.env.PW_CLOCK === 'frozen') { + await (context as any)._wrapApiCall(async () => { + await context.clock.install({ time: 0 }); + await context.clock.pauseAt(1000); + }, true); + } else if (process.env.PW_CLOCK === 'realtime') { + await (context as any)._wrapApiCall(async () => { + await context.clock.install({ time: 0 }); + }, true); + } + return context; }); @@ -301,7 +313,7 @@ const playwrightFixtures: Fixtures = ({ } })); - }, { scope: 'test', _title: 'context' } as any], + }, { scope: 'test', title: 'context', box: true }], _optionContextReuseMode: ['none', { scope: 'worker', option: true }], _optionConnectOptions: [undefined, { scope: 'worker', option: true }], @@ -312,7 +324,7 @@ const playwrightFixtures: Fixtures = ({ mode = 'when-possible'; const reuse = mode === 'when-possible' && normalizeVideoMode(video) === 'off'; await use(reuse); - }, { scope: 'worker', _title: 'context' } as any], + }, { scope: 'worker', title: 'context', box: true }], context: async ({ playwright, browser, _reuseContext, _contextFactory }, use, testInfo) => { attachConnectedHeaderIfNeeded(testInfo, browser); @@ -597,7 +609,7 @@ class ArtifactsRecorder { if ((tracing as any)[this._startedCollectingArtifacts]) return; (tracing as any)[this._startedCollectingArtifacts] = true; - if (this._testInfo._tracing.traceOptions()) + if (this._testInfo._tracing.traceOptions() && (tracing as any)[kTracingStarted]) await tracing.stopChunk({ path: this._testInfo._tracing.generateNextTraceRecordingPath() }); } } diff --git a/packages/playwright/src/worker/fixtureRunner.ts b/packages/playwright/src/worker/fixtureRunner.ts index 8832acf8e2..0d94f40631 100644 --- a/packages/playwright/src/worker/fixtureRunner.ts +++ b/packages/playwright/src/worker/fixtureRunner.ts @@ -40,10 +40,10 @@ class Fixture { this.runner = runner; this.registration = registration; this.value = null; - const shouldGenerateStep = !this.registration.hideStep && !this.registration.name.startsWith('_') && !this.registration.option; - const isInternalFixture = this.registration.location && filterStackFile(this.registration.location.file); + const shouldGenerateStep = !this.registration.box && !this.registration.option; + const isUserFixture = this.registration.location && filterStackFile(this.registration.location.file); const title = this.registration.customTitle || this.registration.name; - const location = isInternalFixture ? this.registration.location : undefined; + const location = isUserFixture ? this.registration.location : undefined; this._stepInfo = shouldGenerateStep ? { category: 'fixture', location } : undefined; this._setupDescription = { title, diff --git a/packages/playwright/src/worker/workerMain.ts b/packages/playwright/src/worker/workerMain.ts index 3237104520..2f0dcc424d 100644 --- a/packages/playwright/src/worker/workerMain.ts +++ b/packages/playwright/src/worker/workerMain.ts @@ -261,7 +261,7 @@ export class WorkerMain extends ProcessRunner { testInfo.expectedStatus = 'failed'; break; case 'slow': - testInfo.slow(); + testInfo._timeoutManager.slow(); break; } }; @@ -570,6 +570,9 @@ export class WorkerMain extends ProcessRunner { if (error instanceof TimeoutManagerError) throw error; firstError = firstError ?? error; + // Skip in modifier prevents others from running. + if (error instanceof SkipError) + break; } } if (firstError) diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index c1ecc81fc1..5a18eded3f 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -4811,13 +4811,13 @@ export type WorkerFixture = (args: Args, use: (r: R) = type TestFixtureValue = Exclude | TestFixture; type WorkerFixtureValue = Exclude | WorkerFixture; export type Fixtures = { - [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined }]; + [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined }]; + [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', 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 }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit'; @@ -7541,112 +7541,7 @@ interface PageAssertions { * @param name Snapshot name. * @param options */ - toHaveScreenshot(name: string|ReadonlyArray, options?: { - /** - * When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different - * treatment depending on their duration: - * - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event. - * - infinite animations are canceled to initial state, and then played over after the screenshot. - * - * Defaults to `"disabled"` that disables animations. - */ - animations?: "disabled"|"allow"; - - /** - * When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be - * changed. Defaults to `"hide"`. - */ - caret?: "hide"|"initial"; - - /** - * An object which specifies clipping of the resulting image. - */ - clip?: { - /** - * x-coordinate of top-left corner of clip area - */ - x: number; - - /** - * y-coordinate of top-left corner of clip area - */ - y: number; - - /** - * width of clipping area - */ - width: number; - - /** - * height of clipping area - */ - height: number; - }; - - /** - * When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to - * `false`. - */ - fullPage?: boolean; - - /** - * Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink - * box `#FF00FF` (customized by `maskColor`) that completely covers its bounding box. - */ - mask?: Array; - - /** - * Specify the color of the overlay box for masked elements, in - * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. - */ - maskColor?: string; - - /** - * An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is - * configurable with `TestConfig.expect`. Unset by default. - */ - maxDiffPixelRatio?: number; - - /** - * An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by - * default. - */ - maxDiffPixels?: number; - - /** - * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. - * Defaults to `false`. - */ - omitBackground?: boolean; - - /** - * When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this - * will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so - * screenshots of high-dpi devices will be twice as large or even larger. - * - * Defaults to `"css"`. - */ - scale?: "css"|"device"; - - /** - * File name containing the stylesheet to apply while making the screenshot. This is where you can hide dynamic - * elements, make elements invisible or change their properties to help you creating repeatable screenshots. This - * stylesheet pierces the Shadow DOM and applies to the inner frames. - */ - stylePath?: string|Array; - - /** - * An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the - * same pixel in compared images, between zero (strict) and one (lax), default is configurable with - * `TestConfig.expect`. Defaults to `0.2`. - */ - threshold?: number; - - /** - * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. - */ - timeout?: number; - }): Promise; + toHaveScreenshot(name: string|ReadonlyArray, options?: PageAssertionsToHaveScreenshotOptions): Promise; /** * This function will wait until two consecutive page screenshots yield the same result, and then compare the last @@ -7661,112 +7556,7 @@ interface PageAssertions { * Note that screenshot assertions only work with Playwright test runner. * @param options */ - toHaveScreenshot(options?: { - /** - * When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different - * treatment depending on their duration: - * - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event. - * - infinite animations are canceled to initial state, and then played over after the screenshot. - * - * Defaults to `"disabled"` that disables animations. - */ - animations?: "disabled"|"allow"; - - /** - * When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be - * changed. Defaults to `"hide"`. - */ - caret?: "hide"|"initial"; - - /** - * An object which specifies clipping of the resulting image. - */ - clip?: { - /** - * x-coordinate of top-left corner of clip area - */ - x: number; - - /** - * y-coordinate of top-left corner of clip area - */ - y: number; - - /** - * width of clipping area - */ - width: number; - - /** - * height of clipping area - */ - height: number; - }; - - /** - * When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to - * `false`. - */ - fullPage?: boolean; - - /** - * Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink - * box `#FF00FF` (customized by `maskColor`) that completely covers its bounding box. - */ - mask?: Array; - - /** - * Specify the color of the overlay box for masked elements, in - * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. - */ - maskColor?: string; - - /** - * An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is - * configurable with `TestConfig.expect`. Unset by default. - */ - maxDiffPixelRatio?: number; - - /** - * An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by - * default. - */ - maxDiffPixels?: number; - - /** - * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. - * Defaults to `false`. - */ - omitBackground?: boolean; - - /** - * When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this - * will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so - * screenshots of high-dpi devices will be twice as large or even larger. - * - * Defaults to `"css"`. - */ - scale?: "css"|"device"; - - /** - * File name containing the stylesheet to apply while making the screenshot. This is where you can hide dynamic - * elements, make elements invisible or change their properties to help you creating repeatable screenshots. This - * stylesheet pierces the Shadow DOM and applies to the inner frames. - */ - stylePath?: string|Array; - - /** - * An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the - * same pixel in compared images, between zero (strict) and one (lax), default is configurable with - * `TestConfig.expect`. Defaults to `0.2`. - */ - threshold?: number; - - /** - * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. - */ - timeout?: number; - }): Promise; + toHaveScreenshot(options?: PageAssertionsToHaveScreenshotOptions): Promise; /** * Ensures the page has the given title. @@ -8448,6 +8238,113 @@ export interface WorkerInfo { workerIndex: number; } +export interface PageAssertionsToHaveScreenshotOptions { + /** + * When set to `"disabled"`, stops CSS animations, CSS transitions and Web Animations. Animations get different + * treatment depending on their duration: + * - finite animations are fast-forwarded to completion, so they'll fire `transitionend` event. + * - infinite animations are canceled to initial state, and then played over after the screenshot. + * + * Defaults to `"disabled"` that disables animations. + */ + animations?: "disabled"|"allow"; + + /** + * When set to `"hide"`, screenshot will hide text caret. When set to `"initial"`, text caret behavior will not be + * changed. Defaults to `"hide"`. + */ + caret?: "hide"|"initial"; + + /** + * An object which specifies clipping of the resulting image. + */ + clip?: { + /** + * x-coordinate of top-left corner of clip area + */ + x: number; + + /** + * y-coordinate of top-left corner of clip area + */ + y: number; + + /** + * width of clipping area + */ + width: number; + + /** + * height of clipping area + */ + height: number; + }; + + /** + * When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Defaults to + * `false`. + */ + fullPage?: boolean; + + /** + * Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink + * box `#FF00FF` (customized by `maskColor`) that completely covers its bounding box. + */ + mask?: Array; + + /** + * Specify the color of the overlay box for masked elements, in + * [CSS color format](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). Default color is pink `#FF00FF`. + */ + maskColor?: string; + + /** + * An acceptable ratio of pixels that are different to the total amount of pixels, between `0` and `1`. Default is + * configurable with `TestConfig.expect`. Unset by default. + */ + maxDiffPixelRatio?: number; + + /** + * An acceptable amount of pixels that could be different. Default is configurable with `TestConfig.expect`. Unset by + * default. + */ + maxDiffPixels?: number; + + /** + * Hides default white background and allows capturing screenshots with transparency. Not applicable to `jpeg` images. + * Defaults to `false`. + */ + omitBackground?: boolean; + + /** + * When set to `"css"`, screenshot will have a single pixel per each css pixel on the page. For high-dpi devices, this + * will keep screenshots small. Using `"device"` option will produce a single pixel per each device pixel, so + * screenshots of high-dpi devices will be twice as large or even larger. + * + * Defaults to `"css"`. + */ + scale?: "css"|"device"; + + /** + * File name containing the stylesheet to apply while making the screenshot. This is where you can hide dynamic + * elements, make elements invisible or change their properties to help you creating repeatable screenshots. This + * stylesheet pierces the Shadow DOM and applies to the inner frames. + */ + stylePath?: string|Array; + + /** + * An acceptable perceived color difference in the [YIQ color space](https://en.wikipedia.org/wiki/YIQ) between the + * same pixel in compared images, between zero (strict) and one (lax), default is configurable with + * `TestConfig.expect`. Defaults to `0.2`. + */ + threshold?: number; + + /** + * Time to retry the assertion for in milliseconds. Defaults to `timeout` in `TestConfig.expect`. + */ + timeout?: number; +} + interface TestConfigWebServer { /** * Shell command to start. For example `npm run start`.. diff --git a/packages/protocol/src/channels.ts b/packages/protocol/src/channels.ts index 13d34f1f51..a1ae5a13e0 100644 --- a/packages/protocol/src/channels.ts +++ b/packages/protocol/src/channels.ts @@ -324,6 +324,7 @@ export type APIRequestContextFetchParams = { failOnStatusCode?: boolean, ignoreHTTPSErrors?: boolean, maxRedirects?: number, + maxRetries?: number, }; export type APIRequestContextFetchOptions = { params?: NameValue[], @@ -337,6 +338,7 @@ export type APIRequestContextFetchOptions = { failOnStatusCode?: boolean, ignoreHTTPSErrors?: boolean, maxRedirects?: number, + maxRetries?: number, }; export type APIRequestContextFetchResult = { response: APIResponse, @@ -1888,6 +1890,7 @@ export interface PageChannel extends PageEventTarget, EventTargetChannel { mouseClick(params: PageMouseClickParams, metadata?: CallMetadata): Promise; mouseWheel(params: PageMouseWheelParams, metadata?: CallMetadata): Promise; touchscreenTap(params: PageTouchscreenTapParams, metadata?: CallMetadata): Promise; + touchscreenTouch(params: PageTouchscreenTouchParams, metadata?: CallMetadata): Promise; accessibilitySnapshot(params: PageAccessibilitySnapshotParams, metadata?: CallMetadata): Promise; pdf(params: PagePdfParams, metadata?: CallMetadata): Promise; startJSCoverage(params: PageStartJSCoverageParams, metadata?: CallMetadata): Promise; @@ -2255,6 +2258,18 @@ export type PageTouchscreenTapOptions = { }; export type PageTouchscreenTapResult = void; +export type PageTouchscreenTouchParams = { + type: 'touchstart' | 'touchend' | 'touchmove' | 'touchcancel', + touchPoints: { + x: number, + y: number, + id?: number, + }[], +}; +export type PageTouchscreenTouchOptions = { + +}; +export type PageTouchscreenTouchResult = void; export type PageAccessibilitySnapshotParams = { interestingOnly?: boolean, root?: ElementHandleChannel, diff --git a/packages/protocol/src/protocol.yml b/packages/protocol/src/protocol.yml index 2bef7c8762..54f356102b 100644 --- a/packages/protocol/src/protocol.yml +++ b/packages/protocol/src/protocol.yml @@ -299,6 +299,7 @@ APIRequestContext: failOnStatusCode: boolean? ignoreHTTPSErrors: boolean? maxRedirects: number? + maxRetries: number? returns: response: APIResponse @@ -1602,6 +1603,27 @@ Page: slowMo: true snapshot: true + touchscreenTouch: + parameters: + type: + type: enum + literals: + - touchstart + - touchend + - touchmove + - touchcancel + touchPoints: + type: array + items: + type: object + properties: + x: number + y: number + id: number? + flags: + slowMo: true + snapshot: true + accessibilitySnapshot: parameters: interestingOnly: boolean? diff --git a/packages/trace-viewer/embedded.html b/packages/trace-viewer/embedded.html new file mode 100644 index 0000000000..7d0fd2f175 --- /dev/null +++ b/packages/trace-viewer/embedded.html @@ -0,0 +1,27 @@ + + + + + + + Playwright Trace Viewer for VS Code + + +
+ + + diff --git a/packages/trace-viewer/src/embedded.tsx b/packages/trace-viewer/src/embedded.tsx new file mode 100644 index 0000000000..8f0a09e560 --- /dev/null +++ b/packages/trace-viewer/src/embedded.tsx @@ -0,0 +1,61 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@web/common.css'; +import { applyTheme } from '@web/theme'; +import '@web/third_party/vscode/codicon.css'; +import React from 'react'; +import * as ReactDOM from 'react-dom'; +import { EmbeddedWorkbenchLoader } from './ui/embeddedWorkbenchLoader'; + +(async () => { + applyTheme(); + + // workaround to send keystrokes back to vscode webview to keep triggering key bindings there + const handleKeyEvent = (e: KeyboardEvent) => { + if (!e.isTrusted) + return; + window.parent?.postMessage({ + type: e.type, + key: e.key, + keyCode: e.keyCode, + code: e.code, + shiftKey: e.shiftKey, + altKey: e.altKey, + ctrlKey: e.ctrlKey, + metaKey: e.metaKey, + repeat: e.repeat, + }, '*'); + }; + window.addEventListener('keydown', handleKeyEvent); + window.addEventListener('keyup', handleKeyEvent); + + if (window.location.protocol !== 'file:') { + if (!navigator.serviceWorker) + throw new Error(`Service workers are not supported.\nMake sure to serve the Trace Viewer (${window.location}) via HTTPS or localhost.`); + navigator.serviceWorker.register('sw.bundle.js'); + if (!navigator.serviceWorker.controller) { + await new Promise(f => { + navigator.serviceWorker.oncontrollerchange = () => f(); + }); + } + + // Keep SW running. + setInterval(function() { fetch('ping'); }, 10000); + } + + ReactDOM.render(, document.querySelector('#root')); +})(); diff --git a/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.css b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.css new file mode 100644 index 0000000000..2274355322 --- /dev/null +++ b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.css @@ -0,0 +1,68 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +.empty-state { + display: flex; + align-items: center; + justify-content: center; + flex: auto; + flex-direction: column; + background-color: var(--vscode-editor-background); + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 100; + line-height: 24px; +} + +body .empty-state { + background: rgba(255, 255, 255, 0.8); +} + +body.dark-mode .empty-state { + background: rgba(0, 0, 0, 0.8); +} + +.empty-state .title { + font-size: 24px; + font-weight: bold; + margin-bottom: 30px; +} + +.progress { + flex: none; + width: 100%; + height: 3px; + z-index: 10; +} + +.inner-progress { + background-color: var(--vscode-progressBar-background); + height: 100%; +} + +.workbench-loader { + contain: size; +} + +/* Limit to a reasonable minimum viewport */ +html, body { + min-width: 550px; + min-height: 450px; + overflow: auto; +} diff --git a/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx new file mode 100644 index 0000000000..17a2211c41 --- /dev/null +++ b/packages/trace-viewer/src/ui/embeddedWorkbenchLoader.tsx @@ -0,0 +1,96 @@ +/* + Copyright (c) Microsoft Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import * as React from 'react'; +import type { ContextEntry } from '../entries'; +import { MultiTraceModel } from './modelUtil'; +import './embeddedWorkbenchLoader.css'; +import { Workbench } from './workbench'; +import { currentTheme, toggleTheme } from '@web/theme'; + +function openPage(url: string, target?: string) { + if (url) + window.parent!.postMessage({ command: 'openExternal', params: { url, target } }, '*'); +} + +export const EmbeddedWorkbenchLoader: React.FunctionComponent = () => { + const [traceURLs, setTraceURLs] = React.useState([]); + const [model, setModel] = React.useState(emptyModel); + const [progress, setProgress] = React.useState<{ done: number, total: number }>({ done: 0, total: 0 }); + const [processingErrorMessage, setProcessingErrorMessage] = React.useState(null); + + React.useEffect(() => { + window.addEventListener('message', async ({ data: { method, params } }) => { + if (method === 'loadTraceRequested') { + setTraceURLs(params.traceUrl ? [params.traceUrl] : []); + setProcessingErrorMessage(null); + } else if (method === 'applyTheme') { + if (currentTheme() !== params.theme) + toggleTheme(); + } + }); + // notify vscode that it is now listening to its messages + window.parent!.postMessage({ type: 'loaded' }, '*'); + }, []); + + React.useEffect(() => { + (async () => { + if (traceURLs.length) { + const swListener = (event: any) => { + if (event.data.method === 'progress') + setProgress(event.data.params); + }; + navigator.serviceWorker.addEventListener('message', swListener); + setProgress({ done: 0, total: 1 }); + const contextEntries: ContextEntry[] = []; + for (let i = 0; i < traceURLs.length; i++) { + const url = traceURLs[i]; + const params = new URLSearchParams(); + params.set('trace', url); + const response = await fetch(`contexts?${params.toString()}`); + if (!response.ok) { + setProcessingErrorMessage((await response.json()).error); + return; + } + contextEntries.push(...(await response.json())); + } + navigator.serviceWorker.removeEventListener('message', swListener); + const model = new MultiTraceModel(contextEntries); + setProgress({ done: 0, total: 0 }); + setModel(model); + } else { + setModel(emptyModel); + } + })(); + }, [traceURLs]); + + React.useEffect(() => { + if (processingErrorMessage) + window.parent?.postMessage({ method: 'showErrorMessage', params: { message: processingErrorMessage } }, '*'); + }, [processingErrorMessage]); + + return
+
+
+
+ + {!traceURLs.length &&
+
Select test to see the trace
+
} +
; +}; + +export const emptyModel = new MultiTraceModel([]); diff --git a/packages/trace-viewer/src/ui/modelUtil.ts b/packages/trace-viewer/src/ui/modelUtil.ts index ba866ad7ca..94d42ba4a8 100644 --- a/packages/trace-viewer/src/ui/modelUtil.ts +++ b/packages/trace-viewer/src/ui/modelUtil.ts @@ -285,6 +285,10 @@ function adjustMonotonicTime(contexts: ContextEntry[], monotonicTimeDelta: numbe for (const frame of page.screencastFrames) frame.timestamp += monotonicTimeDelta; } + for (const resource of context.resources) { + if (resource._monotonicTime) + resource._monotonicTime += monotonicTimeDelta; + } } } diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.css b/packages/trace-viewer/src/ui/networkResourceDetails.css index fce4e8b2c3..ce0648b8c2 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.css +++ b/packages/trace-viewer/src/ui/networkResourceDetails.css @@ -39,6 +39,11 @@ font-weight: bold; } +.network-request-details-general { + white-space: pre; + margin-left: 10px; +} + .network-request-details-tab .cm-wrapper { overflow: hidden; } @@ -52,7 +57,7 @@ .tab-network .toolbar::after { box-shadow: none !important; } - + .tab-network .tabbed-pane-tab.selected { font-weight: bold; } diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx index c5a974b69e..e7b1bad4b6 100644 --- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx +++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx @@ -77,8 +77,14 @@ const RequestTab: React.FunctionComponent<{ }, [resource]); return
-
URL
-
{resource.request.url}
+
General
+
{`URL: ${resource.request.url}`}
+
{`Method: ${resource.request.method}`}
+
{`Status Code: ${ + resource.response.status >= 200 && resource.response.status < 400 + ? `🟢 ${resource.response.status} ${resource.response.statusText}` + : `🔴 ${resource.response.status} ${resource.response.statusText}` + }`}
Request Headers
{resource.request.headers.map(pair => `${pair.name}: ${pair.value}`).join('\n')}
{requestBody &&
Request Body
} diff --git a/packages/trace-viewer/src/ui/snapshotTab.tsx b/packages/trace-viewer/src/ui/snapshotTab.tsx index bdb955c13c..4bc2abc9eb 100644 --- a/packages/trace-viewer/src/ui/snapshotTab.tsx +++ b/packages/trace-viewer/src/ui/snapshotTab.tsx @@ -38,7 +38,8 @@ export const SnapshotTab: React.FunctionComponent<{ setIsInspecting: (isInspecting: boolean) => void, highlightedLocator: string, setHighlightedLocator: (locator: string) => void, -}> = ({ action, sdkLanguage, testIdAttributeName, isInspecting, setIsInspecting, highlightedLocator, setHighlightedLocator }) => { + openPage?: (url: string, target?: string) => Window | any, +}> = ({ action, sdkLanguage, testIdAttributeName, isInspecting, setIsInspecting, highlightedLocator, setHighlightedLocator, openPage }) => { const [measure, ref] = useMeasure(); const [snapshotTab, setSnapshotTab] = React.useState<'action'|'before'|'after'>('action'); @@ -190,7 +191,9 @@ export const SnapshotTab: React.FunctionComponent<{ })}
{ - const win = window.open(popoutUrl || '', '_blank'); + if (!openPage) + openPage = window.open; + const win = openPage(popoutUrl || '', '_blank'); win?.addEventListener('DOMContentLoaded', () => { const injectedScript = new InjectedScript(win as any, false, sdkLanguage, testIdAttributeName, 1, 'chromium', []); new ConsoleAPI(injectedScript); diff --git a/packages/trace-viewer/src/ui/workbench.tsx b/packages/trace-viewer/src/ui/workbench.tsx index c50b345b75..afc003c674 100644 --- a/packages/trace-viewer/src/ui/workbench.tsx +++ b/packages/trace-viewer/src/ui/workbench.tsx @@ -51,7 +51,8 @@ export const Workbench: React.FunctionComponent<{ isLive?: boolean, status?: UITestStatus, inert?: boolean, -}> = ({ model, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive, status, inert }) => { + openPage?: (url: string, target?: string) => Window | any, +}> = ({ model, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive, status, inert, openPage }) => { const [selectedAction, setSelectedActionImpl] = React.useState(undefined); const [revealedStack, setRevealedStack] = React.useState(undefined); const [highlightedAction, setHighlightedAction] = React.useState(); @@ -234,7 +235,8 @@ export const Workbench: React.FunctionComponent<{ isInspecting={isInspecting} setIsInspecting={setIsInspecting} highlightedLocator={highlightedLocator} - setHighlightedLocator={locatorPicked} /> + setHighlightedLocator={locatorPicked} + openPage={openPage} /> { diff --git a/tests/components/ct-vue-vite/package.json b/tests/components/ct-vue-vite/package.json index 64f695ac7c..608a128763 100644 --- a/tests/components/ct-vue-vite/package.json +++ b/tests/components/ct-vue-vite/package.json @@ -13,8 +13,8 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^4.1.0", - "@vue/tsconfig": "^0.1.3", + "@vue/tsconfig": "^0.5.1", "vite": "^5.2.8", - "vue-tsc": "^1.0.0" + "vue-tsc": "^2.0.21" } } diff --git a/tests/components/ct-vue-vite/tsconfig.json b/tests/components/ct-vue-vite/tsconfig.json index cda3ce98be..b74b79834f 100644 --- a/tests/components/ct-vue-vite/tsconfig.json +++ b/tests/components/ct-vue-vite/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@vue/tsconfig/tsconfig.web.json", + "extends": "@vue/tsconfig/tsconfig.dom.json", "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "tests/**/*", "playwright"], "compilerOptions": { "baseUrl": ".", @@ -8,11 +8,5 @@ "*": ["_"], }, "ignoreDeprecations": "5.0" - }, - - "references": [ - { - "path": "./tsconfig.node.json" - } - ] + } } diff --git a/tests/components/ct-vue-vite/tsconfig.node.json b/tests/components/ct-vue-vite/tsconfig.node.json index 7924803d11..43cc105313 100644 --- a/tests/components/ct-vue-vite/tsconfig.node.json +++ b/tests/components/ct-vue-vite/tsconfig.node.json @@ -1,5 +1,5 @@ { - "extends": "@vue/tsconfig/tsconfig.node.json", + "extends": "@vue/tsconfig/tsconfig.dom.json", "include": ["vite.config.*", "playwright.config.*"], "compilerOptions": { "composite": true, diff --git a/tests/config/browserTest.ts b/tests/config/browserTest.ts index 8b4fdc27b9..01b574f105 100644 --- a/tests/config/browserTest.ts +++ b/tests/config/browserTest.ts @@ -88,6 +88,7 @@ const test = baseTest.extend isAndroid: [false, { scope: 'worker' }], isElectron: [false, { scope: 'worker' }], + electronMajorVersion: [0, { scope: 'worker' }], isWebView2: [false, { scope: 'worker' }], contextFactory: async ({ _contextFactory }: any, run) => { diff --git a/tests/electron/electron-app.spec.ts b/tests/electron/electron-app.spec.ts index 37bb69ea9e..c725752e37 100644 --- a/tests/electron/electron-app.spec.ts +++ b/tests/electron/electron-app.spec.ts @@ -314,3 +314,27 @@ test('should return app name / version from manifest', async ({ launchElectronAp version: '1.0.0' }); }); + +test('should report downloads', async ({ launchElectronApp, electronMajorVersion, server }) => { + test.skip(electronMajorVersion < 30, 'Depends on https://github.com/electron/electron/pull/41718'); + + server.setRoute('/download', (req, res) => { + res.setHeader('Content-Type', 'application/octet-stream'); + res.setHeader('Content-Disposition', 'attachment'); + res.end(`Hello world`); + }); + + const app = await launchElectronApp('electron-window-app.js', [], { + acceptDownloads: true, + }); + const window = await app.firstWindow(); + await window.setContent(`download`); + const [download] = await Promise.all([ + window.waitForEvent('download'), + window.click('a') + ]); + const path = await download.path(); + expect(fs.existsSync(path)).toBeTruthy(); + expect(fs.readFileSync(path).toString()).toBe('Hello world'); + await app.close(); +}); diff --git a/tests/electron/electronTest.ts b/tests/electron/electronTest.ts index fb353905d3..33210e9116 100644 --- a/tests/electron/electronTest.ts +++ b/tests/electron/electronTest.ts @@ -31,6 +31,7 @@ type ElectronTestFixtures = PageTestFixtures & { export const electronTest = baseTest.extend(traceViewerFixtures).extend({ browserVersion: [({}, use) => use(process.env.ELECTRON_CHROMIUM_VERSION), { scope: 'worker' }], browserMajorVersion: [({}, use) => use(Number(process.env.ELECTRON_CHROMIUM_VERSION.split('.')[0])), { scope: 'worker' }], + electronMajorVersion: [({}, use) => use(parseInt(require('electron/package.json').version.split('.')[0], 10)), { scope: 'worker' }], isAndroid: [false, { scope: 'worker' }], isElectron: [true, { scope: 'worker' }], isWebView2: [false, { scope: 'worker' }], diff --git a/tests/installation/playwright-electron-should-work.spec.ts b/tests/installation/playwright-electron-should-work.spec.ts index 4de28e8b54..5c6ced0948 100755 --- a/tests/installation/playwright-electron-should-work.spec.ts +++ b/tests/installation/playwright-electron-should-work.spec.ts @@ -15,6 +15,7 @@ */ import { test } from './npmTest'; import fs from 'fs'; +import { expect } from 'packages/playwright-test'; import path from 'path'; test('electron should work', async ({ exec, tsc, writeFiles }) => { @@ -39,3 +40,46 @@ test('electron should work with special characters in path', async ({ exec, tmpW cwd: path.join(folderName) }); }); + +test('should work when wrapped inside @playwright/test and trace is enabled', async ({ exec, tmpWorkspace, writeFiles }) => { + await exec('npm i -D @playwright/test electron@31'); + await writeFiles({ + 'electron-with-tracing.spec.ts': ` + import { test, expect, _electron } from '@playwright/test'; + + test('should work', async ({ trace }) => { + const electronApp = await _electron.launch({ args: [${JSON.stringify(path.join(__dirname, '../electron/electron-window-app.js'))}] }); + + const window = await electronApp.firstWindow(); + if (trace) + await window.context().tracing.start({ screenshots: true, snapshots: true }); + + await window.goto('data:text/html,Playwright

Playwright

'); + await expect(window).toHaveTitle(/Playwright/); + await expect(window.getByRole('heading')).toHaveText('Playwright'); + + const path = test.info().outputPath('electron-trace.zip'); + if (trace) { + await window.context().tracing.stop({ path }); + test.info().attachments.push({ name: 'trace', path, contentType: 'application/zip' }); + } + await electronApp.close(); + }); + `, + }); + const jsonOutputName = test.info().outputPath('report.json'); + await exec('npx playwright test --trace=on --reporter=json electron-with-tracing.spec.ts', { + env: { PLAYWRIGHT_JSON_OUTPUT_NAME: jsonOutputName } + }); + const traces = [ + // our actual trace. + path.join(tmpWorkspace, 'test-results', 'electron-with-tracing-should-work', 'electron-trace.zip'), + // contains the expect() calls + path.join(tmpWorkspace, 'test-results', 'electron-with-tracing-should-work', 'trace.zip'), + ]; + for (const trace of traces) + expect(fs.existsSync(trace)).toBe(true); + const report = JSON.parse(fs.readFileSync(jsonOutputName, 'utf-8')); + expect(new Set(['trace'])).toEqual(new Set(report.suites[0].specs[0].tests[0].results[0].attachments.map(a => a.name))); + expect(new Set(traces.map(p => fs.realpathSync(p)))).toEqual(new Set(report.suites[0].specs[0].tests[0].results[0].attachments.map(a => a.path))); +}); diff --git a/tests/library/browsercontext-add-cookies.spec.ts b/tests/library/browsercontext-add-cookies.spec.ts index 311084a837..e0ef92a00d 100644 --- a/tests/library/browsercontext-add-cookies.spec.ts +++ b/tests/library/browsercontext-add-cookies.spec.ts @@ -391,7 +391,7 @@ it('should(not) block third party cookies', async ({ context, page, server, brow it('should not block third party SameSite=None cookies', async ({ contextFactory, httpsServer, browserName }) => { it.skip(browserName === 'webkit', 'No third party cookies in WebKit'); - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); const context = await contextFactory({ ignoreHTTPSErrors: true, }); diff --git a/tests/library/browsercontext-fetch.spec.ts b/tests/library/browsercontext-fetch.spec.ts index ba01ccc07c..f8c0327c7d 100644 --- a/tests/library/browsercontext-fetch.spec.ts +++ b/tests/library/browsercontext-fetch.spec.ts @@ -435,7 +435,7 @@ it('should return error with wrong credentials', async ({ context, server }) => expect(response2.status()).toBe(401); }); -it('should support HTTPCredentials.sendImmediately for newContext', async ({ contextFactory, server }) => { +it('should support HTTPCredentials.send for newContext', async ({ contextFactory, server }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' }); const context = await contextFactory({ httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' } @@ -459,7 +459,7 @@ it('should support HTTPCredentials.sendImmediately for newContext', async ({ con } }); -it('should support HTTPCredentials.sendImmediately for browser.newPage', async ({ contextFactory, server, browser }) => { +it('should support HTTPCredentials.send for browser.newPage', async ({ contextFactory, server, browser }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' }); const page = await browser.newPage({ httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' } @@ -853,7 +853,7 @@ it('should not hang on a brotli encoded Range request', async ({ context, server headers: { range: 'bytes=0-2', }, - })).rejects.toThrow(/(failed to decompress 'br' encoding: Error: unexpected end of file|Parse Error: Data after \`Connection: close\`)/); + })).rejects.toThrow(/Parse Error: Expected HTTP/); }); it('should dispose', async function({ context, server }) { @@ -1287,3 +1287,21 @@ it('should not work after context dispose', async ({ context, server }) => { await context.close({ reason: 'Test ended.' }); expect(await context.request.get(server.EMPTY_PAGE).catch(e => e.message)).toContain('Test ended.'); }); + +it('should retrty ECONNRESET', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30978' } +}, async ({ context, server }) => { + let requestCount = 0; + server.setRoute('/test', (req, res) => { + if (requestCount++ < 3) { + req.socket.destroy(); + return; + } + res.writeHead(200, { 'content-type': 'text/plain' }); + res.end('Hello!'); + }); + const response = await context.request.get(server.PREFIX + '/test', { maxRetries: 3 }); + expect(response.status()).toBe(200); + expect(await response.text()).toBe('Hello!'); + expect(requestCount).toBe(4); +}); diff --git a/tests/library/browsercontext-reuse.spec.ts b/tests/library/browsercontext-reuse.spec.ts index c25d66d588..14590a3ae3 100644 --- a/tests/library/browsercontext-reuse.spec.ts +++ b/tests/library/browsercontext-reuse.spec.ts @@ -252,6 +252,19 @@ test('should reset tracing', async ({ reusedContext, trace }, testInfo) => { expect(error.message).toContain('Must start tracing before stopping'); }); +test('should work with clock emulation', async ({ reusedContext, trace }, testInfo) => { + let context = await reusedContext(); + + let page = await context.newPage(); + await page.clock.setFixedTime(new Date('2020-01-01T00:00:00.000Z')); + expect(await page.evaluate('new Date().toISOString()')).toBe('2020-01-01T00:00:00.000Z'); + + context = await reusedContext(); + page = context.pages()[0]; + await page.clock.setFixedTime(new Date('2020-01-01T00:00:00Z')); + expect(await page.evaluate('new Date().toISOString()')).toBe('2020-01-01T00:00:00.000Z'); +}); + test('should continue issuing events after closing the reused page', async ({ reusedContext, server }) => { test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/24574' }); diff --git a/tests/library/browsercontext-storage-state.spec.ts b/tests/library/browsercontext-storage-state.spec.ts index 7bd2581c9a..89bb84d2c3 100644 --- a/tests/library/browsercontext-storage-state.spec.ts +++ b/tests/library/browsercontext-storage-state.spec.ts @@ -223,9 +223,9 @@ it('should serialize storageState with lone surrogates', async ({ page, context, expect(storageState.origins[0].localStorage[0].value).toBe(String.fromCharCode(55934)); }); -it('should work when service worker is intefering', async ({ page, context, server, isAndroid, isElectron }) => { +it('should work when service worker is intefering', async ({ page, context, server, isAndroid, isElectron, electronMajorVersion }) => { it.skip(isAndroid); - it.skip(isElectron); + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); server.setRoute('/', (req, res) => { res.writeHead(200, { 'content-type': 'text/html' }); diff --git a/tests/library/capabilities.spec.ts b/tests/library/capabilities.spec.ts index 66fc9058e9..863a3bafca 100644 --- a/tests/library/capabilities.spec.ts +++ b/tests/library/capabilities.spec.ts @@ -139,15 +139,14 @@ it('should not crash on showDirectoryPicker', async ({ page, server, browserName it.skip(browserName === 'chromium' && browserMajorVersion < 99, 'Fixed in Chromium r956769'); it.skip(browserName !== 'chromium', 'showDirectoryPicker is only available in Chromium'); await page.goto(server.EMPTY_PAGE); - await Promise.race([ - page.evaluate(async () => { - const dir = await (window as any).showDirectoryPicker(); - return dir.name; - }).catch(e => expect(e.message).toContain('DOMException: The user aborted a request')), - // The dialog will not be accepted, so we just wait for some time to - // to give the browser a chance to crash. - new Promise(r => setTimeout(r, 1000)) - ]); + page.evaluate(async () => { + const dir = await (window as any).showDirectoryPicker(); + return dir.name; + // In headless it throws (aborted), in headed it stalls (Test ended) and waits for the picker to be accepted. + }).catch(e => expect(e.message).toMatch(/((DOMException|AbortError): The user aborted a request|Test ended)/)); + // The dialog will not be accepted, so we just wait for some time to + // to give the browser a chance to crash. + await page.waitForTimeout(3_000); }); it('should not crash on storage.getDirectory()', async ({ page, server, browserName, isMac }) => { diff --git a/tests/library/chromium/disable-web-security.spec.ts b/tests/library/chromium/disable-web-security.spec.ts new file mode 100644 index 0000000000..fab5599a76 --- /dev/null +++ b/tests/library/chromium/disable-web-security.spec.ts @@ -0,0 +1,68 @@ +/** + * Copyright 2018 Google Inc. All rights reserved. + * Modifications copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { contextTest as it, expect } from '../../config/browserTest'; + +it.use({ + launchOptions: async ({ launchOptions }, use) => { + await use({ ...launchOptions, args: ['--disable-web-security'] }); + } +}); + +it('test utility world in popup w/ --disable-web-security', async ({ page, server }) => { + server.setRoute('/main.html', (req, res) => { + res.writeHead(200, { + 'Content-Type': 'text/html' + }); + res.end(`Click me`); + }); + server.setRoute('/target.html', (req, res) => { + res.writeHead(200, { + 'Content-Type': 'text/html' + }); + res.end(``); + }); + + await page.goto(server.PREFIX + '/main.html'); + const page1Promise = page.context().waitForEvent('page'); + await page.getByRole('link', { name: 'Click me' }).click(); + const page1 = await page1Promise; + await expect(page1).toHaveURL(/target/); +}); + +it('test init script w/ --disable-web-security', async ({ page, server }) => { + server.setRoute('/main.html', (req, res) => { + res.writeHead(200, { + 'Content-Type': 'text/html' + }); + res.end(`Click me`); + }); + server.setRoute('/target.html', (req, res) => { + res.writeHead(200, { + 'Content-Type': 'text/html' + }); + res.end(``); + }); + + await page.context().addInitScript('window.injected = 123'); + await page.goto(server.PREFIX + '/main.html'); + const page1Promise = page.context().waitForEvent('page'); + await page.getByRole('link', { name: 'Click me' }).click(); + const page1 = await page1Promise; + const value = await page1.evaluate('window.injected'); + expect(value).toBe(123); +}); diff --git a/tests/library/chromium/js-coverage.spec.ts b/tests/library/chromium/js-coverage.spec.ts index f36e6cbcbb..860304d51c 100644 --- a/tests/library/chromium/js-coverage.spec.ts +++ b/tests/library/chromium/js-coverage.spec.ts @@ -43,7 +43,7 @@ it('should ignore eval() scripts by default', async function({ page, server }) { }); it('shouldn\'t ignore eval() scripts if reportAnonymousScripts is true', async function({ page, server }) { - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(!!process.env.PW_CLOCK); await page.coverage.startJSCoverage({ reportAnonymousScripts: true }); await page.goto(server.PREFIX + '/jscoverage/eval.html'); const coverage = await page.coverage.stopJSCoverage(); diff --git a/tests/library/global-fetch.spec.ts b/tests/library/global-fetch.spec.ts index a2eb629dc5..5915272621 100644 --- a/tests/library/global-fetch.spec.ts +++ b/tests/library/global-fetch.spec.ts @@ -154,7 +154,7 @@ it('should support WWW-Authenticate: Basic', async ({ playwright, server }) => { expect(credentials).toBe('user:pass'); }); -it('should support HTTPCredentials.sendImmediately', async ({ playwright, server }) => { +it('should support HTTPCredentials.send', async ({ playwright, server }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30534' }); const request = await playwright.request.newContext({ httpCredentials: { username: 'user', password: 'pass', origin: server.PREFIX.toUpperCase(), send: 'always' } @@ -436,7 +436,7 @@ it('should throw an error when maxRedirects is less than 0', async ({ playwright const request = await playwright.request.newContext(); for (const method of ['GET', 'PUT', 'POST', 'OPTIONS', 'HEAD', 'PATCH']) - await expect(async () => request.fetch(`${server.PREFIX}/a/redirect1`, { method, maxRedirects: -1 })).rejects.toThrow(`'maxRedirects' should be greater than or equal to '0'`); + await expect(async () => request.fetch(`${server.PREFIX}/a/redirect1`, { method, maxRedirects: -1 })).rejects.toThrow(`'maxRedirects' must be greater than or equal to '0'`); await request.dispose(); }); @@ -483,3 +483,21 @@ it('should throw after dispose', async ({ playwright, server }) => { await request.dispose(); await expect(request.get(server.EMPTY_PAGE)).rejects.toThrow('Target page, context or browser has been closed'); }); + +it('should retry ECONNRESET', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30978' } +}, async ({ context, server }) => { + let requestCount = 0; + server.setRoute('/test', (req, res) => { + if (requestCount++ < 3) { + req.socket.destroy(); + return; + } + res.writeHead(200, { 'content-type': 'text/plain' }); + res.end('Hello!'); + }); + const response = await context.request.fetch(server.PREFIX + '/test', { maxRetries: 3 }); + expect(response.status()).toBe(200); + expect(await response.text()).toBe('Hello!'); + expect(requestCount).toBe(4); +}); diff --git a/tests/library/headful.spec.ts b/tests/library/headful.spec.ts index f6e4a28488..cfeb9711c9 100644 --- a/tests/library/headful.spec.ts +++ b/tests/library/headful.spec.ts @@ -156,7 +156,7 @@ it('should(not) block third party cookies', async ({ page, server, allowsThirdPa it('should not block third party SameSite=None cookies', async ({ httpsServer, browserName, browser }) => { it.skip(browserName === 'webkit', 'No third party cookies in WebKit'); - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); const page = await browser.newPage({ ignoreHTTPSErrors: true, }); diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts index 41678e85d7..a58a8a38b9 100644 --- a/tests/library/inspector/cli-codegen-1.spec.ts +++ b/tests/library/inspector/cli-codegen-1.spec.ts @@ -557,6 +557,7 @@ await page.Locator("#checkbox").UncheckAsync();`); const locator = await recorder.hoverOverElement('select'); expect(locator).toBe(`locator('#age')`); + await page.locator('select').click(); const [message, sources] = await Promise.all([ page.waitForEvent('console', msg => msg.type() !== 'error'), diff --git a/tests/library/inspector/cli-codegen-3.spec.ts b/tests/library/inspector/cli-codegen-3.spec.ts index 96a6295f13..2c0fff974a 100644 --- a/tests/library/inspector/cli-codegen-3.spec.ts +++ b/tests/library/inspector/cli-codegen-3.spec.ts @@ -631,6 +631,27 @@ await page.GetByLabel("Coun\\"try").ClickAsync();`); expect.soft(sources2.get('C#')!.text).toContain(`await Expect(page.Locator("#second")).ToHaveValueAsync("bar")`); }); + test('should assert value on disabled select', async ({ openRecorder, browserName }) => { + const recorder = await openRecorder(); + + await recorder.setContentAndWait(` + + + `); + + await recorder.page.click('x-pw-tool-item.value'); + await recorder.hoverOverElement('#second'); + const [sources2] = await Promise.all([ + recorder.waitForOutput('JavaScript', '#second'), + recorder.trustedClick(), + ]); + expect.soft(sources2.get('JavaScript')!.text).toContain(`await expect(page.locator('#second')).toHaveValue('bar2')`); + expect.soft(sources2.get('Python')!.text).toContain(`expect(page.locator("#second")).to_have_value("bar2")`); + expect.soft(sources2.get('Python Async')!.text).toContain(`await expect(page.locator("#second")).to_have_value("bar2")`); + expect.soft(sources2.get('Java')!.text).toContain(`assertThat(page.locator("#second")).hasValue("bar2")`); + expect.soft(sources2.get('C#')!.text).toContain(`await Expect(page.Locator("#second")).ToHaveValueAsync("bar2")`); + }); + test('should assert visibility', async ({ openRecorder }) => { const recorder = await openRecorder(); diff --git a/tests/library/page-event-crash.spec.ts b/tests/library/page-event-crash.spec.ts index ea90023630..1bf9c396dd 100644 --- a/tests/library/page-event-crash.spec.ts +++ b/tests/library/page-event-crash.spec.ts @@ -70,9 +70,8 @@ test('should cancel navigation when page crashes', async ({ server, page, crash expect(error.message).toContain('page.goto: Page crashed'); }); -test('should be able to close context when page crashes', async ({ isAndroid, isElectron, isWebView2, page, crash }) => { +test('should be able to close context when page crashes', async ({ isAndroid, isWebView2, page, crash }) => { test.skip(isAndroid); - test.skip(isElectron); test.skip(isWebView2, 'Page.close() is not supported in WebView2'); await page.setContent(`
This page should crash
`); diff --git a/tests/library/playwright.config.ts b/tests/library/playwright.config.ts index 9ab64c22be..8cb0347a1a 100644 --- a/tests/library/playwright.config.ts +++ b/tests/library/playwright.config.ts @@ -128,12 +128,19 @@ for (const browserName of browserNames) { metadata: { platform: process.platform, docker: !!process.env.INSIDE_DOCKER, - headful: !!headed, + headless: (() => { + if (process.env.PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW) + return 'headless-new'; + if (headed) + return 'headed'; + return 'headless'; + })(), browserName, channel, mode, video: !!video, trace: !!trace, + clock: 'clock-' + (process.env.PW_CLOCK || 'default'), }, }); } diff --git a/tests/library/touch.spec.ts b/tests/library/touch.spec.ts new file mode 100644 index 0000000000..f842beb207 --- /dev/null +++ b/tests/library/touch.spec.ts @@ -0,0 +1,76 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { contextTest as it, expect } from '../config/browserTest'; +import type { Locator } from 'playwright-core'; + +it.use({ hasTouch: true }); + +it.fixme(({ browserName }) => browserName === 'firefox'); + +it('slow swipe events @smoke', async ({ page }) => { + it.fixme(); + await page.setContent(`
a
`); + const eventsHandle = await trackEvents(await page.locator('#a')); + const center = await centerPoint(page.locator('#a')); + await page.touchscreen.touch('touchstart', [{ ...center, id: 1 }]); + expect.soft(await eventsHandle.jsonValue()).toEqual([ + 'pointerover', + 'pointerenter', + 'pointerdown', + 'touchstart', + ]); + + await eventsHandle.evaluate(events => events.length = 0); + await page.touchscreen.touch('touchmove', [{ x: center.x + 10, y: center.y + 10, id: 1 }]); + await page.touchscreen.touch('touchmove', [{ x: center.x + 20, y: center.y + 20, id: 1 }]); + expect.soft(await eventsHandle.jsonValue()).toEqual([ + 'pointermove', + 'touchmove', + 'pointermove', + 'touchmove', + ]); + + await eventsHandle.evaluate(events => events.length = 0); + await page.touchscreen.touch('touchend', [{ x: center.x + 20, y: center.y + 20, id: 1 }]); + expect.soft(await eventsHandle.jsonValue()).toEqual([ + 'pointerup', + 'pointerout', + 'pointerleave', + 'touchend', + ]); +}); + + +async function trackEvents(target: Locator) { + const eventsHandle = await target.evaluateHandle(target => { + const events: string[] = []; + for (const event of [ + 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'click', + 'pointercancel', 'pointerdown', 'pointerenter', 'pointerleave', 'pointermove', 'pointerout', 'pointerover', 'pointerup', + 'touchstart', 'touchend', 'touchmove', 'touchcancel',]) + target.addEventListener(event, () => events.push(event), { passive: false }); + return events; + }); + return eventsHandle; +} + +async function centerPoint(e: Locator) { + const box = await e.boundingBox(); + if (!box) + throw new Error('Element is not visible'); + return { x: box.x + box.width / 2, y: box.y + box.height / 2 }; +} \ No newline at end of file diff --git a/tests/library/trace-viewer.spec.ts b/tests/library/trace-viewer.spec.ts index c2634df148..69864380d8 100644 --- a/tests/library/trace-viewer.spec.ts +++ b/tests/library/trace-viewer.spec.ts @@ -1236,3 +1236,38 @@ test('should open snapshot in new browser context', async ({ browser, page, runA await expect(newPage.getByText('hello')).toBeVisible(); await newPage.close(); }); + +function parseMillis(s: string): number { + const matchMs = s.match(/(\d+)ms/); + if (matchMs) + return +matchMs[1]; + const matchSeconds = s.match(/([\d.]+)s/); + if (!matchSeconds) + throw new Error('Failed to parse to millis: ' + s); + return (+matchSeconds[1]) * 1000; +} + +test('should show correct request start time', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31133' }, +}, async ({ page, runAndTrace, server }) => { + server.setRoute('/api', (req, res) => { + setTimeout(() => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('done'); + }, 1100); + }); + const traceViewer = await runAndTrace(async () => { + await page.goto(server.EMPTY_PAGE); + await page.evaluate(() => { + return fetch('/api').then(r => r.text()); + }); + }); + await traceViewer.selectAction('page.evaluate'); + await traceViewer.showNetworkTab(); + await expect(traceViewer.networkRequests).toContainText([/apiGET200text/]); + const line = traceViewer.networkRequests.getByText(/apiGET200text/); + const start = await line.locator('.grid-view-column-start').textContent(); + const duration = await line.locator('.grid-view-column-duration').textContent(); + expect(parseMillis(duration)).toBeGreaterThan(1000); + expect(parseMillis(start)).toBeLessThan(1000); +}); diff --git a/tests/library/video.spec.ts b/tests/library/video.spec.ts index dd73efa876..39dcaecbc6 100644 --- a/tests/library/video.spec.ts +++ b/tests/library/video.spec.ts @@ -206,6 +206,36 @@ it.describe('screencast', () => { expectRedFrames(videoFile, size); }); + it('should continue recording main page after popup closes', async ({ browser, browserName }, testInfo) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/30837' }); + // Firefox does not have a mobile variant and has a large minimum size (500 on windows and 450 elsewhere). + const size = browserName === 'firefox' ? { width: 500, height: 400 } : { width: 320, height: 240 }; + const context = await browser.newContext({ + recordVideo: { + dir: testInfo.outputPath(''), + size + }, + viewport: size, + }); + const page = await context.newPage(); + await page.setContent('clickme'); + const [popup] = await Promise.all([ + page.waitForEvent('popup'), + await page.click('a'), + ]); + await popup.close(); + + await page.evaluate(() => { + document.body.textContent = ''; // remove link + document.body.style.backgroundColor = 'red'; + }); + await waitForRafs(page, 100); + await context.close(); + + const videoFile = await page.video().path(); + expectRedFrames(videoFile, size); + }); + it('should expose video path', async ({ browser }, testInfo) => { const videosPath = testInfo.outputPath(''); const size = { width: 320, height: 240 }; diff --git a/tests/page/expect-boolean.spec.ts b/tests/page/expect-boolean.spec.ts index 719fa33877..a22657bda6 100644 --- a/tests/page/expect-boolean.spec.ts +++ b/tests/page/expect-boolean.spec.ts @@ -455,7 +455,7 @@ test('should print selector syntax error', async ({ page }) => { test.describe(() => { test.skip(({ isAndroid }) => isAndroid, 'server.EMPTY_PAGE is the emulator address 10.0.2.2'); - test.skip(({ isElectron }) => isElectron, 'Protocol error (Storage.getCookies): Browser context management is not supported.'); + test.skip(({ isElectron, electronMajorVersion }) => isElectron && electronMajorVersion < 30, 'Protocol error (Storage.getCookies): Browser context management is not supported.'); test('toBeOK', async ({ page, server }) => { const res = await page.request.get(server.EMPTY_PAGE); diff --git a/tests/page/interception.spec.ts b/tests/page/interception.spec.ts index c381e9f6e3..d71675cc39 100644 --- a/tests/page/interception.spec.ts +++ b/tests/page/interception.spec.ts @@ -33,9 +33,8 @@ it('should work with navigation @smoke', async ({ page, server }) => { expect(requests.get('style.css').isNavigationRequest()).toBe(false); }); -it('should intercept after a service worker', async ({ page, server, browserName, isAndroid, isElectron }) => { +it('should intercept after a service worker', async ({ page, server, browserName, isAndroid }) => { it.skip(isAndroid); - it.skip(isElectron); await page.goto(server.PREFIX + '/serviceworkers/fetchdummy/sw.html'); await page.evaluate(() => window['activationPromise']); diff --git a/tests/page/page-clock.frozen.spec.ts b/tests/page/page-clock.frozen.spec.ts index bddb794da1..b9b319cd63 100644 --- a/tests/page/page-clock.frozen.spec.ts +++ b/tests/page/page-clock.frozen.spec.ts @@ -16,9 +16,12 @@ import { test as it, expect } from './pageTest'; -it.skip(!process.env.PW_FREEZE_TIME); - it('clock should be frozen', async ({ page }) => { - await page.clock.setSystemTime(0); - expect(await page.evaluate('Date.now()')).toBe(0); + it.skip(process.env.PW_CLOCK !== 'frozen'); + expect(await page.evaluate('Date.now()')).toBe(1000); +}); + +it('clock should be realtime', async ({ page }) => { + it.skip(process.env.PW_CLOCK !== 'realtime'); + expect(await page.evaluate('Date.now()')).toBeLessThan(10000); }); diff --git a/tests/page/page-clock.spec.ts b/tests/page/page-clock.spec.ts index 670891a40a..c433052a32 100644 --- a/tests/page/page-clock.spec.ts +++ b/tests/page/page-clock.spec.ts @@ -16,7 +16,7 @@ import { test, expect } from './pageTest'; -test.skip(!!process.env.PW_FREEZE_TIME); +test.skip(!!process.env.PW_CLOCK); declare global { interface Window { @@ -207,34 +207,6 @@ it.describe('fastForward', () => { }); }); -it.describe('fastForwardTo', () => { - it.beforeEach(async ({ page }) => { - await page.clock.install({ time: 0 }); - await page.clock.pauseAt(1000); - }); - - it(`ignores timers which wouldn't be run`, async ({ page, calls }) => { - await page.evaluate(async () => { - setTimeout(() => { - window.stub('should not be logged'); - }, 1000); - }); - await page.clock.fastForward(500); - expect(calls).toEqual([]); - }); - - it('pushes back execution time for skipped timers', async ({ page, calls }) => { - await page.evaluate(async () => { - setTimeout(() => { - window.stub(Date.now()); - }, 1000); - }); - - await page.clock.fastForward(2000); - expect(calls).toEqual([{ params: [1000 + 2000] }]); - }); -}); - it.describe('stubTimers', () => { it.beforeEach(async ({ page }) => { await page.clock.install({ time: 0 }); @@ -245,6 +217,11 @@ it.describe('stubTimers', () => { expect(await page.evaluate(() => Date.now())).toBe(1400); }); + it('should throw for invalid date', async ({ page }) => { + await expect(page.clock.setSystemTime(new Date('invalid'))).rejects.toThrow('Invalid date: Invalid Date'); + await expect(page.clock.setSystemTime('invalid')).rejects.toThrow('clock.setSystemTime: Invalid date: invalid'); + }); + it('replaces global setTimeout', async ({ page, calls }) => { await page.evaluate(async () => { setTimeout(window.stub, 1000); diff --git a/tests/page/page-drag.spec.ts b/tests/page/page-drag.spec.ts index dcf63681a8..c227978f23 100644 --- a/tests/page/page-drag.spec.ts +++ b/tests/page/page-drag.spec.ts @@ -18,10 +18,12 @@ import type { ElementHandle, Route } from 'playwright-core'; import { test as it, expect } from './pageTest'; import { attachFrame } from '../config/utils'; +it.skip(({ browserName, browserMajorVersion }) => browserName === 'chromium' && browserMajorVersion < 91); +it.fixme(({ headless, isLinux }) => isLinux && !headless, 'Stray mouse events on Linux headed mess up the tests.'); +it.fixme(({ headless, isWindows, browserName }) => isWindows && !headless && browserName === 'webkit', 'WebKit win also send stray mouse events.'); + it.describe('Drag and drop', () => { - it.skip(({ browserName, browserMajorVersion }) => browserName === 'chromium' && browserMajorVersion < 91); it.skip(({ isAndroid }) => isAndroid, 'No drag&drop on Android.'); - it.fixme(({ headless, isLinux }) => isLinux && !headless, 'Stray mouse events on Linux headed mess up the tests.'); it('should work @smoke', async ({ page, server }) => { await page.goto(server.PREFIX + '/drag-n-drop.html'); @@ -258,9 +260,7 @@ it.describe('Drag and drop', () => { expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); }); - it('should be able to drag the mouse in a frame', async ({ page, server, isAndroid }) => { - it.fixme(isAndroid); - + it('should be able to drag the mouse in a frame', async ({ page, server }) => { await page.goto(server.PREFIX + '/frames/one-frame.html'); const eventsHandle = await trackEvents(await page.frames()[1].$('html')); await page.mouse.move(30, 30); @@ -336,7 +336,6 @@ it.describe('Drag and drop', () => { }); it('should work if not doing a drag', async ({ page, isLinux, headless }) => { - it.fixme(isLinux && !headless, 'Stray mouse events on Linux headed mess up the tests.'); const eventsHandle = await trackEvents(await page.$('html')); await page.mouse.move(50, 50); await page.mouse.down(); diff --git a/tests/page/page-emulate-media.spec.ts b/tests/page/page-emulate-media.spec.ts index 85caa1dc8f..c895d64eff 100644 --- a/tests/page/page-emulate-media.spec.ts +++ b/tests/page/page-emulate-media.spec.ts @@ -124,6 +124,29 @@ it('should emulate reduced motion', async ({ page }) => { await page.emulateMedia({ reducedMotion: null }); }); +it('should keep reduced motion and color emulation after reload', async ({ page, server }) => { + it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31328' }); + + // Pre-conditions + expect(await page.evaluate(() => matchMedia('(prefers-reduced-motion: reduce)').matches)).toEqual(false); + expect(await page.evaluate(() => matchMedia('(forced-colors: active)').matches)).toBe(false); + + // Emulation + await page.emulateMedia({ forcedColors: 'active', reducedMotion: 'reduce' }); + expect(await page.evaluate(() => matchMedia('(prefers-reduced-motion: reduce)').matches)).toEqual(true); + expect(await page.evaluate(() => matchMedia('(forced-colors: active)').matches)).toBe(true); + + // Force CanonicalBrowsingContext replacement in Firefox. + server.setRoute('/empty.html', (req, res) => { + res.setHeader('Cross-Origin-Opener-Policy', 'same-origin'); + res.end(); + }); + await page.goto(server.EMPTY_PAGE); + + expect(await page.evaluate(() => matchMedia('(prefers-reduced-motion: reduce)').matches)).toEqual(true); + expect(await page.evaluate(() => matchMedia('(forced-colors: active)').matches)).toBe(true); +}); + it('should emulate forcedColors ', async ({ page, browserName }) => { expect(await page.evaluate(() => matchMedia('(forced-colors: none)').matches)).toBe(true); await page.emulateMedia({ forcedColors: 'none' }); diff --git a/tests/page/page-evaluate.spec.ts b/tests/page/page-evaluate.spec.ts index 8414d23b2c..8bc7a57d17 100644 --- a/tests/page/page-evaluate.spec.ts +++ b/tests/page/page-evaluate.spec.ts @@ -362,7 +362,7 @@ it('should properly serialize PerformanceMeasure object', async ({ page }) => { }); it('should properly serialize window.performance object', async ({ page }) => { - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(!!process.env.PW_CLOCK); expect(await page.evaluate(() => performance)).toEqual({ 'navigation': { diff --git a/tests/page/page-event-request.spec.ts b/tests/page/page-event-request.spec.ts index 07c1fcc3ce..cfc2f7a1e2 100644 --- a/tests/page/page-event-request.spec.ts +++ b/tests/page/page-event-request.spec.ts @@ -107,9 +107,8 @@ it('should report requests and responses handled by service worker with routing' expect(interceptedUrls).toEqual(expectedUrls); }); -it('should report navigation requests and responses handled by service worker', async ({ page, server, isAndroid, isElectron, browserName }) => { +it('should report navigation requests and responses handled by service worker', async ({ page, server, isAndroid, browserName }) => { it.fixme(isAndroid); - it.fixme(isElectron); await page.goto(server.PREFIX + '/serviceworkers/stub/sw.html'); await page.evaluate(() => window['activationPromise']); @@ -136,9 +135,8 @@ it('should report navigation requests and responses handled by service worker', } }); -it('should report navigation requests and responses handled by service worker with routing', async ({ page, server, isAndroid, isElectron, browserName }) => { +it('should report navigation requests and responses handled by service worker with routing', async ({ page, server, isAndroid, browserName }) => { it.fixme(isAndroid); - it.fixme(isElectron); await page.route('**/*', route => route.continue()); await page.goto(server.PREFIX + '/serviceworkers/stub/sw.html'); diff --git a/tests/page/page-goto.spec.ts b/tests/page/page-goto.spec.ts index 6703d84498..5ca9ee6e46 100644 --- a/tests/page/page-goto.spec.ts +++ b/tests/page/page-goto.spec.ts @@ -481,7 +481,7 @@ it('js redirect overrides url bar navigation ', async ({ page, server, browserNa it('should succeed on url bar navigation when there is pending navigation', async ({ page, server, browserName }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/21574' }); - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); server.setRoute('/a', (req, res) => { res.writeHead(200, { 'content-type': 'text/html' }); res.end(` @@ -685,8 +685,7 @@ it('should fail when canceled by another navigation', async ({ page, server }) = expect(error.message).toBeTruthy(); }); -it('should work with lazy loading iframes', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron); +it('should work with lazy loading iframes', async ({ page, server, isAndroid }) => { it.fixme(isAndroid); await page.goto(server.PREFIX + '/frames/lazy-frame.html'); @@ -754,7 +753,7 @@ it('should properly wait for load', async ({ page, server, browserName }) => { it('should not resolve goto upon window.stop()', async ({ browserName, page, server }) => { it.fixme(browserName === 'firefox', 'load/domcontentloaded events are flaky'); - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); let response; server.setRoute('/module.js', (req, res) => { @@ -797,7 +796,7 @@ it('should return when navigation is committed if commit is specified', async ({ }); it('should wait for load when iframe attaches and detaches', async ({ page, server }) => { - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); server.setRoute('/empty.html', (req, res) => { res.writeHead(200, { 'content-type': 'text/html' }); res.end(` diff --git a/tests/page/page-history.spec.ts b/tests/page/page-history.spec.ts index 2bc01512dd..cf6eb2d456 100644 --- a/tests/page/page-history.spec.ts +++ b/tests/page/page-history.spec.ts @@ -245,7 +245,7 @@ it('page.goForward during renderer-initiated navigation', async ({ page, server it('regression test for issue 20791', async ({ page, server }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/20791' }); - it.skip(!!process.env.PW_FREEZE_TIME); + it.skip(process.env.PW_CLOCK === 'frozen'); server.setRoute('/iframe.html', (req, res) => { res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }); // iframe access parent frame to log a value from it. diff --git a/tests/page/page-request-continue.spec.ts b/tests/page/page-request-continue.spec.ts index 2fbac43081..dd7ed68b49 100644 --- a/tests/page/page-request-continue.spec.ts +++ b/tests/page/page-request-continue.spec.ts @@ -412,6 +412,27 @@ it('continue should propagate headers to redirects', async ({ page, server, brow expect(serverRequest.headers['custom']).toBe('value'); }); +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'); + await server.setRedirect('/redirect', '/empty.html'); + await page.route('**/redirect', route => { + const headers = route.request().headers(); + headers['custom'] = 'value'; + void route.fallback({ headers }); + }); + + const [serverRequest, response] = await Promise.all([ + server.waitForRequest('/empty.html'), + page.goto(server.PREFIX + '/redirect') + ]); + expect(serverRequest.headers['custom']).toBe('value'); + expect(response.request().url()).toBe(server.EMPTY_PAGE); + expect(response.request().headers()['custom']).toBe('value'); + 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'); diff --git a/tests/page/page-request-fulfill.spec.ts b/tests/page/page-request-fulfill.spec.ts index 7b78c07625..ebde0dbc56 100644 --- a/tests/page/page-request-fulfill.spec.ts +++ b/tests/page/page-request-fulfill.spec.ts @@ -140,10 +140,10 @@ it('should allow mocking binary responses', async ({ page, server, browserName, expect(await img.screenshot()).toMatchSnapshot('mock-binary-response.png'); }); -it('should allow mocking svg with charset', async ({ page, server, browserName, headless, isAndroid, isElectron, mode }) => { +it('should allow mocking svg with charset', async ({ page, server, browserName, headless, isAndroid, isElectron, electronMajorVersion }) => { it.skip(browserName === 'firefox' && !headless, 'Firefox headed produces a different image.'); it.skip(isAndroid); - it.skip(isElectron, 'Protocol error (Storage.getCookies): Browser context management is not supported'); + it.skip(isElectron && electronMajorVersion < 30, 'Protocol error (Storage.getCookies): Browser context management is not supported'); await page.route('**/*', route => { void route.fulfill({ @@ -253,8 +253,8 @@ it('should include the origin header', async ({ page, server, isAndroid }) => { expect(interceptedRequest.headers()['origin']).toEqual(server.PREFIX); }); -it('should fulfill with global fetch result', async ({ playwright, page, server, isElectron, rewriteAndroidLoopbackURL }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill with global fetch result', async ({ playwright, page, server, isElectron, electronMajorVersion, rewriteAndroidLoopbackURL }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); await page.route('**/*', async route => { const request = await playwright.request.newContext(); const response = await request.get(rewriteAndroidLoopbackURL(server.PREFIX + '/simple.json')); @@ -265,8 +265,8 @@ it('should fulfill with global fetch result', async ({ playwright, page, server, expect(await response.json()).toEqual({ 'foo': 'bar' }); }); -it('should fulfill with fetch result', async ({ page, server, isElectron, rewriteAndroidLoopbackURL }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill with fetch result', async ({ page, server, isElectron, electronMajorVersion, rewriteAndroidLoopbackURL }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); await page.route('**/*', async route => { const response = await page.request.get(rewriteAndroidLoopbackURL(server.PREFIX + '/simple.json')); void route.fulfill({ response }); @@ -276,8 +276,8 @@ it('should fulfill with fetch result', async ({ page, server, isElectron, rewrit expect(await response.json()).toEqual({ 'foo': 'bar' }); }); -it('should fulfill with fetch result and overrides', async ({ page, server, isElectron, rewriteAndroidLoopbackURL }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill with fetch result and overrides', async ({ page, server, isElectron, electronMajorVersion, rewriteAndroidLoopbackURL }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); await page.route('**/*', async route => { const response = await page.request.get(rewriteAndroidLoopbackURL(server.PREFIX + '/simple.json')); void route.fulfill({ @@ -295,8 +295,8 @@ it('should fulfill with fetch result and overrides', async ({ page, server, isEl expect(await response.json()).toEqual({ 'foo': 'bar' }); }); -it('should fetch original request and fulfill', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fetch original request and fulfill', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.route('**/*', async route => { const response = await page.request.fetch(route.request()); @@ -309,8 +309,8 @@ it('should fetch original request and fulfill', async ({ page, server, isElectro expect(await page.title()).toEqual('Woof-Woof'); }); -it('should fulfill with multiple set-cookie', async ({ page, server, isElectron }) => { - it.fixme(isElectron, 'Electron 14+ is required'); +it('should fulfill with multiple set-cookie', async ({ page, server, isElectron, electronMajorVersion }) => { + it.skip(isElectron && electronMajorVersion < 14, 'Electron 14+ is required'); const cookies = ['a=b', 'c=d']; await page.route('**/empty.html', async route => { void route.fulfill({ @@ -442,9 +442,9 @@ it('should fulfill json', async ({ page, server }) => { it('should fulfill with gzip and readback', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/29261' }, -}, async ({ page, server, isAndroid, isElectron }) => { +}, async ({ page, server, isAndroid, isElectron, electronMajorVersion }) => { it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); - it.fixme(isElectron, 'error: Browser context management is not supported.'); + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); server.enableGzip('/one-style.html'); await page.route('**/one-style.html', async route => { const response = await route.fetch(); diff --git a/tests/page/page-request-intercept.spec.ts b/tests/page/page-request-intercept.spec.ts index 024919c898..33516606e7 100644 --- a/tests/page/page-request-intercept.spec.ts +++ b/tests/page/page-request-intercept.spec.ts @@ -33,8 +33,8 @@ const it = base.extend<{ rewriteAndroidLoopbackURL(url: string): string }>({ }) }); -it('should fulfill intercepted response', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill intercepted response', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.route('**/*', async route => { const response = await page.request.fetch(route.request()); @@ -55,10 +55,10 @@ it('should fulfill intercepted response', async ({ page, server, isElectron, isA expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!'); }); -it('should fulfill response with empty body', async ({ page, server, isAndroid, isElectron, browserName, browserMajorVersion }) => { +it('should fulfill response with empty body', async ({ page, server, isAndroid, isElectron, electronMajorVersion, browserName, browserMajorVersion }) => { it.skip(browserName === 'chromium' && browserMajorVersion <= 91, 'Fails in Electron that uses old Chromium'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); - it.skip(isElectron, 'Protocol error (Storage.getCookies): Browser context management is not supported.'); + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); await page.route('**/*', async route => { const response = await page.request.fetch(route.request()); await route.fulfill({ @@ -73,8 +73,8 @@ it('should fulfill response with empty body', async ({ page, server, isAndroid, expect(await response.text()).toBe(''); }); -it('should override with defaults when intercepted response not provided', async ({ page, server, browserName, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should override with defaults when intercepted response not provided', async ({ page, server, browserName, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); server.setRoute('/empty.html', (req, res) => { res.setHeader('foo', 'bar'); @@ -95,8 +95,8 @@ it('should override with defaults when intercepted response not provided', async expect(response.headers()).toEqual({ }); }); -it('should fulfill with any response', async ({ page, server, isElectron, rewriteAndroidLoopbackURL }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill with any response', async ({ page, server, isElectron, electronMajorVersion, rewriteAndroidLoopbackURL }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); server.setRoute('/sample', (req, res) => { res.setHeader('foo', 'bar'); @@ -117,8 +117,8 @@ it('should fulfill with any response', async ({ page, server, isElectron, rewrit expect(response.headers()['foo']).toBe('bar'); }); -it('should support fulfill after intercept', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should support fulfill after intercept', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); const requestPromise = server.waitForRequest('/title.html'); await page.route('**', async route => { @@ -132,8 +132,8 @@ it('should support fulfill after intercept', async ({ page, server, isElectron, expect(await response.text()).toBe(original); }); -it('should give access to the intercepted response', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should give access to the intercepted response', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.goto(server.EMPTY_PAGE); @@ -156,8 +156,8 @@ it('should give access to the intercepted response', async ({ page, server, isEl await Promise.all([route.fulfill({ response }), evalPromise]); }); -it('should give access to the intercepted response body', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should give access to the intercepted response body', async ({ page, server, isAndroid, isElectron, electronMajorVersion }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.goto(server.EMPTY_PAGE); @@ -177,7 +177,7 @@ it('should give access to the intercepted response body', async ({ page, server, it('should intercept multipart/form-data request body', async ({ page, server, asset, browserName }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/14624' }); - it.fail(browserName !== 'firefox'); + it.fixme(browserName !== 'firefox'); await page.goto(server.PREFIX + '/input/fileupload.html'); const filePath = path.relative(process.cwd(), asset('file-to-upload.txt')); await page.locator('input[type=file]').setInputFiles(filePath); @@ -194,8 +194,8 @@ it('should intercept multipart/form-data request body', async ({ page, server, a expect(request.postData()).toContain(fs.readFileSync(filePath, 'utf8')); }); -it('should fulfill intercepted response using alias', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill intercepted response using alias', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.route('**/*', async route => { const response = await route.fetch(); @@ -206,8 +206,8 @@ it('should fulfill intercepted response using alias', async ({ page, server, isE expect(response.headers()['content-type']).toContain('text/html'); }); -it('should support timeout option in route.fetch', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should support timeout option in route.fetch', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); server.setRoute('/slow', (req, res) => { @@ -224,8 +224,8 @@ it('should support timeout option in route.fetch', async ({ page, server, isElec expect(error.message).toContain(`Timeout 2000ms exceeded`); }); -it('should not follow redirects when maxRedirects is set to 0 in route.fetch', async ({ page, server, isAndroid, isElectron }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should not follow redirects when maxRedirects is set to 0 in route.fetch', async ({ page, server, isAndroid, isElectron, electronMajorVersion }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); server.setRedirect('/foo', '/empty.html'); @@ -239,8 +239,8 @@ it('should not follow redirects when maxRedirects is set to 0 in route.fetch', a expect(await page.content()).toContain('hello'); }); -it('should intercept with url override', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should intercept with url override', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.route('**/*.html', async route => { const response = await route.fetch({ url: server.PREFIX + '/one-style.html' }); @@ -251,8 +251,8 @@ it('should intercept with url override', async ({ page, server, isElectron, isAn expect((await response.body()).toString()).toContain('one-style.css'); }); -it('should intercept with post data override', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should intercept with post data override', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); const requestPromise = server.waitForRequest('/empty.html'); await page.route('**/*.html', async route => { @@ -266,8 +266,8 @@ it('should intercept with post data override', async ({ page, server, isElectron expect((await request.postBody).toString()).toBe(JSON.stringify({ 'foo': 'bar' })); }); -it('should fulfill popup main request using alias', async ({ page, server, isElectron, isAndroid }) => { - it.fixme(isElectron, 'error: Browser context management is not supported.'); +it('should fulfill popup main request using alias', async ({ page, server, isElectron, electronMajorVersion, isAndroid }) => { + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); it.skip(isAndroid, 'The internal Android localhost (10.0.0.2) != the localhost on the host'); await page.context().route('**/*', async route => { @@ -281,3 +281,39 @@ it('should fulfill popup main request using alias', async ({ page, server, isEle ]); await expect(popup.locator('body')).toHaveText('hello'); }); + +it('request.postData is not null when fetching FormData with a Blob', { + annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/24077' } +}, async ({ server, page, browserName, isElectron, electronMajorVersion }) => { + it.skip(isElectron && electronMajorVersion < 31); + it.fixme(browserName === 'webkit', 'The body is empty in WebKit when intercepting'); + await page.goto(server.EMPTY_PAGE); + await page.setContent(` + + + +`); + let resolvePostData; + const postDataPromise = new Promise(resolve => resolvePostData = resolve); + await page.route(server.PREFIX + '/upload', async (route, request) => { + expect(request.method()).toBe('POST'); + resolvePostData(await request.postData()); + await route.fulfill({ + status: 200, + body: 'ok', + }); + }); + await page.getByTestId('click-me').click(); + const postData = await postDataPromise; + expect(postData).toContain('Content-Disposition: form-data; name="file"; filename="blob"'); + expect(postData).toContain('\r\nhello\r\n'); +}); \ No newline at end of file diff --git a/tests/page/page-route.spec.ts b/tests/page/page-route.spec.ts index ebde1617ea..911521018e 100644 --- a/tests/page/page-route.spec.ts +++ b/tests/page/page-route.spec.ts @@ -152,9 +152,9 @@ it('should contain referer header', async ({ page, server }) => { expect(requests[1].headers().referer).toContain('/one-style.html'); }); -it('should properly return navigation response when URL has cookies', async ({ page, server, isElectron, isAndroid }) => { +it('should properly return navigation response when URL has cookies', async ({ page, server, isAndroid, isElectron, electronMajorVersion }) => { it.skip(isAndroid, 'No isolated context'); - it.fixme(isElectron, 'error: Browser context management is not supported.'); + it.skip(isElectron && electronMajorVersion < 30, 'error: Browser context management is not supported.'); // Setup cookie. await page.goto(server.EMPTY_PAGE); diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index 7f374ac59b..dd1be3fbaa 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -280,12 +280,13 @@ it.describe('page screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-clip-odd-size.png'); }); - it('should work for canvas', async ({ page, server, isElectron, isMac }) => { + it('should work for canvas', async ({ page, server, isElectron, isMac, browserName }) => { it.fixme(isElectron && isMac, 'Fails on the bots'); await page.setViewportSize({ width: 500, height: 500 }); await page.goto(server.PREFIX + '/screenshots/canvas.html'); const screenshot = await page.screenshot(); - expect(screenshot).toMatchSnapshot('screenshot-canvas.png'); + const screenshotPrefix = browserName === 'chromium' && isMac && process.arch === 'arm64' ? '-macOS-arm64' : ''; + expect(screenshot).toMatchSnapshot(`screenshot-canvas${screenshotPrefix}.png`); }); it('should capture canvas changes', async ({ page, isElectron, browserName, isMac, isWebView2 }) => { diff --git a/tests/page/page-screenshot.spec.ts-snapshots/screenshot-canvas-macOS-arm64-chromium.png b/tests/page/page-screenshot.spec.ts-snapshots/screenshot-canvas-macOS-arm64-chromium.png new file mode 100644 index 0000000000..830872e8d2 Binary files /dev/null and b/tests/page/page-screenshot.spec.ts-snapshots/screenshot-canvas-macOS-arm64-chromium.png differ diff --git a/tests/page/page-set-input-files.spec.ts b/tests/page/page-set-input-files.spec.ts index 22ce7151cd..76a53fa571 100644 --- a/tests/page/page-set-input-files.spec.ts +++ b/tests/page/page-set-input-files.spec.ts @@ -16,7 +16,7 @@ */ import { test as it, expect } from './pageTest'; -import { attachFrame, chromiumVersionLessThan } from '../config/utils'; +import { attachFrame } from '../config/utils'; import path from 'path'; import fs from 'fs'; @@ -37,7 +37,7 @@ it('should upload the file', async ({ page, server, asset }) => { }, input)).toBe('contents of the file'); }); -it('should upload a folder', async ({ page, server, browserName, headless, browserVersion, isAndroid }) => { +it('should upload a folder', async ({ page, server, browserName, headless, browserMajorVersion, isAndroid }) => { it.skip(isAndroid); it.skip(os.platform() === 'darwin' && parseInt(os.release().split('.')[0], 10) <= 21, 'WebKit on macOS-12 is frozen'); @@ -54,7 +54,7 @@ it('should upload a folder', async ({ page, server, browserName, headless, brows await input.setInputFiles(dir); expect(new Set(await page.evaluate(e => [...e.files].map(f => f.webkitRelativePath), input))).toEqual(new Set([ // https://issues.chromium.org/issues/345393164 - ...((browserName === 'chromium' && headless && !process.env.PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW && chromiumVersionLessThan(browserVersion, '127.0.6533.0')) ? [] : ['file-upload-test/sub-dir/really.txt']), + ...((browserName === 'chromium' && headless && !process.env.PLAYWRIGHT_CHROMIUM_USE_HEADLESS_NEW && browserMajorVersion < 127) ? [] : ['file-upload-test/sub-dir/really.txt']), 'file-upload-test/file1.txt', 'file-upload-test/file2', ])); diff --git a/tests/page/pageTestApi.ts b/tests/page/pageTestApi.ts index a7b124a84b..cf497e76c0 100644 --- a/tests/page/pageTestApi.ts +++ b/tests/page/pageTestApi.ts @@ -32,6 +32,7 @@ export type PageWorkerFixtures = { browserName: 'chromium' | 'firefox' | 'webkit'; browserVersion: string; browserMajorVersion: number; + electronMajorVersion: number; isAndroid: boolean; isElectron: boolean; isWebView2: boolean; diff --git a/tests/page/retarget.spec.ts b/tests/page/retarget.spec.ts index 65daf1e205..94e0f440e7 100644 --- a/tests/page/retarget.spec.ts +++ b/tests/page/retarget.spec.ts @@ -377,3 +377,18 @@ it('check retargeting', async ({ page, asset }) => { }); } }); + +it('should not retarget anchor into parent label', async ({ page }) => { + await page.setContent(` + + `); + await page.locator('a').click(); + expect(await page.evaluate('window.__clicked')).toBe(1); + + await page.setContent(` + + + `); + await page.locator('a').click(); + expect(await page.evaluate('window.__clicked')).toBe(2); +}); diff --git a/tests/playwright-test/fixture-errors.spec.ts b/tests/playwright-test/fixture-errors.spec.ts index c17db65bce..51c928f156 100644 --- a/tests/playwright-test/fixture-errors.spec.ts +++ b/tests/playwright-test/fixture-errors.spec.ts @@ -256,6 +256,41 @@ test('should detect fixture dependency cycle', async ({ runInlineTest }) => { expect(result.exitCode).toBe(1); }); +test('should hide boxed fixtures in dependency cycle', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'x.spec.ts': ` + import { test as base } from '@playwright/test'; + const test = base.extend({ + storageState: async ({ context, storageState }, use) => { + await use(storageState); + } + }); + test('failed', async ({ page }) => {}); + `, + }); + expect(result.output).toContain('Fixtures "context" -> "storageState" -> "context" form a dependency cycle: -> x.spec.ts:3:25 -> '); + expect(result.exitCode).toBe(1); +}); + +test('should show boxed fixtures in dependency cycle if there are no public fixtures', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'x.spec.ts': ` + import { test as base } from '@playwright/test'; + const test = base.extend({ + f1: [async ({ f2 }, use) => { + await use(f2); + }, { box: true }], + f2: [async ({ f1 }, use) => { + await use(f1); + }, { box: true }], + }); + test('failed', async ({ f1, f2 }) => {}); + `, + }); + expect(result.output).toContain('Fixtures "f1" -> "f2" -> "f1" form a dependency cycle: x.spec.ts:3:25 -> x.spec.ts:3:25 -> x.spec.ts:3:25'); + expect(result.exitCode).toBe(1); +}); + test('should not reuse fixtures from one file in another one', async ({ runInlineTest }) => { const result = await runInlineTest({ 'a.spec.ts': ` diff --git a/tests/playwright-test/playwright.config.ts b/tests/playwright-test/playwright.config.ts index 8536ed992e..6be40d617f 100644 --- a/tests/playwright-test/playwright.config.ts +++ b/tests/playwright-test/playwright.config.ts @@ -49,4 +49,7 @@ export default defineConfig({ }, ], reporter: reporters(), + metadata: { + clock: 'clock-' + (process.env.PW_CLOCK || 'default'), + }, }); diff --git a/tests/playwright-test/reporter-html.spec.ts b/tests/playwright-test/reporter-html.spec.ts index 83992c0bad..e416cd05c1 100644 --- a/tests/playwright-test/reporter-html.spec.ts +++ b/tests/playwright-test/reporter-html.spec.ts @@ -294,6 +294,7 @@ for (const useIntermediateMergeReport of [false] as const) { }); test('should include image diff when screenshot failed to generate due to animation', async ({ runInlineTest, page, showReport }) => { + test.skip(process.env.PW_CLOCK === 'frozen', 'Assumes Date.now() changes'); const result = await runInlineTest({ 'playwright.config.ts': ` module.exports = { use: { viewport: { width: 200, height: 200 }} }; diff --git a/tests/playwright-test/stable-test-runner/package-lock.json b/tests/playwright-test/stable-test-runner/package-lock.json index b05cc3099c..e6bf87ad76 100644 --- a/tests/playwright-test/stable-test-runner/package-lock.json +++ b/tests/playwright-test/stable-test-runner/package-lock.json @@ -5,21 +5,21 @@ "packages": { "": { "dependencies": { - "@playwright/test": "1.44.0-beta-1714435420000" + "@playwright/test": "1.45.0-beta-1718411373000" } }, "node_modules/@playwright/test": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-zwhn/hNFfohqHIvhlZ8gxb6HBijPtYNjjIk0KKDEBShLmUGmyh6fEmLNoF6N2bQDzGDzKrfItbwCVcfD3D0Ubw==", + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-MUSJtFJLYqVgiR6HEHBc9BNlwVoA8hDbb0MaSJLPCEt4Q5jYsD5orNxDXJC5jgWqOEDUzSaCAU+iHs5UbIG9IQ==", "dependencies": { - "playwright": "1.44.0-beta-1714435420000" + "playwright": "1.45.0-beta-1718411373000" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/fsevents": { @@ -36,41 +36,41 @@ } }, "node_modules/playwright": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-WGvILU5q2DIk4kzwKFuY6xopx7vSTRiUCP4VzBJGGVI3VqAc5u4epHRULHegf5zLjlPRgAk8RYKMcpaja+953g==", + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-ytXqNRkVkZVAm8VH1zGlUqJltWbElVkAnqw2fUeXelku2we+ZFL7gnMiSxiKIlfTfrKQgvdlMgWiZ1s4r5cW2Q==", "dependencies": { - "playwright-core": "1.44.0-beta-1714435420000" + "playwright-core": "1.45.0-beta-1718411373000" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-pu0FlCeyIY3N8hIY/UjvGE0TBtVIBa8puVbyKirwHKVW7HSGhq8ZXVI7HywZNN/FLsulHWVnNUXfIoJ18DSn4A==", + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-s9FTt2EMcnY8/BhJEMJN7tW3KogupYIv8DRBMb1fMtJQyFgH+iQwcvmj/an4MiXCtGXgQ0NNhVAbJtVwgjvHNA==", "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } } }, "dependencies": { "@playwright/test": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-zwhn/hNFfohqHIvhlZ8gxb6HBijPtYNjjIk0KKDEBShLmUGmyh6fEmLNoF6N2bQDzGDzKrfItbwCVcfD3D0Ubw==", + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-MUSJtFJLYqVgiR6HEHBc9BNlwVoA8hDbb0MaSJLPCEt4Q5jYsD5orNxDXJC5jgWqOEDUzSaCAU+iHs5UbIG9IQ==", "requires": { - "playwright": "1.44.0-beta-1714435420000" + "playwright": "1.45.0-beta-1718411373000" } }, "fsevents": { @@ -80,18 +80,18 @@ "optional": true }, "playwright": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-WGvILU5q2DIk4kzwKFuY6xopx7vSTRiUCP4VzBJGGVI3VqAc5u4epHRULHegf5zLjlPRgAk8RYKMcpaja+953g==", + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-ytXqNRkVkZVAm8VH1zGlUqJltWbElVkAnqw2fUeXelku2we+ZFL7gnMiSxiKIlfTfrKQgvdlMgWiZ1s4r5cW2Q==", "requires": { "fsevents": "2.3.2", - "playwright-core": "1.44.0-beta-1714435420000" + "playwright-core": "1.45.0-beta-1718411373000" } }, "playwright-core": { - "version": "1.44.0-beta-1714435420000", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.0-beta-1714435420000.tgz", - "integrity": "sha512-pu0FlCeyIY3N8hIY/UjvGE0TBtVIBa8puVbyKirwHKVW7HSGhq8ZXVI7HywZNN/FLsulHWVnNUXfIoJ18DSn4A==" + "version": "1.45.0-beta-1718411373000", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.0-beta-1718411373000.tgz", + "integrity": "sha512-s9FTt2EMcnY8/BhJEMJN7tW3KogupYIv8DRBMb1fMtJQyFgH+iQwcvmj/an4MiXCtGXgQ0NNhVAbJtVwgjvHNA==" } } } diff --git a/tests/playwright-test/stable-test-runner/package.json b/tests/playwright-test/stable-test-runner/package.json index a373e3be9a..97adee767d 100644 --- a/tests/playwright-test/stable-test-runner/package.json +++ b/tests/playwright-test/stable-test-runner/package.json @@ -1,6 +1,6 @@ { "private": true, "dependencies": { - "@playwright/test": "1.44.0-beta-1714435420000" + "@playwright/test": "1.45.0-beta-1718411373000" } } diff --git a/tests/playwright-test/test-modifiers.spec.ts b/tests/playwright-test/test-modifiers.spec.ts index 2b206b448a..0dd41bd0ab 100644 --- a/tests/playwright-test/test-modifiers.spec.ts +++ b/tests/playwright-test/test-modifiers.spec.ts @@ -690,3 +690,50 @@ test('static modifiers should be added in serial mode', async ({ runInlineTest } expect(result.report.suites[0].specs[2].tests[0].annotations).toEqual([{ type: 'skip' }]); expect(result.report.suites[0].specs[3].tests[0].annotations).toEqual([]); }); + +test('should contain only one slow modifier', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'slow.test.ts': ` + import { test } from '@playwright/test'; + test.slow(); + test('pass', { annotation: { type: 'issue', description: 'my-value' } }, () => {}); + `, + 'skip.test.ts': ` + import { test } from '@playwright/test'; + test.skip(); + test('pass', { annotation: { type: 'issue', description: 'my-value' } }, () => {}); + `, + 'fixme.test.ts': ` + import { test } from '@playwright/test'; + test.fixme(); + test('pass', { annotation: { type: 'issue', description: 'my-value' } }, () => {}); +`, + }); + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + expect(result.report.suites[0].specs[0].tests[0].annotations).toEqual([{ type: 'fixme' }, { type: 'issue', description: 'my-value' }]); + expect(result.report.suites[1].specs[0].tests[0].annotations).toEqual([{ type: 'skip' }, { type: 'issue', description: 'my-value' }]); + expect(result.report.suites[2].specs[0].tests[0].annotations).toEqual([{ type: 'slow' }, { type: 'issue', description: 'my-value' }]); +}); + +test('should skip beforeEach hooks upon modifiers', async ({ runInlineTest }) => { + const result = await runInlineTest({ + 'a.test.ts': ` + import { test } from '@playwright/test'; + test('top', () => {}); + + test.describe(() => { + test.skip(({ viewport }) => true); + test.beforeEach(() => { throw new Error(); }); + + test.describe(() => { + test.beforeEach(() => { throw new Error(); }); + test('test', () => {}); + }); + }); + `, + }); + expect(result.exitCode).toBe(0); + expect(result.passed).toBe(1); + expect(result.skipped).toBe(1); +}); diff --git a/tests/playwright-test/timeout.spec.ts b/tests/playwright-test/timeout.spec.ts index 50069b3280..a079c3f70b 100644 --- a/tests/playwright-test/timeout.spec.ts +++ b/tests/playwright-test/timeout.spec.ts @@ -182,7 +182,7 @@ test('should respect fixture timeout', async ({ runInlineTest }) => { slowSetup: [async ({}, use) => { await new Promise(f => setTimeout(f, 2000)); await use('hey'); - }, { timeout: 500, _title: 'custom title' }], + }, { timeout: 500, title: 'custom title' }], slowTeardown: [async ({}, use) => { await use('hey'); await new Promise(f => setTimeout(f, 2000)); @@ -227,7 +227,7 @@ test('should respect test.setTimeout in the worker fixture', async ({ runInlineT slowTeardown: [async ({}, use) => { await use('hey'); await new Promise(f => setTimeout(f, 2000)); - }, { scope: 'worker', timeout: 400, _title: 'custom title' }], + }, { scope: 'worker', timeout: 400, title: 'custom title' }], }); test('test ok', async ({ fixture, noTimeout }) => { await new Promise(f => setTimeout(f, 1000)); diff --git a/tests/webview2/webView2Test.ts b/tests/webview2/webView2Test.ts index b72f57ce93..dcadcebe6d 100644 --- a/tests/webview2/webView2Test.ts +++ b/tests/webview2/webView2Test.ts @@ -30,6 +30,7 @@ export const webView2Test = baseTest.extend(traceViewerFixt browserMajorVersion: [({ browserVersion }, use) => use(Number(browserVersion.split('.')[0])), { scope: 'worker' }], isAndroid: [false, { scope: 'worker' }], isElectron: [false, { scope: 'worker' }], + electronMajorVersion: [0, { scope: 'worker' }], isWebView2: [true, { scope: 'worker' }], browser: [async ({ playwright }, use, testInfo) => { diff --git a/utils/build/build-playwright-driver.sh b/utils/build/build-playwright-driver.sh index 975c66446b..c0864681bc 100755 --- a/utils/build/build-playwright-driver.sh +++ b/utils/build/build-playwright-driver.sh @@ -4,7 +4,7 @@ set -x trap "cd $(pwd -P)" EXIT SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)" -NODE_VERSION="20.14.0" # autogenerated via ./update-playwright-driver-version.mjs +NODE_VERSION="20.15.0" # autogenerated via ./update-playwright-driver-version.mjs cd "$(dirname "$0")" PACKAGE_VERSION=$(node -p "require('../../package.json').version") diff --git a/utils/build_android_driver.sh b/utils/build_android_driver.sh index eae70eebe9..ad36339e75 100755 --- a/utils/build_android_driver.sh +++ b/utils/build_android_driver.sh @@ -1,15 +1,22 @@ #!/usr/bin/env bash -(cd src/server/android/driver ; ./gradlew assemble) +(cd packages/playwright-core/src/server/android/driver ; ./gradlew assemble) if [ "$?" -ne "0" ]; then exit 1 fi -(cd src/server/android/driver ; ./gradlew assembleAndroidTest) +(cd packages/playwright-core/src/server/android/driver ; ./gradlew assembleAndroidTest) if [ "$?" -ne "0" ]; then exit 1 fi # These should be uploaded to the CDN -# cp src/server/android/driver/app/build/outputs/apk/debug/app-debug.apk ./bin/android-driver-target.apk -# cp src/server/android/driver/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk ./bin/android-driver.apk +mkdir -p for-cdn +cp packages/playwright-core/src/server/android/driver/app/build/outputs/apk/debug/app-debug.apk ./for-cdn/android-driver-target.apk +cp packages/playwright-core/src/server/android/driver/app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk ./for-cdn/android-driver.apk +cd for-cdn +zip /tmp/android.zip *.apk +cd .. +rm -r for-cdn +echo "Android driver APKs are in /tmp/android.zip. Upload them to the CDN." + diff --git a/utils/doclint/documentation.js b/utils/doclint/documentation.js index 7972ba507e..7340178b35 100644 --- a/utils/doclint/documentation.js +++ b/utils/doclint/documentation.js @@ -866,6 +866,7 @@ function csharpOptionOverloadSuffix(option, type) { case 'Buffer': return 'Byte'; case 'Serializable': return 'Object'; case 'int': return 'Int'; + case 'long': return 'Int64'; case 'Date': return 'Date'; } throw new Error(`CSharp option "${option}" has unsupported type overload "${type}"`); diff --git a/utils/doclint/generateDotnetApi.js b/utils/doclint/generateDotnetApi.js index eb9e681ff1..9c094026f9 100644 --- a/utils/doclint/generateDotnetApi.js +++ b/utils/doclint/generateDotnetApi.js @@ -82,6 +82,7 @@ classNameMap.set('boolean', 'bool'); classNameMap.set('any', 'object'); classNameMap.set('Buffer', 'byte[]'); classNameMap.set('path', 'string'); +classNameMap.set('Date', 'DateTime'); classNameMap.set('URL', 'string'); classNameMap.set('RegExp', 'Regex'); classNameMap.set('Readable', 'Stream'); @@ -829,7 +830,7 @@ function translateType(type, parent, generateNameCallback = t => t.name, optiona * @param {Documentation.Type} type */ function registerModelType(typeName, type) { - if (['object', 'string', 'int'].includes(typeName)) + if (['object', 'string', 'int', 'long'].includes(typeName)) return; if (typeName.endsWith('Option')) return; diff --git a/utils/generate_types/exported.json b/utils/generate_types/exported.json index 7cd191c644..e7151b75da 100644 --- a/utils/generate_types/exported.json +++ b/utils/generate_types/exported.json @@ -8,5 +8,6 @@ "BrowserNewContextOptionsGeolocation": "Geolocation", "BrowserNewContextOptionsHttpCredentials": "HTTPCredentials", "PageScreenshotOptions": "PageScreenshotOptions", - "LocatorScreenshotOptions": "LocatorScreenshotOptions" + "LocatorScreenshotOptions": "LocatorScreenshotOptions", + "PageAssertionsToHaveScreenshotOptions": "PageAssertionsToHaveScreenshotOptions" } diff --git a/utils/generate_types/index.js b/utils/generate_types/index.js index 209ce04756..eb1527c80b 100644 --- a/utils/generate_types/index.js +++ b/utils/generate_types/index.js @@ -427,7 +427,7 @@ class TypesGenerator { return `{ [key: ${keyType}]: ${valueType}; }`; } let out = type.name; - if (out === 'int' || out === 'float') + if (out === 'int' || out === 'long' || out === 'float') out = 'number'; if (out === 'Array' && direction === 'in') out = 'ReadonlyArray'; diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 0367f3259c..80880f71a7 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -140,13 +140,13 @@ export type WorkerFixture = (args: Args, use: (r: R) = type TestFixtureValue = Exclude | TestFixture; type WorkerFixtureValue = Exclude | WorkerFixture; export type Fixtures = { - [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined }]; + [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined }]; + [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; } & { - [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', 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 }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit';