Searching by Attributes
Searching by attributes
Before continuing, make sure you have read the New Transaction Overview & Setup lesson first.
context("searches for a user by attribute", () => {
const searchAttrs: (keyof User)[] = [
"firstName",
"lastName",
"username",
"email",
"phoneNumber",
];
beforeEach(() => {
cy.getBySelLike("new-transaction").click();
cy.wait("@allUsers");
});
searchAttrs.forEach((attr: keyof User) => {
it(attr, () => {
const targetUser = ctx.allUsers![2];
cy.log(`Searching by **${attr}**`);
cy.getBySel("user-list-search-input").type(targetUser[attr] as string, { force: true });
cy.wait("@usersSearch")
// make sure the backend returns some results
.its("response.body.results")
.should("have.length.gt", 0)
.its("length")
.then((resultsN) => {
cy.getBySelLike("user-list-item")
// make sure the list of results is fully updated
// and shows the number of results returned from the backend
.should("have.length", resultsN)
.first()
.contains(targetUser[attr] as string);
});
cy.visualSnapshot(`User List for Search: ${attr} = ${targetUser[attr]}`);
cy.focused().clear();
cy.getBySel("users-list").should("be.empty");
cy.visualSnapshot("User List Clear Search");
});
});
});
You can find out more information about the custom Cypress commands used in this test here.
First, we create a searchAttrs
array that contains all of the user attributes we intend to search for.
const searchAttrs: (keyof User)[] = [
"firstName",
"lastName",
"username",
"email",
"phoneNumber",
];
Next we have a beforeEach()
hook that clicks on the "New" transaction button and waits for our @allUsers
intercept. Remember, this intercept occurs in the beforeEach()
hook at the top of this spec file.
beforeEach(() => {
cy.getBySelLike("new-transaction").click()
cy.wait("@allUsers")
})
Then, we are looping through the searchAttrs
array to dynamically create our tests, one for each attribute in the array. Remember that Cypress is just JavaScript, which allows us to dynamically generate our tests instead of manually creating a test for each attribute.
searchAttrs.forEach((attr: keyof User) => {
it(attr, () => {
const targetUser = ctx.allUsers![2];
cy.log(`Searching by **${attr}**`);
cy.getBySel("user-list-search-input").type(targetUser[attr] as string, { force: true });
cy.wait("@usersSearch")
// make sure the backend returns some results
.its("response.body.results")
.should("have.length.gt", 0)
.its("length")
.then((resultsN) => {
cy.getBySelLike("user-list-item")
// make sure the list of results is fully updated
// and shows the number of results returned from the backend
.should("have.length", resultsN)
.first()
.contains(targetUser[attr] as string);
});
cy.visualSnapshot(`User List for Search: ${attr} = ${targetUser[attr]}`);
cy.focused().clear();
cy.getBySel("users-list").should("be.empty");
cy.visualSnapshot("User List Clear Search");
});
});
Within our .forEach()
, you can see that the first thing we do is create our .it()
test and pass in the attribute as the test name.
it(attr, () => {
// ...
Next, we grab a user from our ctx
object created in the .beforeEach()
at the top of this spec file.
const targetUser = ctx.allUsers![2];
We then use cy.log() to output a custom message to the Cypress Command Log in the test runner. This makes it easy for us to see what is happening in the test runner and is helpful for debugging.
cy.log(`Searching by **${attr}**`)
We then perform a search for the specific attribute.
cy.getBySel("user-list-search-input").type(targetUser[attr] as string, { force: true });
Next, we wait upon the @usersSearch
intercept, which occurs in the .beforeEach()
at the top of the spec file.
cy.wait("@usersSearch")
We then grab the results
from the response.body
and write an assertion to make sure we have some results, i.e the results
array should not be empty
.its("response.body.results")
.should("have.length.gt", 0)
Then, we get the .length
of the results
array and write an assertion to make sure our UI displays the correct number of results returned from our back-end. We also have an assertion that the first item displayed in the search is the attribute we searched for.
.its("length")
.then((resultsN) => {
cy.getBySelLike("user-list-item")
// make sure the list of results is fully updated
// and shows the number of results returned from the backend
.should("have.length", resultsN)
.first()
.contains(targetUser[attr] as string);
Finally, we make sure that the users list is empty.
cy.focused().clear()
cy.getBySel("users-list").should("be.empty")