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

Reply via email to