Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
半栈学徒
incubator-echarts
提交
65f58a39
I
incubator-echarts
项目概览
半栈学徒
/
incubator-echarts
与 Fork 源项目一致
从无法访问的项目Fork
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
incubator-echarts
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
65f58a39
编写于
9月 01, 2019
作者:
P
pissang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
test: Fix some logic issue of controlling test in dashboard.
上级
e31266d2
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
118 addition
and
64 deletion
+118
-64
test/runTest/cli.js
test/runTest/cli.js
+19
-6
test/runTest/client/client.css
test/runTest/client/client.css
+5
-0
test/runTest/client/client.js
test/runTest/client/client.js
+12
-7
test/runTest/client/index.html
test/runTest/client/index.html
+7
-1
test/runTest/runtime/main.js
test/runTest/runtime/main.js
+18
-19
test/runTest/server.js
test/runTest/server.js
+28
-29
test/runTest/store.js
test/runTest/store.js
+7
-1
test/runTest/util.js
test/runTest/util.js
+22
-1
未找到文件。
test/runTest/cli.js
浏览文件 @
65f58a39
...
...
@@ -4,7 +4,7 @@ const fse = require('fs-extra');
const
fs
=
require
(
'
fs
'
);
const
path
=
require
(
'
path
'
);
const
compareScreenshot
=
require
(
'
./compareScreenshot
'
);
const
{
getTestName
,
getVersionDir
}
=
require
(
'
./util
'
);
const
{
getTestName
,
getVersionDir
,
buildRuntimeCode
}
=
require
(
'
./util
'
);
const
{
origin
}
=
require
(
'
./config
'
);
function
getScreenshotDir
()
{
...
...
@@ -63,7 +63,7 @@ function createWaitTimeout(maxTime) {
});
}
return
{
keepWait
,
waitTimeout
}
return
{
keepWait
,
waitTimeout
}
;
}
async
function
takeScreenshot
(
page
,
elementQuery
,
fileUrl
,
desc
,
version
)
{
...
...
@@ -149,12 +149,14 @@ async function runTestPage(browser, fileUrl, version, runtimeCode) {
// screenshotPromises.push(promise);
// }, 100);
console
.
log
(
'
1111
'
);
// Wait for puppeteerFinishTest() is called
// Or compare the whole page if nothing happened after 10 seconds.
await
Promise
.
race
([
pageFinishPromise
,
waitTimeout
().
then
(()
=>
{
console
.
log
(
'
2222
'
);
// console.warn('Test timeout after 3 seconds.');
// Final shot.
let
desc
=
'
Final Shot
'
;
...
...
@@ -179,6 +181,14 @@ async function runTestPage(browser, fileUrl, version, runtimeCode) {
};
}
async
function
writePNG
(
diffPNG
,
diffPath
)
{
return
new
Promise
(
resolve
=>
{
let
writer
=
fs
.
createWriteStream
(
diffPath
);
diffPNG
.
pack
().
pipe
(
writer
);
writer
.
on
(
'
finish
'
,
()
=>
{
resolve
();});
});
};
async
function
runTest
(
browser
,
testOpt
,
runtimeCode
)
{
testOpt
.
status
===
'
running
'
;
const
fileUrl
=
testOpt
.
fileUrl
;
...
...
@@ -199,7 +209,7 @@ async function runTest(browser, testOpt, runtimeCode) {
);
let
diffPath
=
`
${
path
.
resolve
(
__dirname
,
getScreenshotDir
())}
/
${
shot
.
testName
}
-diff.png`
;
diffPNG
.
pack
().
pipe
(
fs
.
createWriteStream
(
diffPath
)
);
await
writePNG
(
diffPNG
,
diffPath
);
screenshots
.
push
({
actual
:
getClientRelativePath
(
actual
.
screenshotPath
),
...
...
@@ -221,9 +231,10 @@ async function runTest(browser, testOpt, runtimeCode) {
}
async
function
runTests
(
pendingTests
)
{
const
browser
=
await
puppeteer
.
launch
({
headless
:
tru
e
});
const
browser
=
await
puppeteer
.
launch
({
headless
:
fals
e
});
// TODO Not hardcoded.
let
runtimeCode
=
fs
.
readFileSync
(
path
.
join
(
__dirname
,
'
tmp/testRuntime.js
'
),
'
utf-8
'
);
// let runtimeCode = fs.readFileSync(path.join(__dirname, 'tmp/testRuntime.js'), 'utf-8');
let
runtimeCode
=
await
buildRuntimeCode
();
try
{
for
(
let
testOpt
of
pendingTests
)
{
...
...
@@ -243,6 +254,8 @@ async function runTests(pendingTests) {
catch
(
e
)
{
console
.
log
(
e
);
}
await
browser
.
close
();
}
// Handling input arguments.
...
...
@@ -252,6 +265,6 @@ runTests(testsFileUrlList.split(',').map(fileUrl => {
fileUrl
,
name
:
getTestName
(
fileUrl
),
results
:
[],
status
:
'
pending
'
status
:
'
unsettled
'
};
}));
\ No newline at end of file
test/runTest/client/client.css
浏览文件 @
65f58a39
...
...
@@ -39,6 +39,10 @@
padding
:
10px
10px
;
background
:
#162436
;
box-shadow
:
inset
0
0
5px
black
;
position
:
fixed
;
top
:
50px
;
width
:
280px
;
z-index
:
2
;
}
.nav-toolbar
.controls
{
margin-top
:
10px
;
...
...
@@ -49,6 +53,7 @@
background
:
#293c55
;
margin
:
0
;
padding
:
0
;
margin-top
:
80px
;
}
.test-list
li
{
list-style
:
none
;
...
...
test/runTest/client/client.js
浏览文件 @
65f58a39
...
...
@@ -18,7 +18,7 @@ function processTestsData(tests, oldTestsData) {
test
.
summary
=
'
exception
'
;
}
else
{
test
.
summary
=
'
warning
'
test
.
summary
=
'
warning
'
;
}
// Keep select status not change.
...
...
@@ -55,10 +55,11 @@ socket.on('connect', () => {
return
a
.
name
.
localeCompare
(
b
.
name
);
}
return
a
.
percentage
-
b
.
percentage
;
}
}
;
if
(
!
this
.
searchString
)
{
return
this
.
fullTests
.
sort
(
sortFunc
);
// Not modify the original tests data.
return
this
.
fullTests
.
slice
().
sort
(
sortFunc
);
}
return
this
.
fullTests
.
filter
(
test
=>
{
...
...
@@ -74,6 +75,10 @@ socket.on('connect', () => {
return
currentTest
;
},
currentTestUrl
()
{
return
window
.
location
.
origin
+
'
/test/
'
+
this
.
currentTest
.
fileUrl
;
},
isSelectAllIndeterminate
:
{
get
()
{
if
(
!
this
.
tests
.
length
)
{
...
...
@@ -123,7 +128,7 @@ socket.on('connect', () => {
const
tests
=
this
.
fullTests
.
filter
(
test
=>
{
return
test
.
selected
;
}).
map
(
test
=>
{
return
test
.
name
return
test
.
name
;
});
if
(
tests
.
length
>
0
)
{
this
.
running
=
true
;
...
...
@@ -142,7 +147,7 @@ socket.on('connect', () => {
socket
.
on
(
'
update
'
,
msg
=>
{
let
hasFinishedTest
=
!!
msg
.
tests
.
find
(
test
=>
test
.
status
===
'
finished
'
);
if
(
!
hasFinishedTest
&&
firstUpdate
)
{
app
.
$confirm
(
"
It seems you haven't run any test yet!<br />Do you want to start now?
"
,
'
Tip
'
,
{
app
.
$confirm
(
'
It seems you haven
\'
t run any test yet!<br />Do you want to start now?
'
,
'
Tip
'
,
{
confirmButtonText
:
'
Yes
'
,
cancelButtonText
:
'
No
'
,
dangerouslyUseHTMLString
:
true
,
...
...
@@ -150,7 +155,7 @@ socket.on('connect', () => {
}).
then
(
value
=>
{
app
.
running
=
true
;
socket
.
emit
(
'
run
'
,
msg
.
tests
.
map
(
test
=>
test
.
name
));
}).
catch
(()
=>
{})
}).
catch
(()
=>
{})
;
}
// TODO
// app.running = !!msg.running;
...
...
@@ -162,7 +167,7 @@ socket.on('connect', () => {
app
.
$notify
({
title
:
'
Test Complete
'
,
position
:
'
bottom-right
'
})
})
;
app
.
running
=
false
;
});
...
...
test/runTest/client/index.html
浏览文件 @
65f58a39
...
...
@@ -25,7 +25,6 @@
<el-button
v-if=
"running"
title=
"Run Selected"
@
click=
"stopTests"
circle
size=
"mini"
type=
"primary"
icon=
"el-icon-close"
></el-button>
</el-button-group>
<el-button
style=
"margin-left: 10px"
title=
"Sort By Failue Percentage"
@
click=
"toggleSort"
circle
size=
"mini"
type=
"primary"
icon=
"el-icon-sort"
...
...
@@ -62,6 +61,13 @@
</el-aside>
<el-main>
<div
v-if=
"currentTest"
>
<div
class=
"toolbar"
>
<h3>
<a
target=
"_blank"
:href=
"currentTestUrl"
>
{{currentTest.name}}
</a>
</h3>
</div>
<div
class=
"test-result"
v-for=
"result in currentTest.results"
>
<h4>
{{result.desc || result.name}}
</h4>
<el-row
:gutter=
"40"
class=
"screenshots"
>
...
...
test/runTest/runtime/main.js
浏览文件 @
65f58a39
...
...
@@ -4,17 +4,19 @@ import lolex from 'lolex';
const
NativeDate
=
window
.
Date
;
const
fixedTimestamp
=
1566458693300
;
// const actualTimestamp = NativeDate.now();
// function MockDate(params) {
// if (!params) {
// const elapsedTime = NativeDate.now() - actualTimestamp;
// return new NativeDate(fixedTimestamp + elapsedTime);
// }
// else {
// return new NativeDate(params);
// }
// }
// MockDate.prototype = new Date();
const
actualTimestamp
=
NativeDate
.
now
();
function
MockDate
(
params
)
{
if
(
!
params
)
{
const
elapsedTime
=
NativeDate
.
now
()
-
actualTimestamp
;
return
new
NativeDate
(
fixedTimestamp
+
elapsedTime
);
}
else
{
return
new
NativeDate
(
params
);
}
}
MockDate
.
prototype
=
new
Date
();
// Fixed date
window
.
Date
=
MockDate
;
export
function
createScreenshotTest
(
desc
,
elementQuery
,
waitTime
)
{
...
...
@@ -44,11 +46,8 @@ Math.random = function () {
return
val
;
};
// Fixed date
// window.Date = MockDate;
lolex
.
install
({
shouldAdvanceTime
:
true
,
advanceTimeDelta
:
50
,
now
:
fixedTimestamp
});
// lolex.install({
// shouldAdvanceTime: true,
// advanceTimeDelta: 200,
// now: fixedTimestamp
// });
test/runTest/server.js
浏览文件 @
65f58a39
const
handler
=
require
(
'
serve-handler
'
);
const
http
=
require
(
'
http
'
);
const
rollup
=
require
(
'
rollup
'
);
const
resolve
=
require
(
'
rollup-plugin-node-resolve
'
);
const
commonjs
=
require
(
'
rollup-plugin-commonjs
'
);
const
path
=
require
(
'
path
'
);
const
open
=
require
(
'
open
'
);
const
fse
=
require
(
'
fs-extra
'
);
const
{
fork
}
=
require
(
'
child_process
'
);
const
{
port
,
origin
}
=
require
(
'
./config
'
);
const
{
getTestsList
,
prepareTestsList
,
saveTestsList
,
mergeTestsResults
}
=
require
(
'
./store
'
);
const
{
prepareEChartsVersion
}
=
require
(
'
./util
'
);
const
{
prepareEChartsVersion
,
buildRuntimeCode
}
=
require
(
'
./util
'
);
function
serve
()
{
const
server
=
http
.
createServer
((
request
,
response
)
=>
{
...
...
@@ -31,51 +28,53 @@ function serve() {
};
};
async
function
buildRuntimeCode
()
{
const
bundle
=
await
rollup
.
rollup
({
input
:
path
.
join
(
__dirname
,
'
runtime/main.js
'
),
plugins
:
[
resolve
(),
commonjs
()
]
});
const
output
=
await
bundle
.
generate
({
format
:
'
iife
'
,
name
:
'
autorun
'
});
return
output
.
code
;
let
testProcess
;
let
pendingTests
;
function
stopRunningTests
()
{
if
(
testProcess
)
{
testProcess
.
kill
();
testProcess
=
null
;
}
if
(
pendingTests
)
{
pendingTests
.
forEach
(
testOpt
=>
{
if
(
testOpt
.
status
===
'
pending
'
)
{
testOpt
.
status
=
'
unsettled
'
;
}
});
pendingTests
=
null
;
}
}
function
startTests
(
testsNameList
,
socket
)
{
console
.
log
(
testsNameList
.
join
(
'
,
'
));
stopRunningTests
();
return
new
Promise
(
resolve
=>
{
const
pendingTests
=
getTestsList
().
filter
(
testOpt
=>
{
pendingTests
=
getTestsList
().
filter
(
testOpt
=>
{
return
testsNameList
.
includes
(
testOpt
.
name
);
});
for
(
let
testOpt
of
pendingTests
)
{
pendingTests
.
forEach
(
testOpt
=>
{
// Reset all tests results
testOpt
.
status
=
'
pending
'
;
testOpt
.
results
=
[];
}
}
);
socket
.
emit
(
'
update
'
,
{
tests
:
getTestsList
()});
let
child
Process
=
fork
(
path
.
join
(
__dirname
,
'
cli.js
'
),
[
test
Process
=
fork
(
path
.
join
(
__dirname
,
'
cli.js
'
),
[
pendingTests
.
map
(
testOpt
=>
testOpt
.
fileUrl
)
]);
// Finished one test
child
Process
.
on
(
'
message
'
,
testOpt
=>
{
test
Process
.
on
(
'
message
'
,
testOpt
=>
{
mergeTestsResults
([
testOpt
]);
// Merge tests.
socket
.
emit
(
'
update
'
,
{
tests
:
getTestsList
(),
running
:
true
});
saveTestsList
();
});
// Finished all
child
Process
.
on
(
'
exit
'
,
()
=>
{
test
Process
.
on
(
'
exit
'
,
()
=>
{
resolve
();
});
});
...
...
@@ -86,9 +85,6 @@ async function start() {
await
prepareEChartsVersion
();
// Version to test
let
runtimeCode
=
await
buildRuntimeCode
();
// seedrandom use crypto as external module. Set it to null to avoid not defined error.
// TODO
runtimeCode
=
'
window.crypto = null
\n
'
+
runtimeCode
;
fse
.
outputFileSync
(
path
.
join
(
__dirname
,
'
tmp/testRuntime.js
'
),
runtimeCode
,
'
utf-8
'
);
// Start a static server for puppeteer open the html test cases.
...
...
@@ -103,6 +99,9 @@ async function start() {
await
startTests
(
testsNameList
,
socket
);
socket
.
emit
(
'
finish
'
);
});
socket
.
on
(
'
stop
'
,
()
=>
{
stopRunningTests
();
});
});
console
.
log
(
`Dashboard:
${
origin
}
/test/runTest/client/index.html`
);
...
...
test/runTest/store.js
浏览文件 @
65f58a39
...
...
@@ -30,6 +30,11 @@ module.exports.prepareTestsList = async function () {
let
cachedStr
=
fs
.
readFileSync
(
getCacheFilePath
(),
'
utf-8
'
);
_tests
=
JSON
.
parse
(
cachedStr
);
_tests
.
forEach
(
test
=>
{
// In somehow tests are stopped and leave the status pending.
// Set the status to unsettled again.
if
(
test
.
status
===
'
pending
'
)
{
test
.
status
=
'
unsettled
'
;
}
_testsMap
[
test
.
fileUrl
]
=
test
;
});
}
...
...
@@ -49,7 +54,8 @@ module.exports.prepareTestsList = async function () {
let
test
=
{
fileUrl
,
name
:
getTestName
(
fileUrl
),
status
:
'
pending
'
,
// Default status should be unkown
// status: 'pending',
results
:
[]
};
...
...
test/runTest/util.js
浏览文件 @
65f58a39
...
...
@@ -2,6 +2,9 @@ const path = require('path');
const
fse
=
require
(
'
fs-extra
'
);
const
https
=
require
(
'
https
'
);
const
fs
=
require
(
'
fs
'
);
const
rollup
=
require
(
'
rollup
'
);
const
resolve
=
require
(
'
rollup-plugin-node-resolve
'
);
const
commonjs
=
require
(
'
rollup-plugin-commonjs
'
);
module
.
exports
.
getTestName
=
function
(
fileUrl
)
{
return
path
.
basename
(
fileUrl
,
'
.html
'
);
...
...
@@ -42,4 +45,22 @@ module.exports.prepareEChartsVersion = function (version) {
resolve
();
}
});
}
\ No newline at end of file
};
module
.
exports
.
buildRuntimeCode
=
async
function
()
{
const
bundle
=
await
rollup
.
rollup
({
input
:
path
.
join
(
__dirname
,
'
runtime/main.js
'
),
plugins
:
[
resolve
(),
commonjs
()
]
});
const
output
=
await
bundle
.
generate
({
format
:
'
iife
'
,
name
:
'
autorun
'
});
// 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
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录