How to assert a value within a span? - testing

How to assert a dynamic text value within a span using Within assertion method? I would like to check that value
<span class="FilterHeader--results--count">
78
</span>
is within some range (for example 0 to 100).

Use the addCustomDOMProperties method for your case. It is better than another solution because in this case the smart assertion query mechanism will work correctly.
import { Selector } from 'testcafe';
fixture `fixture`;
test('test', async t => {
const span = Selector('.FilterHeader--results--count').addCustomDOMProperties({
integerSpanValue: el => parseInt(el.innerText, 10)
});
await t.expect(span.integerSpanValue).within(0, 100);
});

Convert the text in the span to a number, and then assert that the value is between 0 and 100 (inclusive). There's also a similar example under the Within section in the documentation.
await t
.expect(parseInt(await Selector('span.FilterHeader--results--count').innerText)).within(0,100);

Related

How to get all <a> tag under the <div> in testcafe

In selenium query for selector, if my selector value was (#div-id a). It return all a tags.
Does in testcafe is it posible this to selector function? i just want to avoid looping to get all a tags.
Code Sample
const element = selector('#div-id').find()
var get = await brandUrls.hasAttribute();
console.log(get);
Actual element attached
Yes, it is also possible to achieve the desired behavior with TestCafè in a similar way:
import { Selector } from "testcafe";
// one option
const firstLinkSelector = Selector("#directoryLink-1 a");
// another option
const secondLinkSelector = Selector("#directoryLink-1").find("a");
Read more about the find()-method here.

How to get cypress to return children length of 0 when there isnt any children

So I am writing a test that will add a card to a container(payment-card-container) and I want to confirm an element was added later by seeing if the children have increased by 1. But I am having issues when we try to count the children length when there isnt any. I am currently using the below:
cy.get('[data-test-id="payment-card-container"]')
.children()
.its('length')
.then(length => {
const childrenLength = length;
})
But Cypress seems to get an error because it cant find the children (Error below).
Timed out retrying: Expected to find element: ``, but never found it.
Is there a way this can work when there isnt any children and it returns the value of 0?
The problem with using a jQuery expression like
Cypress.$('[data-test-id="payment-card-container"]').children().length
is you don't get the Cypress retry for async updates.
If adding a payment card calls an API, the above expression will falsely report 0 children instead of waiting for the DOM to update.
There's really no good way to handle the no-cards situation,
Except
set up your test scenario such that there are no cards initially
add a card
confirm that there is now exactly one card
If you must test for zero children, a trailing .should() will remove the error message.
cy.get('[data-test-id="payment-card-container"]')
.children()
.should('have.length', 0); // no error when should expression passes
// Add card here
cy.get('[data-test-id="payment-card-container"]')
.children()
.should('have.length', 1); // waits for async add-card operation
Tested with
<body>
<div data-test-id="payment-card-container"></div>
<script>
setTimeout(() => {
const div = document.querySelector('[data-test-id="payment-card-container"]');
const p = document.createElement('p')
div.appendChild(p)
}, 2000)
</script>
</body>
One hacky way that I could think of is this. You can use the jQuery length and children() property to check the length:
cy.get('body').then(() = > {
if (Cypress.$('[data-test-id="payment-card-container"]').children().length == 0) {
//Do Something
}
else {
//Do Something
}
})

In Testcafe, how can I wait for a 2nd element of the same selector to appear?

I have a scenario in which multiple elements of the same className appear one after the other (it depends on a server response).
What I'm trying to achieve is passing the test only after 2 elements of the same selector are present, but currently, it seems like the test fails because it keeps recognizing 1 element and then straight up fails without waiting for a 2nd one.
This is my code (called from the outside with a count argument of, say, 2) -
import { Selector } from 'testcafe';
export const validateMsg = async (t, headlineText, count = 1) => {
const msgHeadline = Selector('.myClassName').withText(headlineText).exists;
const msgHeadLineExists = await t
.expect(msgHeadline.count)
.gte(count, `Received less than ${count} desired messages with headline ${headlineText}`);
return msgHeadLineExists;
};
I assume this happens because I'm checking whether msgHeadline exists, and it sees the first element when it gets rendered, and immediately fails. I'd like to wait for a 2nd one.
Any ideas?
Just remove the .exists from your selector it returns boolean and then calling .count on it will fail the test.
const msgHeadline = Selector('.myClassName').withText(headlineText);
const msgHeadLineExists = await t
.expect(msgHeadline.count)
.gte(count, `Received less than ${count} desired messages with headline ${headlineText}`);
return msgHeadLineExists;
You can read more here
https://devexpress.github.io/testcafe/documentation/test-api/selecting-page-elements/selectors/using-selectors.html#check-if-an-element-exists
If both elements have same text and only this elements have this specific className then you can use nth() function
const msgHeadline = Selector('.myClassName')..withText(headlineText).nth(1);
await t
.expect(msgHeadline.exists).ok(`Received less than ${count} desired messages with headline ${headlineText}`)
Here you take second element with headlineText and then assert, that it exists. Though i think you should check that it exists and displayed(visible)

How do I iterate over each element in an HTML list when testing with WebdriverIO and Mocha + Chai?

I am trying to assert that each item in a certain <ol> element exists. The closest solution I can find on SO and elsewhere is to use .elements, yet this still does not work. The length of the <ol> element varies on different pages, so it cannot be hardcoded into the test. See my current test below, which should fail at i.should.not.exist but passes.
it('category hierarchy navigation test',function() {
return client
.url(Page.url)
.then(function() {
ItemPage.categoryHierarchy.should.exist;
})
.then(function() {
return client.elements(ItemPage.categoryHierarchy, function(err, res){
for (let i in res.value) {
i.should.not.exist;
}
})
})
})
What is the proper way of getting an array of and iterating over the <li> elements inside an <ol>?

Intern functional test - iterating on set of items

This seems trivial, but I'm attempting to set up a functional test in Intern to check the inner text of a set of span elements in my page all with the same CSS class, but I can't seem to be able to isolate the text within the span. Here is my code:
'Span check': function () {
return this.remote
.findAllByClassName('mySpanClass')
.then(function (elems) {
assert.strictEqual(elems[0].innerHTML(),'Span Text');
})
}
I've run separate tests to verify that the spans are being found... the findAllByClassName function returns an array of two Objects.
Anyone done anything like this?
You need to use getVisibleText() instead:
Gets the visible text within the element. elements are converted
to line breaks in the returned text, and whitespace is normalised per
the usual XML/HTML whitespace normalisation rules.
return this.remote
.findByCssSelector('.mySpanClass')
.getVisibleText()
.then(function (text) {
assert.strictEqual(text, 'Span Text');
});
This would work for a single element.
If you want to check the text of each span, use:
return this.remote
.findAllByCssSelector('.mySpanClass')
.getVisibleText()
.then(function (texts) {
assert.strictEqual(texts, ['Span1 Text', 'Span2 Text']);
});