diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 350d491e2ac4..cae1ef0d82c4 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -5,7 +5,8 @@ _Released 4/23/2024 (PENDING)_ **Bugfixes:** -- Fixes a bug introduced in [`13.6.0`](https://docs.cypress.io/guides/references/changelog#13-6-0) where Cypress would occasionally exit with status code 1, even when a test run was successfully, due to an unhandled WebSocket exception (`Error: WebSocket connection closed`). Addresses [#28523](https://github.com/cypress-io/cypress/issues/28523). +- Fixed a bug introduced in [`13.6.0`](https://docs.cypress.io/guides/references/changelog#13-6-0) where Cypress would occasionally exit with status code 1, even when a test run was successfully, due to an unhandled WebSocket exception (`Error: WebSocket connection closed`). Addresses [#28523](https://github.com/cypress-io/cypress/issues/28523). +- Fixed an issue where Cypress would hang on some commands when an invalid `timeout` option was provided. Fixes [#29323](https://github.com/cypress-io/cypress/issues/29323). **Dependency Updates:** diff --git a/packages/driver/cypress/e2e/commands/querying/querying.cy.js b/packages/driver/cypress/e2e/commands/querying/querying.cy.js index 1b13a61a8bfe..6b4c751be2c6 100644 --- a/packages/driver/cypress/e2e/commands/querying/querying.cy.js +++ b/packages/driver/cypress/e2e/commands/querying/querying.cy.js @@ -18,6 +18,72 @@ describe('src/cy/commands/querying', () => { }) }) + describe('should throw when timeout is not a number', () => { + const options = { timeout: {} } + const getErrMsgForTimeout = (timeout) => `\`cy.get()\` only accepts a \`number\` for its \`timeout\` option. You passed: \`${timeout}\`` + + it('timeout passed as plain object {}', (done) => { + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + + it('timeout passed as some string', (done) => { + options.timeout = 'abc' + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + + it('timeout passed as null', (done) => { + options.timeout = null + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + + it('timeout passed as NaN', (done) => { + options.timeout = NaN + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + + it('timeout passed as Boolean', (done) => { + options.timeout = false + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + + it('timeout passed as array', (done) => { + options.timeout = [] + cy.get('#some-el', options) + cy.on('fail', (err) => { + expect(err.message).to.eq(getErrMsgForTimeout(options.timeout)) + done() + }) + }) + }) + + it('should timeout when element can\'t be found', (done) => { + cy.get('#some-el', { timeout: 100 }) + cy.on('fail', (err) => { + expect(err.message).to.contain('Timed out retrying after 100ms') + done() + }) + }) + it('can increase the timeout', () => { const missingEl = $('
', { id: 'missing-el' }) diff --git a/packages/driver/src/cy/commands/querying/querying.ts b/packages/driver/src/cy/commands/querying/querying.ts index 8e2530610b1f..5416f1084054 100644 --- a/packages/driver/src/cy/commands/querying/querying.ts +++ b/packages/driver/src/cy/commands/querying/querying.ts @@ -1,4 +1,4 @@ -import _ from 'lodash' +import _, { isEmpty } from 'lodash' import $dom from '../../../dom' import $elements from '../../../dom/elements' @@ -16,6 +16,8 @@ type GetOptions = Partial