[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 it and add it as a dependency just like all other dependencies in your package.json file. So let's install Cypress and get our project ready to start end-to-end testing with Cypress.
install:
npm i -D cypress
Run:
npx cypress open
It will create some default tests and run the tests.
Config with eslint:
npm i -D eslint-plugin-cypress
Open .eslintrc.js:
const path = require('path')
module.exports = {
extends: [
'kentcdodds',
'kentcdodds/import',
'kentcdodds/webpack',
'kentcdodds/jest',
'kentcdodds/react',
],
plugins: ['eslint-plugin-cypress'],
env: {'cypress/globals': true},
overrides: [
{
files: ['**/__tests__/**'],
settings: {
'import/resolver': {
jest: {
jestConfigFile: path.join(__dirname, './jest.config.js'),
}
}
}
}
]
}
Update .gitignore:
coverage
node_modules
dist
cypress/videos
cypress/screenshots
Write the first Cypress Test
Cypress starts out your project with a ton of tests, let’s remove those and add our first test that verifies our calculator can add two numbers together using the Cypress selector playground and Cypress commands.
describe('anonymous calculator', () => {
it('can make calculation', () => {
cy.visit('http://localhost:8080')
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)') // get 1
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)') // get +
.click()
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)') // get 3
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)') // get =
.click()
.get('.mNQM6vIr72uG0YPP56ow5')// get display
.should('have.text', '4');
})
})
Configure Cypress in cypress.json
Cypress is fairly simple to configure, but it’s important to optimize our experience in testing Cypress. We’ll configure the baseUrl to make it easier to visit our app and we’ll also move our test files to a folder called e2e to make it more clear what types of tests we want to write with Cypress. We’ll use the cypress.json file, but Cypress can also be configured via command line flags and environment variables.
// cypress.json
{
"baseUrl": "http://localhost:8080",
"integrationFolder": "cypress/e2e/",
"viewportHeight": 900,
"viewportWidth": 400,
"defaultCommandTimeout": 5000
}
We have config the 'baseUrl', so in the test, we can use:
describe('anonymous calculator', () => {
it('can make calculation', () => {
cy.visit('/')
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)')
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)')
.click()
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)')
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)')
.click()
.get('.mNQM6vIr72uG0YPP56ow5')
.should('have.text', '4');
})
})
Installing cypress-testing-library
Our selectors are pretty ridiculous, mostly because we’re using CSS-in-JS and css modules for our react application. But even if we weren’t, using class names as selectors for our application testing is pretty brittle and not really testing in the way a user would. So instead let’s use cypress-testing-library to improve our selectors and make it easier to read our tests.
The following part of code is really hard to read and maintain because those wired selector
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(3)')
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(4)')
.click()
.get('._2S_Gj6clvtEi-dZqCLelKb > :nth-child(5)')
.click()
.get('._1yUJ9HTWYf2v-MMhAEVCAn > :nth-child(5)')
.click()
.get('.mNQM6vIr72uG0YPP56ow5')
To solve the problem, let's install:
npm i -D cypress-testing-library
Inside cypress/support:
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
import 'cypress-testing-library/add-commands' // Import commands.js using ES2015 syntax:
import './commands' // Alternatively you can use CommonJS syntax:
// require('./commands')
Update the tests:
cy.visit('/')
.getByText(/^1$/)
.click()
.getByText(/^\+$/)
.click()
.getByText(/^3$/)
.click()
.getByText(/^\=$/)
.click()
For the display, we need to use 'data-testid':
Update the component:
return (
<div
className={styles.autoScalingText}
style={{transform: `scale(${scale},${scale})`}}
ref={this.node}
data-testid="total"
>
{this.props.children}
</div>
Now the test looks like:
describe('anonymous calculator', () => {
it('can make calculation', () => {
cy.visit('/')
.getByText(/^1$/)
.click()
.getByText(/^\+$/)
.click()
.getByText(/^3$/)
.click()
.getByText(/^\=$/)
.click()
.getByTestId('total')
.should('have.text', '4');
})
})
Scripting Cypress for local development and Continuous Integration
We want to make starting cypress as simple as possible for local development and we need to be able to run a single script that exits when the tests are complete for continuous integration. So let’s add a few scripts to get ourselves setup for this development experience.
Install:
npm install --save-dev start-server-and-test
When we run e2e test, check if it is CI, when we run:
cypress run // not open the broswer
Otherwise:
cypress open
Then we want to run our server first, after get response from server, then we want to run cypress automaticlly:
start-server-and-test start http://localhost:8080 cy:run // run 'start' first, it will start the server wait response from 'http://localhost:8080', if get the response, then run cy:run' command
Scripts:
"scripts": {
"test": "is-ci \"test:coverage\" \"test:watch\"",
"test:coverage": "jest --coverage",
"test:watch": "jest --watch",
"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --watch",
"cy:run": "cypress run",
"cy:open": "cypress open",
"pretest:e2e:run": "npm run build",
"test:e2e": "is-ci \"test:e2e:run\" \"test:e2e:dev",
"test:e2e:run": "start-server-and-test start http://localhost:8080 cy:run",
"test:e2e:dev": "start-server-and-test dev http://localhost:8080 cy:open",
"dev": "webpack-serve",
"build": "webpack --mode=production",
"precommit": "lint-staged",
"postbuild": "cp ./public/index.html ./dist/index.html",
"start": "serve --no-clipboard --listen 8080 dist",
"lint": "jest --config test/jest-lint.js",
"format": "prettier \"**/*.js\" --write",
"validate": "npm run test && && npm run test:e2e:run",
"setup": "npm run setup && npm run validate"
},
Debug a test with Cypress
One of the greatest features of Cypress is how awesome the experience of debugging tests is. You do have to get used to the asynchronous nature of E2E testing, but once you get the hang of that debugging is pretty straightforward, and the ability to debug your own source code is awesome. The fact that your test and source code are executed in the same context also gives you some powerful advantages as well. You can potentially even expose some internal state to your Cypress app.
The way to add a debugger in the Cypress:
describe('anonymous calculator', () => {
it('can make calculation', () => {
cy.visit('/')
.getByText(/^1$/)
.click()
.getByText(/^\+$/)
.click()
.getByText(/^3$/)
.click()
.getByText(/^\=$/)
.then(subject => {
debugger
return subject;
})
.click()
.getByTestId('total')
.should('have.text', '4');
})
})
or
.getByText(/^\=$/)
.debug()
.click()
And
we can add cy.log('xxx'):
cy.log('get by text')
cy.getByText(/^\=$/)
.debug()
.click()
In the component, you can also put a debugger:
ReactDOM.render(
<Component initialState={{}}>
{({state, setState}) => {
debugger
if(window.Cypress) {
window.appState = state
window.setAppState = setState
}
[Cypress] install, configure, and script Cypress for JavaScript web applications -- part1的更多相关文章
- [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 -- part2
Use Cypress to test user registration Let’s write a test to fill out our registration form. Because ...
- [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 中首先实现.后来 ...
随机推荐
- jenkins插件开发(二)
https://wiki.jenkins.io/display/JENKINS/Extend+Jenkins http://commons.apache.org/proper/commons-jell ...
- back to back
back to back 传输,以前在AMBA bus中遇到过,FIFO设计中再次遇到. 查了资料大概意思是:直接传输,不依靠中介,连续多次传输.
- cs231n课程索引
课程资源 课程官网 课程视频-youtube 课程视频-字幕版 官方笔记 官方笔记-中文版 课程作业参考答案
- http协议工作原理(转)
WWW是以Internet作为传输媒介的一个应用系统,WWW网上最基本的传输单位是Web网页.WWW的工作基于客户机/服务器计算模型,由Web 浏览器(客户机)和Web服务器(服务器)构成,两者之间 ...
- magic mouse 2 在Mac上灵敏度太低的解决办法
1.打开终端 2.输入以下代码查看当前鼠标移动速度 defaults read -g com.apple.mouse.scaling 你会看到输出的是 “3”,这是初始速度 3.输入以下代码改变鼠标移 ...
- 【01】webpack的安装过程截图
[05](moyu:最好安装在C盘.默认的安装地址.) []全局安装 01,首先要安装Node.js, Node.js 自带了软件包管理器 npm. 02,Webpack 需要 Node.js v0. ...
- luogu2604 [ZJOI2010]网络扩容
先做一遍普通的dinic 然后再更改源点为超级源,超级源向原源加一条capacity=k && cost=0的边,再加上有费用的边跑最小费用最大流 #include <iostr ...
- 二丶人生苦短,我用python【第二篇】
1 编码 python解释器在加载 .py 文件中的代码时,对内容默认进行ascill编码,因此存在中文会报错,所以需要告诉python解释器,用什么编码来执行源代码.) ASCII码,主要用于显示现 ...
- CodeBlocks "no such file or directory
1但编译时还是会报错:no such file or directory;这是为什么呢? :在项目/构建选项/搜索路径 选项下,点击添加按钮,添加自己的头文件的存放文件夹,搞定... 2.code ...
- Web开发细节搜集
App_Data 百度百科: App_Data文件夹应该包含应用程序的本地数据存储.它通常以文件(诸如Microsoft Access或Microsoft SQL Server Express数据库 ...