Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress - attribute containing text and end of string

Let's assume I have such html:

<div class="my_class" id="first_case">
  <a href="/foo/bar/123"></a>
</div>

<div class="my_class" id="second_case">
  <a href="/foo/bar/1234567"></a>
</div>

I want to make assertion that there is an item with href, which ends with '/123'.

const test_id = '123'

cy.get('.my_class').find('a').should("have.attr", "href").and("contain", '/' + test_id);

It works, however I don't know how to make sure that the assertion is true only for href with exact ending ('/123', as shown in #first_case in first code snippet) and that it is false for other strings starting with such number, for example ('/1234567', as shown in #second_case in first code snippet).

In other words, the assertion should be true for #first_case, but false for #second_case.

I tried using end of string symbol or making new RegExp object, however couldn't make it work. Any help would be appreciated!

like image 211
P D Avatar asked Mar 02 '20 13:03

P D


People also ask

How do I get an element's text contents in Cypress?

How do I get an element's text contents? Cypress commands yield jQuery objects, so you can call methods on them. If the text contains a non-breaking space entity &nbsp; then use the Unicode character \u00a0 instead of &nbsp; .

How do I use attr in Cypress?

attr(name[, value]) Assert that the first element of the selection has the given attribute, using . attr() . Optionally, assert a particular value as well. The return value is available for chaining.


3 Answers

.should() will yield you the href so you can use it in a .then() block however you like (see https://stackoverflow.com/a/48451157/2883129), so you can use .endsWith():

const test_id = '123'

cy.get('.my_class')
  .find('a')
  .should("have.attr", "href")
  .then(href => {
    expect(href.endsWith(test_id)).to.be.true;
  });

Or to make it a bit more readable and a failure message to be clearer, you could use https://www.chaijs.com/plugins/chai-string/:

const test_id = '123'

cy.get('.my_class')
  .find('a')
  .should("have.attr", "href")
  .then(href => {
    expect(href).to.endWith(test_id);
  });
like image 147
Brendan Avatar answered Oct 21 '22 13:10

Brendan


I think there's even easier way to do this. You can use a single cy.get() and single should() because Cypress selectors should behave the same way as jQuery selectors do.

cy.get('.my_class a[href$="/123"]').should('have.length', 1);

$= will match only attributes that end with /123.

like image 34
martin Avatar answered Oct 21 '22 13:10

martin


In vanilla JS, you can try with querySelector() and attribute ends with selector ([name$="value"). Please note, you forgot to close the a element.

const test_id = '123'
var el = document.querySelector(`[href$="${test_id}"]`);
console.log(el);
<div class="my_class" id="first_case">
  <a href="/foo/bar/123"></a>
</div>

<div class="my_class" id="second_case">
  <a href="/foo/bar/1234567"></a>
</div>
like image 34
Mamun Avatar answered Oct 21 '22 12:10

Mamun