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)
})
});
});

[Cypress] install, configure, and script Cypress for JavaScript web applications -- part2的更多相关文章

  1. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part1

    Despite the fact that Cypress is an application that runs natively on your machine, you can install ...

  2. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part3

    Use custom Cypress command for reusable assertions We’re duplicating quite a few commands between th ...

  3. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part4

    Load Data from Test Fixtures in Cypress When creating integration tests with Cypress, we’ll often wa ...

  4. [Cypress] install, configure, and script Cypress for JavaScript web applications -- part5

    Use the Most Robust Selector for Cypress Tests Which selectors your choose for your tests matter, a ...

  5. Cypress系列(3)- Cypress 的初次体验

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 这里的栗子项目时 Cypress ...

  6. Cypress系列(41)- Cypress 的测试报告

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 注意 51 testting 有一篇文章 ...

  7. document.write('<script type=\"text/javascript\"><\/script>')

    document.write('<script type=\"text/javascript\"><\/script>')

  8. <script language = "javascript">, <script type = "text/javascript">和<script language = "application/javascript">(转)

          application/javascript是服务器端处理js文件的mime类型,text/javascript是浏览器处理js的mime类型,后者兼容性更好(虽然application/ ...

  9. 2.1 <script>元素【JavaScript高级程序设计第三版】

    向 HTML 页面中插入 JavaScript 的主要方法,就是使用<script>元素.这个元素由 Netscape 创造并在 Netscape Navigator 2 中首先实现.后来 ...

随机推荐

  1. python--内置常用模块

    一 . 简单的了解模块 你写的每一个py文件都是一个模块. 还有一些我们一直在使用的模块. buildins  内置模块. print, input. random  主要是和随机相关的的内容 ran ...

  2. Python正则表达式与hashlib模块

    菜鸟学python第十六天 1.re模块(正则表达式) 什么是正则表达式 正则表达式是一个由特殊字符组成的序列,他能帮助对字符串的某种对应模式进行查找. 在python中,re 模块使其拥有全部的正则 ...

  3. python27 mysqldb window install

    https://www.codegood.com/archives/129 下载地址 : https://i.cnblogs.com/Files.aspx

  4. IDEA避免JAVA文件自动引入import.*包

    Intellij Idea工具在java文件中怎么避免import java.utils.*这样的导入方式,不推崇导入*这样的做法!Editor->Code Style->Java-> ...

  5. 【js】--常用DOM库工具

    /* 2014年3月16号 常用DOM工具库*/var DOM={}; DOM.getElesByClass=function (strClassName,context){ if(typeof st ...

  6. js 加密混淆

    没有找到合适的加密算法就用的以下方式 拿webpack打包一遍,再拿uglify压缩一遍,再拿eval加密一遍 1. webpack ./init.js ./webpack/bundle.js -p ...

  7. Mac 文档阅读软件Dash软件破解版

    1.Dash 破解版链接 Mac 上阅读开发文档的软件:支持java.spring.springBoot等.百度网盘下载链接和密码如下. 链接:https://pan.baidu.com/s/1RWM ...

  8. EasyUI 动态更新列

    function UpdateRow() { var rows = $('#tbpmgridList').datagrid('getChecked'); var productid = ''; for ...

  9. rabbitmq php 学习

    参考文档:http://www.cnblogs.com/phpinfo/p/4104551...http://blog.csdn.net/historyasamirror/ar... 依赖包安装 yu ...

  10. UITableView点击切换状态分析

    原理:多选+点击动画 初始化和点击都调用的方法 - (void)changeStateAnimated:(BOOL)animated { //不需要动画,初始化的时候 if (animated == ...