Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_46011646
wechaty
提交
dee2ae99
W
wechaty
项目概览
weixin_46011646
/
wechaty
与 Fork 源项目一致
Fork自
wechaty / wechaty
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
W
wechaty
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
dee2ae99
编写于
6月 11, 2016
作者:
Huan (李卓桓)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
better watchDog reset, code cleanup
上级
d931da79
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
209 addition
and
255 deletion
+209
-255
src/puppet-web-bridge.js
src/puppet-web-bridge.js
+27
-19
src/puppet-web-browser.js
src/puppet-web-browser.js
+34
-20
src/puppet-web-injectio.js
src/puppet-web-injectio.js
+12
-10
src/puppet-web.js
src/puppet-web.js
+45
-69
test/puppet-web-spec.js
test/puppet-web-spec.js
+85
-58
test/webdriver-spec.js
test/webdriver-spec.js
+6
-79
未找到文件。
src/puppet-web-bridge.js
浏览文件 @
dee2ae99
...
...
@@ -17,7 +17,7 @@ const log = require('./npmlog-env')
class
Bridge
{
constructor
(
options
)
{
if
(
!
options
||
!
options
.
puppet
)
{
throw
new
Error
(
'
Bridge need a puppet
'
)}
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
new Bridge({puppet: %s, port: %s})
'
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
new Bridge({puppet: %s, port: %s})
'
,
options
.
puppet
.
constructor
.
name
,
options
.
port
)
...
...
@@ -27,23 +27,31 @@ class Bridge {
toString
()
{
return
`Bridge({puppet:
${
this
.
options
.
puppet
.
constructor
.
name
}
, port:
${
this
.
options
.
port
}
})`
}
init
()
{
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
init()
'
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
init()
'
)
return
this
.
inject
()
.
then
(
r
=>
{
log
.
verbose
(
'
PuppetWebBridge
'
,
'
init() inject() return %s
'
,
r
)
return
this
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWebBridge
'
,
'
init() inject() exception: %s
'
,
e
.
message
)
throw
e
})
}
logout
()
{
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
quit()
'
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
quit()
'
)
return
this
.
proxyWechaty
(
'
logout
'
)
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
logout() exception: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
logout() exception: %s
'
,
e
.
message
)
throw
e
})
}
quit
()
{
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
quit()
'
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
quit()
'
)
return
this
.
proxyWechaty
(
'
quit
'
)
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
quit() exception: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
quit() exception: %s
'
,
e
.
message
)
throw
e
})
}
...
...
@@ -56,7 +64,7 @@ class Bridge {
getUserName
()
{
return
this
.
proxyWechaty
(
'
getUserName
'
)
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
getUserName() exception: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
getUserName() exception: %s
'
,
e
.
message
)
throw
e
})
}
...
...
@@ -64,7 +72,7 @@ class Bridge {
send
(
toUserName
,
content
)
{
return
this
.
proxyWechaty
(
'
send
'
,
toUserName
,
content
)
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
send() exception: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
send() exception: %s
'
,
e
.
message
)
throw
e
})
}
...
...
@@ -79,23 +87,23 @@ class Bridge {
const
timeout
=
max
*
(
backoff
*
max
)
/
2
return
retryPromise
({
max
:
max
,
backoff
:
backoff
},
function
(
attempt
)
{
log
.
silly
(
'
Puppet
w
ebBridge
'
,
'
getContact() retryPromise: attampt %s/%s time for timeout %s
'
log
.
silly
(
'
Puppet
W
ebBridge
'
,
'
getContact() retryPromise: attampt %s/%s time for timeout %s
'
,
attempt
,
max
,
timeout
)
return
this
.
proxyWechaty
(
'
getContact
'
,
id
)
.
then
(
r
=>
{
if
(
!
r
)
{
throw
(
'
got empty return
'
)
throw
new
Error
(
'
got empty return
'
)
}
return
r
})
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
proxyWechaty(getContact, %s) exception: %s
'
,
id
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
proxyWechaty(getContact, %s) exception: %s
'
,
id
,
e
.
message
)
throw
e
})
}.
bind
(
this
))
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
retryPromise() getContact() finally FAIL: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
retryPromise() getContact() finally FAIL: %s
'
,
e
.
message
)
throw
e
})
/////////////////////////////////
...
...
@@ -110,17 +118,17 @@ class Bridge {
)
}
inject
()
{
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
inject()
'
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
inject()
'
)
return
co
.
call
(
this
,
function
*
()
{
const
injectio
=
this
.
getInjectio
()
let
r
=
yield
this
.
execute
(
injectio
,
this
.
port
)
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
inject() injected, got [%s]
'
,
r
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
inject() injected, got [%s]
'
,
r
)
r
=
yield
this
.
proxyWechaty
(
'
init
'
)
log
.
verbose
(
'
Puppet
w
ebBridge
'
,
'
inject() Wechaty.init() return: %s
'
,
r
)
log
.
verbose
(
'
Puppet
W
ebBridge
'
,
'
inject() Wechaty.init() return: %s
'
,
r
)
return
r
})
.
catch
(
e
=>
{
log
.
error
(
'
Puppet
w
ebBridge
'
,
'
inject() exception: %s
'
,
e
.
message
)
log
.
error
(
'
Puppet
W
ebBridge
'
,
'
inject() exception: %s
'
,
e
.
message
)
throw
e
})
}
...
...
@@ -138,10 +146,10 @@ class Bridge {
const
argsDecoded
=
`JSON.parse(decodeURIComponent(window.atob('
${
argsEncoded
}
')))`
const
wechatyScript
=
`return (typeof Wechaty !== 'undefined' && Wechaty.
${
wechatyFunc
}
.apply(undefined,
${
argsDecoded
}
))`
log
.
silly
(
'
Puppet
w
ebBridge
'
,
'
proxyWechaty(%s, ...args) %s
'
,
wechatyFunc
,
wechatyScript
)
log
.
silly
(
'
Puppet
W
ebBridge
'
,
'
proxyWechaty(%s, ...args) %s
'
,
wechatyFunc
,
wechatyScript
)
return
this
.
execute
(
wechatyScript
)
.
catch
(
e
=>
{
log
.
error
(
'
PuppetwebBridge
'
,
'
proxyWechaty() exception: %s
'
,
e
.
messag
e
)
log
.
warn
(
'
PuppetWebBridge
'
,
'
proxyWechaty() exception: %s
'
,
e
.
message
||
e
)
throw
e
})
}
...
...
@@ -149,7 +157,7 @@ class Bridge {
execute
(
script
,
...
args
)
{
return
this
.
puppet
.
browser
.
execute
(
script
,
...
args
)
.
catch
(
e
=>
{
log
.
error
(
'
PuppetwebBridge
'
,
'
execute() exception: %s
'
,
e
.
messag
e
)
log
.
warn
(
'
PuppetWebBridge
'
,
'
execute() exception: %s
'
,
e
.
message
||
e
)
throw
e
})
}
...
...
src/puppet-web-browser.js
浏览文件 @
dee2ae99
...
...
@@ -85,7 +85,7 @@ class Browser extends EventEmitter {
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWebBrowser
'
,
'
open() exception: %s
'
,
e
.
message
)
this
.
dead
(
e
.
message
)
throw
e
.
message
throw
e
})
}
...
...
@@ -159,25 +159,39 @@ class Browser extends EventEmitter {
,
attempt
,
timeout
)
return
new
Promise
((
resolve
,
reject
)
=>
{
require
(
'
ps-tree
'
)(
process
.
pid
,
(
err
,
children
)
=>
{
if
(
err
)
{
return
reject
(
err
)
}
const
num
=
children
.
filter
(
child
=>
/phantomjs/i
.
test
(
child
.
COMMAND
)).
length
if
(
num
==
0
)
{
return
resolve
(
'
clean
'
)
this
.
getBrowserPids
()
.
then
(
pids
=>
{
if
(
pids
.
length
===
0
)
{
resolve
(
'
clean
'
)
}
else
{
re
turn
reject
(
'
dirty
'
)
re
ject
(
new
Error
(
'
dirty
'
)
)
}
})
.
catch
(
e
=>
reject
(
e
))
})
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWebBrowser
'
,
'
retryPromise failed: %s
'
,
e
)
log
.
error
(
'
PuppetWebBrowser
'
,
'
retryPromise failed: %s
'
,
e
.
message
)
throw
e
})
}
getBrowserPids
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
require
(
'
ps-tree
'
)(
process
.
pid
,
(
err
,
children
)
=>
{
if
(
err
)
{
reject
(
err
)
return
}
const
pids
=
children
.
filter
(
child
=>
/phantomjs/i
.
test
(
child
.
COMMAND
))
.
map
(
child
=>
child
.
PID
)
resolve
(
pids
)
return
})
})
}
/**
* only wrap addCookies for convinience
*
...
...
@@ -185,7 +199,7 @@ class Browser extends EventEmitter {
* deleteCookie / getCookie / getCookies
*/
addCookies
(
cookie
)
{
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
addCookies() - browser dead
'
)}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
addCookies() - browser dead
'
)
)}
if
(
cookie
.
map
)
{
return
cookie
.
map
(
c
=>
{
...
...
@@ -211,7 +225,7 @@ class Browser extends EventEmitter {
execute
(
script
,
...
args
)
{
//log.verbose('PuppetWebBrowser', `Browser.execute(${script})`)
// log.verbose('PuppetWebBrowser', `Browser.execute() driver.getSession: %s`, util.inspect(this.driver.getSession()))
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
browser dead
'
)
}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
browser dead
'
)
)
}
return
this
.
driver
.
executeScript
.
apply
(
this
.
driver
,
arguments
)
.
catch
(
e
=>
{
...
...
@@ -248,7 +262,7 @@ class Browser extends EventEmitter {
checkSession
(
session
)
{
log
.
verbose
(
'
PuppetWebBrowser
'
,
`checkSession(
${
session
}
)`
)
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
checkSession() - browser dead
'
)}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
checkSession() - browser dead
'
)
)}
return
this
.
driver
.
manage
().
getCookies
()
.
then
(
cookies
=>
{
...
...
@@ -264,8 +278,8 @@ class Browser extends EventEmitter {
cleanSession
(
session
)
{
log
.
verbose
(
'
PuppetWebBrowser
'
,
`cleanSession(
${
session
}
)`
)
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
cleanSession() - browser dead
'
)}
if
(
!
session
)
{
return
Promise
.
reject
(
'
cleanSession() no session
'
)
}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
cleanSession() - browser dead
'
)
)}
if
(
!
session
)
{
return
Promise
.
reject
(
new
Error
(
'
cleanSession() no session
'
)
)
}
const
filename
=
session
return
new
Promise
((
resolve
,
reject
)
=>
{
...
...
@@ -279,9 +293,9 @@ class Browser extends EventEmitter {
}
saveSession
(
session
)
{
log
.
verbose
(
'
PuppetWebBrowser
'
,
`saveSession(
${
session
}
)`
)
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
saveSession() - browser dead
'
)}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
saveSession() - browser dead
'
)
)}
if
(
!
session
)
{
return
Promise
.
reject
(
'
saveSession() no session
'
)
}
if
(
!
session
)
{
return
Promise
.
reject
(
new
Error
(
'
saveSession() no session
'
)
)
}
const
filename
=
session
return
new
Promise
((
resolve
,
reject
)
=>
{
...
...
@@ -321,16 +335,16 @@ class Browser extends EventEmitter {
loadSession
(
session
)
{
log
.
verbose
(
'
PuppetWebBrowser
'
,
`loadSession(
${
session
}
)`
)
if
(
this
.
dead
())
{
return
Promise
.
reject
(
'
loadSession() - browser dead
'
)}
if
(
this
.
dead
())
{
return
Promise
.
reject
(
new
Error
(
'
loadSession() - browser dead
'
)
)}
if
(
!
session
)
{
return
Promise
.
reject
(
'
loadSession() no session
'
)
}
if
(
!
session
)
{
return
Promise
.
reject
(
new
Error
(
'
loadSession() no session
'
)
)
}
const
filename
=
session
return
new
Promise
((
resolve
,
reject
)
=>
{
fs
.
readFile
(
filename
,
(
err
,
jsonStr
)
=>
{
if
(
err
)
{
if
(
err
)
{
log
.
silly
(
'
PuppetWebBrowser
'
,
'
loadSession(%s) skipped because error code: %s
'
,
session
,
err
.
code
)
}
return
reject
(
'
error code:
'
+
err
.
code
)
return
reject
(
new
Error
(
'
error code:
'
+
err
.
code
)
)
}
const
cookies
=
JSON
.
parse
(
jsonStr
)
...
...
src/puppet-web-injectio.js
浏览文件 @
dee2ae99
...
...
@@ -23,7 +23,8 @@ return (function(port) {
var
Wechaty
=
{
glue
:
{
}
// will be initialized by glueAngular() function
// will be initialized by glueAngular() function
}
// glue funcs
,
getLoginStatusCode
:
function
()
{
return
Wechaty
.
glue
.
loginScope
.
code
}
...
...
@@ -41,14 +42,14 @@ return (function(port) {
}
// funcs
,
init
:
init
,
send
:
send
,
clog
:
clog
// Console log
,
slog
:
slog
// log throw Socket
IO
,
log
:
log
,
ding
:
ding
,
quit
:
quit
,
emit
:
emit
,
init
:
init
// initialize Wechaty @ Browser
,
send
:
send
// send message to wechat user
,
clog
:
clog
// log to Console
,
slog
:
slog
// log to Socket
IO
,
log
:
log
// log to both Console & SocketIO
,
ding
:
ding
// simple return 'dong'
,
quit
:
quit
// quit wechat
,
emit
:
emit
// send event to server
,
getContact
:
getContact
,
getUserName
:
getUserName
...
...
@@ -116,8 +117,9 @@ return (function(port) {
}
function
heartBeat
()
{
var
TIMEOUT
=
15000
// 15s
Wechaty
.
emit
(
'
ding
'
,
'
heartbeat@browser
'
)
setTimeout
(
heartBeat
,
15000
)
setTimeout
(
heartBeat
,
TIMEOUT
)
}
function
glueAngular
()
{
...
...
src/puppet-web.js
浏览文件 @
dee2ae99
...
...
@@ -125,11 +125,13 @@ class PuppetWeb extends Puppet {
yield
this
.
browser
.
init
()
yield
this
.
browser
.
open
(
fastUrl
)
if
(
this
.
session
)
{
yield
this
.
browser
.
loadSession
(
this
.
session
).
catch
(
e
=>
{
// fail safe
log
.
verbose
(
'
PuppetWeb
'
,
'
browser.loadSession() exception: %s
'
,
e
.
message
)
yield
this
.
browser
.
loadSession
(
this
.
session
)
.
catch
(
e
=>
{
// fail safe
log
.
verbose
(
'
PuppetWeb
'
,
'
browser.loadSession() exception: %s
'
,
e
.
message
||
e
)
})
}
yield
this
.
browser
.
open
()
return
this
.
browser
// follow func name meaning
}).
catch
(
e
=>
{
log
.
error
(
'
PuppetWeb
'
,
'
initBrowser() exception: %s
'
,
e
.
message
)
throw
e
...
...
@@ -184,11 +186,23 @@ class PuppetWeb extends Puppet {
})
}
onBrowserDead
(
data
)
{
log
.
verbose
(
'
PuppetWeb
'
,
'
onBrowserDead(%s)
'
,
data
)
onBrowserDead
(
e
)
{
// because this function is async, so maybe entry more than one times.
// guard by variable: onBrowserDeadBusy to prevent entrance the 2nd time.
if
(
this
.
onBrowserDeadBusy
)
{
log
.
warn
(
'
PuppetWeb
'
,
'
onBrowserDead() Im busy, dont call me again before I return. this time will return and do nothing
'
)
return
}
this
.
onBrowserDeadBusy
=
true
log
.
verbose
(
'
PuppetWeb
'
,
'
onBrowserDead(%s)
'
,
e
.
message
||
e
)
if
(
!
this
.
browser
||
!
this
.
bridge
)
{
log
.
error
(
'
PuppetWeb
'
,
'
onBrowserDead() browser or bridge not found. do nothing
'
)
return
}
return
co
.
call
(
this
,
function
*
()
{
log
.
verbose
(
'
PuppetWeb
'
,
'
try to reborn browser
'
)
log
.
verbose
(
'
PuppetWeb
'
,
'
onBrowserDead()
try to reborn browser
'
)
yield
this
.
browser
.
quit
()
.
catch
(
e
=>
{
// fail safe
...
...
@@ -201,81 +215,43 @@ class PuppetWeb extends Puppet {
yield
this
.
bridge
.
init
()
log
.
verbose
(
'
PuppetWeb
'
,
'
bridge re-inited
'
)
const
dong
=
yield
this
.
ding
()
if
(
/dong/i
.
test
(
dong
))
{
log
.
verbose
(
'
PuppetWeb
'
,
'
ding() works well after reset
'
)
}
else
{
log
.
warn
(
'
PuppetWeb
'
,
'
ding() get error return after reset:
'
+
dong
)
}
})
.
then
(()
=>
{
log
.
verbose
(
'
PuppetWeb
'
,
'
onBrowserDead() new browser borned
'
)
})
.
catch
(
e
=>
{
.
catch
(
e
=>
{
// Exception
log
.
error
(
'
PuppetWeb
'
,
'
onBrowserDead() exception: %s
'
,
e
.
message
)
throw
e
})
.
then
(()
=>
{
// Finally
log
.
verbose
(
'
PuppetWeb
'
,
'
onBrowserDead() new browser borned
'
)
this
.
onBrowserDeadBusy
=
false
})
}
// feed me in time(after 1st feed), or I'll restart system
watchDog
(
data
)
{
log
.
verbose
(
'
PuppetWeb
'
,
'
watchDog(%s)
'
,
data
)
const
TIMEOUT
=
60000
// 60s
watchDog
(
data
,
options
)
{
log
.
silly
(
'
PuppetWeb
'
,
'
watchDog(%s)
'
,
data
)
options
=
options
||
{}
const
TIMEOUT
=
options
.
timeout
||
60000
// 60s default. can be override in options
if
(
this
.
watchDogTimer
)
{
clearTimeout
(
this
.
watchDogTimer
)
}
this
.
watchDogTimer
=
setTimeout
(
this
.
recoverFromUnknownState
.
bind
(
this
),
TIMEOUT
)
this
.
watchDogTimer
=
setTimeout
(()
=>
{
const
err
=
new
Error
(
'
watchdog timeout after
'
+
Math
.
floor
(
TIMEOUT
/
1000
)
+
'
seconds
'
)
this
.
emit
(
'
error
'
,
err
)
this
.
onBrowserDead
(
err
)
},
TIMEOUT
)
this
.
watchDogTimer
.
unref
()
// dont block quit
}
// recover system from unknown state
recoverFromUnknownState
()
{
log
.
warn
(
'
PuppetWeb
'
,
'
recoverFromUnknownState()
'
)
if
(
!
this
.
browser
||
!
this
.
bridge
)
{
log
.
error
(
'
PuppetWeb
'
,
'
recoverFromUnknownState() browser or bridge not found!
'
)
return
}
// 1. check & reset browser(if needed)
if
(
this
.
browser
.
dead
())
{
log
.
verbose
(
'
PuppetWeb
'
,
'
watchDogReset() browser.dead(), wait it to restore...
'
)
return
}
// 2. check bridge
this
.
ding
()
.
then
(
dong
=>
{
if
(
dong
===
'
dong
'
)
{
log
.
warn
(
'
PuppetWeb
'
,
'
watchDogReset() ding() works well, whats wrong?
'
)
}
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWeb
'
,
'
watchDogReset() ding() exception: %s
'
,
e
.
message
)
throw
e
})
// 3. re-init bridge
this
.
bridge
.
inject
()
.
then
(()
=>
{
log
.
verbose
(
'
PuppetWeb
'
,
'
watchDogReset() bridge.inject() done
'
)
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWeb
'
,
'
watchDogReset() bridge.inject() exception: %s
'
,
e
.
message
)
throw
e
})
// 4. confirm bridge works well
this
.
ding
()
.
then
(
dong
=>
{
if
(
dong
!==
'
dong
'
)
{
log
.
error
(
'
PuppetWeb
'
,
'
watchDogReset() ding() return[%s] not `dong`
'
,
dong
)
}
else
{
log
.
verbose
(
'
PuppetWeb
'
,
'
watchDogReset() ding() works well after reset
'
)
}
})
.
catch
(
e
=>
{
log
.
error
(
'
PuppetWeb
'
,
'
watchDogReset() ding() after reset exception: %s
'
,
e
.
message
)
throw
e
})
}
onServerDing
(
data
)
{
log
.
verbose
(
'
PuppetWeb
'
,
'
onServerDing(%s)
'
,
data
)
log
.
silly
(
'
PuppetWeb
'
,
'
onServerDing(%s)
'
,
data
)
this
.
watchDog
(
data
)
}
onServerScan
(
data
)
{
...
...
@@ -318,7 +294,7 @@ class PuppetWeb extends Puppet {
}
/**
* `unload` event is sent from js@browser to webserver via socketio
* after received `unload`, we should re-inject the Wechaty js code into browser.
* after received `unload`, we should
fix bridge by
re-inject the Wechaty js code into browser.
* possible conditions:
* 1. browser refresh
* 2. browser navigated to a new url
...
...
@@ -425,7 +401,7 @@ class PuppetWeb extends Puppet {
}
reply
(
message
,
replyContent
)
{
if
(
message
.
self
())
{
return
Promise
.
reject
(
'
will not to reply message of myself
'
)
return
Promise
.
reject
(
new
Error
(
'
will not to reply message of myself
'
)
)
}
const
m
=
new
Message
()
...
...
@@ -467,7 +443,7 @@ class PuppetWeb extends Puppet {
ding
(
data
)
{
return
this
.
bridge
.
proxyWechaty
(
'
ding
'
,
data
)
.
catch
(
e
=>
{
log
.
warn
(
'
PuppetWeb
'
,
'
ding(%s) rejected: %s
'
,
data
,
e
.
message
)
log
.
warn
(
'
PuppetWeb
'
,
'
ding(%s) rejected: %s
'
,
data
,
e
.
message
||
e
)
throw
e
})
}
...
...
test/puppet-web-spec.js
浏览文件 @
dee2ae99
const
co
=
require
(
'
co
'
)
const
util
=
require
(
'
util
'
)
const
test
=
require
(
'
tap
'
).
test
const
retryPromise
=
require
(
'
retry-promise
'
).
default
const
log
=
require
(
'
../src/npmlog-env
'
)
...
...
@@ -10,36 +11,6 @@ const SESSION = 'unit-test-session.json'
const
PuppetWeb
=
require
(
'
../src/puppet-web
'
)
function
dingSocket
(
server
)
{
const
maxTime
=
60000
// 60s
const
waitTime
=
500
let
totalTime
=
0
return
new
Promise
((
resolve
,
reject
)
=>
{
log
.
verbose
(
'
TestPuppetWeb
'
,
'
dingSocket()
'
)
return
testDing
()
function
testDing
()
{
// log.silly('TestPuppetWeb', server.socketio)
if
(
!
server
.
socketClient
)
{
totalTime
+=
waitTime
if
(
totalTime
>
maxTime
)
{
return
reject
(
'
timeout after
'
+
totalTime
+
'
ms
'
)
}
log
.
silly
(
'
TestPuppetWeb
'
,
'
waiting socketClient to connect for
'
+
totalTime
+
'
/
'
+
maxTime
+
'
ms...
'
)
setTimeout
(
testDing
,
waitTime
)
return
}
//log.silly('TestPuppetWebServer', server.socketClient)
server
.
socketClient
.
once
(
'
dong
'
,
data
=>
{
log
.
verbose
(
'
TestPuppetWeb
'
,
'
socket recv event dong:
'
+
data
)
return
resolve
(
data
)
})
server
.
socketClient
.
emit
(
'
ding
'
)
}
})
}
test
(
'
PuppetWeb smoke testing
'
,
function
(
t
)
{
let
pw
=
new
PuppetWeb
({
port
:
PORT
,
head
:
HEAD
,
session
:
SESSION
})
t
.
ok
(
pw
,
'
new PuppetWeb
'
)
...
...
@@ -103,39 +74,95 @@ test('Puppet Web server/browser communication', function(t) {
.
then
(
t
.
end
)
})
.
catch
(
e
=>
{
t
.
fail
(
e
)
})
// Exception
return
/////////////////////////////////////////////////////////////////////////////
function
dingSocket
(
server
)
{
const
maxTime
=
60000
// 60s
const
waitTime
=
500
let
totalTime
=
0
return
new
Promise
((
resolve
,
reject
)
=>
{
log
.
verbose
(
'
TestPuppetWeb
'
,
'
dingSocket()
'
)
return
testDing
()
function
testDing
()
{
// log.silly('TestPuppetWeb', server.socketio)
if
(
!
server
.
socketClient
)
{
totalTime
+=
waitTime
if
(
totalTime
>
maxTime
)
{
return
reject
(
'
timeout after
'
+
totalTime
+
'
ms
'
)
}
log
.
silly
(
'
TestPuppetWeb
'
,
'
waiting socketClient to connect for
'
+
totalTime
+
'
/
'
+
maxTime
+
'
ms...
'
)
setTimeout
(
testDing
,
waitTime
)
return
}
//log.silly('TestPuppetWebServer', server.socketClient)
server
.
socketClient
.
once
(
'
dong
'
,
data
=>
{
log
.
verbose
(
'
TestPuppetWeb
'
,
'
socket recv event dong:
'
+
data
)
return
resolve
(
data
)
})
server
.
socketClient
.
emit
(
'
ding
'
)
}
})
}
})
/*
false && test('Puppet Web promise version of server/browser communication', function(t) {
pw = new PuppetWeb({port: PORT, head: HEAD, session: SESSION})
test
(
'
Puppet Web watchdog timer
'
,
function
(
t
)
{
const
pw
=
new
PuppetWeb
({
port
:
PORT
,
head
:
HEAD
,
session
:
SESSION
})
t
.
ok
(
pw
,
'
new PuppetWeb
'
)
pw.init()
.then(r => {
t.pass('pw inited'
)
co
(
function
*
()
{
yield
pw
.
initBrowser
()
yield
pw
.
initBridge
(
)
return dingSocket(pw.server)
})
.then(retSocket => {
t.equal(retSocket, 'dong', 'dingSocket got dong')
return true
})
.catch(e => { // Reject
log.warn('TestPuppetWeb', 'error: %s', e)
t.fail(e)
throw e
})
.then(r => { // Finally 1
t.pass('dingSocket resolved')
return pw.quit()
yield
pw
.
bridge
.
quit
().
catch
(
e
=>
{
/* fail safe */
})
yield
pw
.
browser
.
quit
().
catch
(
e
=>
{
/* fail safe */
})
pw
.
once
(
'
error
'
,
e
=>
{
t
.
ok
(
/watchdog timeout/i
.
test
(
e
),
'
should emit error after watchdog timeout
'
)
})
pw
.
watchDog
(
'
test
'
,
{
timeout
:
1
})
const
dong
=
yield
waitDing
()
t
.
equal
(
dong
,
'
dong
'
,
'
should got dong from ding after watchdog reset
'
)
})
.then(r => { // Finally 2
t.pass('pw.quit() resolved')
t.end()
.
catch
(
e
=>
{
// Exception
t
.
fail
(
e
.
message
||
e
)
})
.catch(e => {
t.fail(e)
throw e
}) // Exception
.
then
(
t
.
end
)
// Finally
return
/////////////////////////////////////////////////////////////////////////////
function
waitDing
()
{
const
max
=
30
const
backoff
=
100
// max = (2*totalTime/backoff) ^ (1/2)
// timeout = 11250 for {max: 15, backoff: 100}
// timeout = 45000 for {max: 30, backoff: 100}
const
timeout
=
max
*
(
backoff
*
max
)
/
2
return
retryPromise
({
max
:
max
,
backoff
:
backoff
},
function
(
attempt
)
{
log
.
silly
(
'
TestPuppetWeb
'
,
'
waitDing() retryPromise: attampt %s/%s time for timeout %s
'
,
attempt
,
max
,
timeout
)
return
pw
.
ding
()
.
then
(
r
=>
{
if
(
!
r
)
{
throw
new
Error
(
'
got empty return
'
)
}
return
r
})
.
catch
(
e
=>
{
log
.
verbose
(
'
TestPuppetWeb
'
,
'
waitDing() exception: %s
'
,
e
.
message
||
e
)
throw
e
})
})
.
catch
(
e
=>
{
log
.
error
(
'
TestPuppetWeb
'
,
'
retryPromise() waitDing() finally FAIL: %s
'
,
e
.
message
)
throw
e
})
}
})
*/
test/webdriver-spec.js
浏览文件 @
dee2ae99
...
...
@@ -16,17 +16,6 @@ const PuppetWebBridge = require('../src/puppet-web-bridge')
const
PORT
=
process
.
env
.
WECHATY_PORT
||
58788
const
HEAD
=
process
.
env
.
WECHATY_HEAD
||
false
function
driverProcessNum
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
require
(
'
ps-tree
'
)(
process
.
pid
,
(
err
,
children
)
=>
{
if
(
err
)
{
return
reject
(
err
)
}
children
.
forEach
(
child
=>
log
.
silly
(
'
TestingWebDriver
'
,
'
ps-tree: %s %s
'
,
child
.
PID
,
child
.
COMMAND
))
const
num
=
children
.
filter
(
child
=>
/phantomjs/i
.
test
(
child
.
COMMAND
)).
length
return
resolve
(
num
)
})
})
}
test
(
'
WebDriver process create & quit test
'
,
function
(
t
)
{
co
(
function
*
()
{
const
b
=
new
PuppetWebBrowser
({
port
:
PORT
,
head
:
HEAD
})
...
...
@@ -37,16 +26,16 @@ test('WebDriver process create & quit test', function(t) {
yield
b
.
open
()
t
.
pass
(
'
opened
'
)
let
n
=
yield
driverProcessNum
()
t
.
ok
(
n
>
0
,
'
driver process exist
'
)
let
pids
=
yield
b
.
getBrowserPids
()
t
.
ok
(
pids
.
length
>
0
,
'
driver process exist
'
)
// console.log(b.driver.getSession())
yield
b
.
quit
()
t
.
pass
(
'
quited
'
)
n
=
yield
driverProcessNum
()
t
.
equal
(
n
,
0
,
'
no driver process after quit
'
)
pids
=
yield
b
.
getBrowserPids
()
t
.
equal
(
pids
.
length
,
0
,
'
no driver process after quit
'
)
})
.
catch
(
e
=>
{
t
.
fail
(
e
)
})
.
then
(
t
.
end
.
bind
(
t
))
...
...
@@ -54,7 +43,6 @@ test('WebDriver process create & quit test', function(t) {
return
})
// XXX WTF with co module???
test
(
'
WebDriver smoke testing
'
,
function
(
t
)
{
const
wb
=
new
PuppetWebBrowser
({
port
:
PORT
,
head
:
HEAD
})
t
.
ok
(
wb
,
'
Browser instnace
'
)
...
...
@@ -66,7 +54,7 @@ test('WebDriver smoke testing', function(t) {
var
driver
// for help function `execute`
co
(
function
*
()
{
const
m
=
yield
driverProcessNum
()
const
m
=
(
yield
wb
.
getBrowserPids
()).
length
t
.
equal
(
m
,
0
,
'
driver process not exist before get()
'
)
driver
=
yield
wb
.
initDriver
()
...
...
@@ -82,7 +70,7 @@ test('WebDriver smoke testing', function(t) {
yield
driver
.
get
(
'
https://wx.qq.com/
'
)
t
.
pass
(
'
driver url opened
'
)
const
n
=
yield
driverProcessNum
()
const
n
=
(
yield
wb
.
getBrowserPids
()).
length
t
.
ok
(
n
>
0
,
'
driver process exist after get()
'
)
const
retAdd
=
yield
execute
(
'
return 1+1
'
)
...
...
@@ -104,64 +92,3 @@ test('WebDriver smoke testing', function(t) {
return
driver
.
executeScript
.
apply
(
driver
,
arguments
)
}
})
test
(
'
WebDriver WTF testing
'
,
function
(
t
)
{
const
wb
=
new
PuppetWebBrowser
({
port
:
PORT
,
head
:
HEAD
})
t
.
ok
(
wb
,
'
Browser instnace
'
)
const
mockPuppet
=
{
browser
:
wb
}
const
bridge
=
new
PuppetWebBridge
({
puppet
:
mockPuppet
,
port
:
PORT
})
t
.
ok
(
bridge
,
'
Bridge instnace
'
)
var
driver
// for help function `execute`
var
injectio
driverProcessNum
()
.
then
(
n
=>
{
t
.
equal
(
n
,
0
,
'
driver process not exist before get()
'
)
return
wb
.
initDriver
()
})
.
then
(
d
=>
{
driver
=
d
t
.
ok
(
driver
,
'
driver inited
'
)
return
bridge
.
getInjectio
()
})
.
then
(
r
=>
{
injectio
=
r
t
.
ok
(
injectio
.
length
>
10
,
'
got injectio
'
)
return
driver
.
get
(
'
https://wx.qq.com/
'
)
})
.
then
(
r
=>
{
t
.
pass
(
'
driver url opened
'
)
return
driverProcessNum
()
})
.
then
(
n
=>
{
t
.
ok
(
n
>
0
,
'
driver process exist after get()
'
)
return
execute
(
'
return 1+1
'
)
})
.
then
(
retAdd
=>
{
t
.
equal
(
retAdd
,
2
,
'
execute js in browser
'
)
return
execute
(
injectio
,
PORT
)
})
.
then
(
retInject
=>
{
t
.
equal
(
retInject
,
'
Wechaty
'
,
'
injected wechaty
'
)
})
.
catch
(
e
=>
t
.
fail
(
'
promise rejected. e:
'
+
e
))
// Rejected
.
then
(
r
=>
wb
.
quit
())
// Finally 1
.
then
(
r
=>
t
.
end
())
// Finally 2
.
catch
(
e
=>
t
.
fail
(
'
exception got:
'
+
e
))
// Exception
return
//////////////////////////////////
function
execute
()
{
return
driver
.
executeScript
.
apply
(
driver
,
arguments
)
}
})
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录