Reputation: 15647
I want to test against the values of an array of elements & the text content of each element should be one of 'a' or 'b'.
it("should display for adventure & cabin charter when both are the only ones selected", () => {
cy.get("button.expCategoryBtn")
.contains("a")
.click();
cy.get("button.expCategoryBtn")
.contains("b")
.click();
// the following line doesnt work
cy.get("div.tag").each(x => {
// the problem line:
// I want to get the text value of each el & expect
// it to be one of a or b
expect(cy.wrap(x).invoke("text")).to.be.oneOf([
"a",
"b"
]);
});
});
EDIT: I did it like this:
it("should display for adventure & cabin charter when both are the only ones selected", () => {
cy.get("button.expCategoryBtn")
.contains("Adventure")
.click();
cy.get("button.expCategoryBtn")
.contains("Cabin Charter")
.click();
cy.get("div.tag")
.invoke("text")
.should("include", "adventure")
.should("include", "cabin_charter")
.should("not.include", "science_and_nature");
});
However, I am not happy with this and would still like some feedback on whats the correct way of testing when we wnat to assert one of multiple values. Thank you.
Upvotes: 4
Views: 17495
Reputation: 31
To check text value being one of many, you can use expect
, as was suggested by Zach, but you can do it without redundant nesting simply using should
:
cy.get('div.tag')
.invoke('text')
.should('be.oneOf', ['adventure', 'cabin_charter']);
Additionally, instead of
cy.get('button.expCategoryBtn')
.contains('Adventure')
you can omit the get
part and just write:
cy.contains('button.expCategoryBtn', 'Adventure')
And the last one, to make it "prettier" instead of multiple should
you can spice it up with and
(it does exactly the same).
So, to sum up
it("should display for adventure & cabin charter when both are the only ones selected", () => {
cy.contains('button.expCategoryBtn', 'Adventure')
.click();
cy.contains('button.expCategoryBtn', 'Cabin Charter')
.click();
cy.get('div.tag')
.invoke('text')
.should('be.oneOf', ['adventure', 'cabin_charter'])
.and('not.include', 'science_and_nature');
});
p.s. I recommend checking cypress documentation to everyone who wants to start learning it, or is familiar but still has questions. It is quite comprehensible, useful and clear.
Upvotes: -1
Reputation: 9418
So the BDD specification would read like:
When user clicks both buttons A and B
Then both tags A and B are displayed
We can use this multiple in Cypress by defining our set of buttons or tags using an array. This array can then be used to test repetitive similar interactions in sequence.
For simplicity I have duplicated the interaction lines with increasing index.
it("should display for adventure & cabin charter when both are the only ones selected", () => {
const buttonText = ["Adventure", "Cabin Charter"];
const tagText = ["adventure","cabin_charter"];
// WHEN both buttons clicked
cy.contains("button.expCategoryBtn", buttonText[0]).click();
cy.contains("button.expCategoryBtn", buttonText[1]).click();
// THEN both tags should be displayed
cy.get("div.tag").should('have.length', 2) // only 2 tags displayed
cy.get("div.tag").eq(0).hould('have.text', tagText[0])
cy.get("div.tag").eq(1).hould('have.text', tagText[1])
});
Note the emphasis on order using indexed arrays. This allows you to test and add for multiple buttons and tags.
Since we use an array we can also wrap the click-display verification inside a for-loop as sequence.
See also the explanation of click
option { multiple: true }
in RunEBook's article:Click a DOM element:
By default, Cypress will error if you're trying to click multiple elements. By passing
{ multiple: true }
Cypress will iteratively apply the click to each element and will also log to the Command Log multiple times.
Upvotes: 0
Reputation: 5889
It kinda sounds like you're trying to do conditional testing, which is not a best practice.
Regardless, you can do this like so:
cy.get("div.tag").each(x => {
expect(x.text()).to.be.oneOf([
"a",
"b"
]);
});
Upvotes: 10