提交 69328d0f 编写于 作者: P pissang

test(visual): add nightly version selection. save params in url

上级 378982ae
......@@ -77,8 +77,10 @@
.test-run-controls {
z-index: 1;
position: sticky;
width: 100%;
padding: 5px 20px;
top: 0px;
background: #896bda;
box-shadow: 0 0 20px rgb(0 0 0 / 20%);
......@@ -116,6 +118,7 @@
.run-config-item .label {
margin-right: 2px;
margin-left: 5px;
text-transform: uppercase;
}
......@@ -184,7 +187,7 @@
.test-result {
padding: 20px;
margin-top: 80px;
margin-top: 20px;
}
.test-result .el-progress__text {
......@@ -227,6 +230,8 @@
.test-screenshots .preview {
cursor: pointer;
color: #409eff;
float: right;
font-size: 20px;
}
.test-screenshots .preview:hover {
text-decoration: underline;
......
......@@ -18,7 +18,30 @@
*/
const socket = io('/client');
const LOCAL_SAVE_KEY = 'visual-regression-testing-config';
// const LOCAL_SAVE_KEY = 'visual-regression-testing-config';
function parseParams(str) {
if (!str) {
return {};
}
const parts = str.split('&');
const params = {};
parts.forEach((part) => {
const kv = part.split('=');
params[kv[0]] = decodeURIComponent(kv[1]);
});
return params;
}
function assembleParams(paramsObj) {
const paramsArr = [];
Object.keys(paramsObj).forEach((key) => {
let val = paramsObj[key];
paramsArr.push(key + '=' + encodeURIComponent(val));
});
return paramsArr.join('&');
}
function processTestsData(tests, oldTestsData) {
tests.forEach((test, idx) => {
......@@ -56,42 +79,64 @@ function processTestsData(tests, oldTestsData) {
return tests;
}
const storedConfig = {};
const urlParams = parseParams(window.location.search.substr(1))
// Save and restore
try {
const runConfig = JSON.parse(urlParams.runConfig);
Object.assign(storedConfig, runConfig);
}
catch (e) {}
const app = new Vue({
el: '#app',
data: {
fullTests: [],
currentTestName: '',
sortBy: 'name',
currentTestName: urlParams.test || '',
searchString: '',
running: false,
allSelected: false,
lastSelectedIndex: -1,
versions: [],
actualVersionsList: [],
expectedVersionsList: [],
loadingVersion: false,
showIframeDialog: false,
previewIframeSrc: '',
previewTitle: '',
runConfig: {
isNightly: false,
runConfig: Object.assign({
sortBy: 'name',
noHeadless: false,
replaySpeed: 5,
isActualNightly: false,
isExpectedNightly: false,
actualVersion: 'local',
expectedVersion: null,
renderer: 'canvas',
threads: 4
}
}, storedConfig)
},
mounted() {
this.fetchVersions();
this.fetchVersions(false);
this.fetchVersions(true);
setTimeout(() => {
this.scrollToCurrent();
}, 500);
},
computed: {
tests() {
let sortFunc = this.sortBy === 'name'
let sortFunc = this.runConfig.sortBy === 'name'
? (a, b) => a.name.localeCompare(b.name)
: (a, b) => {
if (a.percentage === b.percentage) {
......@@ -165,12 +210,40 @@ const app = new Vue({
set() {}
}
},
watch: {
'runConfig.isActualNightly'() {
this.fetchVersions(true);
},
'runConfig.isExpectedNightly'() {
this.fetchVersions(false);
},
'runConfig.sortBy'() {
setTimeout(() => {
this.scrollToCurrent();
}, 100);
}
},
methods: {
goto(url) {
window.location.hash = '#' + url;
scrollToCurrent() {
const el = document.querySelector(`.test-list>li[title="${this.currentTestName}"]`);
if (el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'center'
});
}
},
changeTest(target, testName) {
if (!target.matches('input[type="checkbox"]') && !target.matches('.el-checkbox__inner')) {
app.currentTestName = testName;
updateUrl(true);
}
},
toggleSort() {
this.sortBy = this.sortBy === 'name' ? 'percentage' : 'name';
this.runConfig.sortBy = this.runConfig.sortBy === 'name' ? 'percentage' : 'name';
},
handleSelectAllChange(val) {
// Only select filtered tests.
......@@ -238,38 +311,29 @@ const app = new Vue({
this.showIframeDialog = true;
},
fetchVersions() {
const url = this.runConfig.isNightly
fetchVersions(isActual) {
const prop = isActual ? 'actualVersionsList' : 'expectedVersionsList';
this[prop] = [];
const url = this.runConfig[isActual ? 'isActualNightly' : 'isExpectedNightly']
? 'https://data.jsdelivr.com/v1/package/npm/echarts-nightly'
: 'https://data.jsdelivr.com/v1/package/npm/echarts'
fetch(url, {
mode: 'cors'
}).then(res => res.json()).then(json => {
this.versions = json.versions;
// if (!this.runConfig.expectedVersion) {
// PENDING
// Always override the expected version with latest version
// Avoid forget to change the version to latest in the next release.
this.runConfig.expectedVersion = json.tags.latest;
// }
this[prop] = json.versions;
this[prop].unshift('local');
this.versions.unshift('local');
if (!isActual) {
if (!this[prop].includes(this.runConfig.expectedVersion)) {
this.runConfig.expectedVersion = json.tags.latest;
}
}
});
}
}
});
// Save and restore
try {
Object.assign(app.runConfig, JSON.parse(localStorage.getItem(LOCAL_SAVE_KEY)));
}
catch (e) {}
app.$watch('runConfig', () => {
localStorage.setItem(LOCAL_SAVE_KEY, JSON.stringify(app.runConfig));
}, {deep: true});
function runTests(tests) {
if (!tests.length) {
app.$notify({
......@@ -345,8 +409,30 @@ socket.on('abort', res => {
app.running = false;
});
function updateTestHash() {
app.currentTestName = window.location.hash.slice(1);
// function handleUrlChanged() {
// const params = parseParams(window.location.search.substr(1));
// app.currentTestName = params.test;
// try {
// Object.assign(app.runConfig, JSON.parse(params.runConfig));
// }
// catch (e) {}
// }
function updateUrl(notRefresh) {
const searchUrl = assembleParams({
test: app.currentTestName,
runConfig: JSON.stringify(app.runConfig)
});
if (notRefresh) {
history.pushState({}, '', location.pathname + '?' + searchUrl);
}
else {
window.location.search = '?' + searchUrl;
}
}
updateTestHash();
window.addEventListener('hashchange', updateTestHash);
\ No newline at end of file
// Only update url when version is changed.
app.$watch('runConfig.actualVersion', () => updateUrl());
app.$watch('runConfig.expectedVersion', () => updateUrl());
app.$watch('runConfig.renderer', () => updateUrl());
\ No newline at end of file
......@@ -55,7 +55,7 @@ under the License.
<li v-for="(test, index) in tests"
:title="test.name"
:class="{active: currentTest && currentTest.name === test.name}"
@click.self="goto(test.name)"
@click="changeTest($event.target, test.name)"
>
<span @mouseup="handleSelect(index)" @mouseup.shift="handleShiftSelect(index)">
<el-checkbox v-model="test.selected"></el-checkbox>
......@@ -105,7 +105,7 @@ under the License.
@click="run('selected')"
@command="run"
>
<i class="el-icon-caret-right"></i> Run ({{selectedTests.length}})
<i class="el-icon-caret-right"></i> RUN ({{selectedTests.length}})
<el-dropdown-menu slot="dropdown" >
<el-dropdown-item command="unfinished">Run unfinished ({{unfinishedTests.length}})</el-dropdown-item>
<el-dropdown-item command="failed">Run failed ({{failedTests.length}})</el-dropdown-item>
......@@ -132,17 +132,28 @@ under the License.
></el-slider>
</div> -->
<div class="run-config-item">
<span class="label">Expected</span>
<span class="label">
Expected
<el-tooltip content="Use Nightly Build">
<el-checkbox v-model="runConfig.isExpectedNightly" size="mini"></el-checkbox>
</el-tooltip>
</span>
<el-select size="mini" v-model="runConfig.expectedVersion" placeholder="Select Version"
style="width: 80px;"
:style="`width: ${runConfig.isExpectedNightly ? 160 : 80}px;`"
>
<el-option v-for="version in versions" :key="version" :label="version" :value="version"></el-option>
<el-option v-for="version in expectedVersionsList" :key="version" :label="version" :value="version"></el-option>
</el-select>
<span class="label">Actual</span>
<!-- <i class="el-icon-link"></i> -->
<span class="label">
Actual
<el-tooltip content="Use Nightly Build">
<el-checkbox v-model="runConfig.isActualNightly" size="mini"></el-checkbox>
</el-tooltip>
</span>
<el-select size="mini" v-model="runConfig.actualVersion" placeholder="Select Version"
style="width: 80px;"
:style="`width: ${runConfig.isActualNightly ? 160 : 80}px;`"
>
<el-option v-for="version in versions" :key="version" :label="version" :value="version"></el-option>
<el-option v-for="version in actualVersionsList" :key="version" :label="version" :value="version"></el-option>
</el-select>
</div>
<div class="run-config-item">
......
......@@ -67,9 +67,11 @@ module.exports.prepareEChartsLib = function (version) {
let testLibPath = `${versionFolder}/${module.exports.getEChartsTestFileName()}`;
if (!fs.existsSync(testLibPath)) {
const file = fs.createWriteStream(`${versionFolder}/echarts.js`);
const isNightly = version.includes('-dev');
const packageName = isNightly ? 'echarts-nightly' : 'echarts'
console.log(`Downloading echarts@${version} from `, `https://cdn.jsdelivr.net/npm/echarts@${version}/dist/echarts.js`);
https.get(`https://cdn.jsdelivr.net/npm/echarts@${version}/dist/echarts.js`, response => {
console.log(`Downloading ${packageName}@${version} from `, `https://cdn.jsdelivr.net/npm/${packageName}@${version}/dist/echarts.js`);
https.get(`https://cdn.jsdelivr.net/npm/${packageName}@${version}/dist/echarts.js`, response => {
response.pipe(file);
file.on('finish', () => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册