Want to validate the part of a string shouldn't be null - cypress

I have this following element which contain a string for Practitioner, its value is 1- zzz. How to validate after - it shouldn't be null. Even if there is a string or empty. It shouldn't print null. Also want to select the value under Practitioner (currently hard coded the position of the element as 2)
<div class="styles__container___BfTYi">
<div class="styles__subHeader___18Yg1">Practitioner</div>
<div class="styles__data___1senX">1- zzz</div>
</div>
I have the following code to retrieve the text,
cy.get(pageSelector.practitionerValidator).eq(2).then(function($getText) {
let practitionerName = $getText.text();
var validateLastName = practitionerName.split(' ');
cy.log(validateLastName[1]);
expect(validateLastName[1]).to.not.equal('null');
})

You can directly check that the entire string is not null like this:
cy.get('.styles__data___1senX').then(($ele) => {
expect($ele.text()).to.not.be.null
})
Or if you want to check that your inner text is not empty you can do:
cy.get('.styles__data___1senX').then(($ele) => {
expect($ele.text()).to.not.be.empty
})
You can find the selector from the text Practitioner like this:
cy.contains('Practitioner')
.parent()
.within(() => {
cy.get('div[class*="styles__data__"]').then(($ele) => {
expect($ele.text()).to.not.be.null
})
})

Appreciate the level of detail you gave.
I will be going off this assumption.
the Practitioner string will be random can spaces or no spaces after the - (ie 34- sdfwe, 3- , 1- )
I would use a regex to check the format of the string to check the string starts with a digit followed by a dash and a space with either a string, spaces, or nothing. /\d+\-\s(\w+|\s+)?/
Your code would look a bit like this.
cy.get(pageSelector.practitionerValidator)
.eq(2)
.invoke('text') // get text
.should('match', /\d+\-\s(\w+|\s+)?/) // use regex assertion

Related

How to assert a specific text in cypress

Please see the below code.
I am trying to assert value 2 but my code is not working.
You do something like this:
cy.get('#_evidon_message').should('contain.text', '2')
Based on the information you provided, it isn't clear if you want to check the entire text within the div or just for the number before partners.
If you only want to validate there is a 2 within the entire string, then:
cy.get('#_evidon_message')
.invoke('text')
.should('include.text', '2')
You can use also use regex on the string as well.
cy.get('#_evidon_message')
.invoke('text')
.then(text => {
const regexMatcher = /(\d+) months with (?<numPartners>(\d+)) partners/i
const numPartners = text.match(regexMatcher)?.group?.numPartners
expect(numPartners).to.eq(2)
})
The bold tags <b> are interfering with your text evaluation. It's actually HTML inside
cy.get('#_evidon_message').then($el => {
const html = $el.html()
console.log(html) // yields same as screenshot
})
To access the inner <b> use additional commands, for example
cy.get('#_evidon_message')
.find('b')
.eq(2)
.should('contain', '2')

Cypress test invoke("text") includes char \n. How can I strip it out?

I have a test that checks the contents of a div that has some text a new line and some more text, that can then be copied to the clipboard, My test is currently failing because of the /n.
expected this is my first sentence\nthis is my second sentence
to equal this is my first sentencethis is my second sentence
Is there a way I can strip that out?
subject
.getContainer()
.should("be.visible")
.invoke("text")
.then((text) => {
cy.window()
.its("navigator.clipboard")
.invoke("readText") // The expect bit is coming from this invoke("readText")
.should("equal", text);
});
A string replace with regex will do that
.should("equal", text.replace(/\n/, ''))
In reverse
.then((text) => {
cy.window()
.its("navigator.clipboard")
.invoke("readText")
.then(cbtext => cbtext.replace(/\n/, ''))
.should("equal", text);

Cypress: store value in a variable

I want to store a td value in a variable. Why this code doesn't work?
let storedValue;
cy.get('tbody>tr:nth-child(1)>td:nth-child(3)').invoke('text').then(text =>
{
storedValue = text;
})
cy.contains(storedValue).should('exist');
It returns "cy.contains() can only accept a string, number or regular expression"
A better approach would be to use aliases.
cy.get('tbody>tr:nth-child(1)>td:nth-child(3)').invoke('text').as('storedValue')
cy.get('#storedValue').then((storedValue) => {
//Access storedValue here
cy.log(storedValue) //prints value
})
Or if you just want to check whether the element exists or not, you can directly do:
cy.get('tbody>tr:nth-child(1)>td:nth-child(3)').should('exist')
And for the question of why is your code not working, its because javascript works asynchronously, so instead of the code that gets the text first, the contains statement is executed first and the reason it fails is that storedValue doesn't have anything in it, in short, it is undefined. To fix then you have to add then() so that the code runs in a sequence we intend it to run in.
let storedValue
cy.get('tbody>tr:nth-child(1)>td:nth-child(3)')
.invoke('text')
.then((text) => {
storedValue = text
})
.then(() => {
cy.contains(storedValue).should('exist')
})

Cypress "have.attr" with regular expressions

In Cypress I can match an attribute's value by exact text like this:
cy.get("my-element")
.should("have.attr", "title", "Exact title")
But, is there a way to match the attribute's value by a substring or a regular expression? something like:
cy.get("my-element")
.should("have.attr", "title", /Partial title/)
So far, this is the best I have:
cy.get("my-element")
.should("have.attr", "title")
.then(title => expect(title).to.match(/Partial title/));
Per the Cypress docs, have.attr comes from chai-jquery:
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.
$('#header').should.have.attr('foo');
expect($('body')).to.have.attr('foo', 'bar');
expect($('body')).to.have.attr('foo').match(/bar/);
It only takes an exact value for the attribute directly. However, because the return value changes the subject, you can use chaining as also shown in the Cypress docs:
cy
.get('nav') // yields <nav>
.should('be.visible') // yields <nav>
.should('have.css', 'font-family') // yields 'sans-serif'
.and('match', /serif/)
In your case that would be
cy.get("my-element")
.should("have.attr", "title")
.and("match", /Partial title/);

Copy paste numbers with comma in Kendo numeric text box

I have kendo numeric text box. If i type number like 123456, the widget automatically format the number with comma and dollar symbol as expected. However if i copy and paste number with comma, for example 123,456, the widget does not accept that as input.
JSfiddle demo
How do i fix this or override the defualt behavior
place comma by separated thousand value and place currency of country for Kendo grids
columns.Bound(e => e.Amount).ClientTemplate("#= Amount !== null ? kendo.toString(Amount, 'c', 'en-US') : ''#").Width("5%").Title("Amount");
For instance:
kendo.toString(1234.23, ‘c’, ‘de-DE’) –> 1.234,23 €
kendo.toString(1234.23, ‘c’, ‘sv-SE’) –> 1.234,23 kr
kendo.toString(1234.23, ‘c’, ‘en-US’) –> $1,234.23
only comma separated with two decimal points:
columns.Bound(e => e.Amount).ClientTemplate("#= kendo.format('{0:N2}', kendo.toString(Amount)) #").Width("5%").Title("Amount");
for Example - 1234.44 -> 1,234.44
1234 -> 1,234.00
I think it is a bug in Kendo...
In the source code for the NumericTextBox, there is a _paste handler that appears like it is trying to sanitize the input against the culture's numeric format but then it validates against the unsanitized value...seems to be it should use the sanitized value.
Here's the implementation:
_paste: function (e) {
var that = this;
var element = e.target;
var value = element.value;
var numberFormat = that._format(that.options.format);
setTimeout(function () {
var result = that._parse(element.value);
var isValid = that._numericRegex(numberFormat).test(element.value);
if (result === NULL || that._adjust(result) !== result || !isValid) {
that._update(value);
}
});
},
So, if you paste "123,456", it will _parse() it to 123456(because it knows that "," is the thousands separator) but then the isValid check is still checking against the "123,456" which is bad and so it reverts to the previous value.
If you change the isValid line to
var isValid = that._numericRegex(numberFormat).test(result);
so that it validates against the sanitized value, then it all appears to work as you expect it to....otherwise I can't really see why the sanitize it in the first place.
I realize that changing the kendo source code it not really a valid solution, but I do believe this is a bug that you may have to work around it until it is fixed.
If you have a kendo license, I would contact their support to verify if it is a bug or not. If you don't have a license, let me know and I will submit a request when I have time as I do have a license.

Resources