From cdbdf218b256eb2dc33c49e57ece3128444c7a71 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 9 Sep 2022 15:03:51 -0400 Subject: [PATCH] chore: rename getOriginPolicy to getParentOriginPolicy as the method does not include subdomain, which is a parent of origin policy, as well as add documentation as to why we need this --- packages/app/src/runner/aut-iframe.ts | 2 +- packages/app/src/runner/event-manager.ts | 18 +++--- packages/app/src/runner/index.ts | 6 +- .../cypress/e2e/commands/location.cy.js | 4 +- .../driver/cypress/e2e/cypress/location.cy.js | 57 ++++++++++++++++++- .../driver/src/cross-origin/communicator.ts | 16 +++--- packages/driver/src/cross-origin/cypress.ts | 8 +-- packages/driver/src/cy/commands/navigation.ts | 14 ++--- .../driver/src/cy/commands/origin/index.ts | 24 ++++---- packages/driver/src/cy/commands/waiting.ts | 6 +- packages/driver/src/cypress/cy.ts | 2 +- packages/driver/src/cypress/error_messages.ts | 14 ++--- packages/driver/src/cypress/location.ts | 6 ++ packages/driver/src/cypress/log.ts | 8 +-- packages/driver/src/cypress/state.ts | 4 +- packages/network/lib/cors.ts | 18 +++++- packages/network/test/unit/cors_spec.ts | 16 +++++- .../unit/http/response-middleware.spec.ts | 12 ++-- packages/server/lib/remote_states.ts | 42 +++++++------- .../server/test/integration/server_spec.js | 10 ++-- .../server/test/unit/remote_states.spec.ts | 24 ++++---- packages/server/test/unit/socket_spec.js | 12 ++-- 22 files changed, 204 insertions(+), 119 deletions(-) diff --git a/packages/app/src/runner/aut-iframe.ts b/packages/app/src/runner/aut-iframe.ts index 8f82ab4e2644..ad521dcd8f24 100644 --- a/packages/app/src/runner/aut-iframe.ts +++ b/packages/app/src/runner/aut-iframe.ts @@ -103,7 +103,7 @@ export class AutIframe { const locationTop = Cypress.Location.create(window.location.href) const locationAUT = Cypress.Location.create(currentHref) - return locationTop.originPolicy === locationAUT.originPolicy || locationAUT.originPolicy === 'about://blank' + return locationTop.parentOriginPolicy === locationAUT.parentOriginPolicy || locationAUT.parentOriginPolicy === 'about://blank' } catch (err) { if (err.name === 'SecurityError') { return false diff --git a/packages/app/src/runner/event-manager.ts b/packages/app/src/runner/event-manager.ts index e835d3382602..407102092b52 100644 --- a/packages/app/src/runner/event-manager.ts +++ b/packages/app/src/runner/event-manager.ts @@ -637,13 +637,13 @@ export class EventManager { }) }) - Cypress.primaryOriginCommunicator.on('window:load', ({ url }, originPolicy) => { + Cypress.primaryOriginCommunicator.on('window:load', ({ url }, parentOriginPolicy) => { // Sync stable if the expected origin has loaded. // Only listen to window load events from the most recent secondary origin, This prevents nondeterminism in the case where we redirect to an already // established spec bridge, but one that is not the current or next cy.origin command. - if (cy.state('latestActiveOriginPolicy') === originPolicy) { + if (cy.state('latestActiveParentOriginPolicy') === parentOriginPolicy) { // We remain in an anticipating state until either a load even happens or a timeout. - cy.state('autOrigin', cy.state('autOrigin', cors.getOriginPolicy(url))) + cy.state('autOrigin', cy.state('autOrigin', cors.getParentOriginPolicy(url))) cy.isAnticipatingCrossOriginResponseFor(undefined) cy.isStable(true, 'load') // Prints out the newly loaded URL @@ -665,18 +665,18 @@ export class EventManager { this.localBus.emit('expect:origin', originPolicy) }) - Cypress.primaryOriginCommunicator.on('viewport:changed', (viewport, originPolicy) => { + Cypress.primaryOriginCommunicator.on('viewport:changed', (viewport, parentOriginPolicy) => { const callback = () => { - Cypress.primaryOriginCommunicator.toSpecBridge(originPolicy, 'viewport:changed:end') + Cypress.primaryOriginCommunicator.toSpecBridge(parentOriginPolicy, 'viewport:changed:end') } Cypress.primaryOriginCommunicator.emit('sync:viewport', viewport) this.localBus.emit('viewport:changed', viewport, callback) }) - Cypress.primaryOriginCommunicator.on('before:screenshot', (config, originPolicy) => { + Cypress.primaryOriginCommunicator.on('before:screenshot', (config, parentOriginPolicy) => { const callback = () => { - Cypress.primaryOriginCommunicator.toSpecBridge(originPolicy, 'before:screenshot:end') + Cypress.primaryOriginCommunicator.toSpecBridge(parentOriginPolicy, 'before:screenshot:end') } handleBeforeScreenshot(config, callback) @@ -842,9 +842,9 @@ export class EventManager { this.ws.emit('spec:changed', specFile) } - notifyCrossOriginBridgeReady (originPolicy) { + notifyCrossOriginBridgeReady (parentOriginPolicy) { // Any multi-origin event appends the origin as the third parameter and we do the same here for this short circuit - Cypress.primaryOriginCommunicator.emit('bridge:ready', undefined, originPolicy) + Cypress.primaryOriginCommunicator.emit('bridge:ready', undefined, parentOriginPolicy) } snapshotUnpinned () { diff --git a/packages/app/src/runner/index.ts b/packages/app/src/runner/index.ts index 9f7bd1c1d6b7..33c730ad6f3f 100644 --- a/packages/app/src/runner/index.ts +++ b/packages/app/src/runner/index.ts @@ -201,11 +201,11 @@ export async function teardown () { * Add a cross origin iframe for cy.origin support */ export function addCrossOriginIframe (location) { - const id = `Spec Bridge: ${location.originPolicy}` + const id = `Spec Bridge: ${location.parentOriginPolicy}` // if it already exists, don't add another one if (document.getElementById(id)) { - getEventManager().notifyCrossOriginBridgeReady(location.originPolicy) + getEventManager().notifyCrossOriginBridgeReady(location.parentOriginPolicy) return } @@ -216,7 +216,7 @@ export function addCrossOriginIframe (location) { // container since it needs to match the size of the top window for screenshots $container: document.body, className: 'spec-bridge-iframe', - src: `${location.originPolicy}/${getRunnerConfigFromWindow().namespace}/spec-bridge-iframes`, + src: `${location.parentOriginPolicy}/${getRunnerConfigFromWindow().namespace}/spec-bridge-iframes`, }) } diff --git a/packages/driver/cypress/e2e/commands/location.cy.js b/packages/driver/cypress/e2e/commands/location.cy.js index 9c92cbe6144f..8e31fdc699ca 100644 --- a/packages/driver/cypress/e2e/commands/location.cy.js +++ b/packages/driver/cypress/e2e/commands/location.cy.js @@ -326,7 +326,7 @@ describe('src/cy/commands/location', () => { context('#location', () => { it('returns the location object', () => { cy.location().then((loc) => { - expect(loc).to.have.keys(['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'originPolicy', 'superDomain', 'toString']) + expect(loc).to.have.keys(['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'originPolicy', 'parentOriginPolicy', 'superDomain', 'toString']) }) }) @@ -529,7 +529,7 @@ describe('src/cy/commands/location', () => { expect(_.keys(consoleProps)).to.deep.eq(['Command', 'Yielded']) expect(consoleProps.Command).to.eq('location') - expect(_.keys(consoleProps.Yielded)).to.deep.eq(['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'originPolicy', 'superDomain', 'toString']) + expect(_.keys(consoleProps.Yielded)).to.deep.eq(['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'originPolicy', 'parentOriginPolicy', 'superDomain', 'toString']) }) }) }) diff --git a/packages/driver/cypress/e2e/cypress/location.cy.js b/packages/driver/cypress/e2e/cypress/location.cy.js index f9d2a4525c7b..1040c2634fc7 100644 --- a/packages/driver/cypress/e2e/cypress/location.cy.js +++ b/packages/driver/cypress/e2e/cypress/location.cy.js @@ -225,7 +225,7 @@ describe('src/cypress/location', () => { it('handles subdomains google', function () { const str = this.setup('google').getOriginPolicy() - expect(str).to.eq('https://google.com') + expect(str).to.eq('https://www.google.com') }) it('issue: #255 two domains in the url', function () { @@ -243,12 +243,63 @@ describe('src/cypress/location', () => { it('handles subdomains of private tlds in the public suffix', function () { const str = this.setup('herokuSub').getOriginPolicy() - expect(str).to.eq('https://example.herokuapp.com') + expect(str).to.eq('https://foo.example.herokuapp.com') }) it('falls back to dumb check when invalid tld', function () { const str = this.setup('unknown').getOriginPolicy() + expect(str).to.eq('http://what.is.so.unknown') + }) + }) + + // TODO: getParentOriginPolicy + context('#getParentOriginPolicy', () => { + it('handles ip addresses', function () { + const str = this.setup('local').getParentOriginPolicy() + + expect(str).to.eq('http://127.0.0.1:8080') + }) + + it('handles 1 part localhost', function () { + const str = this.setup('users').getParentOriginPolicy() + + expect(str).to.eq('http://localhost:2020') + }) + + it('handles 2 parts stack', function () { + const str = this.setup('stack').getParentOriginPolicy() + + expect(str).to.eq('https://stackoverflow.com') + }) + + it('handles subdomains google', function () { + const str = this.setup('google').getParentOriginPolicy() + + expect(str).to.eq('https://google.com') + }) + + it('issue: #255 two domains in the url', function () { + const str = this.setup('email').getParentOriginPolicy() + + expect(str).to.eq('http://localhost:3500') + }) + + it('handles private tlds in the public suffix', function () { + const str = this.setup('heroku').getParentOriginPolicy() + + expect(str).to.eq('https://example.herokuapp.com') + }) + + it('handles subdomains of private tlds in the public suffix', function () { + const str = this.setup('herokuSub').getParentOriginPolicy() + + expect(str).to.eq('https://example.herokuapp.com') + }) + + it('falls back to dumb check when invalid tld', function () { + const str = this.setup('unknown').getParentOriginPolicy() + expect(str).to.eq('http://so.unknown') }) }) @@ -256,7 +307,7 @@ describe('src/cypress/location', () => { context('.create', () => { it('returns an object literal', () => { const obj = Location.create(urls.cypress, urls.signin) - const keys = ['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'toString', 'originPolicy', 'superDomain'] + const keys = ['auth', 'authObj', 'hash', 'href', 'host', 'hostname', 'origin', 'pathname', 'port', 'protocol', 'search', 'toString', 'originPolicy', 'parentOriginPolicy', 'superDomain'] expect(obj).to.have.keys(keys) }) diff --git a/packages/driver/src/cross-origin/communicator.ts b/packages/driver/src/cross-origin/communicator.ts index 477407a7f543..8210b8868d7c 100644 --- a/packages/driver/src/cross-origin/communicator.ts +++ b/packages/driver/src/cross-origin/communicator.ts @@ -42,7 +42,7 @@ export class PrimaryOriginCommunicator extends EventEmitter { // where we need to set the crossOriginDriverWindows to source to // communicate back to the iframe if (messageName === 'bridge:ready' && source) { - this.crossOriginDriverWindows[data.originPolicy] = source as Window + this.crossOriginDriverWindows[data.parentOriginPolicy] = source as Window } // reify any logs coming back from the cross-origin spec bridges to serialize snapshot/consoleProp DOM elements as well as select functions. @@ -59,7 +59,7 @@ export class PrimaryOriginCommunicator extends EventEmitter { data.data.err = reifySerializedError(data.data.err, this.userInvocationStack as string) } - this.emit(messageName, data.data, data.originPolicy) + this.emit(messageName, data.data, data.parentOriginPolicy) return } @@ -91,8 +91,8 @@ export class PrimaryOriginCommunicator extends EventEmitter { }) } - toSpecBridge (originPolicy: string, event: string, data?: any) { - debug('=> to spec bridge', originPolicy, event, data) + toSpecBridge (parentOriginPolicy: string, event: string, data?: any) { + debug('=> to spec bridge', parentOriginPolicy, event, data) const preprocessedData = preprocessForSerialization(data) @@ -102,7 +102,7 @@ export class PrimaryOriginCommunicator extends EventEmitter { } // If there is no crossOriginDriverWindows, there is no need to send the message. - this.crossOriginDriverWindows[originPolicy]?.postMessage({ + this.crossOriginDriverWindows[parentOriginPolicy]?.postMessage({ event, data: preprocessedData, }, '*') @@ -183,7 +183,7 @@ export class SpecBridgeCommunicator extends EventEmitter { * @param {Cypress.ObjectLike} data - any meta data to be sent with the event. */ toPrimary (event: string, data?: Cypress.ObjectLike, options: { syncGlobals: boolean } = { syncGlobals: false }) { - const { originPolicy } = $Location.create(window.location.href) + const { parentOriginPolicy } = $Location.create(window.location.href) const eventName = `${CROSS_ORIGIN_PREFIX}${event}` // Preprocess logs before sending through postMessage() to attempt to serialize some DOM nodes and functions. @@ -197,14 +197,14 @@ export class SpecBridgeCommunicator extends EventEmitter { data = preprocessSnapshotForSerialization(data as any) } - debug('<= to Primary ', event, data, originPolicy) + debug('<= to Primary ', event, data, parentOriginPolicy) if (options.syncGlobals) this.syncGlobalsToPrimary() this.handleSubjectAndErr(data, (data: Cypress.ObjectLike) => { window.top?.postMessage({ event: eventName, data, - originPolicy, + parentOriginPolicy, }, '*') }) } diff --git a/packages/driver/src/cross-origin/cypress.ts b/packages/driver/src/cross-origin/cypress.ts index 573716f20a30..49ba75683965 100644 --- a/packages/driver/src/cross-origin/cypress.ts +++ b/packages/driver/src/cross-origin/cypress.ts @@ -37,10 +37,10 @@ const createCypress = () => { }) Cypress.specBridgeCommunicator.on('generate:final:snapshot', (snapshotUrl: string) => { - const currentAutOriginPolicy = cy.state('autOrigin') + const currentAutParentOriginPolicy = cy.state('autParentOrigin') const requestedSnapshotUrlLocation = $Location.create(snapshotUrl) - if (requestedSnapshotUrlLocation.originPolicy === currentAutOriginPolicy) { + if (requestedSnapshotUrlLocation.parentOriginPolicy === currentAutParentOriginPolicy) { // if true, this is the correct specbridge to take the snapshot and send it back const finalSnapshot = cy.createSnapshot(FINAL_SNAPSHOT_NAME) @@ -144,7 +144,7 @@ const onBeforeAppWindowLoad = (Cypress: Cypress.Cypress, cy: $Cy) => (autWindow: const onWindowLoadPrimary = ({ url }) => { cy.isStable(true, 'primary onload') - cy.state('autOrigin', cors.getOriginPolicy(url)) + cy.state('autOrigin', cors.getParentOriginPolicy(url)) Cypress.emit('internal:window:load', { type: 'cross:origin', url }) } @@ -179,7 +179,7 @@ const onBeforeAppWindowLoad = (Cypress: Cypress.Cypress, cy: $Cy) => (autWindow: const remoteLocation = cy.getRemoteLocation() - cy.state('autOrigin', remoteLocation.originPolicy) + cy.state('autParentOrigin', remoteLocation.parentOriginPolicy) Cypress.specBridgeCommunicator.toPrimary('window:load', { url: remoteLocation.href }) cy.isStable(true, 'load') diff --git a/packages/driver/src/cy/commands/navigation.ts b/packages/driver/src/cy/commands/navigation.ts index feaf4cb4c8e3..177996f997aa 100644 --- a/packages/driver/src/cy/commands/navigation.ts +++ b/packages/driver/src/cy/commands/navigation.ts @@ -69,13 +69,13 @@ const timedOutWaitingForPageLoad = (ms, log) => { cy.isAnticipatingCrossOriginResponseFor(undefined) // By default origins is just this location. - let originPolicies = [$Location.create(location.href).originPolicy] + let originPolicies = [$Location.create(location.href).parentOriginPolicy] const currentCommand = cy.queue.state('current') if (currentCommand?.get('name') === 'origin') { // If the current command is a cy.origin command, we should have gotten a request on the origin it expects. - originPolicies = [cy.state('latestActiveOriginPolicy')] + originPolicies = [cy.state('latestActiveParentOriginPolicy')] } else if (Cypress.isCrossOriginSpecBridge && cy.queue.isOnLastCommand()) { // If this is a cross origin spec bridge and we're on the last command, we should have gotten a request on the origin of one of the parents. originPolicies = cy.state('parentOriginPolicies') @@ -342,7 +342,7 @@ const stabilityChanged = (Cypress, state, config, stable) => { const onPageLoadErr = (err) => { state('onPageLoadErr', null) - const { originPolicy } = $Location.create(window.location.href) + const { parentOriginPolicy } = $Location.create(window.location.href) try { $errUtils.throwErrByPath('navigation.cross_origin', { @@ -350,7 +350,7 @@ const stabilityChanged = (Cypress, state, config, stable) => { args: { configFile: Cypress.config('configFile'), message: err.message, - originPolicy, + parentOriginPolicy, }, }) } catch (error) { @@ -1123,9 +1123,9 @@ export default (Commands, Cypress, cy, state, config) => { remote = $Location.create(url) - // if the origin currently matches + // if the parent origin currently matches // then go ahead and change the iframe's src - if (remote.originPolicy === existing.originPolicy) { + if (remote.parentOriginPolicy === existing.parentOriginPolicy) { previouslyVisitedLocation = remote url = $Location.fullyQualifyUrl(url) @@ -1153,7 +1153,7 @@ export default (Commands, Cypress, cy, state, config) => { // we need to throw an error since the user tried to visit a new // origin which isn't allowed within a cy.origin block if (Cypress.isCrossOriginSpecBridge) { - const existingAutOrigin = win ? $Location.create(win.location.href) : $Location.create(Cypress.state('currentActiveOriginPolicy')) + const existingAutOrigin = win ? $Location.create(win.location.href) : $Location.create(Cypress.state('currentActiveParentOriginPolicy')) const params = { remote, existing, originalUrl, previouslyVisitedLocation: existingAutOrigin, log: options._log, isCrossOriginSpecBridge: true, isPrimaryOrigin } return isPrimaryOrigin ? cannotVisitPreviousOrigin(params) : cannotVisitDifferentOrigin(params) diff --git a/packages/driver/src/cy/commands/origin/index.ts b/packages/driver/src/cy/commands/origin/index.ts index 249ea7151118..54b1652e2513 100644 --- a/packages/driver/src/cy/commands/origin/index.ts +++ b/packages/driver/src/cy/commands/origin/index.ts @@ -39,7 +39,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State // If this event has occurred while a cy.origin command is running with // the same origin policy, do not set the time out and allow cy.origin // to handle the ready for origin event - if (cy.state('currentActiveOriginPolicy') === location.originPolicy) { + if (cy.state('currentActiveParentOriginPolicy') === location.parentOriginPolicy) { return } @@ -111,18 +111,18 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State validator.validateLocation(location, urlOrDomain) - const originPolicy = location.originPolicy + const parentOriginPolicy = location.parentOriginPolicy // This is intentionally not reset after leaving the cy.origin command. - cy.state('latestActiveOriginPolicy', originPolicy) + cy.state('latestActiveParentOriginPolicy', parentOriginPolicy) // This is set while IN the cy.origin command. - cy.state('currentActiveOriginPolicy', originPolicy) + cy.state('currentActiveParentOriginPolicy', parentOriginPolicy) return new Bluebird((resolve, reject, onCancel) => { const cleanup = ({ readyForOriginFailed }: {readyForOriginFailed?: boolean} = {}): void => { - cy.state('currentActiveOriginPolicy', undefined) + cy.state('currentActiveParentOriginPolicy', undefined) if (!readyForOriginFailed) { - Cypress.backend('cross:origin:finished', location.originPolicy) + Cypress.backend('cross:origin:finished', location.parentOriginPolicy) } communicator.off('queue:finished', onQueueFinished) @@ -203,20 +203,20 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State } // fired once the spec bridge is set up and ready to receive messages - communicator.once('bridge:ready', async (_data, specBridgeOriginPolicy) => { - if (specBridgeOriginPolicy === originPolicy) { + communicator.once('bridge:ready', async (_data, specBridgeParentOriginPolicy) => { + if (specBridgeParentOriginPolicy === parentOriginPolicy) { // now that the spec bridge is ready, instantiate Cypress with the current app config and environment variables for initial sync when creating the instance - communicator.toSpecBridge(originPolicy, 'initialize:cypress', { + communicator.toSpecBridge(parentOriginPolicy, 'initialize:cypress', { config: preprocessConfig(Cypress.config()), env: preprocessEnv(Cypress.env()), }) - await Cypress.backend('cross:origin:bridge:ready', { originPolicy }) + await Cypress.backend('cross:origin:bridge:ready', { parentOriginPolicy }) // once the secondary origin page loads, send along the // user-specified callback to run in that origin try { - communicator.toSpecBridge(originPolicy, 'run:origin:fn', { + communicator.toSpecBridge(parentOriginPolicy, 'run:origin:fn', { args: options?.args || undefined, fn: callbackFn.toString(), // let the spec bridge version of Cypress know if config read-only values can be overwritten since window.top cannot be accessed in cross-origin iframes @@ -230,7 +230,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State duringUserTestExecution: Cypress.state('duringUserTestExecution'), hookId: Cypress.state('hookId'), originCommandBaseUrl: location.href, - parentOriginPolicies: [cy.getRemoteLocation('originPolicy')], + parentOriginPolicies: [cy.getRemoteLocation('parentOriginPolicy')], isStable: Cypress.state('isStable'), autOrigin: Cypress.state('autOrigin'), }, diff --git a/packages/driver/src/cy/commands/waiting.ts b/packages/driver/src/cy/commands/waiting.ts index 1c0a4873b2f8..98f5091b2534 100644 --- a/packages/driver/src/cy/commands/waiting.ts +++ b/packages/driver/src/cy/commands/waiting.ts @@ -282,14 +282,14 @@ export default (Commands, Cypress, cy, state) => { }) } - Cypress.primaryOriginCommunicator.on('wait:for:xhr', ({ args: [str, options] }, originPolicy) => { + Cypress.primaryOriginCommunicator.on('wait:for:xhr', ({ args: [str, options] }, parentOriginPolicy) => { options.isCrossOriginSpecBridge = true waitString(null, str, options).then((responses) => { - Cypress.primaryOriginCommunicator.toSpecBridge(originPolicy, 'wait:for:xhr:end', responses) + Cypress.primaryOriginCommunicator.toSpecBridge(parentOriginPolicy, 'wait:for:xhr:end', responses) }).catch((err) => { options._log?.error(err) err.hasSpecBridgeError = true - Cypress.primaryOriginCommunicator.toSpecBridge(originPolicy, 'wait:for:xhr:end', err) + Cypress.primaryOriginCommunicator.toSpecBridge(parentOriginPolicy, 'wait:for:xhr:end', err) }) }) diff --git a/packages/driver/src/cypress/cy.ts b/packages/driver/src/cypress/cy.ts index dcb5ec931ac9..60122429ec0b 100644 --- a/packages/driver/src/cypress/cy.ts +++ b/packages/driver/src/cypress/cy.ts @@ -583,7 +583,7 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert this.Cypress.action('app:window:load', this.state('window')) const remoteLocation = this.getRemoteLocation() - cy.state('autOrigin', remoteLocation.originPolicy) + cy.state('autOrigin', remoteLocation.parentOriginPolicy) this.Cypress.primaryOriginCommunicator.toAllSpecBridges('window:load', { url: remoteLocation.href }) } catch (err: any) { // this catches errors thrown by user-registered event handlers diff --git a/packages/driver/src/cypress/error_messages.ts b/packages/driver/src/cypress/error_messages.ts index a8bb7269b7ef..c8ca06624cfb 100644 --- a/packages/driver/src/cypress/error_messages.ts +++ b/packages/driver/src/cypress/error_messages.ts @@ -980,7 +980,7 @@ export default { }, navigation: { - cross_origin ({ message, originPolicy, configFile, projectRoot }) { + cross_origin ({ message, parentOriginPolicy, configFile, projectRoot }) { return { message: stripIndent`\ Cypress detected a cross origin error happened on page load: @@ -989,7 +989,7 @@ export default { Before the page load, you were bound to the origin policy: - > ${originPolicy} + > ${parentOriginPolicy} A cross origin error happens when your application navigates to a new URL which does not match the origin policy above. @@ -1026,13 +1026,13 @@ export default { message: stripIndent`\ Timed out after waiting \`${ms}ms\` for your remote page to load on origin(s): - - ${originPolicies.map((originPolicy) => `\`${originPolicy}\``).join('\n -')} + - ${originPolicies.map((parentOriginPolicy) => `\`${parentOriginPolicy}\``).join('\n -')} A cross-origin request for \`${crossOriginUrl.href}\` was detected. A command that triggers cross-origin navigation must be immediately followed by a ${cmd('origin')} command: - \`cy.origin('${crossOriginUrl.originPolicy}', () => {\` + \`cy.origin('${crossOriginUrl.parentOriginPolicy}', () => {\` \` \` \`})\` @@ -1276,7 +1276,7 @@ export default { \`\` - \`cy.origin('${args.previousUrl.originPolicy}', () => {\` + \`cy.origin('${args.previousUrl.parentOriginPolicy}', () => {\` \` \` \`})\` @@ -2165,7 +2165,7 @@ export default { ${args.experimentalSessionAndOrigin ? `You likely forgot to use ${cmd('origin')}:` : `In order to visit a different origin, you can enable the \`experimentalSessionAndOrigin\` flag and use ${cmd('origin')}:` } ${args.isCrossOriginSpecBridge ? - `\`cy.origin('${args.previousUrl.originPolicy}', () => {\` + `\`cy.origin('${args.previousUrl.parentOriginPolicy}', () => {\` \` cy.visit('${args.previousUrl}')\` \` \` \`})\`` : @@ -2173,7 +2173,7 @@ export default { \`\`` } - \`cy.origin('${args.attemptedUrl.originPolicy}', () => {\` + \`cy.origin('${args.attemptedUrl.parentOriginPolicy}', () => {\` \` cy.visit('${args.originalUrl}')\` \` \` \`})\` diff --git a/packages/driver/src/cypress/location.ts b/packages/driver/src/cypress/location.ts index 50a24e0e5a19..2960fd33c63c 100644 --- a/packages/driver/src/cypress/location.ts +++ b/packages/driver/src/cypress/location.ts @@ -29,6 +29,7 @@ export interface LocationObject { protocol: string search: string originPolicy: string + parentOriginPolicy: string superDomain: string toString: () => string } @@ -109,6 +110,10 @@ export class $Location { return cors.getOriginPolicy(this.remote.href) } + getParentOriginPolicy () { + return cors.getParentOriginPolicy(this.remote.href) + } + getSuperDomain () { return cors.getSuperDomain(this.remote.href) } @@ -131,6 +136,7 @@ export class $Location { protocol: this.getProtocol(), search: this.getSearch(), originPolicy: this.getOriginPolicy(), + parentOriginPolicy: this.getParentOriginPolicy(), superDomain: this.getSuperDomain(), toString: _.bind(this.getToString, this), } diff --git a/packages/driver/src/cypress/log.ts b/packages/driver/src/cypress/log.ts index b059cbbbc3c7..d7e30d7103ea 100644 --- a/packages/driver/src/cypress/log.ts +++ b/packages/driver/src/cypress/log.ts @@ -374,16 +374,16 @@ export class Log { } if (this.config('experimentalSessionAndOrigin') && !Cypress.isCrossOriginSpecBridge) { - const activeSpecBridgeOriginPolicyIfApplicable = this.state('currentActiveOriginPolicy') || undefined + const activeSpecBridgeParentOriginPolicyIfApplicable = this.state('currentActiveParentOriginPolicy') || undefined // @ts-ignore - const { originPolicy: originPolicyThatIsSoonToBeOrIsActive } = Cypress.Location.create(this.state('anticipatingCrossOriginResponse')?.href || this.state('url')) + const { parentOriginPolicy: parentOriginPolicyThatIsSoonToBeOrIsActive } = Cypress.Location.create(this.state('anticipatingCrossOriginResponse')?.href || this.state('url')) - if (activeSpecBridgeOriginPolicyIfApplicable && activeSpecBridgeOriginPolicyIfApplicable === originPolicyThatIsSoonToBeOrIsActive) { + if (activeSpecBridgeParentOriginPolicyIfApplicable && activeSpecBridgeParentOriginPolicyIfApplicable === parentOriginPolicyThatIsSoonToBeOrIsActive) { Cypress.emit('request:snapshot:from:spec:bridge', { log: this, name, options, - specBridge: activeSpecBridgeOriginPolicyIfApplicable, + specBridge: activeSpecBridgeParentOriginPolicyIfApplicable, addSnapshot: this.addSnapshot, }) diff --git a/packages/driver/src/cypress/state.ts b/packages/driver/src/cypress/state.ts index 9039ae6d61ef..3f15686c311b 100644 --- a/packages/driver/src/cypress/state.ts +++ b/packages/driver/src/cypress/state.ts @@ -22,8 +22,8 @@ export interface StateFunc { (k: 'logGroupIds', v?: Array): Array (k: 'autOrigin', v?: string): string (k: 'originCommandBaseUrl', v?: string): string - (k: 'currentActiveOriginPolicy', v?: string): string - (k: 'latestActiveOriginPolicy', v?: string): string + (k: 'currentActiveParentOriginPolicy', v?: string): string + (k: 'latestActiveParentOriginPolicy', v?: string): string (k: 'duringUserTestExecution', v?: boolean): boolean (k: 'onQueueEnd', v?: () => void): () => void (k: 'onFail', v?: (err: Error) => void): (err: Error) => void diff --git a/packages/network/lib/cors.ts b/packages/network/lib/cors.ts index 323d7c5a7de5..dc730f580fd8 100644 --- a/packages/network/lib/cors.ts +++ b/packages/network/lib/cors.ts @@ -151,9 +151,25 @@ export function urlMatchesOriginProtectionSpace (urlStr, origin) { export function getOriginPolicy (url: string) { // @ts-ignore - const { port, protocol } = new URL(url) + const { port, protocol, hostname } = new URL(url) // origin policy is comprised of: + // protocol+ subdomain + superdomain + port (subdomain is not factored in) + return _.compact([`${protocol}//${hostname}`, port]).join(':') +} + +/** + * We use the parent origin policy in the driver to determine whether or not we need to reload/interact with the AUT, and + * currently in the spec bridge to interact with the AUT frame, which uses document.domain set to the parent + * @param url - the full absolute url + * @returns the parent origin policy - + * ex: http://www.example.com:8081/my/path -> http://example.com:8081/my/path + */ +export function getParentOriginPolicy (url: string) { + // @ts-ignore + const { port, protocol } = new URL(url) + + // parent origin policy is comprised of: // protocol + superdomain + port (subdomain is not factored in) return _.compact([`${protocol}//${getSuperDomain(url)}`, port]).join(':') } diff --git a/packages/network/test/unit/cors_spec.ts b/packages/network/test/unit/cors_spec.ts index 2f447b237ac9..0d58174e551c 100644 --- a/packages/network/test/unit/cors_spec.ts +++ b/packages/network/test/unit/cors_spec.ts @@ -583,6 +583,18 @@ describe('lib/cors', () => { }) }) + context('.getParentOriginPolicy', () => { + it('ports', () => { + expect(cors.getParentOriginPolicy('https://example.com')).to.equal('https://example.com') + expect(cors.getParentOriginPolicy('http://example.com:8080')).to.equal('http://example.com:8080') + }) + + it('subdomain', () => { + expect(cors.getParentOriginPolicy('http://www.example.com')).to.equal('http://example.com') + expect(cors.getParentOriginPolicy('http://www.app.herokuapp.com:8080')).to.equal('http://app.herokuapp.com:8080') + }) + }) + context('.getOriginPolicy', () => { it('ports', () => { expect(cors.getOriginPolicy('https://example.com')).to.equal('https://example.com') @@ -590,8 +602,8 @@ describe('lib/cors', () => { }) it('subdomain', () => { - expect(cors.getOriginPolicy('http://www.example.com')).to.equal('http://example.com') - expect(cors.getOriginPolicy('http://www.app.herokuapp.com:8080')).to.equal('http://app.herokuapp.com:8080') + expect(cors.getOriginPolicy('http://www.example.com')).to.equal('http://www.example.com') + expect(cors.getOriginPolicy('http://www.app.herokuapp.com:8080')).to.equal('http://www.app.herokuapp.com:8080') }) }) }) diff --git a/packages/proxy/test/unit/http/response-middleware.spec.ts b/packages/proxy/test/unit/http/response-middleware.spec.ts index 378b5da84167..51912564f5e7 100644 --- a/packages/proxy/test/unit/http/response-middleware.spec.ts +++ b/packages/proxy/test/unit/http/response-middleware.spec.ts @@ -314,8 +314,8 @@ describe('http/response-middleware', function () { // set the secondary remote states remoteStates.addEventListeners(eventEmitter) - props.secondaryOrigins?.forEach((originPolicy) => { - eventEmitter.emit('cross:origin:bridge:ready', { originPolicy }) + props.secondaryOrigins?.forEach((parentOriginPolicy) => { + eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy }) }) ctx = { @@ -736,8 +736,8 @@ describe('http/response-middleware', function () { // set the secondary remote states remoteStates.addEventListeners(eventEmitter) - props.secondaryOrigins?.forEach((originPolicy) => { - eventEmitter.emit('cross:origin:bridge:ready', { originPolicy }) + props.secondaryOrigins?.forEach((parentOriginPolicy) => { + eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy }) }) ctx = { @@ -1585,8 +1585,8 @@ describe('http/response-middleware', function () { // set the secondary remote states remoteStates.addEventListeners(eventEmitter) - props.secondaryOrigins?.forEach((originPolicy) => { - eventEmitter.emit('cross:origin:bridge:ready', { originPolicy }) + props.secondaryOrigins?.forEach((parentOriginPolicy) => { + eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy }) }) remoteStates.isPrimaryOrigin = () => false diff --git a/packages/server/lib/remote_states.ts b/packages/server/lib/remote_states.ts index 01d63d1c0133..ee1cc98ca3d9 100644 --- a/packages/server/lib/remote_states.ts +++ b/packages/server/lib/remote_states.ts @@ -52,7 +52,7 @@ export class RemoteStates { } get (url: string) { - const state = this.remoteStates.get(cors.getOriginPolicy(url)) + const state = this.remoteStates.get(cors.getParentOriginPolicy(url)) debug('getting remote state: %o for: %s', state, url) @@ -68,16 +68,16 @@ export class RemoteStates { } isInOriginStack (url: string): boolean { - return this.originStack.includes(cors.getOriginPolicy(url)) + return this.originStack.includes(cors.getParentOriginPolicy(url)) } isSecondaryOrigin (url: string): boolean { // start at 1 to exclude the primary origin - return this.originStack.indexOf(cors.getOriginPolicy(url), 1) !== -1 + return this.originStack.indexOf(cors.getParentOriginPolicy(url), 1) !== -1 } isPrimaryOrigin (url: string): boolean { - return this.originStack[0] === cors.getOriginPolicy(url) + return this.originStack[0] === cors.getParentOriginPolicy(url) } reset () { @@ -124,7 +124,7 @@ export class RemoteStates { state = urlOrState } - const remoteOriginPolicy = cors.getOriginPolicy(state.origin) + const remoteOriginPolicy = cors.getParentOriginPolicy(state.origin) if (options.isCrossOrigin) { this.remoteStates.set(remoteOriginPolicy, state) @@ -146,24 +146,24 @@ export class RemoteStates { } addEventListeners (eventEmitter: EventEmitter) { - eventEmitter.on('cross:origin:bridge:ready', ({ originPolicy }) => { - debug(`received cross:origin:bridge:ready, add origin ${originPolicy} to remote states`) + eventEmitter.on('cross:origin:bridge:ready', ({ parentOriginPolicy }) => { + debug(`received cross:origin:bridge:ready, add origin ${parentOriginPolicy} to remote states`) - const existingOrigin = this.remoteStates.get(originPolicy) + const existingOrigin = this.remoteStates.get(parentOriginPolicy) // since this is just the cy.origin starting, we don't want to override // the existing origin if it already exists if (!existingOrigin) { - this.set(originPolicy, { isCrossOrigin: true }) + this.set(parentOriginPolicy, { isCrossOrigin: true }) } - this.addOrigin(originPolicy) + this.addOrigin(parentOriginPolicy) }) - eventEmitter.on('cross:origin:finished', (originPolicy) => { - debug(`received cross:origin:finished, remove ${originPolicy} from origin stack`) + eventEmitter.on('cross:origin:finished', (parentOriginPolicy) => { + debug(`received cross:origin:finished, remove ${parentOriginPolicy} from origin stack`) - this.removeCurrentOrigin(originPolicy) + this.removeCurrentOrigin(parentOriginPolicy) }) } @@ -175,21 +175,21 @@ export class RemoteStates { return this._config } - private addOrigin (originPolicy) { - this.originStack.push(originPolicy) + private addOrigin (parentOriginPolicy) { + this.originStack.push(parentOriginPolicy) - debug('added origin: ', originPolicy) + debug('added origin: ', parentOriginPolicy) } - private removeCurrentOrigin (originPolicy) { - const currentOriginPolicy = this.originStack[this.originStack.length - 1] + private removeCurrentOrigin (parentOriginPolicy) { + const currentParentOriginPolicy = this.originStack[this.originStack.length - 1] - if (originPolicy !== currentOriginPolicy) { - throw new Error(`Tried to remove origin ${originPolicy} but ${currentOriginPolicy} was found. This should never happen and likely is a bug. Please open an issue.`) + if (parentOriginPolicy !== currentParentOriginPolicy) { + throw new Error(`Tried to remove origin ${parentOriginPolicy} but ${currentParentOriginPolicy} was found. This should never happen and likely is a bug. Please open an issue.`) } this.originStack.pop() - debug('removed current origin: ', originPolicy) + debug('removed current origin: ', parentOriginPolicy) } } diff --git a/packages/server/test/integration/server_spec.js b/packages/server/test/integration/server_spec.js index 9aeeb1fedab2..4145da2f3d76 100644 --- a/packages/server/test/integration/server_spec.js +++ b/packages/server/test/integration/server_spec.js @@ -945,7 +945,7 @@ describe('Server', () => { fileServer: this.fileServer, }) - this.server.socket.localBus.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.server.socket.localBus.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) expect(this.server.remoteStates.current()).to.deep.eq({ auth: undefined, @@ -1056,7 +1056,7 @@ describe('Server', () => { this.server.remoteStates.set('http://localhost:3500/') // this will be the current origin - this.server.socket.localBus.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.server.socket.localBus.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) return this.server._onResolveUrl('http://localhost:3500/', {}, this.automationRequest, { hasAlreadyVisitedUrl: true }) .then(() => { @@ -1091,7 +1091,7 @@ describe('Server', () => { this.server.remoteStates.set('http://localhost:3500/') // this will be the current origin - this.server.socket.localBus.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.server.socket.localBus.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) return this.server._onResolveUrl('http://localhost:3500/', {}, this.automationRequest, { isCrossOrigin: true }) .then(() => { @@ -1123,7 +1123,7 @@ describe('Server', () => { 'Content-Type': 'text/html', }) - this.server.socket.localBus.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.server.socket.localBus.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) return this.server._onResolveUrl('http://www.cypress.io/', {}, this.automationRequest, { isCrossOrigin: true, auth: { username: 'u', password: 'p' } }) .then(() => { @@ -1144,7 +1144,7 @@ describe('Server', () => { fileServer: null, }) - this.server.socket.localBus.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.server.socket.localBus.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) // Verify the existing secondary remote state is not overridden expect(this.server.remoteStates.current()).to.deep.eq({ diff --git a/packages/server/test/unit/remote_states.spec.ts b/packages/server/test/unit/remote_states.spec.ts index ae3ce77a0e89..e749c17857bc 100644 --- a/packages/server/test/unit/remote_states.spec.ts +++ b/packages/server/test/unit/remote_states.spec.ts @@ -132,21 +132,21 @@ describe('remote states', () => { context('#isSecondaryOrigin', () => { it('returns true when the requested url is a secondary origin', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) const isSecondaryOrigin = this.remoteStates.isSecondaryOrigin('https://staging.google.com') expect(isSecondaryOrigin).to.be.true }) it('returns false when the requested url is the primary origin', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) const isSecondaryOrigin = this.remoteStates.isSecondaryOrigin('http://localhost:3500') expect(isSecondaryOrigin).to.be.false }) it('returns false when the requested url is not in the origin stack', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) const isSecondaryOrigin = this.remoteStates.isSecondaryOrigin('https://foobar.com') expect(isSecondaryOrigin).to.be.false @@ -161,7 +161,7 @@ describe('remote states', () => { }) it('returns false when the requested url is not the primary origin', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) const isPrimaryOrigin = this.remoteStates.isPrimaryOrigin('http://google.com') expect(isPrimaryOrigin).to.be.false @@ -170,7 +170,7 @@ describe('remote states', () => { context('#removeCurrentOrigin', () => { it('removes the current origin from the stack', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) expect(this.remoteStates.isInOriginStack('https://google.com')).to.be.true this.remoteStates.removeCurrentOrigin('https://google.com') @@ -179,7 +179,7 @@ describe('remote states', () => { }) it('throws an error when trying to remove the incorrect origin', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) expect(this.remoteStates.isInOriginStack('https://google.com')).to.be.true expect(() => this.remoteStates.removeCurrentOrigin('http://notfound.com')) @@ -189,7 +189,7 @@ describe('remote states', () => { context('#reset', () => { it('resets the origin stack and remote states to the primary', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) expect(this.remoteStates.isInOriginStack('https://google.com')).to.be.true expect(this.remoteStates.get('https://google.com')).to.not.be.undefined @@ -203,7 +203,7 @@ describe('remote states', () => { context('#current', () => { it('returns the remote state for the current origin in the stack', function () { - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'https://google.com' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'https://google.com' }) this.remoteStates.set('https://staging.google.com/foo/bar', { isCrossOrigin: true }) const state = this.remoteStates.current() @@ -414,7 +414,7 @@ describe('remote states', () => { expect(currentState.origin).to.equal('http://localhost:3500') - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) currentState = this.remoteStates.current() expect(currentState.origin).to.equal('http://cypress.io') @@ -426,7 +426,7 @@ describe('remote states', () => { expect(currentState.origin).to.equal('http://localhost:3500') - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) currentState = this.remoteStates.current() expect(currentState.origin).to.equal('http://cypress.io') @@ -444,7 +444,7 @@ describe('remote states', () => { // simulate a cy.origin by calling cross:origin:bridge:ready followed by setting // the origin with specific auth options and finally calling cross:origin:finished - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) this.remoteStates.set('http://cypress.io', { auth: { username: 'u', password: 'p' }, isCrossOrigin: true }) currentState = this.remoteStates.current() expect(currentState.origin).to.equal('http://cypress.io') @@ -452,7 +452,7 @@ describe('remote states', () => { this.eventEmitter.emit('cross:origin:finished', 'http://cypress.io') // verify calling cross:origin:bridge:ready doesn't reset the previous state - this.eventEmitter.emit('cross:origin:bridge:ready', { originPolicy: 'http://cypress.io' }) + this.eventEmitter.emit('cross:origin:bridge:ready', { parentOriginPolicy: 'http://cypress.io' }) currentState = this.remoteStates.current() expect(currentState.origin).to.equal('http://cypress.io') diff --git a/packages/server/test/unit/socket_spec.js b/packages/server/test/unit/socket_spec.js index db7020b0482c..d65a094e7e7a 100644 --- a/packages/server/test/unit/socket_spec.js +++ b/packages/server/test/unit/socket_spec.js @@ -601,13 +601,13 @@ describe('lib/socket', () => { context('on(cross:origin:bridge:ready)', () => { it('emits cross:origin:bridge:ready on local bus', function (done) { - this.server.socket.localBus.once('cross:origin:bridge:ready', ({ originPolicy }) => { - expect(originPolicy).to.equal('http://foobar.com') + this.server.socket.localBus.once('cross:origin:bridge:ready', ({ parentOriginPolicy }) => { + expect(parentOriginPolicy).to.equal('http://foobar.com') done() }) - this.client.emit('backend:request', 'cross:origin:bridge:ready', { originPolicy: 'http://foobar.com' }, () => {}) + this.client.emit('backend:request', 'cross:origin:bridge:ready', { parentOriginPolicy: 'http://foobar.com' }, () => {}) }) }) @@ -623,14 +623,14 @@ describe('lib/socket', () => { context('on(cross:origin:finished)', () => { it('emits cross:origin:finished on local bus', function (done) { - this.server.socket.localBus.once('cross:origin:finished', (originPolicy) => { - expect(originPolicy).to.equal('http://foobar.com') + this.server.socket.localBus.once('cross:origin:finished', (parentOriginPolicy) => { + expect(parentOriginPolicy).to.equal('http://foobar.com') done() }) // add the origin before calling cross:origin:finished (otherwise we'll fail trying to remove the origin) - this.client.emit('backend:request', 'cross:origin:bridge:ready', { originPolicy: 'http://foobar.com' }, () => {}) + this.client.emit('backend:request', 'cross:origin:bridge:ready', { parentOriginPolicy: 'http://foobar.com' }, () => {}) this.client.emit('backend:request', 'cross:origin:finished', 'http://foobar.com', () => {}) })