From ec79a76c8c97ef16afad81b3b932bf5194a639ec Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Wed, 28 Oct 2020 11:56:57 +0800 Subject: [PATCH 01/20] feat: added Front-end e2e test YAML file --- .github/workflows/frontend-e2e-test.yml | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/frontend-e2e-test.yml diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml new file mode 100644 index 0000000000..727d70f69d --- /dev/null +++ b/.github/workflows/frontend-e2e-test.yml @@ -0,0 +1,31 @@ +name: Front-end e2e test + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + frontend-e2e: + name: Front-end e2e test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Setup Node.JS environment for Front-end + uses: actions/setup-node@v1 + with: + node-version: 14.x + + - name: Install Front-end dependencies + run: yarn install + + - name: start Front-end and Test + run: | + yarn start & + sleep 10 && + curl http://localhost:8000 && + yarn test \ No newline at end of file From eb6634d31f59a0568c31b19ee7b40428f2a0e88b Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Wed, 28 Oct 2020 17:40:08 +0800 Subject: [PATCH 02/20] feat: added login e2e test --- package.json | 1 + src/e2e/Login.e2e.js | 28 ++++++++++++++++++++++++++++ yarn.lock | 25 ++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/e2e/Login.e2e.js diff --git a/package.json b/package.json index ae92bb8987..3e60ea2044 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "mockjs": "^1.0.1-beta3", "prettier": "^2.0.1", "pro-download": "1.0.1", + "puppeteer": "^5.4.1", "puppeteer-core": "^4.0.1", "stylelint": "^13.0.0" }, diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js new file mode 100644 index 0000000000..00cd97758c --- /dev/null +++ b/src/e2e/Login.e2e.js @@ -0,0 +1,28 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const puppeteer = require('puppeteer'); + +describe('Login', () => { + it('should login with failure', async () => { + const browser = await puppeteer.launch({ headless: true }); + const page = await browser.newPage(); + await page.goto('http://localhost:8000'); + await page.type('#control-ref_username', 'admin'); + await page.type('#control-ref_password', 'wrong_password'); + await page.click('.ant-btn-lg'); + await page.waitForSelector('.ant-notification-notice-icon-error'); // should display error + await page.close(); + browser.close(); + }); + + it('should login with succcess', async () => { + const browser = await puppeteer.launch({ headless: true }); + const page = await browser.newPage(); + await page.goto('http://localhost:8000'); + await page.type('#control-ref_username', 'admin'); + await page.type('#control-ref_password', 'admin'); + await page.click('.ant-btn-lg'); + await page.waitForSelector('.ant-notification-notice-icon-success'); + await page.close(); + browser.close(); + }); +}); diff --git a/yarn.lock b/yarn.lock index 41c0eaccab..a7eb036052 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6288,6 +6288,11 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" +devtools-protocol@0.0.809251: + version "0.0.809251" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.809251.tgz#300b3366be107d5c46114ecb85274173e3999518" + integrity sha512-pf+2OY6ghMDPjKkzSWxHMq+McD+9Ojmq5XVRYpv/kPd9sTMQxzEt21592a31API8qRjro0iYYOc3ag46qF/1FA== + dicer@0.2.5: version "0.2.5" resolved "https://registry.npm.taobao.org/dicer/download/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" @@ -11588,7 +11593,7 @@ node-fetch@2.6.0, node-fetch@^2.6.0: resolved "https://registry.npm.taobao.org/node-fetch/download/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha1-5jNFY4bUqlWGP2dqerDaqP3ssP0= -node-fetch@2.6.1: +node-fetch@2.6.1, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.npm.taobao.org/node-fetch/download/node-fetch-2.6.1.tgz?cache=0&sync_timestamp=1599309120224&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnode-fetch%2Fdownload%2Fnode-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha1-BFvTI2Mfdu0uK1VXM5RBa2OaAFI= @@ -13492,6 +13497,24 @@ puppeteer-core@~1.12.0: rimraf "^2.6.1" ws "^6.1.0" +puppeteer@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.4.1.tgz#f2038eb23a0f593ed2cce0d6e7cd5c43aecd6756" + integrity sha512-8u6r9tFm3gtMylU4uCry1W/CeAA8uczKMONvGvivkTsGqKA7iB7DWO2CBFYlB9GY6/IEoq9vkI5slJWzUBkwNw== + dependencies: + debug "^4.1.0" + devtools-protocol "0.0.809251" + extract-zip "^2.0.0" + https-proxy-agent "^4.0.0" + node-fetch "^2.6.1" + pkg-dir "^4.2.0" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^3.0.2" + tar-fs "^2.0.0" + unbzip2-stream "^1.3.3" + ws "^7.2.3" + q@^1.1.2: version "1.5.1" resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" From 3db65456a63245ac4c21e3da629aa794bfdc33b3 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Wed, 28 Oct 2020 18:48:52 +0800 Subject: [PATCH 03/20] feat: update Login.e2e.js --- src/e2e/Login.e2e.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index 00cd97758c..3193320e04 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -1,28 +1,39 @@ /* eslint-disable import/no-extraneous-dependencies */ const puppeteer = require('puppeteer'); +let browser; +beforeAll(async () => { + browser = await puppeteer.launch({ headless: false }); +}); + describe('Login', () => { - it('should login with failure', async () => { - const browser = await puppeteer.launch({ headless: true }); + test('Login fail', async () => { const page = await browser.newPage(); await page.goto('http://localhost:8000'); await page.type('#control-ref_username', 'admin'); await page.type('#control-ref_password', 'wrong_password'); await page.click('.ant-btn-lg'); await page.waitForSelector('.ant-notification-notice-icon-error'); // should display error + const element = await page.$('.ant-notification-notice-description'); + const text = await (await element.getProperty('textContent')).jsonValue(); + expect(text).toBe('username or password error'); await page.close(); - browser.close(); - }); + }, 10000); - it('should login with succcess', async () => { - const browser = await puppeteer.launch({ headless: true }); + test('Login success', async () => { const page = await browser.newPage(); await page.goto('http://localhost:8000'); await page.type('#control-ref_username', 'admin'); await page.type('#control-ref_password', 'admin'); await page.click('.ant-btn-lg'); await page.waitForSelector('.ant-notification-notice-icon-success'); + const element = await page.$('.ant-notification-notice-description'); + const text = await (await element.getProperty('textContent')).jsonValue(); + expect(text).toBe('Login Success'); await page.close(); - browser.close(); + }, 10000); + + afterAll(async () => { + await browser.close(); }); }); From 9df055c2e17b192c74eba94a233e897c16154f61 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Wed, 28 Oct 2020 19:06:42 +0800 Subject: [PATCH 04/20] Update Login.e2e.js --- src/e2e/Login.e2e.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index 3193320e04..c6f1e51fa8 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -3,7 +3,7 @@ const puppeteer = require('puppeteer'); let browser; beforeAll(async () => { - browser = await puppeteer.launch({ headless: false }); + browser = await puppeteer.launch({ headless: true }); }); describe('Login', () => { From a783814f71625d63131ab3b188c9c371bb5dacdf Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Thu, 29 Oct 2020 13:46:40 +0800 Subject: [PATCH 05/20] feat: added e2e readme --- src/e2e/Login.e2e.js | 17 +++++++++++++++++ src/e2e/README.md | 22 ++++++++++++++++++++++ src/e2e/README.zh-CN.md | 22 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/e2e/README.md create mode 100644 src/e2e/README.zh-CN.md diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index 3193320e04..26a39e5dad 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -1,3 +1,20 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* eslint-disable import/no-extraneous-dependencies */ const puppeteer = require('puppeteer'); diff --git a/src/e2e/README.md b/src/e2e/README.md new file mode 100644 index 0000000000..25573fd4de --- /dev/null +++ b/src/e2e/README.md @@ -0,0 +1,22 @@ +### Local writing test cases + +1. Installing dependencies and running local development environments + + ```Bash + yarn install && yarn start + ``` + +2. Add a new test case file to the `src/e2e` folder +3. Run test cases + + ```Bash + yarn test + ``` + + If you want to run a particular test file separately, you can execute the following command + + ```Bash + yarn test ${yourFileName}.e2e.js + ``` + + The test results will be displayed on the console. diff --git a/src/e2e/README.zh-CN.md b/src/e2e/README.zh-CN.md new file mode 100644 index 0000000000..d53a006f1c --- /dev/null +++ b/src/e2e/README.zh-CN.md @@ -0,0 +1,22 @@ +### 本地书写测试案例 + +1. 安装依赖并运行本地开发环境 + + ```Bash + yarn install && yarn start + ``` + +2. 在 `src/e2e` 文件夹增加新的测试案例文件 +3. 运行测试案例 + + ```Bash + yarn test + ``` + + 如果你想单独运行某一个测试文件,可以执行如下命令 + + ```Bash + yarn test ${yourFileName}.e2e.js + ``` + + 测试结果将会在控制台显示。 From d75590f541be4bc1d5d48a7bcd28bb35ff428090 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Thu, 29 Oct 2020 15:04:15 +0800 Subject: [PATCH 06/20] feat: added licence --- src/e2e/Login.e2e.js | 4 ++-- src/e2e/README.md | 21 ++++++++++++++++++++- src/e2e/README.zh-CN.md | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index 26a39e5dad..c290a6844f 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -24,13 +24,13 @@ beforeAll(async () => { }); describe('Login', () => { - test('Login fail', async () => { + test('Login failed', async () => { const page = await browser.newPage(); await page.goto('http://localhost:8000'); await page.type('#control-ref_username', 'admin'); await page.type('#control-ref_password', 'wrong_password'); await page.click('.ant-btn-lg'); - await page.waitForSelector('.ant-notification-notice-icon-error'); // should display error + await page.waitForSelector('.ant-notification-notice-icon-error'); const element = await page.$('.ant-notification-notice-description'); const text = await (await element.getProperty('textContent')).jsonValue(); expect(text).toBe('username or password error'); diff --git a/src/e2e/README.md b/src/e2e/README.md index 25573fd4de..d5cd2fa42c 100644 --- a/src/e2e/README.md +++ b/src/e2e/README.md @@ -1,4 +1,23 @@ -### Local writing test cases + + +### Writing test cases 1. Installing dependencies and running local development environments diff --git a/src/e2e/README.zh-CN.md b/src/e2e/README.zh-CN.md index d53a006f1c..80509772f8 100644 --- a/src/e2e/README.zh-CN.md +++ b/src/e2e/README.zh-CN.md @@ -1,3 +1,22 @@ + + ### 本地书写测试案例 1. 安装依赖并运行本地开发环境 From 47a42b5a7e82da09ee95c4619af447b3e0d5042c Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Thu, 29 Oct 2020 19:12:15 +0800 Subject: [PATCH 07/20] feat: added start-server-and-test package --- .github/workflows/frontend-e2e-test.yml | 10 +- package.json | 2 + src/e2e/Login.e2e.js | 2 +- yarn.lock | 186 ++++++++++++++++++++++-- 4 files changed, 179 insertions(+), 21 deletions(-) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index 727d70f69d..cf507edbaa 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Setup Node.JS environment for Front-end + - name: Setup Node.js environment for Front-end uses: actions/setup-node@v1 with: node-version: 14.x @@ -23,9 +23,5 @@ jobs: - name: Install Front-end dependencies run: yarn install - - name: start Front-end and Test - run: | - yarn start & - sleep 10 && - curl http://localhost:8000 && - yarn test \ No newline at end of file + - name: Start Front-end and Test + run: yarn test:e2e diff --git a/package.json b/package.json index 3e60ea2044..58b36194bd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "prettier": "prettier -c --write \"**/*\"", "site": "yarn run fetch:blocks && yarn run build", "start": "umi dev", + "test:e2e": "start-server-and-test 'yarn start' http://localhost:8000 'yarn test'", "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none umi dev", "start:no-mock": "cross-env MOCK=none umi dev", "start:no-ui": "cross-env UMI_UI=none umi dev", @@ -73,6 +74,7 @@ "react-device-detect": "^1.12.1", "react-dom": "^16.8.6", "react-helmet-async": "^1.0.4", + "start-server-and-test": "^1.11.5", "swagger-ui-react": "^3.33.0", "umi": "^3.1.2", "umi-request": "^1.0.8", diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index c290a6844f..e25b6f7984 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -20,7 +20,7 @@ const puppeteer = require('puppeteer'); let browser; beforeAll(async () => { - browser = await puppeteer.launch({ headless: false }); + browser = await puppeteer.launch({ headless: true }); }); describe('Login', () => { diff --git a/yarn.lock b/yarn.lock index a7eb036052..a22c2b7d41 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1595,6 +1595,11 @@ resolved "https://registry.npm.taobao.org/@hapi/hoek/download/@hapi/hoek-8.5.1.tgz?cache=0&sync_timestamp=1593915910245&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40hapi%2Fhoek%2Fdownload%2F%40hapi%2Fhoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" integrity sha1-/elgZMpEbeyMVajC8TCVewcMbgY= +"@hapi/hoek@^9.0.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.0.tgz#6c9eafc78c1529248f8f4d92b0799a712b6052c6" + integrity sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw== + "@hapi/joi@16.1.8": version "16.1.8" resolved "https://registry.npm.taobao.org/@hapi/joi/download/@hapi/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839" @@ -1618,6 +1623,13 @@ dependencies: "@hapi/hoek" "^8.3.0" +"@hapi/topo@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" + integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.npm.taobao.org/@istanbuljs/load-nyc-config/download/@istanbuljs/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -2000,6 +2012,23 @@ react-is "^16.9.0" shortid "^2.2.14" +"@sideway/address@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.0.tgz#0b301ada10ac4e0e3fa525c90615e0b61a72b78d" + integrity sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.npm.taobao.org/@sindresorhus/is/download/@sindresorhus/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -4304,6 +4333,13 @@ axe-core@^3.5.4: resolved "https://registry.npm.taobao.org/axe-core/download/axe-core-3.5.5.tgz#84315073b53fa3c0c51676c588d59da09a192227" integrity sha1-hDFQc7U/o8DFFnbFiNWdoJoZIic= +axios@^0.19.2: + version "0.19.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" + integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== + dependencies: + follow-redirects "1.5.10" + axobject-query@^2.1.2: version "2.2.0" resolved "https://registry.npm.taobao.org/axobject-query/download/axobject-query-2.2.0.tgz?cache=0&sync_timestamp=1592784633932&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxobject-query%2Fdownload%2Faxobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -4580,7 +4616,7 @@ blink-diff@^1.0.13: preceptor-core "~0.10.0" promise "6.0.0" -bluebird@^3.5.5: +bluebird@3.7.2, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha1-nyKcFb4nJFT/qXOs4NvueaGww28= @@ -5036,6 +5072,11 @@ chardet@^0.7.0: resolved "https://registry.npm.taobao.org/chardet/download/chardet-0.7.0.tgz?cache=0&sync_timestamp=1594010705529&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchardet%2Fdownload%2Fchardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha1-kAlISfCTfy7twkJdDSip5fDLrZ4= +check-more-types@2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= + check-types@^8.0.3: version "8.0.3" resolved "https://registry.npm.taobao.org/check-types/download/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" @@ -6129,6 +6170,20 @@ debug@4, debug@4.1.1, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" +debug@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" + integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + dependencies: + ms "2.1.2" + +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^0.7.2: version "0.7.4" resolved "https://registry.npm.taobao.org/debug/download/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" @@ -6471,7 +6526,7 @@ duplexer3@^0.1.4: resolved "https://registry.npm.taobao.org/duplexer3/download/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.2" resolved "https://registry.npm.taobao.org/duplexer/download/duplexer-0.1.2.tgz?cache=0&sync_timestamp=1597220926027&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fduplexer%2Fdownload%2Fduplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha1-Or5DrvODX4rgd9E23c4PJ2sEAOY= @@ -7392,6 +7447,19 @@ event-emitter@^0.3.5: d "1" es5-ext "~0.10.14" +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE= + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + eventemitter3@^4.0.0: version "4.0.6" resolved "https://registry.npm.taobao.org/eventemitter3/download/eventemitter3-4.0.6.tgz#1258f6fa51b4908aadc2cd624fcd6e64f99f49d6" @@ -7435,10 +7503,10 @@ execa@1.0.0, execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@4.0.3, execa@^4.0.0, execa@^4.0.3: - version "4.0.3" - resolved "https://registry.npm.taobao.org/execa/download/execa-4.0.3.tgz?cache=0&sync_timestamp=1594148311641&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" - integrity sha1-CjTau61tZhAL1vLFdshmlAPzF/I= +execa@3.4.0, execa@^3.2.0: + version "3.4.0" + resolved "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz?cache=0&sync_timestamp=1594148311641&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" + integrity sha1-wI7UVQ72XYWPrCaf/IVyRG8364k= dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -7447,13 +7515,14 @@ execa@4.0.3, execa@^4.0.0, execa@^4.0.3: merge-stream "^2.0.0" npm-run-path "^4.0.0" onetime "^5.1.0" + p-finally "^2.0.0" signal-exit "^3.0.2" strip-final-newline "^2.0.0" -execa@^3.2.0: - version "3.4.0" - resolved "https://registry.npm.taobao.org/execa/download/execa-3.4.0.tgz?cache=0&sync_timestamp=1594148311641&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha1-wI7UVQ72XYWPrCaf/IVyRG8364k= +execa@4.0.3, execa@^4.0.0, execa@^4.0.3: + version "4.0.3" + resolved "https://registry.npm.taobao.org/execa/download/execa-4.0.3.tgz?cache=0&sync_timestamp=1594148311641&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fexeca%2Fdownload%2Fexeca-4.0.3.tgz#0a34dabbad6d66100bd6f2c576c8669403f317f2" + integrity sha1-CjTau61tZhAL1vLFdshmlAPzF/I= dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -7462,7 +7531,6 @@ execa@^3.2.0: merge-stream "^2.0.0" npm-run-path "^4.0.0" onetime "^5.1.0" - p-finally "^2.0.0" signal-exit "^3.0.2" strip-final-newline "^2.0.0" @@ -7903,6 +7971,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + follow-redirects@^1.0.0: version "1.13.0" resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" @@ -8023,6 +8098,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= + fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.npm.taobao.org/fs-constants/download/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" @@ -10123,6 +10203,17 @@ joi2types@~1.0.7: "@types/json-schema" "^7.0.4" json-schema-to-typescript "^8.2.0" +joi@^17.1.1: + version "17.3.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.3.0.tgz#f1be4a6ce29bc1716665819ac361dfa139fff5d2" + integrity sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.0" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + js-file-download@^0.4.1: version "0.4.12" resolved "https://registry.npm.taobao.org/js-file-download/download/js-file-download-0.4.12.tgz#10c70ef362559a5b23cdbdc3bd6f399c3d91d821" @@ -10459,6 +10550,11 @@ last-call-webpack-plugin@^3.0.0: lodash "^4.17.5" webpack-sources "^1.1.0" +lazy-ass@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= + lazy-cache@^0.2.3: version "0.2.7" resolved "https://registry.npm.taobao.org/lazy-cache/download/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" @@ -10948,6 +11044,11 @@ map-obj@^4.0.0: resolved "https://registry.npm.taobao.org/map-obj/download/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" integrity sha1-uRIhtUJzS58UJWwBMsiXxdclb9U= +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ= + map-visit@^1.0.0: version "1.0.0" resolved "https://registry.npm.taobao.org/map-visit/download/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" @@ -11442,7 +11543,7 @@ ms@2.1.1: resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.1.tgz?cache=0&sync_timestamp=1588851173181&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo= -ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1588851173181&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= @@ -12338,6 +12439,13 @@ pathfinding@^0.4.18: dependencies: heap "0.2.5" +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha1-/lo0sMvOErWqaitAPuLnO2AvFEU= + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.1.1" resolved "https://registry.npm.taobao.org/pbkdf2/download/pbkdf2-3.1.1.tgz?cache=0&sync_timestamp=1591275684229&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpbkdf2%2Fdownload%2Fpbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" @@ -13409,6 +13517,13 @@ prr@~1.0.1: resolved "https://registry.npm.taobao.org/prr/download/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= +ps-tree@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" + integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== + dependencies: + event-stream "=3.3.4" + psl@^1.1.28: version "1.8.0" resolved "https://registry.npm.taobao.org/psl/download/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -15280,6 +15395,13 @@ rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.2: dependencies: tslib "^1.9.0" +rxjs@^6.5.5: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" + integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz?cache=0&sync_timestamp=1589129010497&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -15869,6 +15991,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8= + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -15911,6 +16040,19 @@ stackframe@^1.1.1: resolved "https://registry.npm.taobao.org/stackframe/download/stackframe-1.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fstackframe%2Fdownload%2Fstackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" integrity sha1-UkKUktY8YuuYmATBFVLj0i53kwM= +start-server-and-test@^1.11.5: + version "1.11.5" + resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.11.5.tgz#692cb4c9cf8ba9a992ef8b0010f839041183f687" + integrity sha512-XUGifPzbJcgD6tqWMFvbxnra1KByRuiw6Oc9FHR3tPm7UxB70a4iFDIuXfOAFtMJLvOJuwB3gnMUZxko8gtLow== + dependencies: + bluebird "3.7.2" + check-more-types "2.24.0" + debug "4.2.0" + execa "3.4.0" + lazy-ass "1.6.0" + ps-tree "1.2.0" + wait-on "5.2.0" + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.npm.taobao.org/state-toggle/download/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -15966,6 +16108,13 @@ stream-buffers@1.0.1: resolved "https://registry.npm.taobao.org/stream-buffers/download/stream-buffers-1.0.1.tgz#9a44a37555f96a5b78a5a765f0c48446cb160b8c" integrity sha1-mkSjdVX5alt4padl8MSERssWC4w= +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ= + dependencies: + duplexer "~0.1.1" + stream-each@^1.1.0: version "1.2.3" resolved "https://registry.npm.taobao.org/stream-each/download/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" @@ -16859,7 +17008,7 @@ through2@^3.0.0, through2@^3.0.1: inherits "^2.0.4" readable-stream "2 || 3" -through@^2.3.6, through@^2.3.8: +through@2, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -17799,6 +17948,17 @@ w3c-xmlserializer@^1.1.2: webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" +wait-on@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.2.0.tgz#6711e74422523279714a36d52cf49fb47c9d9597" + integrity sha512-U1D9PBgGw2XFc6iZqn45VBubw02VsLwnZWteQ1au4hUVHasTZuFSKRzlTB2dqgLhji16YVI8fgpEpwUdCr8B6g== + dependencies: + axios "^0.19.2" + joi "^17.1.1" + lodash "^4.17.19" + minimist "^1.2.5" + rxjs "^6.5.5" + walker@^1.0.7, walker@~1.0.5: version "1.0.7" resolved "https://registry.npm.taobao.org/walker/download/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" From c9c6730736dce3b2859bc1b8c70f96418bf2e379 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Fri, 30 Oct 2020 14:03:33 +0800 Subject: [PATCH 08/20] feat: update login test case --- src/e2e/Login.e2e.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/e2e/Login.e2e.js b/src/e2e/Login.e2e.js index f72a3858d7..c0560e77bf 100644 --- a/src/e2e/Login.e2e.js +++ b/src/e2e/Login.e2e.js @@ -19,26 +19,28 @@ const puppeteer = require('puppeteer'); let browser; -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; +const BASE_URL = `http://localhost:${process.env.PORT || 8002}`; const domSelectors = { inputUserName: '#control-ref_username', inputPassWord: '#control-ref_password', buttonLogin: '.ant-btn-lg', notificationNotice: '.ant-notification-notice', notificationLogin: '.ant-notification-notice-description', + loginSuccessIcon: '.ant-notification-notice-icon-success', + loginFailedIcon: '.ant-notification-notice-icon-error', }; -const loginFailedDatas = { +const loginFailedData = { userName: 'admin', passWord: '123456', }; -const loginSuccessDatas = { +const loginSuccessData = { userName: 'admin', passWord: 'admin', }; beforeAll(async () => { browser = await puppeteer.launch({ - headless: true, + headless: false, }); }); @@ -46,26 +48,20 @@ describe('Login', () => { test('Login failed with wrong password', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputUserName, loginFailedDatas.userName); - await page.type(domSelectors.inputPassWord, loginFailedDatas.passWord); + await page.type(domSelectors.inputUserName, loginFailedData.userName); + await page.type(domSelectors.inputPassWord, loginFailedData.passWord); await page.click(domSelectors.buttonLogin); - await page.waitForSelector(domSelectors.notificationNotice); - const element = await page.$(domSelectors.notificationLogin); - const text = await (await element.getProperty('textContent')).jsonValue(); - expect(text).toBe('username or password error'); + await page.waitForSelector(domSelectors.loginFailedIcon); await page.close(); }, 10000); - test('Login success', async () => { + test('Login success then Logout', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputUserName, loginSuccessDatas.userName); - await page.type(domSelectors.inputPassWord, loginSuccessDatas.passWord); + await page.type(domSelectors.inputUserName, loginSuccessData.userName); + await page.type(domSelectors.inputPassWord, loginSuccessData.passWord); await page.click(domSelectors.buttonLogin); - await page.waitForSelector(domSelectors.notificationNotice); - const element = await page.$(domSelectors.notificationLogin); - const text = await (await element.getProperty('textContent')).jsonValue(); - expect(text).toBe('Login Success'); + await page.waitForSelector(domSelectors.loginSuccessIcon); await page.close(); }, 10000); From ad9db178c51f276cbfa51416ec7c8d8c32b683b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=90=9A=E8=87=B4=E8=BF=9C?= Date: Fri, 30 Oct 2020 14:27:32 +0800 Subject: [PATCH 09/20] Update frontend-e2e-test.yml --- .github/workflows/frontend-e2e-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index 18758e0bcf..82a51c8a8b 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -7,6 +7,7 @@ on: pull_request: branches: - master + - v2.0 jobs: frontend-e2e: From 6682d5ff6893632528c3a270e8082c536a0e634f Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Sat, 31 Oct 2020 11:26:37 +0800 Subject: [PATCH 10/20] feat: added logout test case --- .github/workflows/frontend-e2e-test.yml | 5 ++++- frontend/src/e2e/Login.e2e.js | 28 ++++++++++++++++--------- frontend/src/e2e/README.zh-CN.md | 2 +- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index 18758e0bcf..f36789d521 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -7,7 +7,7 @@ on: pull_request: branches: - master - + jobs: frontend-e2e: name: Front-end e2e test @@ -20,6 +20,9 @@ jobs: with: node-version: 14.x + - name: Go to Front-end directory + run: cd frontend/ + - name: Install Front-end dependencies run: yarn install diff --git a/frontend/src/e2e/Login.e2e.js b/frontend/src/e2e/Login.e2e.js index b3f027293f..21ef276ad8 100644 --- a/frontend/src/e2e/Login.e2e.js +++ b/frontend/src/e2e/Login.e2e.js @@ -21,21 +21,24 @@ const puppeteer = require('puppeteer'); let browser; const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; const domSelectors = { - inputUserName: '#control-ref_username', - inputPassWord: '#control-ref_password', + inputusername: '#control-ref_username', + inputpassword: '#control-ref_password', buttonLogin: '.ant-btn-lg', notificationNotice: '.ant-notification-notice', notificationLogin: '.ant-notification-notice-description', loginSuccessIcon: '.ant-notification-notice-icon-success', loginFailedIcon: '.ant-notification-notice-icon-error', + userProfile: '.ant-space-horizontal div:nth-child(2)', + dropdownMenuItem: '.ant-dropdown-menu-item', + logoutButton: '.ant-dropdown-menu-item span[aria-label="logout"]', }; const loginFailedData = { - userName: 'admin', - passWord: '123456', + username: 'admin', + password: '123456', }; const loginSuccessData = { - userName: 'admin', - passWord: 'admin', + username: 'admin', + password: 'admin', }; beforeAll(async () => { @@ -48,8 +51,8 @@ describe('Login', () => { test('Login failed with wrong password', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputUserName, loginFailedData.userName); - await page.type(domSelectors.inputPassWord, loginFailedData.passWord); + await page.type(domSelectors.inputusername, loginFailedData.username); + await page.type(domSelectors.inputpassword, loginFailedData.password); await page.click(domSelectors.buttonLogin); await page.waitForSelector(domSelectors.loginFailedIcon); await page.close(); @@ -58,10 +61,15 @@ describe('Login', () => { test('Login success then Logout', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputUserName, loginSuccessData.userName); - await page.type(domSelectors.inputPassWord, loginSuccessData.passWord); + await page.type(domSelectors.inputusername, loginSuccessData.username); + await page.type(domSelectors.inputpassword, loginSuccessData.password); await page.click(domSelectors.buttonLogin); await page.waitForSelector(domSelectors.loginSuccessIcon); + await page.waitForNavigation(); + await page.click(domSelectors.userProfile); + await page.waitForSelector(domSelectors.dropdownMenuItem); + await page.click(domSelectors.logoutButton); + await page.waitForNavigation(); await page.close(); }, 10000); diff --git a/frontend/src/e2e/README.zh-CN.md b/frontend/src/e2e/README.zh-CN.md index da9ebc53e0..debac21ccb 100644 --- a/frontend/src/e2e/README.zh-CN.md +++ b/frontend/src/e2e/README.zh-CN.md @@ -17,7 +17,7 @@ # --> -### 本地书写测试案例 +### 本地编写测试案例 1. 安装依赖并运行本地开发环境 From 85e353d1e8649426265e4374d6bfaef9a5c4a958 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Sat, 31 Oct 2020 11:49:49 +0800 Subject: [PATCH 11/20] Update frontend-e2e-test.yml --- .github/workflows/frontend-e2e-test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index 82a51c8a8b..59d8540e42 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -21,6 +21,9 @@ jobs: with: node-version: 14.x + - name: Go to front-end directory + run: cd frontend/ + - name: Install Front-end dependencies run: yarn install From 2452ad0d213b51bea1e3d15cb2e05b4c722c9fda Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Sun, 1 Nov 2020 00:41:45 +0800 Subject: [PATCH 12/20] feat: added login failed with empty input --- .../src/e2e/{Login.e2e.js => LoginAndLogout.e2e.js} | 10 ++++++++++ 1 file changed, 10 insertions(+) rename frontend/src/e2e/{Login.e2e.js => LoginAndLogout.e2e.js} (88%) diff --git a/frontend/src/e2e/Login.e2e.js b/frontend/src/e2e/LoginAndLogout.e2e.js similarity index 88% rename from frontend/src/e2e/Login.e2e.js rename to frontend/src/e2e/LoginAndLogout.e2e.js index 21ef276ad8..762837e1dd 100644 --- a/frontend/src/e2e/Login.e2e.js +++ b/frontend/src/e2e/LoginAndLogout.e2e.js @@ -58,6 +58,16 @@ describe('Login', () => { await page.close(); }, 10000); + test('Login failed with empty username password', async () => { + const page = await browser.newPage(); + await page.goto(BASE_URL); + await page.type(domSelectors.inputusername, ''); + await page.type(domSelectors.inputpassword, ''); + await page.click(domSelectors.buttonLogin); + await page.waitForSelector('.ant-form-item-explain'); + await page.close(); + }, 10000); + test('Login success then Logout', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); From 637aefc4a4c56ef68364a45ae3c19653709fb912 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Mon, 2 Nov 2020 09:52:39 +0800 Subject: [PATCH 13/20] feat: update CI --- .github/workflows/frontend-e2e-test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index cc3c60d799..89d1b7a652 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -8,7 +8,10 @@ on: branches: - master - v2.0 - +defaults: + run: + working-directory: frontend + jobs: frontend-e2e: name: Front-end e2e test @@ -21,11 +24,8 @@ jobs: with: node-version: 14.x - - name: Go to Front-end directory - run: cd frontend/ - - name: Install Front-end dependencies run: yarn install - - name: Start Front-end and Test + - name: Start Front-end then Test run: yarn test:e2e From f60e412b3294a43ce27cd25f6170aba1c04f60e7 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Mon, 2 Nov 2020 11:03:23 +0800 Subject: [PATCH 14/20] feat: update text --- .github/workflows/frontend-e2e-test.yml | 2 +- frontend/src/e2e/LoginAndLogout.e2e.js | 19 +++++++++--------- frontend/src/e2e/README.md | 26 ++++++++++++------------- frontend/src/e2e/README.zh-CN.md | 22 ++++++++++----------- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/.github/workflows/frontend-e2e-test.yml b/.github/workflows/frontend-e2e-test.yml index 89d1b7a652..58652c933c 100644 --- a/.github/workflows/frontend-e2e-test.yml +++ b/.github/workflows/frontend-e2e-test.yml @@ -27,5 +27,5 @@ jobs: - name: Install Front-end dependencies run: yarn install - - name: Start Front-end then Test + - name: Start Front-end then test run: yarn test:e2e diff --git a/frontend/src/e2e/LoginAndLogout.e2e.js b/frontend/src/e2e/LoginAndLogout.e2e.js index 762837e1dd..a22dc21ae6 100644 --- a/frontend/src/e2e/LoginAndLogout.e2e.js +++ b/frontend/src/e2e/LoginAndLogout.e2e.js @@ -21,8 +21,8 @@ const puppeteer = require('puppeteer'); let browser; const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; const domSelectors = { - inputusername: '#control-ref_username', - inputpassword: '#control-ref_password', + inputUsername: '#control-ref_username', + inputPassword: '#control-ref_password', buttonLogin: '.ant-btn-lg', notificationNotice: '.ant-notification-notice', notificationLogin: '.ant-notification-notice-description', @@ -43,7 +43,7 @@ const loginSuccessData = { beforeAll(async () => { browser = await puppeteer.launch({ - headless: false, + headless: true, }); }); @@ -51,8 +51,8 @@ describe('Login', () => { test('Login failed with wrong password', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputusername, loginFailedData.username); - await page.type(domSelectors.inputpassword, loginFailedData.password); + await page.type(domSelectors.inputUsername, loginFailedData.username); + await page.type(domSelectors.inputPassword, loginFailedData.password); await page.click(domSelectors.buttonLogin); await page.waitForSelector(domSelectors.loginFailedIcon); await page.close(); @@ -61,8 +61,8 @@ describe('Login', () => { test('Login failed with empty username password', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputusername, ''); - await page.type(domSelectors.inputpassword, ''); + await page.type(domSelectors.inputUsername, ''); + await page.type(domSelectors.inputPassword, ''); await page.click(domSelectors.buttonLogin); await page.waitForSelector('.ant-form-item-explain'); await page.close(); @@ -71,13 +71,14 @@ describe('Login', () => { test('Login success then Logout', async () => { const page = await browser.newPage(); await page.goto(BASE_URL); - await page.type(domSelectors.inputusername, loginSuccessData.username); - await page.type(domSelectors.inputpassword, loginSuccessData.password); + await page.type(domSelectors.inputUsername, loginSuccessData.username); + await page.type(domSelectors.inputPassword, loginSuccessData.password); await page.click(domSelectors.buttonLogin); await page.waitForSelector(domSelectors.loginSuccessIcon); await page.waitForNavigation(); await page.click(domSelectors.userProfile); await page.waitForSelector(domSelectors.dropdownMenuItem); + await page.waitForSelector(domSelectors.logoutButton); await page.click(domSelectors.logoutButton); await page.waitForNavigation(); await page.close(); diff --git a/frontend/src/e2e/README.md b/frontend/src/e2e/README.md index 6e9e9b5ad5..b211b01c47 100644 --- a/frontend/src/e2e/README.md +++ b/frontend/src/e2e/README.md @@ -19,23 +19,23 @@ ### Writing test cases -1. Installing dependencies and running local development environments +1. Install dependencies then run in development mode - ```sh - yarn install && yarn start - ``` +```sh +$ yarn install && yarn start +``` -2. Add a new test case file to the `src/e2e` folder +2. Add a new test case file under the `src/e2e` folder 3. Run test cases - ```sh - yarn test - ``` +```sh +$ yarn test +``` - If you want to run a particular test file separately, you can execute the following command +If you want to run a particular test file separately, you can execute the following command - ```sh - yarn test ${yourFileName}.e2e.js - ``` +```sh +$ yarn test ${yourFileName}.e2e.js +``` - The test results will be displayed on the console. +The test results will be displayed on the console. diff --git a/frontend/src/e2e/README.zh-CN.md b/frontend/src/e2e/README.zh-CN.md index debac21ccb..e2f671b132 100644 --- a/frontend/src/e2e/README.zh-CN.md +++ b/frontend/src/e2e/README.zh-CN.md @@ -21,21 +21,21 @@ 1. 安装依赖并运行本地开发环境 - ```sh - yarn install && yarn start - ``` +```sh +$ yarn install && yarn start +``` 2. 在 `src/e2e` 文件夹增加新的测试案例文件 3. 运行测试案例 - ```sh - yarn test - ``` +```sh +$ yarn test +``` - 如果你想单独运行某一个测试文件,可以执行如下命令 +如果你想单独运行某一个测试文件,可以执行如下命令 - ```sh - yarn test ${yourFileName}.e2e.js - ``` +```sh +$ yarn test ${yourFileName}.e2e.js +``` - 测试结果将会在控制台显示。 +测试结果将会在控制台显示。 From 72bbbe139c1b1a612fe1499b560faff1faefd7d2 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Mon, 2 Nov 2020 12:17:04 +0800 Subject: [PATCH 15/20] feat: added public.js --- .../{LoginAndLogout.e2e.js => Login.e2e.js} | 31 +++------- frontend/src/e2e/Logout.e2e.js | 56 +++++++++++++++++++ frontend/src/e2e/public.js | 39 +++++++++++++ 3 files changed, 103 insertions(+), 23 deletions(-) rename frontend/src/e2e/{LoginAndLogout.e2e.js => Login.e2e.js} (66%) create mode 100644 frontend/src/e2e/Logout.e2e.js create mode 100644 frontend/src/e2e/public.js diff --git a/frontend/src/e2e/LoginAndLogout.e2e.js b/frontend/src/e2e/Login.e2e.js similarity index 66% rename from frontend/src/e2e/LoginAndLogout.e2e.js rename to frontend/src/e2e/Login.e2e.js index a22dc21ae6..e566df56fd 100644 --- a/frontend/src/e2e/LoginAndLogout.e2e.js +++ b/frontend/src/e2e/Login.e2e.js @@ -18,32 +18,27 @@ /* eslint-disable import/no-extraneous-dependencies */ const puppeteer = require('puppeteer'); +const { + setupLogin, + BASE_URL +} = require('./public') + let browser; -const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; const domSelectors = { inputUsername: '#control-ref_username', inputPassword: '#control-ref_password', buttonLogin: '.ant-btn-lg', - notificationNotice: '.ant-notification-notice', - notificationLogin: '.ant-notification-notice-description', - loginSuccessIcon: '.ant-notification-notice-icon-success', loginFailedIcon: '.ant-notification-notice-icon-error', - userProfile: '.ant-space-horizontal div:nth-child(2)', - dropdownMenuItem: '.ant-dropdown-menu-item', - logoutButton: '.ant-dropdown-menu-item span[aria-label="logout"]', }; const loginFailedData = { username: 'admin', password: '123456', }; -const loginSuccessData = { - username: 'admin', - password: 'admin', -}; beforeAll(async () => { browser = await puppeteer.launch({ headless: true, + slowMo: 100 }); }); @@ -68,19 +63,9 @@ describe('Login', () => { await page.close(); }, 10000); - test('Login success then Logout', async () => { + test('Login success', async () => { const page = await browser.newPage(); - await page.goto(BASE_URL); - await page.type(domSelectors.inputUsername, loginSuccessData.username); - await page.type(domSelectors.inputPassword, loginSuccessData.password); - await page.click(domSelectors.buttonLogin); - await page.waitForSelector(domSelectors.loginSuccessIcon); - await page.waitForNavigation(); - await page.click(domSelectors.userProfile); - await page.waitForSelector(domSelectors.dropdownMenuItem); - await page.waitForSelector(domSelectors.logoutButton); - await page.click(domSelectors.logoutButton); - await page.waitForNavigation(); + await setupLogin(page); await page.close(); }, 10000); diff --git a/frontend/src/e2e/Logout.e2e.js b/frontend/src/e2e/Logout.e2e.js new file mode 100644 index 0000000000..718dbbbecb --- /dev/null +++ b/frontend/src/e2e/Logout.e2e.js @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* eslint-disable import/no-extraneous-dependencies */ +const puppeteer = require('puppeteer'); + +const { + setupLogin +} = require('./public') + +let browser +const domSelectors = { + userProfile: '.ant-space-horizontal div:nth-child(2)', + dropdownMenuItem: '.ant-dropdown-menu-item', + buttonLogin:".ant-btn-lg", + logoutButton: '.ant-dropdown > ul > li:nth-child(3)', +}; + +describe('Logout', () => { + +beforeAll(async () => { + browser = await puppeteer.launch({ + headless: true, + slowMo: 100 + }); +}); + +test('Logout', async () => { + const page = await browser.newPage(); + await setupLogin(page) + await page.click(domSelectors.userProfile); + await page.waitForSelector(domSelectors.dropdownMenuItem); + await page.waitForSelector(domSelectors.logoutButton); + await page.click(domSelectors.logoutButton); + await page.waitForSelector(domSelectors.buttonLogin); + await page.close(); +}, 10000); + +afterAll(async () => { + await browser.close(); +}); +}); diff --git a/frontend/src/e2e/public.js b/frontend/src/e2e/public.js new file mode 100644 index 0000000000..4a823fc2f3 --- /dev/null +++ b/frontend/src/e2e/public.js @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; + +const loginSuccessData = { + username: 'admin', + password: 'admin', + }; + +const domSelectors = { + inputUsername: '#control-ref_username', + inputPassword: '#control-ref_password', + buttonLogin: '.ant-btn-lg', + loginSuccessIcon: '.ant-notification-notice-icon-success', + }; + +export const setupLogin = async (page)=>{ + await page.goto(BASE_URL); + await page.type(domSelectors.inputUsername, loginSuccessData.username); + await page.type(domSelectors.inputPassword, loginSuccessData.password); + await page.click(domSelectors.buttonLogin); + await page.waitForSelector(domSelectors.loginSuccessIcon); + await page.waitForNavigation(); +} From 24e3394aedfc178508ee74995339b2c4dbe6c0c5 Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Mon, 2 Nov 2020 12:28:04 +0800 Subject: [PATCH 16/20] feat: change logout timeout --- frontend/src/e2e/Logout.e2e.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/e2e/Logout.e2e.js b/frontend/src/e2e/Logout.e2e.js index 718dbbbecb..400e106192 100644 --- a/frontend/src/e2e/Logout.e2e.js +++ b/frontend/src/e2e/Logout.e2e.js @@ -48,7 +48,7 @@ test('Logout', async () => { await page.click(domSelectors.logoutButton); await page.waitForSelector(domSelectors.buttonLogin); await page.close(); -}, 10000); +}, 50000); afterAll(async () => { await browser.close(); From 76c7a9133b89906f9458ae093daf65d6dec0dfbe Mon Sep 17 00:00:00 2001 From: litesun <7sunmiao@gmail.com> Date: Mon, 2 Nov 2020 15:06:41 +0800 Subject: [PATCH 17/20] feat: Added e2e test documentation link to development.md --- docs/develop.md | 2 ++ docs/develop.zh-CN.md | 2 ++ frontend/src/e2e/Login.e2e.js | 2 +- frontend/src/e2e/Logout.e2e.js | 42 +++++++++++----------- frontend/src/e2e/{public.js => service.js} | 30 ++++++++-------- 5 files changed, 41 insertions(+), 37 deletions(-) rename frontend/src/e2e/{public.js => service.js} (60%) diff --git a/docs/develop.md b/docs/develop.md index 54431cea59..301b12f54a 100644 --- a/docs/develop.md +++ b/docs/develop.md @@ -35,6 +35,8 @@ $ yarn install ```sh $ yarn start ``` +### wirte e2e test case +Please refer to [e2e documentation](../frontend/src/e2e/README.md). ## manager-api diff --git a/docs/develop.zh-CN.md b/docs/develop.zh-CN.md index 99f02535d9..91259075b3 100644 --- a/docs/develop.zh-CN.md +++ b/docs/develop.zh-CN.md @@ -38,6 +38,8 @@ $ yarn install ```sh $ yarn start ``` +### 编写 e2e 测试案例 +请参考 [e2e 文档](../frontend/src/e2e/README.zh-CN.md)。 ## manager-api 开发 diff --git a/frontend/src/e2e/Login.e2e.js b/frontend/src/e2e/Login.e2e.js index e566df56fd..1829daa912 100644 --- a/frontend/src/e2e/Login.e2e.js +++ b/frontend/src/e2e/Login.e2e.js @@ -21,7 +21,7 @@ const puppeteer = require('puppeteer'); const { setupLogin, BASE_URL -} = require('./public') +} = require('./service') let browser; const domSelectors = { diff --git a/frontend/src/e2e/Logout.e2e.js b/frontend/src/e2e/Logout.e2e.js index 400e106192..cef92cfd26 100644 --- a/frontend/src/e2e/Logout.e2e.js +++ b/frontend/src/e2e/Logout.e2e.js @@ -20,37 +20,37 @@ const puppeteer = require('puppeteer'); const { setupLogin -} = require('./public') +} = require('./service') -let browser +let browser; const domSelectors = { userProfile: '.ant-space-horizontal div:nth-child(2)', dropdownMenuItem: '.ant-dropdown-menu-item', - buttonLogin:".ant-btn-lg", + buttonLogin: ".ant-btn-lg", logoutButton: '.ant-dropdown > ul > li:nth-child(3)', }; describe('Logout', () => { -beforeAll(async () => { - browser = await puppeteer.launch({ - headless: true, - slowMo: 100 + beforeAll(async () => { + browser = await puppeteer.launch({ + headless: true, + slowMo: 100 + }); }); -}); -test('Logout', async () => { - const page = await browser.newPage(); - await setupLogin(page) - await page.click(domSelectors.userProfile); - await page.waitForSelector(domSelectors.dropdownMenuItem); - await page.waitForSelector(domSelectors.logoutButton); - await page.click(domSelectors.logoutButton); - await page.waitForSelector(domSelectors.buttonLogin); - await page.close(); -}, 50000); + test('Logout', async () => { + const page = await browser.newPage(); + await setupLogin(page); + await page.click(domSelectors.userProfile); + await page.waitForSelector(domSelectors.dropdownMenuItem); + await page.waitForSelector(domSelectors.logoutButton); + await page.click(domSelectors.logoutButton); + await page.waitForSelector(domSelectors.buttonLogin); + await page.close(); + }, 50000); -afterAll(async () => { - await browser.close(); -}); + afterAll(async () => { + await browser.close(); + }); }); diff --git a/frontend/src/e2e/public.js b/frontend/src/e2e/service.js similarity index 60% rename from frontend/src/e2e/public.js rename to frontend/src/e2e/service.js index 4a823fc2f3..84bfcb0d5d 100644 --- a/frontend/src/e2e/public.js +++ b/frontend/src/e2e/service.js @@ -18,22 +18,22 @@ export const BASE_URL = `http://localhost:${process.env.PORT || 8000}`; const loginSuccessData = { - username: 'admin', - password: 'admin', - }; + username: 'admin', + password: 'admin', +}; const domSelectors = { - inputUsername: '#control-ref_username', - inputPassword: '#control-ref_password', - buttonLogin: '.ant-btn-lg', - loginSuccessIcon: '.ant-notification-notice-icon-success', - }; + inputUsername: '#control-ref_username', + inputPassword: '#control-ref_password', + buttonLogin: '.ant-btn-lg', + loginSuccessIcon: '.ant-notification-notice-icon-success', +}; -export const setupLogin = async (page)=>{ - await page.goto(BASE_URL); - await page.type(domSelectors.inputUsername, loginSuccessData.username); - await page.type(domSelectors.inputPassword, loginSuccessData.password); - await page.click(domSelectors.buttonLogin); - await page.waitForSelector(domSelectors.loginSuccessIcon); - await page.waitForNavigation(); +export const setupLogin = async (page) => { + await page.goto(BASE_URL); + await page.type(domSelectors.inputUsername, loginSuccessData.username); + await page.type(domSelectors.inputPassword, loginSuccessData.password); + await page.click(domSelectors.buttonLogin); + await page.waitForSelector(domSelectors.loginSuccessIcon); + await page.waitForNavigation(); } From 40b9a26846e1f7ba2292e48222a538a65b34f01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=90=9A=E8=87=B4=E8=BF=9C?= Date: Mon, 2 Nov 2020 23:47:53 +0800 Subject: [PATCH 18/20] Update develop.md --- docs/develop.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/develop.md b/docs/develop.md index 301b12f54a..c09867f7a0 100644 --- a/docs/develop.md +++ b/docs/develop.md @@ -35,8 +35,10 @@ $ yarn install ```sh $ yarn start ``` -### wirte e2e test case -Please refer to [e2e documentation](../frontend/src/e2e/README.md). + +### Add E2E test cases + +Please refer to [E2E Documentation](../frontend/src/e2e/README.md). ## manager-api From 0a5c9f04173d2d1990fdc5e41bae5f177aa74825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=90=9A=E8=87=B4=E8=BF=9C?= Date: Mon, 2 Nov 2020 23:48:32 +0800 Subject: [PATCH 19/20] Update develop.zh-CN.md --- docs/develop.zh-CN.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/develop.zh-CN.md b/docs/develop.zh-CN.md index 91259075b3..a30ddfe635 100644 --- a/docs/develop.zh-CN.md +++ b/docs/develop.zh-CN.md @@ -38,8 +38,10 @@ $ yarn install ```sh $ yarn start ``` -### 编写 e2e 测试案例 -请参考 [e2e 文档](../frontend/src/e2e/README.zh-CN.md)。 + +### 编写 E2E 测试案例 + +请参考 [E2E 文档](../frontend/src/e2e/README.zh-CN.md)。 ## manager-api 开发 From 99cdf74a9f5bbc1d70ba8b51613709e5648e7808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=90=9A=E8=87=B4=E8=BF=9C?= Date: Mon, 2 Nov 2020 23:49:16 +0800 Subject: [PATCH 20/20] Update README.md --- frontend/src/e2e/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/e2e/README.md b/frontend/src/e2e/README.md index b211b01c47..fc5d609062 100644 --- a/frontend/src/e2e/README.md +++ b/frontend/src/e2e/README.md @@ -17,7 +17,7 @@ # --> -### Writing test cases +### Add E2E test cases 1. Install dependencies then run in development mode