support partial matching text,html,value (#3259)

* add "be.focused" to chai_jquery

* add comment explaining the mess

* add type definitions

* refactor assertion to use jquery assertion

* remove trailing whitespace

* add test for multiple elements, update typedefs

* fix failing tests: not.be.visible -> not.exist

* allow should(not.be.visible) for failed selectors

* remove unrelated visibility changes

* support partial matching text,html,value,id

* add partials for html,text,value ONLY, add typedefs, fix tests

* address changes
This commit is contained in:
Ben Kucera
2019-07-09 09:30:15 -05:00
committed by Zach Bloomquist
parent 2c4663f67b
commit 52ca8ed839
4 changed files with 119 additions and 12 deletions

48
cli/types/index.d.ts vendored
View File

@@ -3694,6 +3694,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'have.html', value: string): Chainable<Subject>
/**
* Assert that the html of the first element of the selection partially contains the given html, using `.html()`.
* @example
* cy.get('#result').should('contain.html', '<em>John Doe</em>')
* @see http://chaijs.com/plugins/chai-jquery/#htmlhtml
* @see https://on.cypress.io/assertions
*/
(chainer: 'contain.html', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection has the given id, using `.attr('id')`.
* @example
@@ -3719,6 +3727,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'have.text', value: string): Chainable<Subject>
/**
* Assert that the text of the first element of the selection partially contains the given text, using `.text()`.
* @example
* cy.get('#result').should('contain.text', 'John Doe')
* @see http://chaijs.com/plugins/chai-jquery/#texttext
* @see https://on.cypress.io/assertions
*/
(chainer: 'contain.text', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection has the given value, using `.val()`.
* @example
@@ -3727,6 +3743,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'have.value', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection partially contains the given value, using `.val()`.
* @example
* cy.get('textarea').should('contain.value', 'foo bar baz')
* @see http://chaijs.com/plugins/chai-jquery/#valuevalue
* @see https://on.cypress.io/assertions
*/
(chainer: 'contain.value', value: string): Chainable<Subject>
/**
* Assert that the selection matches a given selector, using `.is()`. Note that this overrides the built-in chai assertion. If the object asserted against is not a jQuery object, the original implementation will be called.
* @example
@@ -3874,6 +3898,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.have.html', value: string): Chainable<Subject>
/**
* Assert that the html of the first element of the selection does not contain the given html, using `.html()`.
* @example
* cy.get('#result').should('not.contain.html', '<em>John Doe</em>')
* @see http://chaijs.com/plugins/chai-jquery/#htmlhtml
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.contain.html', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection does not have the given id, using `.attr('id')`.
* @example
@@ -3899,6 +3931,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.have.text', value: string): Chainable<Subject>
/**
* Assert that the text of the first element of the selection does not contain the given text, using `.text()`.
* @example
* cy.get('#result').should('not.contain.text', 'John Doe')
* @see http://chaijs.com/plugins/chai-jquery/#texttext
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.contain.text', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection does not have the given value, using `.val()`.
* @example
@@ -3907,6 +3947,14 @@ declare namespace Cypress {
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.have.value', value: string): Chainable<Subject>
/**
* Assert that the first element of the selection does not contain the given value, using `.val()`.
* @example
* cy.get('textarea').should('not.contain.value', 'foo bar baz')
* @see http://chaijs.com/plugins/chai-jquery/#valuevalue
* @see https://on.cypress.io/assertions
*/
(chainer: 'not.contain.value', value: string): Chainable<Subject>
/**
* Assert that the selection does not match a given selector, using `.is()`. Note that this overrides the built-in chai assertion. If the object asserted against is not a jQuery object, the original implementation will be called.
* @example

View File

@@ -124,6 +124,13 @@ cy.wrap('foobar').should('have.string', 'bar')
cy.wrap('foobar').should('include', 'foo')
cy.wrap('foo').should('contain.value')
cy.wrap('foo').should('contain.text')
cy.wrap('foo').should('contain.html')
cy.wrap('foo').should('not.contain.value')
cy.wrap('foo').should('not.contain.text')
cy.wrap('foo').should('not.contain.html')
cy.wrap([1, 2, 3]).should('include.members', [1, 2])
;
() => {

View File

@@ -43,14 +43,37 @@ $chaiJquery = (chai, chaiUtils, callbacks = {}) ->
try
# ## reset obj to wrapped
orig = ctx._obj
ctx._obj = wrap(ctx)
if ctx._obj.length is 0
ctx._obj = ctx._obj.selector
## apply the assertion
ctx.assert(bool, args...)
ctx._obj = orig
catch err
## send it up with the obj and whether it was negated
callbacks.onError(err, method, ctx._obj, flag(ctx, "negate"))
assertPartial = (ctx, method, actual, expected, message, notMessage, args...) ->
if ctx.__flags.contains
return assert(
ctx
method
_.includes(actual, expected),
'expected #{this}'+ ' to contain ' + message
'expected #{this}'+ ' not to contain ' + notMessage
args...
)
return assert(
ctx
method
actual is expected
'expected #{this}'+ ' to have ' + message
'expected #{this}'+ ' not to have ' + notMessage
args...
)
chai.Assertion.addMethod "data", ->
assertDom(@, "data")
@@ -92,12 +115,13 @@ $chaiJquery = (chai, chaiUtils, callbacks = {}) ->
actual = wrap(@).html()
assert(
assertPartial(
@,
"html",
actual is html,
'expected #{this} to have HTML #{exp}, but the HTML was #{act}',
'expected #{this} not to have HTML #{exp}',
actual
html
'HTML #{exp}, but the HTML was #{act}',
'HTML #{exp}',
html,
actual
)
@@ -113,12 +137,13 @@ $chaiJquery = (chai, chaiUtils, callbacks = {}) ->
actual = wrap(@).text()
assert(
assertPartial(
@,
"text",
actual is text,
'expected #{this} to have text #{exp}, but the text was #{act}',
'expected #{this} not to have text #{exp}',
actual
text
'text #{exp}, but the text was #{act}',
'text #{exp}',
text,
actual
)
@@ -134,12 +159,13 @@ $chaiJquery = (chai, chaiUtils, callbacks = {}) ->
actual = wrap(@).val()
assert(
assertPartial(
@,
"value",
actual is value,
'expected #{this} to have value #{exp}, but the value was #{act}',
'expected #{this} not to have value #{exp}',
actual
value
'value #{exp}, but the value was #{act}',
'value #{exp}',
value,
actual
)

View File

@@ -1019,6 +1019,11 @@ describe "src/cy/commands/assertions", ->
expect(null).to.have.html("foo")
it "partial match", ->
expect(@$div).to.contain.html('button')
expect(@$div).to.not.contain.html('span')
cy.get('button').should('contain.html', 'button')
context "text", ->
beforeEach ->
@$div = $("<div>foo</div>")
@@ -1050,6 +1055,12 @@ describe "src/cy/commands/assertions", ->
"expected **<div>** to have text **bar**, but the text was **foo**"
)
it "partial match", ->
expect(@$div).to.have.text('foo')
expect(@$div).to.contain.text('o')
cy.get('div').should('contain.text', 'iv').should('contain.text', 'd')
cy.get('div').should('not.contain.text', 'fizzbuzz').should('contain.text', 'Nest')
it "throws when obj is not DOM", (done) ->
cy.on "fail", (err) =>
expect(@logs.length).to.eq(1)
@@ -1107,6 +1118,21 @@ describe "src/cy/commands/assertions", ->
expect({}).to.have.value("foo")
it "partial match", ->
expect(@$input).to.contain.value('oo')
expect(@$input).to.not.contain.value('oof')
cy.get('input')
.invoke('val','foobar')
.should('contain.value', 'bar')
.should('contain.value', 'foo')
cy.wrap(null).then ->
cy.$$('<input value="foo1">').prependTo(cy.$$('body'))
cy.$$('<input value="foo2">').prependTo(cy.$$('body'))
cy.get('input').should ($els) ->
expect($els).to.have.value('foo2')
expect($els).to.contain.value('foo')
.should('contain.value', 'oo2')
context "descendants", ->
beforeEach ->
@$div = $("<div><button>button</button></div>")