Skip to content

Commit

Permalink
Allow for multiple onReadyStateChange calls (#1195)
Browse files Browse the repository at this point in the history
* Closes #1150 
* Closes #2374 

* Allow for multiple onReadyStateChange calls by implementing new recursive prevention
  • Loading branch information
meDavid authored and chrisbreiding committed Oct 3, 2018
1 parent 797673d commit 9229b22
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 23 deletions.
37 changes: 15 additions & 22 deletions packages/driver/src/cypress/server.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -359,17 +359,20 @@ create = (options = {}) ->

xhr = @
fns = {}
called = {}
overrides = {}
readyStates = {}

onLoadFn = ->
## bail if we've already been called to prevent
## infinite recursion
return if called.onload
bailIfRecursive = (fn) ->
isCalled = false

called.onload = true
return () ->
return if isCalled
isCalled = true
try
return fn.apply(arguments)
finally
isCalled = false

onLoadFn = ->
proxy._setDuration(timeStart)
proxy._setStatus()
proxy._setResponseHeaders()
Expand All @@ -391,12 +394,6 @@ create = (options = {}) ->
options.onAnyResponse(route, proxy)

onErrorFn = ->
## bail if we've already been called to prevent
## infinite recursion
return if called.onerror

called.onerror = true

## its possible our real onerror handler
## throws so we need to catch those errors too
try
Expand All @@ -407,12 +404,6 @@ create = (options = {}) ->
options.onError(proxy, err)

onReadyStateFn = ->
## bail if we've already been called with this
## readyState to prevent infinite recursions
return if readyStates[@readyState]

readyStates[@readyState] = true

## catch synchronous errors caused
## by the onreadystatechange function
try
Expand All @@ -423,9 +414,11 @@ create = (options = {}) ->
xhr.onreadystatechange = null
options.onError(proxy, err)

overrides.onload = onLoadFn
overrides.onerror = onErrorFn
overrides.onreadystatechange = onReadyStateFn
## bail if eventhandlers have already been called to prevent
## infinite recursion
overrides.onload = bailIfRecursive(onLoadFn)
overrides.onerror = bailIfRecursive(onErrorFn)
overrides.onreadystatechange = bailIfRecursive(onReadyStateFn)

props.forEach (prop) ->
## if we currently have one of these properties then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ describe "src/cy/commands/task", ->
expect(lastLog.get("error")).to.eq(err)
expect(lastLog.get("state")).to.eq("failed")

expect(err.message).to.eq("cy.task('bar') failed with the following error:\n\nThe task 'bar' was not handled in the plugins file. The following tasks are registered: return:arg, wait\n\nFix this in your plugins file here:\n#{Cypress.config('pluginsFile')}\n\nhttps://on.cypress.io/api/task")
expect(err.message).to.eq("cy.task('bar') failed with the following error:\n\nThe task 'bar' was not handled in the plugins file. The following tasks are registered: return:arg, wait, create:long:file\n\nFix this in your plugins file here:\n#{Cypress.config('pluginsFile')}\n\nhttps://on.cypress.io/api/task")
done()

cy.task("bar")
Expand Down
21 changes: 21 additions & 0 deletions packages/driver/test/cypress/integration/commands/xhr_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ describe "src/cy/commands/xhr", ->
expect(onreadystatechanged).to.be.true
expect(xhr.status).to.eq(404)

it "allows multiple readystatechange calls", ->
responseText = null
responseStatuses = 0

cy
.server()
.route({ url: /longtext.txt/ }).as("getLongText")
.task('create:long:file')
.window().then (win) ->
xhr = new win.XMLHttpRequest()
xhr.onreadystatechange = ->
responseText = xhr.responseText
if xhr.readyState == 3
responseStatuses++
xhr.open("GET", "/_test-output/longtext.txt?" + Cypress._.random(0, 1e6))
xhr.send()
null
.wait("@getLongText").then (xhr) ->
expect(responseStatuses).to.be.gt(1)
expect(xhr.status).to.eq(200)

it "works with jquery too", ->
failed = false
onloaded = false
Expand Down
12 changes: 12 additions & 0 deletions packages/driver/test/cypress/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const _ = require('lodash')
const path = require('path')
const fs = require('fs-extra')
const Promise = require('bluebird')

module.exports = (on) => {
Expand All @@ -8,5 +11,14 @@ module.exports = (on) => {
'wait' () {
return Promise.delay(2000)
},
'create:long:file' () {
const filePath = path.join(__dirname, '..', '_test-output', 'longtext.txt')
const longText = _.times(2000).map(() => {
return _.times(20).map(() => Math.random()).join(' ')
}).join('\n\n')

fs.outputFileSync(filePath, longText)
return null
},
})
}

0 comments on commit 9229b22

Please sign in to comment.