From ca01e29ab8989af14cdddc7e3ffb30a96e73c3b8 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Tue, 6 Dec 2022 17:52:48 -0500 Subject: [PATCH] fix: re include document domain injections for spec-bridge and injection and disable origin-agent-cluster (#25013) * Revert "chore: remove document.domain usage for cross-origin testing (#24945)" This reverts commit a3d3074e707ee3daceaf22cdc14fbfba3dd96896. * fix: set origin-agent-cluster=?0 for the spec bridge iframe * re apply comment that was reverted in 1fa1246b5ca08bc2ac64d9c8306078e437210f7b * Update packages/server/lib/routes-e2e.ts Co-authored-by: Matt Schile * chore: update document.domain immutable target from chrome 106 -> chrome 109 Co-authored-by: Matt Schile --- packages/driver/src/cypress.ts | 7 +++---- packages/proxy/lib/http/response-middleware.ts | 2 +- packages/proxy/lib/http/util/inject.ts | 4 +++- packages/proxy/lib/http/util/rewriter.ts | 2 +- packages/server/lib/controllers/iframes.ts | 2 +- packages/server/lib/html/spec-bridge-iframe.html | 3 +++ packages/server/lib/routes-e2e.ts | 7 +++++++ packages/server/lib/routes.ts | 2 +- .../server/test/integration/http_requests_spec.js | 15 +++++++++++++-- 9 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/driver/src/cypress.ts b/packages/driver/src/cypress.ts index 0dc86ec067a6..21ffeea18488 100644 --- a/packages/driver/src/cypress.ts +++ b/packages/driver/src/cypress.ts @@ -180,10 +180,9 @@ class $Cypress { configure (config: Record = {}) { const domainName = config.remote ? config.remote.domainName : undefined - // set domainName but allow us to turn off this feature in testing. not - // needed for cross-origin spec bridge, since it is strictly used - // same-origin - if (domainName && !this.isCrossOriginSpecBridge && config.testingType === 'e2e') { + // set domainName but allow us to turn + // off this feature in testing + if (domainName && config.testingType === 'e2e') { document.domain = domainName } diff --git a/packages/proxy/lib/http/response-middleware.ts b/packages/proxy/lib/http/response-middleware.ts index bac35119a5cd..5553254b99aa 100644 --- a/packages/proxy/lib/http/response-middleware.ts +++ b/packages/proxy/lib/http/response-middleware.ts @@ -301,7 +301,7 @@ const SetInjectionLevel: ResponseMiddleware = function () { } if (this.res.wantsInjection) { - // Chrome plans to make document.domain immutable in Chrome 106, with the default value + // Chrome plans to make document.domain immutable in Chrome 109, with the default value // of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header // so that we can continue to support tests that visit multiple subdomains in a single spec. // https://github.com/cypress-io/cypress/issues/20147 diff --git a/packages/proxy/lib/http/util/inject.ts b/packages/proxy/lib/http/util/inject.ts index 570c0eb460e5..f6c20bfe64b9 100644 --- a/packages/proxy/lib/http/util/inject.ts +++ b/packages/proxy/lib/http/util/inject.ts @@ -28,11 +28,13 @@ export function full (domain) { }) } -export async function fullCrossOrigin (options: FullCrossOriginOpts) { +export async function fullCrossOrigin (domain, options: FullCrossOriginOpts) { const contents = await getRunnerCrossOriginInjectionContents() return oneLine` diff --git a/packages/server/lib/routes-e2e.ts b/packages/server/lib/routes-e2e.ts index f74c6071c4c7..68b65ed60c88 100644 --- a/packages/server/lib/routes-e2e.ts +++ b/packages/server/lib/routes-e2e.ts @@ -98,6 +98,13 @@ export const createRoutesE2E = ({ routesE2E.get('/__cypress/spec-bridge-iframes', (req, res) => { debug('handling cross-origin iframe for domain: %s', req.hostname) + // Chrome plans to make document.domain immutable in Chrome 109, with the default value + // of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header + // in the spec-bridge-iframe to allow setting document.domain to the bare domain + // to guarantee the spec bridge can communicate with the injected code. + // @see https://github.com/cypress-io/cypress/issues/25010 + res.setHeader('Origin-Agent-Cluster', '?0') + files.handleCrossOriginIframe(req, res, config.namespace) }) diff --git a/packages/server/lib/routes.ts b/packages/server/lib/routes.ts index 27e727773eb5..dad8f7a6e840 100644 --- a/packages/server/lib/routes.ts +++ b/packages/server/lib/routes.ts @@ -80,7 +80,7 @@ export const createCommonRoutes = ({ router.get(clientRoute, (req: Request & { proxiedUrl?: string }, res) => { const nonProxied = req.proxiedUrl?.startsWith('/') ?? false - // Chrome plans to make document.domain immutable in Chrome 106, with the default value + // Chrome plans to make document.domain immutable in Chrome 109, with the default value // of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header // so that we can continue to support tests that visit multiple subdomains in a single spec. // https://github.com/cypress-io/cypress/issues/20147 diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index bda82a276334..9a202258d16c 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -322,6 +322,17 @@ describe('Routes', () => { }) }) + it('correctly sets the "origin-agent-cluster" to opt in to setting document.domain on spec bridge iframes', function () { + return this.rp('http://localhost:2020/__cypress/spec-bridge-iframes') + .then((res) => { + expect(res.statusCode).to.eq(200) + + expect(res.body).to.match(/document.domain = \'localhost\'/) + + expect(res.headers['origin-agent-cluster']).to.eq('?0') + }) + }) + it('sets title to projectName', function () { return this.rp('http://localhost:2020/__') .then((res) => { @@ -2651,7 +2662,7 @@ describe('Routes', () => { }) }) - it('does not inject document.domain on AUT iframe requests that do not match current superDomain', function () { + it('injects document.domain on AUT iframe requests that do not match current superDomain', function () { nock('http://www.foobar.com') .get('/') .reply(200, 'hi', { @@ -2671,7 +2682,7 @@ describe('Routes', () => { const body = cleanResponseBody(res.body) - expect(body).not.to.include('document.domain =') + expect(body).to.include(`