chore: (multi-domain) support multiple remote states (#20752)

This commit is contained in:
Matt Schile
2022-03-28 15:26:51 -06:00
committed by GitHub
parent 453d1ca546
commit fedb65c97c
41 changed files with 1480 additions and 602 deletions
+5 -5
View File
@@ -19,6 +19,7 @@ import RequestMiddleware from './request-middleware'
import ResponseMiddleware from './response-middleware'
import { DeferredSourceMapCache } from '@packages/rewriter'
import type { Browser } from '@packages/server/lib/browsers/types'
import type { RemoteStates } from '@packages/server/lib/remote_states'
export const debugVerbose = Debug('cypress-verbose:proxy:http')
@@ -61,7 +62,7 @@ export type ServerCtx = Readonly<{
shouldCorrelatePreRequests?: () => boolean
getCurrentBrowser: () => Browser | Partial<Browser> & Pick<Browser, 'family'> | null
getFileServerToken: () => string
getRemoteState: CyServer.getRemoteState
remoteStates: RemoteStates
getRenderedHTMLOrigins: Http['getRenderedHTMLOrigins']
netStubbingState: NetStubbingState
middleware: HttpMiddlewareStacks
@@ -74,7 +75,6 @@ const READONLY_MIDDLEWARE_KEYS: (keyof HttpMiddlewareThis<{}>)[] = [
'buffers',
'config',
'getFileServerToken',
'getRemoteState',
'netStubbingState',
'next',
'end',
@@ -201,7 +201,7 @@ export class Http {
deferredSourceMapCache: DeferredSourceMapCache
getCurrentBrowser: () => Browser | Partial<Browser> & Pick<Browser, 'family'> | null
getFileServerToken: () => string
getRemoteState: () => any
remoteStates: RemoteStates
middleware: HttpMiddlewareStacks
netStubbingState: NetStubbingState
preRequests: PreRequests = new PreRequests()
@@ -219,7 +219,7 @@ export class Http {
this.shouldCorrelatePreRequests = opts.shouldCorrelatePreRequests || (() => false)
this.getCurrentBrowser = opts.getCurrentBrowser
this.getFileServerToken = opts.getFileServerToken
this.getRemoteState = opts.getRemoteState
this.remoteStates = opts.remoteStates
this.middleware = opts.middleware
this.netStubbingState = opts.netStubbingState
this.socket = opts.socket
@@ -240,7 +240,7 @@ export class Http {
shouldCorrelatePreRequests: this.shouldCorrelatePreRequests,
getCurrentBrowser: this.getCurrentBrowser,
getFileServerToken: this.getFileServerToken,
getRemoteState: this.getRemoteState,
remoteStates: this.remoteStates,
request: this.request,
middleware: _.cloneDeep(this.middleware),
netStubbingState: this.netStubbingState,
@@ -141,9 +141,10 @@ function reqNeedsBasicAuthHeaders (req, { auth, origin }: Cypress.RemoteState) {
}
const MaybeSetBasicAuthHeaders: RequestMiddleware = function () {
const remoteState = this.getRemoteState()
// get the remote state for the proxied url
const remoteState = this.remoteStates.get(this.req.proxiedUrl)
if (remoteState.auth && reqNeedsBasicAuthHeaders(this.req, remoteState)) {
if (remoteState?.auth && reqNeedsBasicAuthHeaders(this.req, remoteState)) {
const { auth } = remoteState
const base64 = Buffer.from(`${auth.username}:${auth.password}`).toString('base64')
@@ -164,12 +165,12 @@ const SendRequestOutgoing: RequestMiddleware = function () {
const requestBodyBuffered = !!this.req.body
const { strategy, origin, fileServer } = this.getRemoteState()
const { strategy, origin, fileServer } = this.remoteStates.current()
if (strategy === 'file' && requestOptions.url.startsWith(origin)) {
this.req.headers['x-cypress-authorization'] = this.getFileServerToken()
requestOptions.url = requestOptions.url.replace(origin, fileServer)
requestOptions.url = requestOptions.url.replace(origin, fileServer as string)
}
if (requestBodyBuffered) {
+17 -10
View File
@@ -230,16 +230,22 @@ const PatchExpressSetHeader: ResponseMiddleware = function () {
}
const MaybeDelayForMultiDomain: ResponseMiddleware = function () {
const isCrossDomain = !reqMatchesOriginPolicy(this.req, this.getRemoteState())
const isCrossDomain = !reqMatchesOriginPolicy(this.req, this.remoteStates.current())
const isPreviousOrigin = this.remoteStates.isInOriginStack(this.req.proxiedUrl)
const isHTML = resContentTypeIs(this.incomingRes, 'text/html')
const isRenderedHTML = reqWillRenderHtml(this.req)
const isAUTFrame = this.req.isAUTFrame
if (this.config.experimentalMultiDomain && isCrossDomain && isAUTFrame && (isHTML || isRenderedHTML)) {
this.debug('is cross-domain, delay until domain:ready event')
// delay the response if this is a cross-origin (and not returning to a previous origin) html request from the AUT iframe
if (this.config.experimentalMultiDomain && isCrossDomain && !isPreviousOrigin && isAUTFrame && (isHTML || isRenderedHTML)) {
this.debug('is cross-domain, delay until ready:for:domain event')
this.serverBus.once('ready:for:domain', () => {
this.debug('ready for domain, let it go')
this.serverBus.once('ready:for:domain', ({ failed }) => {
this.debug(`ready for domain${failed ? ' failed' : ''}, let it go`)
if (!failed) {
this.res.wantsInjection = 'fullMultiDomain'
}
this.next()
})
@@ -267,7 +273,7 @@ const SetInjectionLevel: ResponseMiddleware = function () {
this.debug('determine injection')
const isReqMatchOriginPolicy = reqMatchesOriginPolicy(this.req, this.getRemoteState())
const isReqMatchOriginPolicy = reqMatchesOriginPolicy(this.req, this.remoteStates.current())
const getInjectionLevel = () => {
if (this.incomingRes.headers['x-cypress-file-server-error'] && !this.res.isInitial) {
this.debug('- partial injection (x-cypress-file-server-error)')
@@ -275,10 +281,11 @@ const SetInjectionLevel: ResponseMiddleware = function () {
return 'partial'
}
const isSecondaryOrigin = this.remoteStates.isSecondaryOrigin(this.req.proxiedUrl)
const isHTML = resContentTypeIs(this.incomingRes, 'text/html')
const isAUTFrame = this.req.isAUTFrame
if (this.config.experimentalMultiDomain && !isReqMatchOriginPolicy && isAUTFrame && (isHTML || isRenderedHTML)) {
if (this.config.experimentalMultiDomain && isSecondaryOrigin && isAUTFrame && (isHTML || isRenderedHTML)) {
this.debug('- multi-domain injection')
return 'fullMultiDomain'
@@ -397,7 +404,7 @@ const determineIfNeedsMultiDomainHandling = (ctx: HttpMiddlewareThis<ResponseMid
!!ctx.req.isAUTFrame &&
(
(previousAUTRequestUrl && !cors.urlOriginsMatch(previousAUTRequestUrl, ctx.req.proxiedUrl))
|| !reqMatchesOriginPolicy(ctx.req, ctx.getRemoteState())
|| !ctx.remoteStates.isPrimaryOrigin(ctx.req.proxiedUrl)
)
)
}
@@ -490,7 +497,7 @@ const MaybeSendRedirectToClient: ResponseMiddleware = function () {
return this.next()
}
setInitialCookie(this.res, this.getRemoteState(), true)
setInitialCookie(this.res, this.remoteStates.current(), true)
debug('redirecting to new url %o', { statusCode, newUrl })
this.res.redirect(Number(statusCode), newUrl)
@@ -504,7 +511,7 @@ const CopyResponseStatusCode: ResponseMiddleware = function () {
}
const ClearCyInitialCookie: ResponseMiddleware = function () {
setInitialCookie(this.res, this.getRemoteState(), false)
setInitialCookie(this.res, this.remoteStates.current(), false)
this.next()
}
+1
View File
@@ -28,6 +28,7 @@
"@cypress/request-promise": "4.2.6",
"@cypress/sinon-chai": "2.9.1",
"@packages/resolve-dist": "0.0.0-development",
"@packages/server": "0.0.0-development",
"@types/express": "4.17.2",
"@types/supertest": "2.0.10",
"express": "4.17.1",
@@ -11,13 +11,14 @@ import { expect } from 'chai'
import supertest from 'supertest'
import { allowDestroy } from '@packages/network'
import { EventEmitter } from 'events'
import { RemoteStates } from '@packages/server/lib/remote_states'
const Request = require('@packages/server/lib/request')
const getFixture = async () => {}
context('network stubbing', () => {
let config
let remoteState
let remoteStates: RemoteStates
let netStubbingState: NetStubbingState
let app
let destinationApp
@@ -27,7 +28,7 @@ context('network stubbing', () => {
beforeEach((done) => {
config = {}
remoteState = {}
remoteStates = new RemoteStates(() => {})
socket = new EventEmitter()
socket.toDriver = sinon.stub()
app = express()
@@ -39,7 +40,7 @@ context('network stubbing', () => {
config,
middleware: defaultMiddleware,
getCurrentBrowser: () => ({ family: 'chromium' }),
getRemoteState: () => remoteState,
remoteStates,
getFileServerToken: () => 'fake-token',
request: new Request(),
getRenderedHTMLOrigins: () => ({}),
@@ -62,6 +63,7 @@ context('network stubbing', () => {
server = allowDestroy(destinationApp.listen(() => {
destinationPort = server.address().port
remoteStates.set(`http://localhost:${destinationPort}`)
done()
}))
})
@@ -71,26 +73,12 @@ context('network stubbing', () => {
})
it('can make a vanilla request', (done) => {
remoteState.strategy = 'http'
remoteState.props = {
port: `${destinationPort}`,
tld: 'localhost',
domain: '',
}
supertest(app)
.get(`/http://localhost:${destinationPort}`)
.expect('it worked', done)
})
it('does not add CORS headers to all responses', () => {
remoteState.strategy = 'http'
remoteState.props = {
port: `${destinationPort}`,
tld: 'localhost',
domain: '',
}
return supertest(app)
.get(`/http://localhost:${destinationPort}`)
.then((res) => {
@@ -241,13 +229,6 @@ context('network stubbing', () => {
})
})
remoteState.strategy = 'http'
remoteState.props = {
port: `${destinationPort}`,
tld: 'localhost',
domain: '',
}
// capture unintercepted content-length
await supertest(app)
.post(`/http://localhost:${destinationPort}`)
+6 -3
View File
@@ -1,4 +1,4 @@
import { HttpMiddleware, _runStage } from '../../../lib/http'
import { HttpMiddleware, HttpStages, _runStage } from '../../../lib/http'
export function testMiddleware (middleware: HttpMiddleware<any>[], ctx = {}) {
const fullCtx = {
@@ -6,7 +6,6 @@ export function testMiddleware (middleware: HttpMiddleware<any>[], ctx = {}) {
req: {},
res: {},
config: {},
getRemoteState: () => {},
middleware: {
0: middleware,
@@ -15,5 +14,9 @@ export function testMiddleware (middleware: HttpMiddleware<any>[], ctx = {}) {
...ctx,
}
return _runStage(0, fullCtx)
const onError = (error) => {
throw error
}
return _runStage(HttpStages.IncomingRequest, fullCtx, onError)
}
+2 -5
View File
@@ -5,7 +5,6 @@ import sinon from 'sinon'
describe('http', function () {
context('Http.handle', function () {
let config
let getRemoteState
let middleware
let incomingRequest
let incomingResponse
@@ -14,8 +13,6 @@ describe('http', function () {
beforeEach(function () {
config = {}
getRemoteState = sinon.stub().returns({})
incomingRequest = sinon.stub()
incomingResponse = sinon.stub()
error = sinon.stub()
@@ -26,7 +23,7 @@ describe('http', function () {
[HttpStages.Error]: [error],
}
httpOpts = { config, getRemoteState, middleware }
httpOpts = { config, middleware }
})
it('calls IncomingRequest stack, then IncomingResponse stack', function () {
@@ -99,7 +96,7 @@ describe('http', function () {
const resAdded = {}
const errorAdded = {}
let expectedKeys = ['req', 'res', 'config', 'getRemoteState', 'middleware']
let expectedKeys = ['req', 'res', 'config', 'middleware']
incomingRequest.callsFake(function () {
expect(this).to.include.keys(expectedKeys)
@@ -4,6 +4,7 @@ import { expect } from 'chai'
import { testMiddleware } from './helpers'
import { CypressIncomingRequest, CypressOutgoingResponse } from '../../../lib'
import { HttpBuffer, HttpBuffers } from '../../../lib/http/util/buffers'
import { RemoteStates } from '@packages/server/lib/remote_states'
describe('http/request-middleware', () => {
it('exports the members in the correct order', () => {
@@ -119,4 +120,117 @@ describe('http/request-middleware', () => {
})
})
})
describe('MaybeSetBasicAuthHeaders', () => {
const { MaybeSetBasicAuthHeaders } = RequestMiddleware
it('adds auth header from remote state', async () => {
const headers = {}
const remoteStates = new RemoteStates(() => {})
remoteStates.set('https://www.cypress.io/', { auth: { username: 'u', password: 'p' } })
const ctx = {
req: {
proxiedUrl: 'https://www.cypress.io/',
headers,
},
res: {} as Partial<CypressOutgoingResponse>,
remoteStates,
}
await testMiddleware([MaybeSetBasicAuthHeaders], ctx)
.then(() => {
const expectedAuthHeader = `Basic ${Buffer.from('u:p').toString('base64')}`
expect(ctx.req.headers['authorization']).to.equal(expectedAuthHeader)
})
})
it('does not add auth header if origins do not match', async () => {
const headers = {}
const remoteStates = new RemoteStates(() => {})
remoteStates.set('https://cypress.io/', { auth: { username: 'u', password: 'p' } }) // does not match due to subdomain
const ctx = {
req: {
proxiedUrl: 'https://www.cypress.io/',
headers,
},
res: {} as Partial<CypressOutgoingResponse>,
remoteStates,
}
await testMiddleware([MaybeSetBasicAuthHeaders], ctx)
.then(() => {
expect(ctx.req.headers['authorization']).to.be.undefined
})
})
it('does not add auth header if remote does not have auth', async () => {
const headers = {}
const remoteStates = new RemoteStates(() => {})
remoteStates.set('https://www.cypress.io/')
const ctx = {
req: {
proxiedUrl: 'https://www.cypress.io/',
headers,
},
res: {} as Partial<CypressOutgoingResponse>,
remoteStates,
}
await testMiddleware([MaybeSetBasicAuthHeaders], ctx)
.then(() => {
expect(ctx.req.headers['authorization']).to.be.undefined
})
})
it('does not add auth header if remote not found', async () => {
const headers = {}
const remoteStates = new RemoteStates(() => {})
remoteStates.set('http://localhost:3500', { auth: { username: 'u', password: 'p' } })
const ctx = {
req: {
proxiedUrl: 'https://www.cypress.io/',
headers,
},
res: {} as Partial<CypressOutgoingResponse>,
remoteStates,
}
await testMiddleware([MaybeSetBasicAuthHeaders], ctx)
.then(() => {
expect(ctx.req.headers['authorization']).to.be.undefined
})
})
it('does not update auth header from remote if request already has auth', async () => {
const headers = {
authorization: 'token',
}
const remoteStates = new RemoteStates(() => {})
remoteStates.set('https://www.cypress.io/', { auth: { username: 'u', password: 'p' } })
const ctx = {
req: {
proxiedUrl: 'https://www.cypress.io/',
headers,
},
res: {} as Partial<CypressOutgoingResponse>,
remoteStates,
}
await testMiddleware([MaybeSetBasicAuthHeaders], ctx)
.then(() => {
expect(ctx.req.headers['authorization']).to.equal('token')
})
})
})
})
@@ -3,9 +3,9 @@ import ResponseMiddleware from '../../../lib/http/response-middleware'
import { debugVerbose } from '../../../lib/http'
import { expect } from 'chai'
import sinon from 'sinon'
import {
testMiddleware,
} from './helpers'
import { testMiddleware } from './helpers'
import { RemoteStates } from '@packages/server/lib/remote_states'
import EventEmitter from 'events'
describe('http/response-middleware', function () {
it('exports the members in the correct order', function () {
@@ -173,6 +173,57 @@ describe('http/response-middleware', function () {
})
})
it('doesn\'t do anything when request is for a previous origin in the stack', function () {
prepareContext({
req: {
isAUTFrame: true,
proxiedUrl: 'http://www.foobar.com/test',
},
incomingRes: {
headers: {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://foobar.com', 'http://example.com'],
config: {
experimentalMultiDomain: true,
},
})
return testMiddleware([MaybeDelayForMultiDomain], ctx)
.then(() => {
expect(ctx.serverBus.emit).not.to.be.called
})
})
it('waits for server signal if req is not of a previous origin, letting it continue after receiving ready:for:domain', function () {
prepareContext({
req: {
isAUTFrame: true,
proxiedUrl: 'http://www.idp.com/test',
},
incomingRes: {
headers: {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://foobar.com', 'http://example.com'],
config: {
experimentalMultiDomain: true,
},
})
const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'http://www.idp.com/test' })
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]({ originPolicy: 'http://idp.com' })
expect(ctx.res.wantsInjection).to.equal('fullMultiDomain')
return promise
})
it('waits for server signal if res is html, letting it continue after receiving ready:for:domain', function () {
prepareContext({
incomingRes: {
@@ -182,7 +233,7 @@ describe('http/response-middleware', function () {
},
req: {
isAUTFrame: true,
proxiedUrl: 'protocol://host/originalUrl',
proxiedUrl: 'http://www.foobar.com/test',
},
config: {
experimentalMultiDomain: true,
@@ -191,9 +242,9 @@ describe('http/response-middleware', function () {
const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'protocol://host/originalUrl' })
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'http://www.foobar.com/test' })
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]()
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]({ originPolicy: 'http://foobar.com' })
return promise
})
@@ -208,7 +259,7 @@ describe('http/response-middleware', function () {
],
},
isAUTFrame: true,
proxiedUrl: 'protocol://host/originalUrl',
proxiedUrl: 'http://www.foobar.com/test',
},
config: {
experimentalMultiDomain: true,
@@ -217,9 +268,37 @@ describe('http/response-middleware', function () {
const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'protocol://host/originalUrl' })
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'http://www.foobar.com/test' })
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]()
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]({ originPolicy: 'http://foobar.com' })
expect(ctx.res.wantsInjection).to.equal('fullMultiDomain')
return promise
})
it('waits for server signal, letting it continue after receiving ready:for:domain failed', function () {
prepareContext({
req: {
isAUTFrame: true,
proxiedUrl: 'http://www.idp.com/test',
},
incomingRes: {
headers: {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://foobar.com', 'http://example.com'],
config: {
experimentalMultiDomain: true,
},
})
const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html', { href: 'http://www.idp.com/test' })
ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]({ failed: true })
expect(ctx.res.wantsInjection).to.be.undefined
@@ -227,6 +306,18 @@ describe('http/response-middleware', function () {
})
function prepareContext (props) {
const remoteStates = new RemoteStates(() => {})
const eventEmitter = new EventEmitter()
// set the primary remote state
remoteStates.set('http://127.0.0.1:3501')
// set the secondary remote states
remoteStates.addEventListeners(eventEmitter)
props.secondaryOrigins?.forEach((originPolicy) => {
eventEmitter.emit('ready:for:domain', { originPolicy })
})
ctx = {
incomingRes: {
headers: {},
@@ -245,11 +336,7 @@ describe('http/response-middleware', function () {
emit: sinon.stub(),
once: sinon.stub(),
},
getRemoteState () {
return {
strategy: 'foo',
}
},
remoteStates,
debug () {},
onError (error) {
throw error
@@ -353,6 +440,32 @@ describe('http/response-middleware', function () {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://foobar.com'],
config: {
experimentalMultiDomain: true,
},
})
return testMiddleware([SetInjectionLevel], ctx)
.then(() => {
expect(ctx.res.wantsInjection).to.equal('fullMultiDomain')
})
})
it('injects "fullMultiDomain" when request is in origin stack for cross-domain html"', function () {
prepareContext({
req: {
proxiedUrl: 'http://example.com',
isAUTFrame: true,
cookies: {},
headers: {},
},
incomingRes: {
headers: {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://example.com', 'http://foobar.com'],
config: {
experimentalMultiDomain: true,
},
@@ -416,6 +529,40 @@ describe('http/response-middleware', function () {
})
})
it('injects partial when request is for top-level origin', function () {
prepareContext({
renderedHTMLOrigins: {},
getRenderedHTMLOrigins () {
return this.renderedHTMLOrigins
},
req: {
proxiedUrl: 'http://127.0.0.1:3501/',
isAUTFrame: true,
cookies: {},
headers: {
'accept': [
'text/html',
'application/xhtml+xml',
],
},
},
incomingRes: {
headers: {
'content-type': 'text/html',
},
},
secondaryOrigins: ['http://foobar.com'],
config: {
experimentalMultiDomain: true,
},
})
return testMiddleware([SetInjectionLevel], ctx)
.then(() => {
expect(ctx.res.wantsInjection).to.equal('partial')
})
})
it('does not set Origin-Agent-Cluster header to false when injection is not expected', function () {
prepareContext({})
@@ -442,6 +589,18 @@ describe('http/response-middleware', function () {
})
function prepareContext (props) {
const remoteStates = new RemoteStates(() => {})
const eventEmitter = new EventEmitter()
// set the primary remote state
remoteStates.set('http://127.0.0.1:3501')
// set the secondary remote states
remoteStates.addEventListeners(eventEmitter)
props.secondaryOrigins?.forEach((originPolicy) => {
eventEmitter.emit('ready:for:domain', { originPolicy })
})
ctx = {
incomingRes: {
headers: {},
@@ -460,14 +619,7 @@ describe('http/response-middleware', function () {
},
...props.req,
},
getRemoteState () {
return {
strategy: 'http',
props: {
port: '3501', tld: '127.0.0.1', domain: '',
},
}
},
remoteStates,
debug: (formatter, ...args) => {
debugVerbose(`%s %s %s ${formatter}`, ctx.req.method, ctx.req.proxiedUrl, ctx.stage, ...args)
},
@@ -577,13 +729,6 @@ describe('http/response-middleware', function () {
getPreviousAUTRequestUrl () {
return 'https://different.site'
},
getRemoteState () {
// nonsense, but it's the simplest way to match origin policy
return {
strategy: 'file',
origin: 'http',
}
},
})
await testMiddleware([CopyCookiesFromIncomingRes], ctx)
@@ -622,17 +767,11 @@ describe('http/response-middleware', function () {
},
req: {
isAUTFrame: true,
proxiedUrl: 'http://www.foobar.com/multi-domain.html',
},
res: {
append: appendStub,
},
getRemoteState () {
// nonsense, but it's the simplest way to match origin policy
return {
strategy: 'file',
origin: 'http',
}
},
})
await testMiddleware([CopyCookiesFromIncomingRes], ctx)
@@ -651,17 +790,11 @@ describe('http/response-middleware', function () {
},
req: {
isAUTFrame: true,
proxiedUrl: 'http://www.foobar.com/multi-domain.html',
},
res: {
append: appendStub,
},
getRemoteState () {
// nonsense, but it's the simplest way to match origin policy
return {
strategy: 'file',
origin: 'http',
}
},
})
ctx.getPreviousAUTRequestUrl = () => ctx.req.proxiedUrl
@@ -778,6 +911,18 @@ describe('http/response-middleware', function () {
})
function prepareContext (props) {
const remoteStates = new RemoteStates(() => {})
const eventEmitter = new EventEmitter()
// set the primary remote state
remoteStates.set('http://foobar.com')
// set the secondary remote states
remoteStates.addEventListeners(eventEmitter)
props.secondaryOrigins?.forEach((originPolicy) => {
eventEmitter.emit('ready:for:domain', { originPolicy })
})
return {
incomingRes: {
headers: {},
@@ -789,7 +934,7 @@ describe('http/response-middleware', function () {
...props.res,
},
req: {
proxiedUrl: 'http:127.0.0.1:3501/multi-domain.html',
proxiedUrl: 'http://127.0.0.1:3501/multi-domain.html',
headers: {},
...props.req,
},
@@ -805,11 +950,7 @@ describe('http/response-middleware', function () {
return { family: 'chromium' }
},
getPreviousAUTRequestUrl () {},
getRemoteState () {
return {
strategy: 'foo',
}
},
remoteStates,
debug () {},
onError (error) {
throw error
@@ -841,33 +982,3 @@ describe('http/response-middleware', function () {
}
})
})
// beforeEach(function () {
// ctx = {
// req: {
// proxiedUrl: 'http://proxy.com',
// cookies: {
// '__cypress.initial': true,
// },
// headers: {
// accept: ['text/html', 'application/xhtml+xml'],
// },
// },
// res: {
// setHeader: sinon.stub(),
// },
// getRemoteState: () => {
// return {
// strategy: 'http',
// props: {
// domain: 'proxy',
// port: '80',
// tld: 'com',
// },
// }
// },
// getRenderedHTMLOrigins: () => {
// return {}
// },
// }
// })