[Cypress] install, configure, and script Cypress for JavaScript web applications -- part2

Use Cypress to test user registration

Let’s write a test to fill out our registration form. Because we’ll be running this against a live backend, we need to generate the user’s information to avoid re-runs from trying to create new users that already exist. There are trade-offs with this approach. You should probably also clean out the application database before all of your tests start (how you accomplish this is pretty application-specific). Also, if your application requires email confirmation, I recommend you mock that on the backend and automatically set the user as confirmed during tests.

 

Let's create a helper method first.

support/generate.js

import {build, fake} from 'test-data-bot'

const userBuilder = build('User').fields(
    {
        username: fake(f => f.internet.userName()),
        password: fake(f => f.internet.password())
    }
)

export {userBuilder}

 

Then, create tests:

e2e/register.js

import {userBuilder} from '../support/generate'

describe('should register a new user', () => {
    it('should register a new user', () => {
        const user = userBuilder();
        cy.visit('/')
            .getByText(/register/i)
            .click()
            .getByLabelText(/username/i)
            .type(user.username)
            .getByLabelText(/password/i)
            .type(user.password)
            .getByText(/submit/i)
            .click()
            .url()
            .should('eq', `${Cypress.config().baseUrl}/`)
            .window()
            .its('localStorage.token')
            .should('be.a', 'string')
    });
});

 

Cypress Driven Development

Because Cypress allows you to use all the developer tools you’re used to from Google Chrome, you can actually use Cypress as your main application development workflow. If you’ve ever tried to develop a feature that required you to be in a certain state you’ve probably felt the pain of repeatedly refreshing the page and clicking around to get into that state. Instead, you can use cypress to do that and developer your application entirely in Cypress.

 

Simulate HTTP Errors in Cypress Tests

Normally I prefer to test error states using integration or unit tests, but there are some situations where it can be really useful to mock out a response to test a specific scenario in an E2E test. Let’s use the cypress server and route commands to mock a response from our registration request to test the error state.

    it(`should show an error message if there's an error registering`, () => {
        cy.server()
        cy.route({
          method: 'POST',
          url: 'http://localhost:3000/register',
          status: 500,
          response: {},
        })
        cy.visit('/register')
          .getByText(/submit/i)
          .click()
          .getByText(/error.*try again/i)
      })

 

Test user login with Cypress

 To test user login we need to have a user to login with. We could seed the database with a user and that may be the right choice for your application. In our case though we’ll just go through the registration process again and then login as the user and make the same assertions we made for registration.

import {userBuilder} from '../support/generate'

describe('should register a new user', () => {
    it('should register a new user', () => {
        const user = userBuilder();
        cy.visit('/')
            .getByText(/register/i)
            .click()
            .getByLabelText(/username/i)
            .type(user.username)
            .getByLabelText(/password/i)
            .type(user.password)
            .getByText(/submit/i)
            .click()

            // now we have new user
            .getByText(/logout/i)
            .click()

            // login again
            .getByText(/login/i)
            .click()
            .getByLabelText(/username/i)
            .type(user.username)
            .getByLabelText(/password/i)
            .type(user.password)
            .getByText(/submit/i)
            .click()

            // verify the user in localStorage
            .url()
            .should('eq', `${Cypress.config().baseUrl}/`)
            .window()
            .its('localStorage.token')
            .should('be.a', 'string')
            .getByTestId('username-display', {timeout: 500})
            .should('have.text', user.username)
    });
});

 

Create a user with cy.request from Cypress

We’re duplicating a lot of logic between our registration and login tests and not getting any additional confidence, so lets reduce the duplicate logic and time in our tests using cy.request to get a user registered rather than clicking through the application to register a new user.

import {userBuilder} from '../support/generate'

describe('should register a new user', () => {
    it('should register a new user', () => {
        const user = userBuilder();
        // send a http request to server to create a new user
        cy.request({
            url: 'http://localhost:3000/register',
            method: 'POST',
            body: user
        })
        cy.visit('/')
            .getByText(/login/i)
            .click()
            .getByLabelText(/username/i)
            .type(user.username)
            .getByLabelText(/password/i)
            .type(user.password)
            .getByText(/submit/i)
            .click()

            // verify the user in localStorage
            .url()
            .should('eq', `${Cypress.config().baseUrl}/`)
            .window()
            .its('localStorage.token')
            .should('be.a', 'string')
            .getByTestId('username-display', {timeout: 500})
            .should('have.text', user.username)
    });
});

 

Keep tests isolated and focused with custom Cypress commands

We’re going to need a newly created user for several tests so let’s move our cy.request command to register a new user into a custom Cypress command so we can use that wherever we need a new user.

 

Because we need to create user very often in the test, it is good to create a command to simply the code:

//support/commands.js


import {userBuilder} from '../support/generate'

Cypress.Commands.add('createUser', (overrides) => {
    const user = userBuilder(overrides);
    // send a http request to server to create a new user
    cy.request({
        url: 'http://localhost:3000/register',
        method: 'POST',
        body: user
    }).then(response => response.body.user)
})

We chain .then() call is to get the created user and pass down to the test.

 

describe('should register a new user', () => {
    it('should register a new user', () => {
        cy.createUser().then(user => {
            cy.visit('/')
            .getByText(/login/i)
            .click()
            .getByLabelText(/username/i)
            .type(user.username)
            .getByLabelText(/password/i)
            .type(user.password)
            .getByText(/submit/i)
            .click()

            // verify the user in localStorage
            .url()
            .should('eq', `${Cypress.config().baseUrl}/`)
            .window()
            .its('localStorage.token')
            .should('be.a', 'string')
            .getByTestId('username-display', {timeout: 500})
            .should('have.text', user.username)
        })
    });
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值