diff --git a/packages/driver/src/cypress/chai_jquery.js b/packages/driver/src/cypress/chai_jquery.js index 8cff7ffd33..ea432c6d83 100644 --- a/packages/driver/src/cypress/chai_jquery.js +++ b/packages/driver/src/cypress/chai_jquery.js @@ -13,7 +13,7 @@ const selectors = { focused: 'focused', } -const attrs = { +const accessors = { attr: 'attribute', css: 'CSS property', prop: 'property', @@ -25,6 +25,12 @@ const attrs = { // the methods on it const wrap = (ctx) => $(ctx._obj) +const maybeCastNumberToString = (num) => { + // if this is a finite number (no Infinity or NaN) + // cast to a string + return _.isFinite(num) ? `${num}` : num +} + const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { const { inspect, flag } = chaiUtils @@ -111,6 +117,8 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { }) chai.Assertion.addMethod('id', function (id) { + id = maybeCastNumberToString(id) + return assert( this, 'id', @@ -145,6 +153,8 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { }) chai.Assertion.addMethod('text', function (text) { + text = maybeCastNumberToString(text) + assertDom( this, 'text', @@ -168,6 +178,8 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { }) chai.Assertion.addMethod('value', function (value) { + value = maybeCastNumberToString(value) + assertDom( this, 'value', @@ -250,23 +262,23 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { }) }) - _.each(attrs, (description, attr) => { - return chai.Assertion.addMethod(attr, function (name, val) { + _.each(accessors, (description, accessor) => { + return chai.Assertion.addMethod(accessor, function (name, val) { assertDom( this, - attr, + accessor, `expected #{this} to have ${description} #{exp}`, `expected #{this} not to have ${description} #{exp}`, name, ) - const actual = wrap(this)[attr](name) + const actual = wrap(this)[accessor](name) // when we only have 1 argument dont worry about val if (arguments.length === 1) { assert( this, - attr, + accessor, actual !== undefined, `expected #{this} to have ${description} #{exp}`, `expected #{this} not to have ${description} #{exp}`, @@ -276,7 +288,7 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { // change the subject this._obj = actual } else { - // if we don't have an attribute here at all we need to + // if we don't have an accessor here at all we need to // have a different failure message let message; let negatedMessage @@ -290,9 +302,17 @@ const $chaiJquery = (chai, chaiUtils, callbacks = {}) => { negatedMessage = `expected \#{this} not to have ${description} ${inspect(name)} with the value \#{exp}, but the value was \#{act}` } + // only cast .attr() as a string + // since prop stores the native javascript type + // and we don't want to optimistically cast those + // values as a string + if (accessor === 'attr') { + val = maybeCastNumberToString(val) + } + assert( this, - attr, + accessor, (actual != null) && (actual === val), message, negatedMessage, diff --git a/packages/driver/test/cypress/fixtures/jquery.html b/packages/driver/test/cypress/fixtures/jquery.html index 9dee06f92b..47244043e6 100644 --- a/packages/driver/test/cypress/fixtures/jquery.html +++ b/packages/driver/test/cypress/fixtures/jquery.html @@ -7,7 +7,7 @@
foojQuery
diff --git a/packages/driver/test/cypress/integration/commands/assertions_spec.js b/packages/driver/test/cypress/integration/commands/assertions_spec.js index 7e4c1b1dd9..3d69391bf8 100644 --- a/packages/driver/test/cypress/integration/commands/assertions_spec.js +++ b/packages/driver/test/cypress/integration/commands/assertions_spec.js @@ -1316,6 +1316,14 @@ describe('src/cy/commands/assertions', () => { expect(this.logs.length).to.eq(8) }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#data-number').then(($el) => { + expect($el).to.have.data('number', 222) + expect($el).not.to.have.data('number', '222') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) @@ -1357,6 +1365,14 @@ describe('src/cy/commands/assertions', () => { ) }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('.999').then(($el) => { + expect($el).to.have.class(999) + expect($el).to.have.class('999') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) @@ -1428,6 +1444,14 @@ describe('src/cy/commands/assertions', () => { ) }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#456').then(($el) => { + expect($el).to.have.id(456) + expect($el).to.have.id('456') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) @@ -1581,6 +1605,13 @@ describe('src/cy/commands/assertions', () => { } }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#number').then(($el) => { + expect($el).to.have.text(123) + }) + }) + it('partial match', function () { expect(this.$div).to.have.text('foo') expect(this.$div).to.contain.text('o') @@ -1663,6 +1694,14 @@ describe('src/cy/commands/assertions', () => { } }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#value-number').then(($el) => { + expect($el).to.have.value(123) + expect($el).to.have.value('123') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) @@ -2431,6 +2470,14 @@ describe('src/cy/commands/assertions', () => { ) }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#attr-number').then(($el) => { + expect($el).to.have.attr('num', 777) + expect($el).to.have.attr('num', '777') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) @@ -2534,6 +2581,19 @@ describe('src/cy/commands/assertions', () => { ) }) + // https://github.com/cypress-io/cypress/issues/7314 + it('supports a number argument', () => { + cy.get('#prop-number').then(($el) => { + $el.prop('foo', 444) + $el.prop('bar', '333') + + expect($el).to.have.prop('foo', 444) + expect($el).not.to.have.prop('foo', '444') + expect($el).not.to.have.prop('bar', 333) + expect($el).to.have.prop('bar', '333') + }) + }) + it('throws when obj is not DOM', function (done) { cy.on('fail', (err) => { expect(this.logs.length).to.eq(1) diff --git a/packages/driver/test/cypress/integration/e2e/keyboard_spec.js b/packages/driver/test/cypress/integration/e2e/keyboard_spec.js index a9dc256783..2f5a1d187f 100644 --- a/packages/driver/test/cypress/integration/e2e/keyboard_spec.js +++ b/packages/driver/test/cypress/integration/e2e/keyboard_spec.js @@ -7,7 +7,7 @@ describe('keyboard', () => { it('fires keyboard and click events with modifier', () => { cy .window().then((win) => { - win.$('input').one('keyup', (e) => { + win.$('#input').one('keyup', (e) => { expect(e.ctrlKey).to.be.true expect(e.which).to.equal(83) @@ -17,7 +17,7 @@ describe('keyboard', () => { expect(e.ctrlKey).to.be.true }) - cy.get('input').type('{ctrl}s', { release: false }) + cy.get('#input').type('{ctrl}s', { release: false }) cy.get('button').click() }) @@ -26,11 +26,11 @@ describe('keyboard', () => { it('releases modifiers between tests', () => { cy .window().then((win) => { - win.$('input').one('keyup', (e) => { + win.$('#input').one('keyup', (e) => { expect(e.ctrlKey).to.be.false }) - cy.get('input').type('s') + cy.get('#input').type('s') }) }) @@ -48,28 +48,28 @@ describe('keyboard', () => { characters.forEach(([char, asciiCode, keyCode]) => { it(`for ${char}`, () => { cy.window().then((win) => { - win.$('input').one('keydown', (e) => { + win.$('#input').one('keydown', (e) => { expect(e.charCode).to.equal(0) expect(e.which).to.equal(keyCode) expect(e.keyCode).to.equal(keyCode) }) - win.$('input').one('keypress', (e) => { + win.$('#input').one('keypress', (e) => { expect(e.charCode).to.equal(asciiCode) expect(e.which).to.equal(asciiCode) expect(e.keyCode).to.equal(asciiCode) }) - win.$('input').one('keyup', (e) => { + win.$('#input').one('keyup', (e) => { expect(e.charCode).to.equal(0) expect(e.which).to.equal(keyCode) expect(e.keyCode).to.equal(keyCode) }) - cy.get('input').type(char) + cy.get('#input').type(char) }) }) })