Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix timeout progress bar for cy.wait #7882

Merged
merged 12 commits into from
Jul 20, 2020
97 changes: 97 additions & 0 deletions packages/driver/cypress/integration/commands/waiting_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,103 @@ describe('src/cy/commands/waiting', () => {
})
})
})

describe('timeouts', function () {
it('sets default requestTimeout', {
requestTimeout: 199,
}, function (done) {
cy.on('command:retry', () => {
expect(this.lastLog.get('timeout')).to.eq(199)

done()
})

cy
.server()
.route('GET', '*', {}).as('fetch')
.wait('@fetch')
})

it('sets custom requestTimeout', function (done) {
cy.on('command:retry', () => {
expect(this.lastLog.get('timeout')).to.eq(199)

done()
})

cy
.server()
.route('GET', '*', {}).as('fetch')
.wait('@fetch', { requestTimeout: 199 })
})

it('sets default responseTimeout', {
responseTimeout: 299,
}, function (done) {
cy.on('command:retry', () => {
expect(this.lastLog.get('timeout')).to.eq(299)

done()
})

cy
.server({ delay: 100 })
.route('GET', '*', {}).as('fetch')
.window().then((win) => {
xhrGet(win, '/foo')

return null
})
.wait('@fetch')
})

it('sets custom responseTimeout', function (done) {
cy.on('command:retry', () => {
expect(this.lastLog.get('timeout')).to.eq(299)

done()
})

cy
.server({ delay: 100 })
.route('GET', '*', {}).as('fetch')
.window().then((win) => {
xhrGet(win, '/foo')

return null
})
.wait('@fetch', { responseTimeout: 299 })
})

it('updates to requestTimeout and responseTimeout at the proper times', function (done) {
let log
let retryCount = 0

cy.on('command:retry', () => {
log = log || this.lastLog
retryCount++
if (retryCount === 1) {
expect(log.get('timeout')).to.eq(100)

// trigger request to move onto response timeout verification
const win = cy.state('window')

xhrGet(win, '/foo')
}

if (retryCount === 2) {
expect(log.get('timeout')).to.eq(299)

done()
}
})

cy
.server({ delay: 100 })
.route('GET', '*', {}).as('fetch')
.wait('@fetch', { requestTimeout: 100, responseTimeout: 299 })
})
})
})
})
})
11 changes: 9 additions & 2 deletions packages/driver/src/cy/commands/waiting.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module.exports = (Commands, Cypress, cy, state) => {

if (options.log !== false) {
options._log = Cypress.log({
timeout: cy.timeout(),
timeout: ms,
consoleProps () {
return {
'Waited For': `${ms}ms before continuing`,
Expand All @@ -55,7 +55,6 @@ module.exports = (Commands, Cypress, cy, state) => {

if (options.log !== false) {
log = options._log = Cypress.log({
timeout: options.timeout,
type: 'parent',
aliasType: 'route',
options: userOptions,
Expand Down Expand Up @@ -156,13 +155,21 @@ module.exports = (Commands, Cypress, cy, state) => {
options = _.omit(options, '_runnableTimeout')
options.timeout = requestTimeout || Cypress.config('requestTimeout')

if (log) {
log.set('timeout', options.timeout)
}

return checkForXhr(alias, 'request', index, num, options)
}

const waitForResponse = () => {
options = _.omit(options, '_runnableTimeout')
options.timeout = responseTimeout || Cypress.config('responseTimeout')

if (log) {
log.set('timeout', options.timeout)
}

return checkForXhr(alias, 'response', index, num, options)
}

Expand Down
10 changes: 10 additions & 0 deletions packages/reporter/src/commands/command-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ export default class Command extends Instrument {
this.renderProps = props.renderProps || {}
this.visible = props.visible

if (this.timeout !== props.timeout) {
panzarino marked this conversation as resolved.
Show resolved Hide resolved
const timeElapsed = Date.now() - new Date(this.wallClockStartedAt).getTime()
const percentageComplete = timeElapsed / this.timeout
const newTimeout = (props.timeout - timeElapsed) / (1 - percentageComplete)
const newPosition = percentageComplete * newTimeout - timeElapsed

this.timeout = newTimeout
this.wallClockStartedAt = new Date(new Date(this.wallClockStartedAt).getTime() - newPosition).toJSON()
panzarino marked this conversation as resolved.
Show resolved Hide resolved
}

this._checkLongRunning()
}

Expand Down
3 changes: 2 additions & 1 deletion packages/reporter/src/commands/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ const Progress = observer(({ model }: ProgressProps) => {
const percentageRemaining = timeRemaining / model.timeout * 100 || 0

return (
<div className='command-progress'>
// we add a key here to ensure a rerender and restart of the animation on change
<div className='command-progress' key={timeRemaining}>
<span style={{ animationDuration: `${timeRemaining}ms`, width: `${percentageRemaining}%` }} />
</div>
)
Expand Down