未验证 提交 0694d1a2 编写于 作者: Y Yi Shen 提交者: GitHub

Merge pull request #11229 from apache/test-autorun

Automatic visual regression testing tool: add preview dialog
...@@ -107,7 +107,7 @@ Then, open the test cases under `~/workspace/echarts/test` in Web browser. You c ...@@ -107,7 +107,7 @@ Then, open the test cases under `~/workspace/echarts/test` in Web browser. You c
```bash ```bash
# puppeteer is not in the devDependencies and needs to be installed manually # puppeteer is not in the devDependencies and needs to be installed manually
npm install puppeteer npm install puppeteer --no-save
npm run test:visual npm run test:visual
``` ```
......
...@@ -25,22 +25,32 @@ ...@@ -25,22 +25,32 @@
// `true` by default for debugging. // `true` by default for debugging.
sourceMap == null && (sourceMap = true); sourceMap == null && (sourceMap = true);
var params = {};
location.search.slice(1).split('&').forEach(item => {
var kv = item.split('=');
params[kv[0]] = kv[1];
});
// Set default renderer in dev mode from hash. // Set default renderer in dev mode from hash.
var matchResult = location.href.match(/[?&]__RENDERER__=(canvas|svg)(&|$)/); if (params.__RENDERER__) {
if (matchResult) { window.__ECHARTS__DEFAULT__RENDERER__ = params.__RENDERER__;
window.__ECHARTS__DEFAULT__RENDERER__ = matchResult[1];
} }
// Set echarts source code. // Set echarts source code.
var matchResult = location.href.match(/[?&]__ECDIST__=(webpack-req-ec|webpack-req-eclibec|webpackold-req-ec|webpackold-req-eclibec)(&|$)/); var ecDistPath;
var ecDistPath = 'dist/echarts'; if (params.__ECDIST__) {
if (matchResult) {
ecDistPath = ({ ecDistPath = ({
'webpack-req-ec': '../echarts-boilerplate/echarts-webpack/dist/webpack-req-ec', 'webpack-req-ec': '../echarts-boilerplate/echarts-webpack/dist/webpack-req-ec',
'webpack-req-eclibec': '../echarts-boilerplate/echarts-webpack/dist/webpack-req-eclibec', 'webpack-req-eclibec': '../echarts-boilerplate/echarts-webpack/dist/webpack-req-eclibec',
'webpackold-req-ec': '../echarts-boilerplate/echarts-webpackold/dist/webpackold-req-ec', 'webpackold-req-ec': '../echarts-boilerplate/echarts-webpackold/dist/webpackold-req-ec',
'webpackold-req-eclibec': '../echarts-boilerplate/echarts-webpackold/dist/webpackold-req-eclibec', 'webpackold-req-eclibec': '../echarts-boilerplate/echarts-webpackold/dist/webpackold-req-eclibec',
})[matchResult[1]]; })[params.__ECDIST__];
if (!ecDistPath && params.__ECDIST__.match(/[0-9.]/)) {
// Version number
ecDistPath = 'test/runTest/tmp/__version__/' + params.__ECDIST__ + '/echarts';
}
}
if (!ecDistPath) {
ecDistPath = 'dist/echarts';
} }
if (typeof require !== 'undefined') { if (typeof require !== 'undefined') {
......
...@@ -31,6 +31,9 @@ module.exports.blacklist = [ ...@@ -31,6 +31,9 @@ module.exports.blacklist = [
'scatter-gps.html', 'scatter-gps.html',
'webkit-dep.html', 'webkit-dep.html',
// Image size not match
'symbol2.html',
// This case will have timeout // This case will have timeout
'visualMap-performance1.html', 'visualMap-performance1.html',
'lines-bus.html', 'lines-bus.html',
......
...@@ -162,7 +162,7 @@ async function runTestPage(browser, testOpt, version, runtimeCode, isExpected) { ...@@ -162,7 +162,7 @@ async function runTestPage(browser, testOpt, version, runtimeCode, isExpected) {
timeout: 10000 timeout: 10000
}); });
await waitTime(200); // Wait for animation or something else. Pending await waitTime(500); // Wait for animation or something else. Pending
// Final shot. // Final shot.
await page.mouse.move(0, 0); await page.mouse.move(0, 0);
let desc = 'Full Shot'; let desc = 'Full Shot';
......
...@@ -170,6 +170,14 @@ ...@@ -170,6 +170,14 @@
margin-top: 60px; margin-top: 60px;
} }
.test-screenshots .preview {
cursor: pointer;
color: #409eff;
}
.test-screenshots .preview:hover {
text-decoration: underline;
}
.test-screenshots img { .test-screenshots img {
/* height: 200px; */ /* height: 200px; */
width: 100%; width: 100%;
...@@ -196,6 +204,11 @@ ...@@ -196,6 +204,11 @@
color: #f56c6c color: #f56c6c
} }
iframe {
border: none;
overflow: overlay;
}
::-webkit-scrollbar { ::-webkit-scrollbar {
height: 8px; height: 8px;
......
...@@ -70,6 +70,10 @@ const app = new Vue({ ...@@ -70,6 +70,10 @@ const app = new Vue({
versions: [], versions: [],
showIframeDialog: false,
previewIframeSrc: '',
previewTitle: '',
runConfig: { runConfig: {
noHeadless: false, noHeadless: false,
replaySpeed: 5, replaySpeed: 5,
...@@ -207,6 +211,25 @@ const app = new Vue({ ...@@ -207,6 +211,25 @@ const app = new Vue({
stopTests() { stopTests() {
this.running = false; this.running = false;
socket.emit('stop'); socket.emit('stop');
},
preview(test, version) {
let searches = [];
let ecVersion = test[version + 'Version'];
if (ecVersion !== 'local') {
searches.push('__ECDIST__=' + ecVersion);
}
if (test.useSVG) {
searches.push('__RENDERER__=svg');
}
let src = test.fileUrl;
if (searches.length) {
src = src + '?' + searches.join('&');
}
this.previewIframeSrc = `../../${src}`;
this.previewTitle = src;
this.showIframeDialog = true;
} }
} }
}); });
......
...@@ -175,8 +175,9 @@ under the License. ...@@ -175,8 +175,9 @@ under the License.
<el-card shadow="hover"> <el-card shadow="hover">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>Expected - {{currentTest.expectedVersion || ''}}</span> <span>Expected - {{currentTest.expectedVersion || ''}}</span>
<i title="Preview" class="el-icon-view preview" @click="preview(currentTest, 'expected')"></i>
</div> </div>
<el-image :src="result.expected"></el-image> <el-image :src="result.expected" :preview-src-list="[result.expected]"></el-image>
</el-card> </el-card>
</el-col> </el-col>
...@@ -184,8 +185,9 @@ under the License. ...@@ -184,8 +185,9 @@ under the License.
<el-card shadow="hover"> <el-card shadow="hover">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>Actual - {{currentTest.actualVersion || ''}}</span> <span>Actual - {{currentTest.actualVersion || ''}}</span>
<i title="Preview" class="el-icon-view preview" @click="preview(currentTest, 'actual')"></i>
</div> </div>
<el-image :src="result.actual"></el-image> <el-image :src="result.actual" :preview-src-list="[result.actual]"></el-image>
</el-card> </el-card>
</el-col> </el-col>
...@@ -194,7 +196,7 @@ under the License. ...@@ -194,7 +196,7 @@ under the License.
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>Diff - {{result.diffRatio.toFixed(4)}}</span> <span>Diff - {{result.diffRatio.toFixed(4)}}</span>
</div> </div>
<el-image :src="result.diff"></el-image> <el-image :src="result.diff" :preview-src-list="[result.diff]"></el-image>
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
...@@ -203,19 +205,11 @@ under the License. ...@@ -203,19 +205,11 @@ under the License.
<div class="test-errors"> <div class="test-errors">
<el-row :gutter="40"> <el-row :gutter="40">
<el-col :span="12"> <el-col :span="12">
<el-alert <el-alert title="Expected Errors" type="error" show-icon></el-alert>
title="Expected Errors"
type="error"
show-icon>
</el-alert>
<div class="error-item" v-for="error in currentTest.expectedErrors">{{error}}</div> <div class="error-item" v-for="error in currentTest.expectedErrors">{{error}}</div>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-alert <el-alert title="Actual Errors" type="error" show-icon> </el-alert>
title="Actual Errors"
type="error"
show-icon>
</el-alert>
<div class="error-item" v-for="error in currentTest.actualErrors">{{error}}</div> <div class="error-item" v-for="error in currentTest.actualErrors">{{error}}</div>
</el-col> </el-col>
</el-row> </el-row>
...@@ -224,28 +218,29 @@ under the License. ...@@ -224,28 +218,29 @@ under the License.
<div class="test-logs"> <div class="test-logs">
<el-row :gutter="40"> <el-row :gutter="40">
<el-col :span="12"> <el-col :span="12">
<el-alert <el-alert title="Expected Logs" type="info" show-icon> </el-alert>
title="Expected Logs"
type="info"
show-icon>
</el-alert>
<div class="log-item" v-for="log in currentTest.expectedLogs">{{log}}</div> <div class="log-item" v-for="log in currentTest.expectedLogs">{{log}}</div>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-alert <el-alert title="Actual Logs" type="info" show-icon>
title="Actual Logs"
type="info"
show-icon>
</el-alert> </el-alert>
<div class="log-item" v-for="log in currentTest.actualLogs">{{log}}</div> <div class="log-item" v-for="log in currentTest.actualLogs">{{log}}</div>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
</div>
<div class="test-result-nav"> <el-dialog
:visible.sync="showIframeDialog"
:center="true"
width="850px"
>
<div slot="title">
{{previewTitle}}
<a target="_blank" :href="'../../' + previewTitle"><i class="el-icon-link"></i>Open in New Window</a>
</div> </div>
</div> <iframe :src="previewIframeSrc" width="800" height="600"></iframe>
</el-dialog>
</el-main> </el-main>
</el-container> </el-container>
</el-container> </el-container>
......
...@@ -184,7 +184,7 @@ function checkPuppeteer() { ...@@ -184,7 +184,7 @@ function checkPuppeteer() {
async function start() { async function start() {
if (!checkPuppeteer()) { if (!checkPuppeteer()) {
// TODO Check version. // TODO Check version.
console.error(`Can't find puppeteer >= 1.19.0, use 'npm install puppeteer' to install or update`); console.error(`Can't find puppeteer >= 1.19.0, use 'npm install puppeteer --no-save' to install or update`);
return; return;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册