From 448e87c0b32c149a0bf4e0fe7042955ff62e70dc Mon Sep 17 00:00:00 2001 From: Prashant Trar Date: Sun, 14 Apr 2024 12:22:25 +0530 Subject: [PATCH] fix: added validation for timeout for query operations --- .../e2e/commands/querying/querying.cy.js | 58 +++++++++++++++++++ .../src/cy/commands/querying/querying.ts | 12 ++++ 2 files changed, 70 insertions(+) diff --git a/packages/driver/cypress/e2e/commands/querying/querying.cy.js b/packages/driver/cypress/e2e/commands/querying/querying.cy.js index 1b13a61a8bfe..69d856177788 100644 --- a/packages/driver/cypress/e2e/commands/querying/querying.cy.js +++ b/packages/driver/cypress/e2e/commands/querying/querying.cy.js @@ -18,6 +18,64 @@ describe('src/cy/commands/querying', () => { }) }) + describe('should throw when timeout is not a number', () => { + it('timeout passed as plain object {}', (done) => { + cy.get('#some-el', { timeout: {} }) + cy.on('fail', (err) => { + expect(err.message).to.eq('contains invalid timeout - [object Object]') + done() + }) + }) + + it('timeout passed as some string', (done) => { + cy.get('#some-el', { timeout: 'abc' }) + cy.on('fail', (err) => { + expect(err.message).to.eq('contains invalid timeout - abc') + done() + }) + }) + + it('timeout passed as null', (done) => { + cy.get('#some-el', { timeout: null }) + cy.on('fail', (err) => { + expect(err.message).to.eq('contains invalid timeout - null') + done() + }) + }) + + it('timeout passed as NaN', (done) => { + cy.get('#some-el', { timeout: NaN }) + cy.on('fail', (err) => { + expect(err.message).to.eq('contains invalid timeout - NaN') + done() + }) + }) + + it('timeout passed as Boolean', (done) => { + cy.get('#some-el', { timeout: false }) + cy.on('fail', (err) => { + expect(err.message).to.eq('contains invalid timeout - false') + done() + }) + }) + + it('timeout passed as array', (done) => { + cy.get('#some-el', { timeout: [] }) + cy.on('fail', (err) => { + expect(err.message).to.eq(`contains invalid 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..89931c179b53 100644 --- a/packages/driver/src/cy/commands/querying/querying.ts +++ b/packages/driver/src/cy/commands/querying/querying.ts @@ -142,6 +142,12 @@ function getAlias (selector, log, cy) { } export default (Commands, Cypress, cy, state) => { + function validateTimeoutFromOpts (options: GetOptions | ContainsOptions | ShadowOptions = {}) { + if (_.isPlainObject(options) && options.hasOwnProperty('timeout') && !_.isFinite(options.timeout)) { + $errUtils.throwErr(new Error(`contains invalid timeout - ${options.timeout}`)) + } + } + Commands.addQuery('get', function get (selector, userOptions: GetOptions = {}) { if ((userOptions === null) || _.isArray(userOptions) || !_.isPlainObject(userOptions)) { $errUtils.throwErrByPath('get.invalid_options', { @@ -149,6 +155,8 @@ export default (Commands, Cypress, cy, state) => { }) } + validateTimeoutFromOpts(userOptions) + const log = userOptions._log || Cypress.log({ message: selector, type: 'parent', @@ -253,6 +261,8 @@ export default (Commands, Cypress, cy, state) => { $errUtils.throwErrByPath('contains.empty_string') } + validateTimeoutFromOpts(userOptions) + // find elements by the :cy-contains pseudo selector // and any submit inputs with the attributeContainsWord selector const selector = $dom.getContainsSelector(text, filter, { matchCase: true, ...userOptions }) @@ -361,6 +371,8 @@ export default (Commands, Cypress, cy, state) => { consoleProps: () => ({}), }) + validateTimeoutFromOpts(userOptions) + this.set('timeout', userOptions.timeout) this.set('onFail', (err) => { switch (err.type) {