Fixtures
In the signup-1.integration.spec.js test, every back-end stub has the response set inline, like the api/users
stub
cy.route("POST", "**/api/users", {
user: {
username: "Tester",
email: "user@realworld.io",
token:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkN2ZhZjc4YTkzNGFiMDRhZjRhMzE0MCIsInVzZXJuYW1lIjoidGVzdGVyNzk1MzYiLCJleHAiOjE1NzM4MzY2ODAsImlhdCI6MTU2ODY0OTA4MH0.zcHxMz2Vx5h-EoiUZlRyUw0z_A_6AIZ0LzQgROvsPqw"
}
}).as("signup-request");
but we can leverage the Cypress fixtures and move the responses out of the test code.
The steps are straightforward:
create a file in the
cypress/fixtures
directory, ex.cypress/fixtures/users/signup.json
move the above response inside it (transforming it into a valid JSON)
File: cypress/fixtures/users/signup.json
{
"user": {
"username": "tester",
"email": "user@realworld.io",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkN2ZiNmVhZDkzZWQ5MDhiMGU3MDMzYiIsInVzZXJuYW1lIjoidGVzdGVyIiwiZXhwIjoxNTczODM4NTg3LCJpYXQiOjE1Njg2NTA5ODd9.jeAccqZi6dOqokwjRPFl4fzHE5s5p8sB32NgXwlgrxQ"
}
}
- replace the static response of the code with
"fixture:users/signup"
, Cypress looks for theusers/signup.json
file starting from thecypress/fixture
directory
-cy.route("POST", "**/api/users", {
- user: {
- username: "Tester",
- email: "user@realworld.io",
- token:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkN2ZhZjc4YTkzNGFiMDRhZjRhMzE0MCIsInVzZXJuYW1lIjoidGVzdGVyNzk1MzYiLCJleHAiOjE1NzM4MzY2ODAsImlhdCI6MTU2ODY0OTA4MH0.zcHxMz2Vx5h-EoiUZlRyUw0z_A_6AIZ0LzQgROvsPqw"
- }
-).as("signup-request");
+cy.route("POST", "**/api/users", "fixture:users/signup").as("signup-request");
- do the same for the
**/api/tags
and**/api/articles/feed**
stub
File: cypress/fixtures/tags/empty-tags.json
{ "tags": [] }
File: cypress/fixtures/articles/empty-articles.json
{ "articles": [], "articlesCount": 0 }
-cy.route("GET", "**/api/tags", { tags: [] }).as("tags");
-cy.route("GET", "**/api/articles/feed**", { articles: [], articlesCount: 0 }).as("feed");
+cy.route("GET", "**/api/tags", "fixture:tags/empty-tags").as("tags");
+cy.route("GET", "**/api/articles/feed**", "fixture:articles/empty-articles").as("feed");
The result is the same but the test code is way cleaner!
File: cypress/integration/examples/signup-integration/signup-2.integration.spec.js
/// <reference types="Cypress" />
import { paths } from "../../../../realworld/frontend/src/components/App";
import { noArticles } from "../../../../realworld/frontend/src/components/ArticleList";
import { strings } from "../../../../realworld/frontend/src/components/Register";
context("Signup flow", () => {
it("The happy path should work", () => {
const user = {
username: "Tester",
email: "user@realworld.io",
password: "mysupersecretpassword"
};
// set up AJAX call interception
cy.server();
cy.route("POST", "**/api/users", "fixture:users/signup").as("signup-request");
cy.route("GET", "**/api/tags", "fixture:tags/empty-tags").as("tags");
cy.route("GET", "**/api/articles/feed**", "fixture:articles/empty-articles").as("feed");
cy.visit(paths.register);
// form filling
cy.findByPlaceholderText(strings.username)
.type(user.username)
.findByPlaceholderText(strings.email)
.type(user.email)
.findByPlaceholderText(strings.password)
.type(user.password);
// form submit...
cy.get("form")
.within(() => cy.findByText(strings.signUp))
.click();
// ... and AJAX call waiting
cy.wait("@signup-request")
.should(xhr =>
expect(xhr.request.body).deep.equal({
user: {
username: user.username,
email: user.email,
password: user.password
}
})
)
.wait(["@tags", "@feed"]);
// end of the flow
cy.findByText(noArticles).should("be.visible");
});
});
Author: Stefano Magni