Skip to content

Commit

Permalink
feat: Add timeout period to retry error message (#9123)
Browse files Browse the repository at this point in the history
  • Loading branch information
sainthkh authored Dec 16, 2020
1 parent 3d1565e commit cfaf1ad
Show file tree
Hide file tree
Showing 16 changed files with 58 additions and 48 deletions.
4 changes: 2 additions & 2 deletions packages/desktop-gui/cypress/fixtures/runs.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"failedTests": [
{
"body": "function () {}",
"error": "Timed out retrying: cy.click() failed because this element is being covered by another element:",
"error": "Timed out retrying after 4000ms: cy.click() failed because this element is being covered by another element:",
"id": "175e807c-ce85-5f94-938c-e2e30b090633",
"instanceId": "d1609552-31b5-50c1-b307-c27c9553ccb8",
"stack": "Error: Uncaught ReferenceError:\n at Object.$Cypress.Utils._.cypressErr (http://localhost:2020/__cypress/static/js/cypress.js:4678:15)\n at Object.$Cypress.Utils._.throwErr (http://localhost:2020/__cypress/static/js/cypress.js:4642:22)\n at Object.$Cypress.Utils._.throwErrByPath (http://localhost:2020/__cypress/static/js/cypress.js:4670:21)",
Expand All @@ -53,7 +53,7 @@
},
{
"body": "function () {}",
"error": "Timed out retrying: cy.click() failed because this element is being covered by another element:",
"error": "Timed out retrying after 4000ms: cy.click() failed because this element is being covered by another element:",
"failedFromHookId": "h1",
"id": "ef0d934e-a247-5e60-b801-3c5be5aa8796",
"instanceId": "d1609552-31b5-50c1-b307-c27c9553ccb8",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,7 @@ describe('src/cy/commands/actions/trigger', () => {
it('throws when provided invalid event type', function (done) {
cy.on('fail', (err) => {
expect(this.logs.length).to.eq(2)
expect(err.message).to.eq('Timed out retrying: `cy.trigger()` `eventConstructor` option must be a valid event (e.g. \'MouseEvent\', \'KeyboardEvent\'). You passed: `FooEvent`')
expect(err.message).to.eq('Timed out retrying after 100ms: `cy.trigger()` `eventConstructor` option must be a valid event (e.g. \'MouseEvent\', \'KeyboardEvent\'). You passed: `FooEvent`')

done()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ describe('src/cy/commands/assertions', () => {

it('throws when eventually times out', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.eq('Timed out retrying: expected \'<button>\' to have class \'does-not-have-class\'')
expect(err.message).to.eq('Timed out retrying after 50ms: expected \'<button>\' to have class \'does-not-have-class\'')

done()
})
Expand Down
36 changes: 18 additions & 18 deletions packages/driver/cypress/integration/commands/connectors_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ describe('src/cy/commands/connectors', () => {
}

cy.on('fail', (err) => {
expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because the property: `foo` returned a `regexp` value instead of a function. `cy.invoke()` can only be used on properties that return callable functions.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because the property: `foo` returned a `regexp` value instead of a function. `cy.invoke()` can only be used on properties that return callable functions.')
expect(err.message).to.include('`cy.invoke()` waited for the specified property `foo` to return a function, but it never did.')
expect(err.message).to.include('If you want to assert on the property\'s value, then switch to use `cy.its()` and add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: \'bar\' }).its(\'foo\').should(\'eq\', \'bar\')`')
Expand All @@ -636,7 +636,7 @@ describe('src/cy/commands/connectors', () => {
}

cy.on('fail', (err) => {
expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because the property: `bar` returned a `string` value instead of a function. `cy.invoke()` can only be used on properties that return callable functions.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because the property: `bar` returned a `string` value instead of a function. `cy.invoke()` can only be used on properties that return callable functions.')
expect(err.message).to.include('`cy.invoke()` waited for the specified property `bar` to return a function, but it never did.')
expect(err.message).to.include('If you want to assert on the property\'s value, then switch to use `cy.its()` and add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: \'bar\' }).its(\'foo\').should(\'eq\', \'bar\')`')
Expand Down Expand Up @@ -972,7 +972,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because the property: `foo` does not exist on your subject.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because the property: `foo` does not exist on your subject.')
expect(err.message).to.include('`cy.invoke()` waited for the specified property `foo` to exist, but it never did.')
expect(err.message).to.include('If you do not expect the property `foo` to exist, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: \'bar\' }).its(\'quux\').should(\'not.exist\')`')
Expand Down Expand Up @@ -1019,9 +1019,9 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.eq('Timed out retrying: expected \'foo\' to equal \'bar\'')
expect(err.message).to.eq('Timed out retrying after 100ms: expected \'foo\' to equal \'bar\'')

expect(lastLog.get('error').message).to.eq('Timed out retrying: expected \'foo\' to equal \'bar\'')
expect(lastLog.get('error').message).to.eq('Timed out retrying after 100ms: expected \'foo\' to equal \'bar\'')

done()
})
Expand All @@ -1033,7 +1033,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because your subject is: `undefined`. You cannot invoke any functions such as `foo` on a `undefined` value.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because your subject is: `undefined`. You cannot invoke any functions such as `foo` on a `undefined` value.')
expect(err.message).to.include('If you expect your subject to be `undefined`, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap(undefined).should(\'be.undefined\')`')
expect(err.docsUrl).to.eq('https://on.cypress.io/invoke')
Expand All @@ -1049,7 +1049,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because the property: `foo` is not a function, and instead returned a `undefined` value.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because the property: `foo` is not a function, and instead returned a `undefined` value.')
expect(err.message).to.include('`cy.invoke()` waited for the specified property `foo` to become a callable function, but it never did.')
expect(err.message).to.include('If you expect the property `foo` to be `undefined`, then switch to use `cy.its()` and add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: undefined }).its(\'foo\').should(\'be.undefined\')`')
Expand All @@ -1066,7 +1066,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.invoke()` errored because the property: `baz` does not exist on your subject.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.invoke()` errored because the property: `baz` does not exist on your subject.')
expect(lastLog.get('error').message).to.include(err.message)
expect(err.docsUrl).to.eq('https://on.cypress.io/invoke')

Expand Down Expand Up @@ -1522,7 +1522,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `foo` does not exist on your subject.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `foo` does not exist on your subject.')
expect(err.message).to.include('`cy.its()` waited for the specified property `foo` to exist, but it never did.')
expect(err.message).to.include('If you do not expect the property `foo` to exist, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: \'bar\' }).its(\'quux\').should(\'not.exist\')`')
Expand All @@ -1539,7 +1539,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `foo` returned a `undefined` value.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `foo` returned a `undefined` value.')
expect(err.message).to.include('`cy.its()` waited for the specified property `foo` to become accessible, but it never did.')
expect(err.message).to.include('If you expect the property `foo` to be `undefined`, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: undefined }).its(\'foo\').should(\'be.undefined\')`')
Expand All @@ -1556,7 +1556,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `foo` returned a `null` value.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `foo` returned a `null` value.')
expect(err.message).to.include('`cy.its()` waited for the specified property `foo` to become accessible, but it never did.')
expect(err.message).to.include('If you expect the property `foo` to be `null`, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: null }).its(\'foo\').should(\'be.null\')`')
Expand All @@ -1573,7 +1573,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `b` does not exist on your subject.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `b` does not exist on your subject.')
expect(err.message).to.include('`cy.its()` waited for the specified property `b` to exist, but it never did.')
expect(err.message).to.include('If you do not expect the property `b` to exist, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: \'bar\' }).its(\'quux\').should(\'not.exist\')`')
Expand All @@ -1590,7 +1590,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `a` returned a `undefined` value.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `a` returned a `undefined` value.')
expect(err.message).to.include('`cy.its()` waited for the specified property `a` to become accessible, but it never did.')
expect(err.message).to.include('If you expect the property `a` to be `undefined`, then add an assertion such as:')
expect(err.message).to.include('`cy.wrap({ foo: undefined }).its(\'foo\').should(\'be.undefined\')`')
Expand Down Expand Up @@ -1628,7 +1628,7 @@ describe('src/cy/commands/connectors', () => {

it('can handle getter that throws', (done) => {
const spy = cy.spy((err) => {
expect(err.message).to.eq('Timed out retrying: some getter error')
expect(err.message).to.eq('Timed out retrying after 100ms: some getter error')

done()
}).as('onFail')
Expand All @@ -1650,7 +1650,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: `cy.its()` errored because the property: `baz` does not exist on your subject.')
expect(err.message).to.include('Timed out retrying after 100ms: `cy.its()` errored because the property: `baz` does not exist on your subject.')
expect(err.docsUrl).to.eq('https://on.cypress.io/its')
expect(lastLog.get('error').message).to.include(err.message)
expect(lastLog.get('error').message).to.include(err.message)
Expand All @@ -1670,7 +1670,7 @@ describe('src/cy/commands/connectors', () => {
[null, undefined].forEach((val) => {
it(`throws on traversed '${val}' subject`, (done) => {
cy.on('fail', (err) => {
expect(err.message).to.include(`Timed out retrying: \`cy.its()\` errored because the property: \`a\` returned a \`${val}\` value. The property: \`b\` does not exist on a \`${val}\` value.`)
expect(err.message).to.include(`Timed out retrying after 100ms: \`cy.its()\` errored because the property: \`a\` returned a \`${val}\` value. The property: \`b\` does not exist on a \`${val}\` value.`)
expect(err.message).to.include('`cy.its()` waited for the specified property `b` to become accessible, but it never did.')
expect(err.message).to.include('If you do not expect the property `b` to exist, then add an assertion such as:')
expect(err.message).to.include(`\`cy.wrap({ foo: ${val} }).its('foo.baz').should('not.exist')\``)
Expand All @@ -1684,7 +1684,7 @@ describe('src/cy/commands/connectors', () => {

it(`throws on initial '${val}' subject`, (done) => {
cy.on('fail', (err) => {
expect(err.message).to.include(`Timed out retrying: \`cy.its()\` errored because your subject is: \`${val}\`. You cannot access any properties such as \`foo\` on a \`${val}\` value.`)
expect(err.message).to.include(`Timed out retrying after 100ms: \`cy.its()\` errored because your subject is: \`${val}\`. You cannot access any properties such as \`foo\` on a \`${val}\` value.`)
expect(err.message).to.include(`If you expect your subject to be \`${val}\`, then add an assertion such as:`)
expect(err.message).to.include(`\`cy.wrap(${val}).should('be.${val}')\``)
expect(err.docsUrl).to.eq('https://on.cypress.io/its')
Expand Down Expand Up @@ -1767,7 +1767,7 @@ describe('src/cy/commands/connectors', () => {
cy.on('fail', (err) => {
const { lastLog } = this

expect(err.message).to.include('Timed out retrying: expected \'bar\' to equal \'baz\'')
expect(err.message).to.include('Timed out retrying after 200ms: expected \'bar\' to equal \'baz\'')
expect(lastLog.get('error').message).to.include(err.message)

done()
Expand Down
6 changes: 3 additions & 3 deletions packages/driver/cypress/integration/commands/files_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ describe('src/cy/commands/files', () => {
expect(lastLog.get('state')).to.eq('failed')

expect(err.message).to.eq(stripIndent`
Timed out retrying: \`cy.readFile(\"foo.json\")\` failed because the file does not exist at the following path:
Timed out retrying after 50ms: \`cy.readFile(\"foo.json\")\` failed because the file does not exist at the following path:
\`/path/to/foo.json\``)

Expand All @@ -274,7 +274,7 @@ describe('src/cy/commands/files', () => {
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq(stripIndent`\
Timed out retrying: \`cy.readFile(\"foo.json\")\` failed because the file exists when expected not to exist at the following path:
Timed out retrying after 50ms: \`cy.readFile(\"foo.json\")\` failed because the file exists when expected not to exist at the following path:
\`/path/to/foo.json\``)

Expand All @@ -297,7 +297,7 @@ describe('src/cy/commands/files', () => {
expect(this.logs.length).to.eq(1)
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')
expect(err.message).to.eq('Timed out retrying: expected \'foo\' to equal \'contents\'')
expect(err.message).to.eq('Timed out retrying after 50ms: expected \'foo\' to equal \'contents\'')

done()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ describe('src/cy/commands/querying - shadow dom', () => {

it('has a custom error message if it cannot find a root', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.equal(`Timed out retrying: Expected the subject to host a shadow root, but never found it.`)
expect(err.message).to.equal(`Timed out retrying after 0ms: Expected the subject to host a shadow root, but never found it.`)
expect(err.docsUrl).to.equal('https://on.cypress.io/shadow')

done()
Expand Down
4 changes: 3 additions & 1 deletion packages/driver/src/cy/retries.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ const create = (Cypress, state, timeout, clearTimeout, whenStable, finishAsserti

({ error, onFail } = options)

const prependMsg = $errUtils.errByPath('miscellaneous.retry_timed_out').message
const prependMsg = $errUtils.errByPath('miscellaneous.retry_timed_out', {
ms: options._runnableTimeout,
}).message

const retryErrProps = $errUtils.modifyErrMsg(error, prependMsg, (msg1, msg2) => {
return `${msg2}${msg1}`
Expand Down
4 changes: 3 additions & 1 deletion packages/driver/src/cypress/error_messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,9 @@ module.exports = {
docsUrl: 'https://on.cypress.io/cannot-execute-commands-outside-test',
},
private_custom_command_interface: 'You cannot use the undocumented private command interface: `{{method}}`',
retry_timed_out: 'Timed out retrying: ',
retry_timed_out ({ ms }) {
return `Timed out retrying after ${ms}ms: `
},
},

mocha: {
Expand Down
Loading

4 comments on commit cfaf1ad

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on cfaf1ad Dec 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.2.0/circle-develop-cfaf1ad82c15692d48d0d18ba8c53f8da15901e2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on cfaf1ad Dec 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 ia32 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.2.0/appveyor-develop-cfaf1ad82c15692d48d0d18ba8c53f8da15901e2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on cfaf1ad Dec 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AppVeyor has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.2.0/appveyor-develop-cfaf1ad82c15692d48d0d18ba8c53f8da15901e2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on cfaf1ad Dec 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/6.2.0/circle-develop-cfaf1ad82c15692d48d0d18ba8c53f8da15901e2/cypress.tgz

Please sign in to comment.