This is an automated email from the ASF dual-hosted git repository. shenyi pushed a commit to branch test-autorun in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/test-autorun by this push: new 2973d0c test: improve ui of recording screenshots. 2973d0c is described below commit 2973d0c9c74c9c3b0f463aa87a2e680ecd28c899 Author: pissang <bm2736...@gmail.com> AuthorDate: Sat Sep 7 23:55:36 2019 +0800 test: improve ui of recording screenshots. --- test/runTest/Timeline.js | 24 +++++++++++++++++---- test/runTest/cli.js | 44 +++++++++++++++++++------------------- test/runTest/client/client.css | 6 +++++- test/runTest/client/index.html | 13 ++++++----- test/runTest/recorder/index.html | 16 +++++++++----- test/runTest/recorder/recorder.css | 25 +++++++++++++++++++++- test/runTest/recorder/recorder.js | 32 +++++++++++++++++++++++++-- test/runTest/util.js | 10 ++++++++- 8 files changed, 129 insertions(+), 41 deletions(-) diff --git a/test/runTest/Timeline.js b/test/runTest/Timeline.js index 2151939..b227468 100644 --- a/test/runTest/Timeline.js +++ b/test/runTest/Timeline.js @@ -1,3 +1,5 @@ +const {waitTime} = require('./util'); + module.exports = class Timeline { constructor(page) { @@ -17,7 +19,7 @@ module.exports = class Timeline { } - async runAction(action, playbackSpeed) { + async runAction(action, takeScreenshot, playbackSpeed) { this.stop(); playbackSpeed = playbackSpeed || 1; @@ -45,7 +47,7 @@ module.exports = class Timeline { self._elapsedTime += dTime * playbackSpeed; self._current = current; - await self._update(); + await self._update(takeScreenshot); if (self._currentOpIndex >= self._ops.length) { // Finished resolve(); @@ -66,7 +68,7 @@ module.exports = class Timeline { } } - async _update() { + async _update(takeScreenshot) { let op = this._ops[this._currentOpIndex]; if (op.time > this._elapsedTime) { @@ -85,11 +87,25 @@ module.exports = class Timeline { await page.mouse.up(); break; case 'mousemove': - page.mouse.move(op.x, op.y); + await page.mouse.move(op.x, op.y); + break; + case 'screenshot': + await takeScreenshot(); break; } this._currentOpIndex++; + // If next op is an auto screenshot + let nextOp = this._ops[this._currentOpIndex]; + console.log(nextOp.type); + if (nextOp && nextOp.type === 'screenshot-auto') { + // TODO Configuration time + await waitTime(300); + console.log(Date.now()); + await takeScreenshot(); + console.log(Date.now()); + this._currentOpIndex++; + } } }; \ No newline at end of file diff --git a/test/runTest/cli.js b/test/runTest/cli.js index d0ac3bc..9f60116 100644 --- a/test/runTest/cli.js +++ b/test/runTest/cli.js @@ -5,7 +5,7 @@ const fs = require('fs'); const path = require('path'); const program = require('commander'); const compareScreenshot = require('./compareScreenshot'); -const {testNameFromFile, fileNameFromTest, getVersionDir, buildRuntimeCode} = require('./util'); +const {testNameFromFile, fileNameFromTest, getVersionDir, buildRuntimeCode, waitTime} = require('./util'); const {origin} = require('./config'); const Timeline = require('./Timeline'); @@ -48,19 +48,14 @@ function replaceEChartsVersion(interceptedRequest, version) { } } -function waitTime(time) { - return new Promise(resolve => { - setTimeout(() => { - resolve(); - }, time); - }); -} - -async function takeScreenshot(page, fullPage, fileUrl, desc, version) { +async function takeScreenshot(page, fullPage, fileUrl, desc, version, minor) { let screenshotName = testNameFromFile(fileUrl); if (desc) { screenshotName += '-' + slugify(desc, { replacement: '-', lower: true }); } + if (minor) { + screenshotName += '-' + minor; + } let screenshotPrefix = version ? 'expected' : 'actual'; fse.ensureDirSync(path.join(__dirname, getScreenshotDir())); let screenshotPath = path.join(__dirname, `${getScreenshotDir()}/${screenshotName}-${screenshotPrefix}.png`); @@ -91,14 +86,23 @@ async function runActions(page, testOpt, version, screenshots) { window.scrollTo(x, y); }, action.scrollX, action.scrollY); - await timeline.runAction(action, playbackSpeed); - // Wait for animation finished - // TODO Configuration. - await waitTime(action.wait == null ? 200 : action.wait); + let count = 0; + async function _innerTakeScreenshot() { + const desc = action.desc || action.name; + const {screenshotName, screenshotPath} = await takeScreenshot(page, false, testOpt.fileUrl, desc, version, count++); + screenshots.push({screenshotName, desc, screenshotPath}); + } + await timeline.runAction(action, _innerTakeScreenshot, playbackSpeed); - const desc = action.desc || action.name; - const {screenshotName, screenshotPath} = await takeScreenshot(page, false, testOpt.fileUrl, desc, version); - screenshots.push({screenshotName, desc, screenshotPath}); + if (count === 0) { + // TODO Configuration time + await waitTime(300); + await _innerTakeScreenshot(); + } + + // const desc = action.desc || action.name; + // const {screenshotName, screenshotPath} = await takeScreenshot(page, false, testOpt.fileUrl, desc, version); + // screenshots.push({screenshotName, desc, screenshotPath}); } timeline.stop(); } @@ -132,18 +136,14 @@ async function runTestPage(browser, testOpt, version, runtimeCode) { console.error(e); } + await waitTime(500); // Wait for animation or something else. // Final shot. let desc = 'Full Shot'; const {screenshotName, screenshotPath} = await takeScreenshot(page, true, fileUrl, desc, version); - screenshots.push({screenshotName, desc, screenshotPath}); await runActions(page, testOpt, version, screenshots); - if (!screenshots.length) { - waitTime(500); // Wait for animation or something else. - } - await page.close(); return { diff --git a/test/runTest/client/client.css b/test/runTest/client/client.css index 1991711..05d3ed9 100644 --- a/test/runTest/client/client.css +++ b/test/runTest/client/client.css @@ -108,10 +108,14 @@ } .test-screenshots { - margin-top: 80px; + margin-top: 20px; padding: 0 20px; } +.test-screenshots h4 { + margin-top: 60px; +} + .test-screenshots img { /* height: 200px; */ width: 100%; diff --git a/test/runTest/client/index.html b/test/runTest/client/index.html index 07880e0..7f0ccd0 100644 --- a/test/runTest/client/index.html +++ b/test/runTest/client/index.html @@ -69,11 +69,14 @@ <a target="_blank" :href="currentTestRecordUrl"><i class="el-icon-video-camera"></i>Record Interaction</a> </div> - <div class="test-screenshots" v-for="result in currentTest.results"> - <h4>{{result.desc || result.name}}</h4> + <div class="test-screenshots" v-for="(result, idx) in currentTest.results"> + <!-- Not display title if it's same with previous --> + <h4 v-if="result.desc !== (currentTest.results[idx - 1] && currentTest.results[idx - 1].desc)"> + {{result.desc || result.name}} + </h4> <el-row :gutter="40" class="screenshots"> <el-col :span="8"> - <el-card> + <el-card shadow="hover"> <div slot="header" class="clearfix"> <span>Expected</span> </div> @@ -82,7 +85,7 @@ </el-col> <el-col :span="8"> - <el-card> + <el-card shadow="hover"> <div slot="header" class="clearfix"> <span>Actual</span> </div> @@ -91,7 +94,7 @@ </el-col> <el-col :span="8"> - <el-card> + <el-card shadow="hover"> <div slot="header" class="clearfix"> <span>Diff({{result.diffRatio.toFixed(4)}})</span> </div> diff --git a/test/runTest/recorder/index.html b/test/runTest/recorder/index.html index 79e9a4e..3707cda 100644 --- a/test/runTest/recorder/index.html +++ b/test/runTest/recorder/index.html @@ -8,7 +8,7 @@ <body> <div id="app" style="display: none"> <iframe :src="url"></iframe> - <div id="recording-status" v-if="currentAction"> + <div id="recording-status"> <el-button :icon="recordingAction ? 'el-icon-video-camera' : 'el-icon-video-camera'" class="recording-button" circle :type="recordingAction ? 'danger' : 'info'" @@ -20,25 +20,31 @@ <el-card class="box-card"> <div slot="header" class="clearfix"> <span>Actions</span> - <div style="float:right"> + <div class="toolbar"> <el-button type="primary" size="mini" icon="el-icon-caret-right" circle @click="run"></el-button> <el-button type="primary" size="mini" icon="el-icon-circle-plus" @click="newAction">New</el-button> + + <el-popover title="Configuration" class="configuration"> + <div class="config-item"> + <el-checkbox v-model="config.screenshotAfterMouseUp">Auto screenshot after mouse up</el-checkbox> + </div> + <i slot="reference" class="el-icon-setting"></i> + </el-popover> </div> </div> <div v-for="action in actions" :class="{'action-item': true, 'active': action.name === currentAction.name}" @click.self="select(action.name)"> {{action.name}} - <div style="float:right" class="operations"> <el-popover> <div style="text-align: center">{ scrollX: {{action.scrollX}}, scrollY: {{action.scrollY}} }</div> <div v-for="op in action.ops" style="text-align: center">{{op}}</div> - <!-- <el-button slot="reference" size="mini">OP ({{action.ops.length}})</el-button> --> <div slot="reference"> <span>Data ({{action.ops.length}})</span> <i slot="reference" class="el-icon-caret-bottom"></i> </div> </el-popover> - <i slot="reference" class="el-icon-delete" @click="doDelete(action.name)"></i> + <i class="el-icon-delete" @click="doDelete(action.name)"></i> + <i class="el-icon-refresh-left" @click="clearOps(action.name)"></i> </div> </div> </el-card> diff --git a/test/runTest/recorder/recorder.css b/test/runTest/recorder/recorder.css index 2bce7aa..5769db7 100644 --- a/test/runTest/recorder/recorder.css +++ b/test/runTest/recorder/recorder.css @@ -104,6 +104,25 @@ iframe { width: 300px; } +#actions .toolbar { + float: right; + margin-top: -5px; +} + +#actions .toolbar>* { + display: inline-block; + vertical-align: middle; +} +#actions .toolbar i.el-icon-setting { + font-size: 20px; + cursor: pointer; + margin-left: 10px; +} + +#actions .toolbar .config-item { + margin: 5px 0; +} + #actions .action-item { line-height: 40px; padding: 0 20px; @@ -111,7 +130,7 @@ iframe { cursor: pointer; } - +\ #actions .action-item:hover { background: #eee; } @@ -129,6 +148,10 @@ iframe { display: inline-block; vertical-align: middle; } +#actions .action-item .operations i { + margin-left: 5px; + font-size: 18px; +} #actions .action-item .operations .el-icon-delete { color: #F56C6C; diff --git a/test/runTest/recorder/recorder.js b/test/runTest/recorder/recorder.js index 548e2a6..60d88fb 100644 --- a/test/runTest/recorder/recorder.js +++ b/test/runTest/recorder/recorder.js @@ -10,6 +10,9 @@ const app = new Vue({ currentAction: null, recordingAction: null, + config: { + screenshotAfterMouseUp: true + }, drawerVisible: true }, @@ -50,6 +53,20 @@ const app = new Vue({ }).catch(e => {}); }, + clearOps(actionName) { + app.$confirm('Aure you sure?', 'Clear this action', { + confirmButtonText: 'Yes', + cancelButtonText: 'No', + type: 'warning' + }).then(() => { + this.deletePopoverVisible = false; + let action = this.actions.find(action => action.name === actionName); + if (action) { + action.ops = []; + } + }).catch(e => {}); + }, + run() { socket.emit('runSingle', { testName: app.currentTestName @@ -71,10 +88,14 @@ function saveData() { function keyboardRecordingHandler(e) { if (e.key.toLowerCase() === 'r' && e.shiftKey) { if (!app.recordingAction) { + // Create a new action if currentAction has ops. + if (!app.currentAction || app.currentAction.ops.length > 0) { + app.newAction(); + } + app.recordingAction = app.currentAction; if (app.recordingAction) { let $iframe = document.body.querySelector('iframe'); - app.recordingAction.ops = []; app.recordingAction.scrollY = $iframe.contentWindow.scrollY; app.recordingAction.scrollX = $iframe.contentWindow.scrollX; app.recordingAction.timestamp = Date.now(); @@ -93,12 +114,19 @@ function recordIframeEvents(iframe, app) { function addMouseOp(type, e) { if (app.recordingAction) { + let time = Date.now() - app.recordingAction.timestamp; app.recordingAction.ops.push({ type, - time: Date.now() - app.recordingAction.timestamp, + time: time, x: e.clientX, y: e.clientY }); + if (type === 'mouseup' && app.config.screenshotAfterMouseUp) { + app.recordingAction.ops.push({ + time: time + 1, // TODO, Add delay time? + type: 'screenshot-auto' + }); + } app.$notify.info({ title: type, message: `(x: ${e.clientX}, y: ${e.clientY})`, diff --git a/test/runTest/util.js b/test/runTest/util.js index 3226594..49737f5 100644 --- a/test/runTest/util.js +++ b/test/runTest/util.js @@ -70,4 +70,12 @@ module.exports.buildRuntimeCode = async function () { // seedrandom use crypto as external module. Set it to null to avoid not defined error. // TODO return 'window.crypto = null\n' + output.code; -}; \ No newline at end of file +}; + +module.exports.waitTime = function (time) { + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, time); + }); +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org