diff --git a/src/puppet-web/browser-driver.ts b/src/puppet-web/browser-driver.ts index 9596f586d3473247f85c7e28fc27e58dfd5ce648..db1ea3db74b45d2c0dc7b06abb7f0661c95ab8c5 100644 --- a/src/puppet-web/browser-driver.ts +++ b/src/puppet-web/browser-driver.ts @@ -237,11 +237,23 @@ export class BrowserDriver { const session = await driver.getSession() if (!session) { log.verbose('PuppetWebBrowserDriver', 'valid() found an invalid driver') - } else { - log.silly('PuppetWebBrowserDriver', 'valid() driver ok') + return false + } + + let two + try { + two = await this.executeScript('return 1+1') + } catch (e) { + two = e + log.warn('BrowserDriver', 'valid() fail: %s', e.message) + } + + if (two !== 2) { + return false } - return !!session + log.silly('PuppetWebBrowserDriver', 'valid() driver ok') + return true } // public driver1(): WebDriver @@ -286,8 +298,8 @@ export class BrowserDriver { // } public close() { return this.driver.close() } - public executeAsyncScript() { return this.driver.executeAsyncScript.apply(this.driver, arguments) } - public executeScript() { return this.driver.executeScript.apply(this.driver, arguments) } + public executeAsyncScript(script: string|Function, ...args: any[]) { return this.driver.executeAsyncScript.apply(this.driver, arguments) } + public executeScript (script: string|Function, ...args: any[]) { return this.driver.executeScript.apply(this.driver, arguments) } public get(url: string) { return this.driver.get(url) } public getSession() { return this.driver.getSession() } public manage() { return this.driver.manage() } diff --git a/src/puppet-web/browser.ts b/src/puppet-web/browser.ts index d6be9db79859ca5fbe7c98661f8dda366c3efe86..aa875d33f1d52b5101d0fdddf16877322df6a787 100644 --- a/src/puppet-web/browser.ts +++ b/src/puppet-web/browser.ts @@ -133,10 +133,16 @@ export class Browser extends EventEmitter { public async quit(): Promise { log.verbose('PuppetWebBrowser', 'quit()') - if (this.state.current() === 'close' && this.state.inprocess()) { - const e = new Error('quit() be called when state.current() is close with inprocess()?') - log.warn('PuppetWebBrowser', e.message) - throw e + if (this.state.current() === 'close') { + if (this.state.inprocess()) { + const e = new Error('quit() on a browser with state.current():`close` and inprocess():`true` ?') + log.warn('PuppetWebBrowser', e.message) + throw e + } else { // stable + const e = new Error('quit() on a already quit-ed browser') + log.warn('PuppetWebBrowser', e.message) + throw e + } } this.state.current('close', false) diff --git a/src/puppet-web/puppet-web.ts b/src/puppet-web/puppet-web.ts index c152bdbd4c9b38aabe823843952b93411db7480b..28b67914f5b92ad653fb4ca1e7788010a77cb3da 100644 --- a/src/puppet-web/puppet-web.ts +++ b/src/puppet-web/puppet-web.ts @@ -135,39 +135,37 @@ export class PuppetWeb extends Puppet { try { - if (this.bridge) { // TODO use StateMonitor - await this.bridge.quit() - .catch(e => { // fail safe - log.warn('PuppetWeb', 'quit() bridge.quit() exception: %s', e.message) - }) - log.verbose('PuppetWeb', 'quit() bridge.quit() this.bridge = null') - // this.bridge = null - } else { log.warn('PuppetWeb', 'quit() without a bridge') } - - if (this.server) { // TODO use StateMonitor - await this.server.quit() - // this.server = null - log.verbose('PuppetWeb', 'quit() server.quit() this.server = null') - } else { log.verbose('PuppetWeb', 'quit() without a server') } - - if (this.browser) { // TODO use StateMonitor - await this.browser.quit() - .catch(e => { // fail safe - log.warn('PuppetWeb', 'quit() browser.quit() exception: %s', e.message) - }) - log.verbose('PuppetWeb', 'quit() server.quit() this.browser = null') - // this.browser = null - } else { log.warn('PuppetWeb', 'quit() without a browser') } + await this.bridge.quit() + .catch(e => { // fail safe + log.warn('PuppetWeb', 'quit() bridge.quit() exception: %s', e.message) + }) + // log.verbose('PuppetWeb', 'quit() bridge.quit() this.bridge = null') + // this.bridge = null + + await this.server.quit() + .catch(e => { // fail safe + log.warn('PuppetWeb', 'quit() server.quit() exception: %s', e.message) + }) + // this.server = null + // log.verbose('PuppetWeb', 'quit() server.quit() this.server = null') + + await this.browser.quit() + .catch(e => { // fail safe + log.warn('PuppetWeb', 'quit() browser.quit() exception: %s', e.message) + }) + // log.verbose('PuppetWeb', 'quit() server.quit() this.browser = null') + // this.browser = null this.state.current('dead') + log.silly('PuppetWeb', 'quit() done') + + return + } catch (e) { log.error('PuppetWeb', 'quit() exception: %s', e.message) this.state.current('dead') throw e } - - log.silly('PuppetWeb', 'quit() done') - this.state.current('dead') } public createBrowser() { diff --git a/src/puppet.ts b/src/puppet.ts index 216ff7a2758593453f3188e8367bc5e5d91c3292..cf59798542db76a5b43bd9c599dc60d359d94e7f 100644 --- a/src/puppet.ts +++ b/src/puppet.ts @@ -14,7 +14,7 @@ import { EventEmitter } from 'events' import { Sayable -} from './config' +} from './config' import { Contact } from './contact' import { Message } from './message' import { StateMonitor } from './state-monitor' diff --git a/test/puppet-web/watchdog.spec.ts b/test/puppet-web/watchdog.spec.ts index a4615542fd467c1d20d6d5a181948997f035f07c..daef58217866044ab4f883363e4b08fa08e1305a 100644 --- a/test/puppet-web/watchdog.spec.ts +++ b/test/puppet-web/watchdog.spec.ts @@ -6,6 +6,7 @@ * */ import { test } from 'ava' +import * as sinon from 'sinon' /* tslint:disable:no-var-requires */ const retryPromise = require('retry-promise').default @@ -21,7 +22,7 @@ import { const PROFILE = 'unit-test-session.wechaty.json' -test('Puppet Web watchdog timer', async t => { +test('timer', async t => { const pw = new PuppetWeb({profile: PROFILE}) t.truthy(pw, 'should instantiate a PuppetWeb') @@ -31,7 +32,7 @@ test('Puppet Web watchdog timer', async t => { Watchdog.onFeed.call(pw, { data: 'initing directly' }) t.pass('should ok with default food type') - const origLogLevel = log.level() + const savedLevel = log.level() if (log.level() === 'info') { log.level('silent') t.pass('set log.level = silent to mute log when watchDog reset wechaty temporary') @@ -43,19 +44,20 @@ test('Puppet Web watchdog timer', async t => { { pw.removeListener('error', failOnUnexpectedErrorEvent) - let errorCounter = 0 - pw.once('error', e => errorCounter++) + // let errorCounter = 0 + const spy = sinon.spy() + pw.once('error', spy) pw.emit('watchdog', { data: 'active_for_timeout_1ms' , timeout: 1 }) - await new Promise(resolve => setTimeout(resolve, 10)) // wait untill reset - t.is(errorCounter, 1, 'should get event[error] after watchdog timeout') + await new Promise(resolve => setTimeout(resolve, 10)) // wait until reset + t.truthy(spy.calledOnce, 'should get event[error] after watchdog timeout') pw.addListener('error', failOnUnexpectedErrorEvent) } - // pw.once('error', e => t.fail('waitDing() triggered watchDogReset()')) + pw.once('error', e => t.fail('waitDing() triggered watchDogReset()')) const EXPECTED_DING_DATA = 'dingdong' pw.emit('watchdog', { data: 'feed to extend the dog life', timeout: 120000 }) @@ -63,7 +65,7 @@ test('Puppet Web watchdog timer', async t => { const dong = await waitDing(EXPECTED_DING_DATA) t.is(dong, EXPECTED_DING_DATA, 'should get EXPECTED_DING_DATA from ding after watchdog reset, and restored log level') - log.level(origLogLevel) + log.level(savedLevel) await pw.quit() return