Skip to content

Commit

Permalink
Merge branch 'feature-multidomain' of github.com:cypress-io/cypress i…
Browse files Browse the repository at this point in the history
…nto issue-19545-fix-secondary-domain-command-state
  • Loading branch information
AtofStryker committed Jan 12, 2022
2 parents 62486fb + 2ee9893 commit 4356a78
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 60 deletions.
25 changes: 15 additions & 10 deletions packages/driver/src/cy/multi-domain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
// @ts-ignore
const communicator = Cypress.multiDomainCommunicator

communicator.on('html:received', () => {
const sendReadyForDomain = () => {
// lets the proxy know to allow the response for the secondary
// domain html through, so the page will finish loading
Cypress.backend('ready:for:domain')
}

communicator.on('delaying:html', () => {
// when a secondary domain is detected by the proxy, it holds it up
// to provide time for the spec bridge to be set up. normally, the queue
// will not continue until the page is stable, but this signals it to go
Expand All @@ -22,10 +28,7 @@ export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
// cy.isAnticipatingMultiDomain(true) will free the queue to move forward.
// if the next command isn't switchToDomain, this timeout will hit and
// the test will fail with a cross-origin error
timeoutId = setTimeout(() => {
// TODO: when we throw an error make sure to clear this timeout
Cypress.backend('ready:for:domain')
}, 2000)
timeoutId = setTimeout(sendReadyForDomain, 2000)
})

Commands.addAll({
Expand Down Expand Up @@ -69,13 +72,17 @@ export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
})

if (typeof domain !== 'string') {
sendReadyForDomain()

$errUtils.throwErrByPath('switchToDomain.invalid_domain_argument', {
onFail: log,
args: { arg: $utils.stringify(domain) },
})
}

if (typeof callbackFn !== 'function') {
sendReadyForDomain()

$errUtils.throwErrByPath('switchToDomain.invalid_fn_argument', {
onFail: log,
args: { arg: $utils.stringify(callbackFn) },
Expand Down Expand Up @@ -212,9 +219,9 @@ export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,

// If three or more arguments are passed in, verify the second argument is actually the done fn
if (done !== doneByReference) {
Cypress.backend('ready:for:domain')
sendReadyForDomain()

$errUtils.throwErrByPath('switchToDomain.done_reference_mismatch')
$errUtils.throwErrByPath('switchToDomain.done_reference_mismatch', { onFail: log })
}

communicator.once('done:called', doneAndCleanup)
Expand Down Expand Up @@ -262,9 +269,7 @@ export function addCommands (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
// receive messages
communicator.once('bridge:ready', () => {
state('readyForMultiDomain', true)
// let the proxy know to let the response for the secondary
// domain html through, so the page will finish loading
Cypress.backend('ready:for:domain')
sendReadyForDomain()
})

cy.once('internal:window:load', ({ type }) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/proxy/lib/http/response-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ const MaybeDelayForMultiDomain: ResponseMiddleware = function () {
this.next()
})

this.serverBus.emit('delaying:cross:domain:html')
this.serverBus.emit('cross:domain:delaying:html')

return
}
Expand Down
4 changes: 2 additions & 2 deletions packages/proxy/test/unit/http/response-middleware.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ describe('http/response-middleware', function () {

const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)

expect(ctx.serverBus.emit).to.be.calledWith('delaying:cross:domain:html')
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html')

ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]()

Expand All @@ -193,7 +193,7 @@ describe('http/response-middleware', function () {

const promise = testMiddleware([MaybeDelayForMultiDomain], ctx)

expect(ctx.serverBus.emit).to.be.calledWith('delaying:cross:domain:html')
expect(ctx.serverBus.emit).to.be.calledWith('cross:domain:delaying:html')

ctx.serverBus.once.withArgs('ready:for:domain').args[0][1]()

Expand Down
4 changes: 2 additions & 2 deletions packages/runner-shared/src/event-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export const eventManager = {
})
})

ws.on('cross:domain:html:received', () => {
Cypress.multiDomainCommunicator.emit('html:received')
ws.on('cross:domain:delaying:html', () => {
Cypress.multiDomainCommunicator.emit('delaying:html')
})

_.each(localToReporterEvents, (event) => {
Expand Down
14 changes: 5 additions & 9 deletions packages/server/lib/browsers/chrome.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,12 @@ let gettingFrameTree

// eslint-disable-next-line @cypress/dev/arrow-body-multiline-braces
const _updateFrameTree = (client) => async () => {
debug('get frame tree')
debug('update frame tree')

gettingFrameTree = new Promise<void>(async (resolve) => {
frameTree = (await client.send('Page.getFrameTree')).frameTree

debug('got frame tree')
debug('frame tree updated')

gettingFrameTree = null

Expand All @@ -350,14 +350,10 @@ const _updateFrameTree = (client) => async () => {
// the CDP is tied up during that event and can't be utilized. so we maintain
// a reference to it that's updated when it's likely to have been changed
const _listenForFrameTreeChanges = (client) => {
debug('frames changed')
debug('listen for frame tree changes')

// these events are often called a bunch in a row, so debounce them
const onUpdate = _.debounce(_updateFrameTree(client), 100)

client.on('Page.frameAttached', onUpdate)
client.on('Page.frameDetached', onUpdate)
client.on('Page.frameNavigated', onUpdate)
client.on('Page.frameAttached', _updateFrameTree(client))
client.on('Page.frameDetached', _updateFrameTree(client))
}

const _continueRequest = (client, params, header?) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/server/lib/server-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
this._baseUrl = null
this._fileServer = null

this._eventBus.on('delaying:cross:domain:html', () => {
this._eventBus.on('cross:domain:delaying:html', () => {
this.socket.localBus.once('ready:for:domain', () => {
this._eventBus.emit('ready:for:domain')
})

this.socket.toDriver('cross:domain:html:received')
this.socket.toDriver('cross:domain:delaying:html')
})
}

Expand Down
2 changes: 1 addition & 1 deletion packages/server/test/integration/http_requests_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3021,7 +3021,7 @@ describe('Routes', () => {
'Content-Type': 'text/html',
})

this.server._eventBus.on('delaying:cross:domain:html', () => {
this.server._eventBus.on('cross:domain:delaying:html', () => {
this.server._eventBus.emit('ready:for:domain', { shouldInject: true })
})

Expand Down
33 changes: 0 additions & 33 deletions packages/server/test/unit/browsers/chrome_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,6 @@ describe('lib/browsers/chrome', () => {

this.criClient.on.withArgs('Page.frameAttached').yield()

// wait for the debounce
await new Promise((resolve) => setTimeout(resolve, 150))

await this.criClient.on.withArgs('Fetch.requestPaused').args[0][1]({
frameId: 'aut-frame-id',
requestId: '1234',
Expand Down Expand Up @@ -460,9 +457,6 @@ describe('lib/browsers/chrome', () => {

this.criClient.on.withArgs('Page.frameAttached').yield()

// wait for the debounce
await new Promise((resolve) => setTimeout(resolve, 150))

expect(this.criClient.send).to.be.calledWith('Page.getFrameTree')
})

Expand All @@ -471,35 +465,8 @@ describe('lib/browsers/chrome', () => {

this.criClient.on.withArgs('Page.frameDetached').yield()

// wait for the debounce
await new Promise((resolve) => setTimeout(resolve, 150))

expect(this.criClient.send).to.be.calledWith('Page.getFrameTree')
})

it('gets frame tree on Page.frameNavigated', async function () {
await chrome.open('chrome', 'http://', {}, this.automation)

this.criClient.on.withArgs('Page.frameNavigated').yield()

// wait for the debounce
await new Promise((resolve) => setTimeout(resolve, 150))

expect(this.criClient.send).to.be.calledWith('Page.getFrameTree')
})

it('debounces getting frame tree when multiple events fire in a row', async function () {
await chrome.open('chrome', 'http://', {}, this.automation)

this.criClient.on.withArgs('Page.frameNavigated').yield()
this.criClient.on.withArgs('Page.frameDetached').yield()
this.criClient.on.withArgs('Page.frameNavigated').yield()

// wait for the debounce
await new Promise((resolve) => setTimeout(resolve, 150))

expect(this.criClient.send.withArgs('Page.getFrameTree')).to.be.calledOnce
})
})
})

Expand Down

0 comments on commit 4356a78

Please sign in to comment.