New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contains() method returns partial last match #158

Closed
bahmutov opened this Issue Jun 9, 2016 · 4 comments

Comments

3 participants
@bahmutov
Collaborator

bahmutov commented Jun 9, 2016

Given HTML fragment

<ul>
  <li>foo</li>
  <li>bar</li>
  <li>bar foo</li>
</ul

then contains returns last element with partial match

cy.get('ul').contains('li', 'foo') 
// returns <li>bar foo</li>

It would be nice to prefer exact string match in case of multiple matches.
We also just wrote our own regular expression command for this case

function textCommand (subject, selector, regex) {
  if (!subject || !Cypress.Utils.hasElement(subject)) {
    subject = this.prop('withinSubject') || this.$$('body')
  }

  if (typeof regex === 'string') {
    regex = new RegExp(regex)
  }

  var log = Cypress.Log.command({
    name: 'text',
    message: ['finding text', selector, regex],
    $el: subject,
    onConsole: function () {
      return {
        Subject: subject,
        selector: selector,
        regex: regex
      }
    }
  })

  const items = Array.from(subject.find(selector))
  const found = items.find((el) => regex.test(el.outerText))
  log.snapshot().end()
  return found
}
// use like cy.get('.element').text('span', /foo$/)
Cypress.addDualCommand('text', textCommand)
@brian-mann

This comment has been minimized.

Member

brian-mann commented Jun 10, 2016

Doing some preliminary testing, this is actually caused by you passing the li selector as the first argument. If you hypothetically only passed in the content without the selector this would work.

@brian-mann

This comment has been minimized.

Member

brian-mann commented Jun 10, 2016

Okay I was able to fix both of your requests, however I don't think we'll opt into preferring "exact string matches" over partial matches.

In 0.16.2 the first <li> will be returned instead of the last. I'm not sure why we had code that was returning the last element when the selector was provided as an argument. After I removed that code all 70+ tests around cy.contains still passed. Must have been an oversight.

Additionally I was able to add in RegExp support without any performance problems. There could be some weird edge cases around this but I added a bunch of tests and they all pass.

@brian-mann brian-mann self-assigned this Jun 10, 2016

@brian-mann brian-mann added this to the 0.16.2 milestone Jun 10, 2016

@bahmutov

This comment has been minimized.

Collaborator

bahmutov commented Jun 10, 2016

nice!

@bahmutov bahmutov closed this Jun 10, 2016

@brian-mann

This comment has been minimized.

Member

brian-mann commented Jun 13, 2016

Fixed in 0.16.2.

@cypress-io cypress-io locked as resolved and limited conversation to collaborators Dec 6, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.