[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)
})
});
});
[Cypress] install, configure, and script Cypress for JavaScript web applications -- part2的更多相关文章
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- Cypress系列(3)- Cypress 的初次体验
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 这里的栗子项目时 Cypress ...
- Cypress系列(41)- Cypress 的测试报告
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 注意 51 testting 有一篇文章 ...
- document.write('<script type=\"text/javascript\"><\/script>')
document.write('<script type=\"text/javascript\"><\/script>')
- <script language = "javascript">, <script type = "text/javascript">和<script language = "application/javascript">(转)
application/javascript是服务器端处理js文件的mime类型,text/javascript是浏览器处理js的mime类型,后者兼容性更好(虽然application/ ...
- 2.1 <script>元素【JavaScript高级程序设计第三版】
向 HTML 页面中插入 JavaScript 的主要方法,就是使用<script>元素.这个元素由 Netscape 创造并在 Netscape Navigator 2 中首先实现.后来 ...
随机推荐
- 关于$test$plusargs和$value$plusargs的小结
见: http://www.cnblogs.com/nanoty/p/4355245.html
- 5.电影搜索之 自动填充,也叫autocomplete、搜索建议!
什么叫自动填充,用过百度的应该都知道!当你输入关键词之后,会有一个下拉的候选列表,都是与你输入的内容相关的,这个就是自动填充的搜索建议.一般的搜索引擎或者站内搜索都会有这个功能. 今天分享下这个功能的 ...
- 【php】 给数组重建索引
array_values $a = [1,2]; unset($a[1]); $a[] = 3; print_r($a); // 输出 [0=>1,2=>3]
- 咕咕咕,skkyk的博客生活从此开始了
2019-5-9 咕咕咕,skkyk的博客生活从此开始了 我是划水时长两个半小时的个人OIer skkyk,我喜欢打表,暴零,骗分,瞎搞(律师函警告); 2019-6-14 中考结束的第二天 我们苦逼 ...
- Java-确定被加载类的路径
如何输出当前类在硬盘的物理路径 package com.tj; import java.net.URL; import java.security.CodeSource; import java.se ...
- nodemailer发送邮件遇到的一些问题
使用nodemailer发送邮件一直困惑了我好几天,百度谷歌都没有找到的几个问题,方便大家排查. 我使用的是0.7.1版本,其他的版本好像报错,就没用. 错误信息:Mail from command ...
- rsync同步命令
rsync同步时,--delete删除目标目录比源目录多余文件的方法1 .实例说明 服务器A上同步/tmp/work目录到远程服务器B的/tmp/work目录下, 同时删除B服务器/tmp/work ...
- LINUX DNS客户端 解析域名慢的问题。
Linux系统下域名解析的配置文件是/etc/resolv.conf cat /etc/resolv.conf # Generated by NetworkManager options single ...
- AWR报告中Parse CPU to Parse Elapsd%的理解
AWR报告中Parse CPU to Parse Elapsd%的理解 原文自:http://dbua.iteye.com/blog/827243 Parse CPU to Parse Ela ...
- Snmp的学习总结(二)
一.SNMP简介 SNMP指的是简单网络管理协议.它属于TCP/IP五层协议中的应用层协议.它提供了一种简单和方便的模式来管理网络中的各个元素.这里的元素就是各个被管理的对象,可以是因特网中的某个硬件 ...