提交 dee2ae99 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

better watchDog reset, code cleanup

上级 d931da79
......@@ -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('PuppetwebBridge', 'new Bridge({puppet: %s, port: %s})'
log.verbose('PuppetWebBridge', '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('PuppetwebBridge', 'init()')
log.verbose('PuppetWebBridge', '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('PuppetwebBridge', 'quit()')
log.verbose('PuppetWebBridge', 'quit()')
return this.proxyWechaty('logout')
.catch(e => {
log.error('PuppetwebBridge', 'logout() exception: %s', e.message)
log.error('PuppetWebBridge', 'logout() exception: %s', e.message)
throw e
})
}
quit() {
log.verbose('PuppetwebBridge', 'quit()')
log.verbose('PuppetWebBridge', 'quit()')
return this.proxyWechaty('quit')
.catch(e => {
log.error('PuppetwebBridge', 'quit() exception: %s', e.message)
log.error('PuppetWebBridge', 'quit() exception: %s', e.message)
throw e
})
}
......@@ -56,7 +64,7 @@ class Bridge {
getUserName() {
return this.proxyWechaty('getUserName')
.catch(e => {
log.error('PuppetwebBridge', 'getUserName() exception: %s', e.message)
log.error('PuppetWebBridge', '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('PuppetwebBridge', 'send() exception: %s', e.message)
log.error('PuppetWebBridge', '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('PuppetwebBridge', 'getContact() retryPromise: attampt %s/%s time for timeout %s'
log.silly('PuppetWebBridge', '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('PuppetwebBridge', 'proxyWechaty(getContact, %s) exception: %s', id, e.message)
log.error('PuppetWebBridge', 'proxyWechaty(getContact, %s) exception: %s', id, e.message)
throw e
})
}.bind(this))
.catch(e => {
log.error('PuppetwebBridge', 'retryPromise() getContact() finally FAIL: %s', e.message)
log.error('PuppetWebBridge', 'retryPromise() getContact() finally FAIL: %s', e.message)
throw e
})
/////////////////////////////////
......@@ -110,17 +118,17 @@ class Bridge {
)
}
inject() {
log.verbose('PuppetwebBridge', 'inject()')
log.verbose('PuppetWebBridge', 'inject()')
return co.call(this, function* () {
const injectio = this.getInjectio()
let r = yield this.execute(injectio, this.port)
log.verbose('PuppetwebBridge', 'inject() injected, got [%s]', r)
log.verbose('PuppetWebBridge', 'inject() injected, got [%s]', r)
r = yield this.proxyWechaty('init')
log.verbose('PuppetwebBridge', 'inject() Wechaty.init() return: %s', r)
log.verbose('PuppetWebBridge', 'inject() Wechaty.init() return: %s', r)
return r
})
.catch (e => {
log.error('PuppetwebBridge', 'inject() exception: %s', e.message)
log.error('PuppetWebBridge', '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('PuppetwebBridge', 'proxyWechaty(%s, ...args) %s', wechatyFunc, wechatyScript)
log.silly('PuppetWebBridge', 'proxyWechaty(%s, ...args) %s', wechatyFunc, wechatyScript)
return this.execute(wechatyScript)
.catch(e => {
log.error('PuppetwebBridge', 'proxyWechaty() exception: %s', e.message)
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.message)
log.warn('PuppetWebBridge', 'execute() exception: %s', e.message || e)
throw e
})
}
......
......@@ -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 {
return reject('dirty')
reject(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)
......
......@@ -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 SocketIO
, 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() {
......
......@@ -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
})
}
......
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
})
}
})
*/
......@@ -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.
先完成此消息的编辑!
想要评论请 注册