Skip to content

Commit 3443933

Browse files
author
fanniehuang
committed
feat(e2e): 测试案例执行完毕,生网页版成测试报告
re #80
1 parent 6b6f50e commit 3443933

File tree

18 files changed

+20054
-30
lines changed

18 files changed

+20054
-30
lines changed

packages/wxa-cli/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@webank/wxa-cli2-apple",
3-
"version": "1.0.65",
3+
"version": "1.0.67",
44
"description": "cli for wxa development",
55
"main": "dist/wxa.js",
66
"scripts": {
@@ -66,11 +66,12 @@
6666
"htmlparser2": "^3.10.1",
6767
"inquirer": "^6.2.0",
6868
"js-base64": "^2.4.0",
69-
"lodash": "^4.17.15",
7069
"json5": "^2.1.1",
70+
"lodash": "^4.17.15",
7171
"mkdirp": "^0.5.1",
7272
"mockjs": "^1.1.0",
7373
"node-notifier": "^5.2.1",
74+
"open": "^8.0.6",
7475
"postcss": "^7.0.27",
7576
"postcss-pxtorpx-pro": "^1.0.0",
7677
"promise.prototype.finally": "^3.1.0",

packages/wxa-cli/scripts/buildLib.sh

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
# npx webpack "./lib/shim/promise.finally.js" --mode production --env.platform=node -o ./lib-dist/es/promise.finally.js
22

3-
rm -f ./dist/tester/wxa-e2eTest/e2eTestCaseTpl.ejs
4-
rm -f ./dist/tester/wxa-e2eTest/e2eTpl.ejs
5-
rm -f ./dist/tester/imageSimilarity/dHash.py
6-
rm -f ./dist/tester/imageSimilarity/init.py
3+
# rm -f ./dist/tester/wxa-e2eTest/e2eTestCaseTpl.ejs
4+
# rm -f ./dist/tester/wxa-e2eTest/e2eTpl.ejs
5+
# rm -f ./dist/tester/wxa-e2eTest/e2eResultTpl.ejs
6+
# rm -f ./dist/tester/imageSimilarity/dHash.py
7+
# rm -f ./dist/tester/imageSimilarity/init.py
78
rm -rf ./lib-dist/wxa-e2eTest
9+
rm -rf ./dist/tester/wxa-e2eTest/staticWeb
10+
811
mkdir -p ./lib-dist/wxa-e2eTest
912
mkdir -p ./dist/tester/wxa-e2eTest
1013
mkdir -p ./dist/tester/imageSimilarity
11-
ln ./src/tester/wxa-e2eTest/state.js ./lib-dist/wxa-e2eTest/state.js
12-
ln ./src/tester/wxa-e2eTest/e2eTestSuite.js ./lib-dist/wxa-e2eTest/e2eTestSuite.js
13-
ln ./src/tester/wxa-e2eTest/e2eMockWxMethod.js ./lib-dist/wxa-e2eTest/e2eMockWxMethod.js
14-
ln ./src/tester/wxa-e2eTest/e2eRecordBtn.wxa ./lib-dist/wxa-e2eTest/e2eRecordBtn.wxa
15-
ln ./src/tester/wxa-e2eTest/e2eTestCaseTpl.ejs ./dist/tester/wxa-e2eTest/e2eTestCaseTpl.ejs
16-
ln ./src/tester/wxa-e2eTest/e2eTpl.ejs ./dist/tester/wxa-e2eTest/e2eTpl.ejs
17-
18-
ln ./src/tester/imageSimilarity/dHash.py ./dist/tester/imageSimilarity/dHash.py
19-
ln ./src/tester/imageSimilarity/init.py ./dist/tester/imageSimilarity/init.py
14+
15+
ln -fs ../../../src/tester/wxa-e2eTest/staticWeb ./dist/tester/wxa-e2eTest/staticWeb
16+
ln -f ./src/tester/wxa-e2eTest/state.js ./lib-dist/wxa-e2eTest/state.js
17+
ln -f ./src/tester/wxa-e2eTest/e2eTestSuite.js ./lib-dist/wxa-e2eTest/e2eTestSuite.js
18+
ln -f ./src/tester/wxa-e2eTest/e2eMockWxMethod.js ./lib-dist/wxa-e2eTest/e2eMockWxMethod.js
19+
ln -f ./src/tester/wxa-e2eTest/e2eRecordBtn.wxa ./lib-dist/wxa-e2eTest/e2eRecordBtn.wxa
20+
ln -f ./src/tester/wxa-e2eTest/e2eTestCaseTpl.ejs ./dist/tester/wxa-e2eTest/e2eTestCaseTpl.ejs
21+
ln -f ./src/tester/wxa-e2eTest/e2eTpl.ejs ./dist/tester/wxa-e2eTest/e2eTpl.ejs
22+
23+
ln -f ./src/tester/imageSimilarity/dHash.py ./dist/tester/imageSimilarity/dHash.py
24+
ln -f ./src/tester/imageSimilarity/init.py ./dist/tester/imageSimilarity/init.py
25+
ln -f ./src/tester/wxa-e2eTest/e2eResultTpl.ejs ./dist/tester/wxa-e2eTest/e2eResultTpl.ejs
2026

2127
echo $MODE;
2228
if test "$MODE" = 'dev'

packages/wxa-cli/src/tester/imageSimilarity/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,4 @@ export function diff(timeStamp, caseList) {
1313
execSync(`${executable[process.platform]} "${pyPath}" ${timeStamp} ${argv}`, {
1414
stdio: 'inherit',
1515
});
16-
return process.exit(0);
1716
}

packages/wxa-cli/src/tester/imageSimilarity/init.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ def GetDirList(self, cur_path, cur_type):
8686
生成结果
8787
'''
8888
def WriteFile(self, out_dir):
89-
json_path = os.path.join(target_path, ".replay_result", out_dir, "diff_result.json")
90-
if os.path.exists(json_path):
91-
os.remove(json_path)
92-
with open(json_path, 'xt', encoding='utf-8') as f:
93-
f.write(json.dumps(self.case_result,ensure_ascii=False,sort_keys=True, indent=4))
89+
js_path = os.path.join(target_path, ".replay_result", out_dir, "py_diff_result.js")
90+
if os.path.exists(js_path):
91+
os.remove(js_path)
92+
with open(js_path, 'xt', encoding='utf-8') as f:
93+
f.write("var py_diff_result = " + json.dumps(self.case_result,ensure_ascii=False,sort_keys=True, indent=4))
9494

9595
def FilterFun(self, item):
9696
if item in self.argv:
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<link href="./static/antd.min.css" rel="stylesheet" type="text/css">
5+
<link href="./static/style.css" rel="stylesheet" type="text/css">
6+
</head>
7+
<body>
8+
<div id="app">
9+
<a-layout>
10+
<a-layout-header class="header">
11+
<div style="color: #fff;">测试案例执行时间:{{time}}</div>
12+
</a-layout-header>
13+
<a-layout-content style="padding: 20px 0 50px">
14+
<a-layout style="padding: 24px 0; background: #fff">
15+
<a-layout-sider width="200" style="background: #fff">
16+
<a-menu
17+
mode="inline"
18+
style="height: 100%"
19+
@click="clickMenu"
20+
>
21+
<a-menu-item :key="index" v-for="(item,index) in testCase">
22+
<div v-if="item.diffIndex.length !== 0" class="font-red">执行失败:{{item.name}}</div>
23+
<div v-else style="color: rgb(120,199,86)">执行成功:{{item.name}}</div>
24+
</a-menu-item>
25+
</a-menu>
26+
</a-layout-sider>
27+
<a-layout-content :style="{ margin: '24px 24px 24px', overflow: 'initial', background: '#fff' }">
28+
<a-collapse
29+
:default-active-key="['1','2']">
30+
<a-collapse-panel key="1" header="执行失败的步骤截屏" v-if="currentTestCase.diffImgSrc.length > 0">
31+
<template v-for="item in currentTestCase.diffImgSrc">
32+
<a-space>
33+
<a-card title="diff高亮图" style="width: 300px">
34+
35+
<a-image :width="250" :src="item.diff" />
36+
</a-card>
37+
<a-card title="本次截屏" style="width: 300px">
38+
<a-image :width="250":src="item.current" />
39+
</a-card>
40+
<a-card title="比较基准截屏" style="width: 300px">
41+
<a-image :width="250" :src="item.base" />
42+
</a-card>
43+
</a-space>
44+
</template>
45+
</a-collapse-panel>
46+
<a-collapse-panel key="2" header="本次案例全步骤截屏" :disabled="false">
47+
<a-card v-for="(item,index) in currentTestCase.imgSrc" :title="`步骤${index+1}截屏`" style="width: 300px;display: inline-block;margin-bottom: 10px;margin-right: 10px">
48+
<a-image :width="250" :src="item" />
49+
</a-card>
50+
51+
</a-collapse-panel>
52+
</a-layout-content>
53+
</a-layout>
54+
</a-layout-content>
55+
<a-layout-footer style="text-align: center">
56+
wxa e2e ©2021 Created by mumbleFe
57+
</a-layout-footer>
58+
</a-layout>
59+
</div>
60+
<script src="./static/[email protected]"></script>
61+
<script src="./static/moment.js"></script>
62+
<script src="./static/antd.min.js"></script>
63+
<script src="../.replay_result/<%- time%>/py_diff_result.js"></script>
64+
<script>
65+
66+
let time = '<%- time%>';
67+
let diffFailValue = 1000;
68+
let testCase = JSON.parse('<%- testCase %>');
69+
var app = Vue.createApp({
70+
data(){
71+
if (typeof py_diff_result !== 'undefined' && py_diff_result[time]) {
72+
py_diff_result[time].forEach(pyDiffItem => {
73+
var cur_case = testCase.find((testCaseItem) => {
74+
return testCaseItem.name === pyDiffItem.case_name
75+
})
76+
if (!cur_case) return;
77+
var diffIndex = [];
78+
for (let i = 0; i < cur_case.totalScreenCount; i++) {
79+
let cur_diffItem = pyDiffItem[`${i}.png`];
80+
if (!cur_diffItem) {
81+
return diffIndex.push(i);
82+
}
83+
if (cur_diffItem.diff_result > diffFailValue) {
84+
return diffIndex.push(i);
85+
}
86+
}
87+
cur_case.diffIndex = diffIndex;
88+
})
89+
}
90+
return {
91+
time,
92+
testCase,
93+
selectedKeys: ''
94+
}
95+
},
96+
created() {
97+
this.testCase.forEach(item => {
98+
item.diffImgSrc = [];
99+
if (item.diffIndex && item.diffIndex.length !== 0) {
100+
item.diffIndex.forEach(diffIndexItem => {
101+
item.diffImgSrc.push({
102+
diff: `../.replay_result/${this.time}/${item.name}/screenshot/diff/${diffIndexItem}.png`,
103+
base: `../${item.name}/base_screenshot/${diffIndexItem}.png`,
104+
current: `../.replay_result/${this.time}/${item.name}/screenshot/${diffIndexItem}.png`,
105+
})
106+
})
107+
}
108+
item.imgSrc = [];
109+
for (let i = 0; i < item.totalScreenCount; i++) {
110+
if (this.time === 'base_screenshot') {
111+
item.imgSrc.push(`../${item.name}/${this.time}/${i}.png`)
112+
} else {
113+
item.imgSrc.push(`../.replay_result/${this.time}/${item.name}/screenshot/${i}.png`)
114+
}
115+
116+
}
117+
})
118+
},
119+
computed: {
120+
currentTestCase() {
121+
return this.testCase[this.selectedKeys] || this.testCase[0]
122+
}
123+
},
124+
methods: {
125+
clickMenu(e) {
126+
this.selectedKeys = e.key
127+
}
128+
}
129+
})
130+
app.use(antd.Layout)
131+
app.use(antd.Card)
132+
app.use(antd.Row)
133+
app.use(antd.Col)
134+
app.use(antd.Image)
135+
app.use(antd.Menu)
136+
app.use(antd.PageHeader)
137+
app.use(antd.Collapse)
138+
app.use(antd.Space)
139+
140+
app.mount('#app')
141+
</script>
142+
</body>
143+
</html>

packages/wxa-cli/src/tester/wxa-e2eTest/e2eTestCase2js.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,19 @@ const e2eStartTools = (data) => {
2424
});
2525
};
2626

27+
const e2eStaticWeb2js = (data) => {
28+
return new Promise((resolve, reject) => {
29+
ejs.renderFile(path.join(__dirname, './e2eResultTpl.ejs'), data, (err, str) => {
30+
if (err) {
31+
return reject(err);
32+
}
33+
resolve(str);
34+
});
35+
});
36+
};
2737

2838
module.exports = {
2939
e2eRecord2js,
3040
e2eStartTools,
41+
e2eStaticWeb2js
3142
};

packages/wxa-cli/src/tester/wxa-e2eTest/runTestCase.js

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import {formatDate, writeFile} from '../../utils';
22
import path from 'path';
33
import fs from 'fs';
4-
import {e2eRecord2js} from './e2eTestCase2js.js';
4+
import {e2eRecord2js, e2eStaticWeb2js} from './e2eTestCase2js.js';
55
import {exec, execSync} from 'child_process';
66
import e2eMockWxMethod from './e2eMockWxMethod';
77
import {diff as pyDiff} from '../imageSimilarity/index.js';
8+
import open from 'open';
9+
810
// -t 跑测试用例
911
// -s --screenshot 进行截屏比对
1012
// --base 截屏作为expected基准,不对截屏进行比对
1113
export default async function(cmd, wxaConfigs) {
12-
1314
const sleep = t => new Promise(resolve => setTimeout(resolve, t));
1415
let testDir = path.join(process.cwd(), cmd.outDir);
1516
// --test=“xxx”指定用例,或--test默认执行outDir下所有用例
@@ -86,13 +87,42 @@ export default async function(cmd, wxaConfigs) {
8687
execSync(`npx jest ${path.join(testDir, '.cache', 'index.test.js').split(path.sep).join('/')}`, {
8788
stdio: 'inherit'
8889
});
89-
if (cmd.pyDiff && !cmd.base && !cmd.record) {
90-
pyDiff(screenshotPath, testCaseNameArr)
91-
}
92-
process.exit(0);
9390
} catch(err) {
94-
process.exit(-1);
9591
}
96-
97-
92+
if (cmd.pyDiff && !cmd.base && !cmd.record) {
93+
pyDiff(screenshotPath, testCaseNameArr)
94+
}
95+
let testCase = [];
96+
testCaseNameArr.forEach((item) => {
97+
let baseDir = path.join(testDir, item, 'base_screenshot')
98+
let currentDiffDir = path.join(testDir, '.replay_result', screenshotPath, item, 'screenshot', 'diff')
99+
let files = fs.readdirSync(baseDir);
100+
let diffIndex = [];
101+
if (!cmd.base && !cmd.record) {
102+
let diffFiles = fs.readdirSync(currentDiffDir);
103+
let diffIndex = [];
104+
diffFiles.forEach(item => {
105+
diffIndex.push(item.split('.')[0])
106+
})
107+
}
108+
testCase.push({
109+
name: item,
110+
totalScreenCount: files.length,
111+
diffIndex
112+
})
113+
})
114+
let staticWebString = await e2eStaticWeb2js({
115+
time: screenshotPath,
116+
testCase: JSON.stringify(testCase)
117+
})
118+
let docPath = path.join(testDir, '.doc', `${screenshotPath}.html`)
119+
writeFile(docPath, staticWebString)
120+
// 复制文档目录
121+
execSync(`cp -r ${path.join(__dirname, './staticWeb/staticFile')} ${path.join(testDir, '.doc', 'static')}`);
122+
console.log(`cp -r ${path.join(__dirname, './staticWeb/staticFile')} ${path.join(testDir, '.doc', 'static')}`)
123+
// 使用指定浏览器打开
124+
open(`${docPath}`, { app: {
125+
name: open.apps.chrome
126+
}});
127+
process.exit(0);
98128
}

0 commit comments

Comments
 (0)