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

code clean

上级 07878c04
### Please run `npm run doctor` and paste the output here ### Run `npm run doctor` and paste the output here
### Expected behavior ### Expected behavior
...@@ -10,3 +10,4 @@ ...@@ -10,3 +10,4 @@
### Steps to reproduce the behavior (and fixes, if any) ### Steps to reproduce the behavior (and fixes, if any)
### Paste the full output logs here with `WECHATY_LOG=silly` set
...@@ -22,13 +22,13 @@ ...@@ -22,13 +22,13 @@
"lint": "npm run eslint && npm run tslint", "lint": "npm run eslint && npm run tslint",
"eslint": "eslint \"{bin,example,src,test}/**/*.js\"", "eslint": "eslint \"{bin,example,src,test}/**/*.js\"",
"tslint": "tslint \"{bin,example,src,test}/**/*.ts\" && tsc --noEmit", "tslint": "tslint \"{bin,example,src,test}/**/*.ts\" && tsc --noEmit",
"sloc": "sloc . --details --format cli-table --keys total,source,comment --exclude \"node_modules|doc\" && sloc . --exclude \"node_modules|doc\"",
"pretest": "npm run lint && npm run clean && npm run build", "pretest": "npm run lint && npm run clean && npm run build",
"sloc": "sloc . --details --format cli-table --keys total,source,comment --exclude \"\\.\\./|dist/|doc/|node_modules/\" && sloc ./ --exclude \"\\.\\./|dist/|doc/|node_modules/\"",
"test": "npm run test:chrome", "test": "npm run test:chrome",
"posttest": "npm run clean && npm run sloc", "posttest": "npm run clean && npm run sloc",
"test:phantomjs": "cross-env LC_ALL=C WECHATY_LOG=info WECHATY_HEAD=phantomjs ava --timeout=10m \"dist/test/*.spec.js\"", "test:phantomjs": "cross-env LC_ALL=C WECHATY_LOG=info WECHATY_HEAD=phantomjs ava --timeout=10m \"dist/test/*.spec.js\"",
"test:phantomjs.bak": "cross-env LC_ALL=C WECHATY_LOG=info WECHATY_HEAD=phantomjs ava --timeout=10m \"dist/{src,test}/**/*.spec.js\"", "test:phantomjs.bak": "cross-env LC_ALL=C WECHATY_LOG=info WECHATY_HEAD=phantomjs ava --timeout=10m \"dist/{src,test}/**/*.spec.js\"",
"test:chrome": "cross-env LC_ALL=C WECHATY_LOG=info WECHATY_HEAD=chrome ava --concurrency 2 --ext js --timeout=10m \"dist/{src,test}/**/*.spec.js\"", "test:chrome": "cross-env LC_ALL=C WECHATY_LOG=verbose WECHATY_HEAD=chrome ava --concurrency 0 --ext js --timeout=10m \"dist/{src,test}/**/*.spec.js\"",
"testdev": "cross-env LC_ALL=C WECHATY_LOG=silly ava --ext ts --serial --verbose --fail-fast --timeout=3m", "testdev": "cross-env LC_ALL=C WECHATY_LOG=silly ava --ext ts --serial --verbose --fail-fast --timeout=3m",
"testdist": "WECHATY_HEAD=phantomjs ava --ext ts --verbose --fail-fast --timeout=3m", "testdist": "WECHATY_HEAD=phantomjs ava --ext ts --verbose --fail-fast --timeout=3m",
"ava": "cross-env LC_ALL=C WECHATY_LOG=verbose ts-node node_modules/.bin/ava \"{src,test}/**/*.spec.js\"", "ava": "cross-env LC_ALL=C WECHATY_LOG=verbose ts-node node_modules/.bin/ava \"{src,test}/**/*.spec.js\"",
......
...@@ -5,15 +5,19 @@ ...@@ -5,15 +5,19 @@
* *
*/ */
// const log = require('npmlog') // const log = require('npmlog')
import Brolog from 'brolog' import {
Brolog
} from 'brolog'
const level = process.env['WECHATY_LOG'] const level = process.env['WECHATY_LOG']
// use a typescript switch/case/default: never to replace regex
const levelRegexStr = 'silly|verbose|info|warn|error|silent' const levelRegexStr = 'silly|verbose|info|warn|error|silent'
const levelRegex = new RegExp(levelRegexStr, 'i') const levelRegex = new RegExp(levelRegexStr, 'i')
if (levelRegex.test(level)) { if (levelRegex.test(level)) {
// log.level = level.toLowerCase() // log.level = level.toLowerCase()
Brolog.level(level) Brolog.level(level)
Brolog.verbose('Brolog', 'WECHATY_LOG set level to %s', level) Brolog.silly('Brolog', 'WECHATY_LOG set level to %s', level)
} }
else if (level) { else if (level) {
Brolog.warn('Brolog', 'env WECHATY_LOG(%s) must be one of silly|verbose|info|warn|error|silent', level) Brolog.warn('Brolog', 'env WECHATY_LOG(%s) must be one of silly|verbose|info|warn|error|silent', level)
......
...@@ -161,6 +161,9 @@ export type RecommendInfo = { ...@@ -161,6 +161,9 @@ export type RecommendInfo = {
export interface Sayable { export interface Sayable {
say(content: string, replyTo?: any|any[]): Promise<void> say(content: string, replyTo?: any|any[]): Promise<void>
} }
export interface Sleepable {
sleep(millisecond: number): Promise<void>
}
export * from './brolog-env' export * from './brolog-env'
......
...@@ -40,7 +40,7 @@ export class BrowserCookie { ...@@ -40,7 +40,7 @@ export class BrowserCookie {
public async read(): Promise<CookieType[]> { public async read(): Promise<CookieType[]> {
// just check cookies, no file operation // just check cookies, no file operation
log.verbose('PuppetWebBrowserCookie', 'checkSession()') log.verbose('PuppetWebBrowserCookie', 'read()')
// if (this.browser.dead()) { // if (this.browser.dead()) {
// throw new Error('checkSession() - browser dead') // throw new Error('checkSession() - browser dead')
...@@ -50,16 +50,16 @@ export class BrowserCookie { ...@@ -50,16 +50,16 @@ export class BrowserCookie {
try { try {
// `as any as DriverCookie` because selenium-webdriver @types is outdated with 2.x, where we r using 3.0 // `as any as DriverCookie` because selenium-webdriver @types is outdated with 2.x, where we r using 3.0
const cookies = await this.driver.manage().getCookies() as any as CookieType[] const cookies = await this.driver.manage().getCookies() as any as CookieType[]
log.silly('PuppetWebBrowserCookie', 'checkSession %s', cookies.map(c => c.name).join(',')) log.silly('PuppetWebBrowserCookie', 'read() %s', cookies.map(c => c.name).join(','))
return cookies return cookies
} catch (e) { } catch (e) {
log.error('PuppetWebBrowserCookie', 'checkSession() getCookies() exception: %s', e && e.message || e) log.error('PuppetWebBrowserCookie', 'read() getCookies() exception: %s', e && e.message || e)
throw e throw e
} }
} }
public async clean(): Promise<void> { public async clean(): Promise<void> {
log.verbose('PuppetWebBrowserCookie', `cleanSession(${this.storeFile})`) log.verbose('PuppetWebBrowserCookie', 'clean() file %s', this.storeFile)
if (!this.storeFile) { if (!this.storeFile) {
return return
} }
...@@ -70,7 +70,7 @@ export class BrowserCookie { ...@@ -70,7 +70,7 @@ export class BrowserCookie {
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
fs.unlink(filename, err => { fs.unlink(filename, err => {
if (err && err.code !== 'ENOENT') { if (err && err.code !== 'ENOENT') {
log.silly('PuppetWebBrowserCookie', 'cleanSession() unlink session file %s fail: %s', filename, err.message) log.silly('PuppetWebBrowserCookie', 'clean() unlink store file %s fail: %s', filename, err.message)
} }
resolve() resolve()
}) })
...@@ -79,9 +79,9 @@ export class BrowserCookie { ...@@ -79,9 +79,9 @@ export class BrowserCookie {
} }
public async save(): Promise<void> { public async save(): Promise<void> {
log.silly('PuppetWebBrowserCookie', `saveSession(${this.storeFile})`) log.silly('PuppetWebBrowserCookie', 'save() to file %s', this.storeFile)
if (!this.storeFile) { if (!this.storeFile) {
log.verbose('PuppetWebBrowserCookie', 'save() no session store file') log.verbose('PuppetWebBrowserCookie', 'save() no store file')
return return
} }
const storeFile = this.storeFile const storeFile = this.storeFile
...@@ -114,42 +114,41 @@ export class BrowserCookie { ...@@ -114,42 +114,41 @@ export class BrowserCookie {
// .then(cookies => { // .then(cookies => {
// log.silly('PuppetWeb', 'saving %d cookies for session: %s', cookies.length // log.silly('PuppetWeb', 'saving %d cookies for session: %s', cookies.length
// , util.inspect(cookies.map(c => { return {name: c.name /*, value: c.value, expiresType: typeof c.expires, expires: c.expires*/} }))) // , util.inspect(cookies.map(c => { return {name: c.name /*, value: c.value, expiresType: typeof c.expires, expires: c.expires*/} })))
log.silly('PuppetWebBrowserCookie', 'saving %d cookies for session: %s', cookies.length, cookies.map(c => c.name).join(',')) log.silly('PuppetWebBrowserCookie', 'save() saving %d cookies: %s', cookies.length, cookies.map(c => c.name).join(','))
const jsonStr = JSON.stringify(cookies) const jsonStr = JSON.stringify(cookies)
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
fs.writeFile(storeFile, jsonStr, err => { fs.writeFile(storeFile, jsonStr, err => {
if (err) { if (err) {
log.error('PuppetWebBrowserCookie', 'saveSession() fail to write file %s: %s', filename, err.errno) log.error('PuppetWebBrowserCookie', 'save() fail to write file %s: %s', filename, err.errno)
reject(err) reject(err)
} }
log.silly('PuppetWebBrowserCookie', 'saved session(%d cookies) to %s', cookies.length, filename) log.silly('PuppetWebBrowserCookie', 'save() %d cookies to %s', cookies.length, filename)
resolve(cookies) resolve(cookies)
}) })
}) })
} catch (e) { } catch (e) {
log.error('PuppetWebBrowserCookie', 'saveSession() getCookies() exception: %s', e.message) log.error('PuppetWebBrowserCookie', 'save() getCookies() exception: %s', e.message)
throw e throw e
} }
} }
public async load(): Promise<void> { public async load(): Promise<void> {
log.verbose('PuppetWebBrowserCookie', 'loadSession() from %s', this.storeFile ? this.storeFile : '' )
if (!this.storeFile) { if (!this.storeFile) {
log.verbose('PuppetWebBrowserCookie', 'load() no session store file') log.silly('PuppetWebBrowserCookie', 'load() skipped because no session store file')
return return
// } else if (this.browser.dead()) { // } else if (this.browser.dead()) {
// throw new Error('loadSession() - browser dead') // throw new Error('loadSession() - browser dead')
} }
const storeFile = this.storeFile const storeFile = this.storeFile
log.verbose('PuppetWebBrowserCookie', 'load() from %s', storeFile)
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
fs.readFile(storeFile, (err, jsonStr) => { fs.readFile(storeFile, (err, jsonStr) => {
if (err) { if (err) {
if (err) { log.silly('PuppetWebBrowserCookie', 'loadSession(%s) skipped because error code: %s', this.storeFile, err.code) } if (err) { log.silly('PuppetWebBrowserCookie', 'load(%s) skipped because error code: %s', this.storeFile, err.code) }
return reject(new Error('error code:' + err.code)) return reject(new Error('error code:' + err.code))
} }
const cookies = JSON.parse(jsonStr.toString()) const cookies = JSON.parse(jsonStr.toString())
...@@ -161,7 +160,7 @@ export class BrowserCookie { ...@@ -161,7 +160,7 @@ export class BrowserCookie {
resolve(cookies) resolve(cookies)
}) })
.catch(e => { .catch(e => {
log.error('PuppetWebBrowserCookie', 'loadSession() addCookies() exception: %s', e.message) log.error('PuppetWebBrowserCookie', 'load() add() exception: %s', e.message)
reject(e) reject(e)
}) })
}) })
......
...@@ -27,46 +27,48 @@ export class BrowserDriver { ...@@ -27,46 +27,48 @@ export class BrowserDriver {
} }
public async init(): Promise<this> { public async init(): Promise<this> {
log.verbose('PuppetWebBrowser', 'initDriver() for head: %s', this.head) log.verbose('PuppetWebBrowserDriver', 'init() for head: %s', this.head)
if (this.driver) { if (this.driver) {
await this.driver.close() try {
await this.driver.quit() await this.driver.close()
await this.driver.quit()
} catch (e) {
log.warn('PuppetWebBrowserDriver', 'init() this.driver.{close,quit}() exception: %s'
, e.message
)
}
} }
const head = this.head switch (this.head) {
case 'phantomjs':
switch (true) {
case !head: // no head default to phantomjs
case /phantomjs/i.test(head):
case /phantom/i.test(head):
this.driver = this.getPhantomJsDriver() this.driver = this.getPhantomJsDriver()
break break
case /firefox/i.test(head): case 'firefox':
this.driver = new Builder() this.driver = new Builder()
.setAlertBehavior('ignore') .setAlertBehavior('ignore')
.forBrowser('firefox') .forBrowser('firefox')
.build() .build()
break break
case /chrome/i.test(head): case 'chrome':
this.driver = this.getChromeDriver() this.driver = this.getChromeDriver()
break break
default: // unsupported browser head default: // unsupported browser head
throw new Error('unsupported head: ' + head) throw new Error('unsupported head: ' + this.head)
} }
this.driver.manage() await this.driver.manage()
.timeouts() .timeouts()
.setScriptTimeout(10000) .setScriptTimeout(10000)
return this return this
} }
private getChromeDriver(): WebDriver { private getChromeDriver(): WebDriver {
log.verbose('PuppetWebBrowser', 'getChromeDriver()') log.verbose('PuppetWebBrowserDriver', 'getChromeDriver()')
/** /**
* http://stackoverflow.com/a/27733960/1123955 * http://stackoverflow.com/a/27733960/1123955
...@@ -88,6 +90,7 @@ export class BrowserDriver { ...@@ -88,6 +90,7 @@ export class BrowserDriver {
// , binary: require('chromedriver').path // , binary: require('chromedriver').path
} }
if (Config.isDocker) { if (Config.isDocker) {
log.verbose('PuppetWebBrowserDriver', 'getChromeDriver() wechaty in docker confirmed(should not show this in CI)')
options['binary'] = Config.CMD_CHROMIUM options['binary'] = Config.CMD_CHROMIUM
} }
...@@ -138,8 +141,8 @@ export class BrowserDriver { ...@@ -138,8 +141,8 @@ export class BrowserDriver {
.set('phantomjs.binary.path', phantomjsExe) .set('phantomjs.binary.path', phantomjsExe)
.set('phantomjs.cli.args', phantomjsArgs) .set('phantomjs.cli.args', phantomjsArgs)
log.silly('PuppetWebBrowser', 'phantomjs binary: ' + phantomjsExe) log.silly('PuppetWebBrowserDriver', 'phantomjs binary: ' + phantomjsExe)
log.silly('PuppetWebBrowser', 'phantomjs args: ' + phantomjsArgs.join(' ')) log.silly('PuppetWebBrowserDriver', 'phantomjs args: ' + phantomjsArgs.join(' '))
const driver = new Builder() const driver = new Builder()
.withCapabilities(customPhantom) .withCapabilities(customPhantom)
...@@ -177,7 +180,7 @@ export class BrowserDriver { ...@@ -177,7 +180,7 @@ export class BrowserDriver {
// public driver1(newDriver?: WebDriver | null): WebDriver | void { // public driver1(newDriver?: WebDriver | null): WebDriver | void {
// if (newDriver !== undefined) { // if (newDriver !== undefined) {
// log.verbose('PuppetWebBrowser', 'driver(%s)' // log.verbose('PuppetWebBrowserDriver', 'driver(%s)'
// , newDriver // , newDriver
// ? newDriver.constructor.name // ? newDriver.constructor.name
// : null // : null
...@@ -199,12 +202,12 @@ export class BrowserDriver { ...@@ -199,12 +202,12 @@ export class BrowserDriver {
// if (!this.driver) { // if (!this.driver) {
// const e = new Error('no driver') // const e = new Error('no driver')
// log.warn('PuppetWebBrowser', 'driver() exception: %s', e.message) // log.warn('PuppetWebBrowserDriver', 'driver() exception: %s', e.message)
// throw e // throw e
// } // }
// // if (!this.driver.getSession()) { // // if (!this.driver.getSession()) {
// // const e = new Error('no driver session') // // const e = new Error('no driver session')
// // log.warn('PuppetWebBrowser', 'driver() exception: %s', e.message) // // log.warn('PuppetWebBrowserDriver', 'driver() exception: %s', e.message)
// // this.driver.quit() // // this.driver.quit()
// // throw e // // throw e
// // } // // }
...@@ -213,8 +216,8 @@ export class BrowserDriver { ...@@ -213,8 +216,8 @@ export class BrowserDriver {
// } // }
public close() { return this.driver.close() } public close() { return this.driver.close() }
public executeScript() { return this.driver.executeScript.apply(this.driver, arguments) }
public executeAsyncScript() { return this.driver.executeAsyncScript.apply(this.driver, arguments) } public executeAsyncScript() { return this.driver.executeAsyncScript.apply(this.driver, arguments) }
public executeScript() { return this.driver.executeScript.apply(this.driver, arguments) }
public get(url: string) { return this.driver.get(url) } public get(url: string) { return this.driver.get(url) }
public getSession() { return this.driver.getSession() } public getSession() { return this.driver.getSession() }
public manage() { return this.driver.manage() } public manage() { return this.driver.manage() }
......
...@@ -55,7 +55,7 @@ export class Browser extends EventEmitter { ...@@ -55,7 +55,7 @@ export class Browser extends EventEmitter {
public toString() { return `Browser({head:${this.setting.head})` } public toString() { return `Browser({head:${this.setting.head})` }
public async init(): Promise<this> { public async init(): Promise<void> {
// this.targetState('open') // this.targetState('open')
// this.currentState('opening') // this.currentState('opening')
this.state.target('open') this.state.target('open')
...@@ -92,7 +92,7 @@ export class Browser extends EventEmitter { ...@@ -92,7 +92,7 @@ export class Browser extends EventEmitter {
// this.currentState('open') // this.currentState('open')
this.state.current('open') this.state.current('open')
return this return
} catch (e) { } catch (e) {
log.error('PuppetWebBrowser', 'init() exception: %s', e.message) log.error('PuppetWebBrowser', 'init() exception: %s', e.message)
...@@ -116,11 +116,12 @@ export class Browser extends EventEmitter { ...@@ -116,11 +116,12 @@ export class Browser extends EventEmitter {
} }
} }
public async refresh(): Promise<any> { public async refresh(): Promise<void> {
log.verbose('PuppetWebBrowser', 'refresh()') log.verbose('PuppetWebBrowser', 'refresh()')
return await this.driver await this.driver
.navigate() .navigate()
.refresh() .refresh()
return
} }
public async restart(): Promise<void> { public async restart(): Promise<void> {
...@@ -137,7 +138,7 @@ export class Browser extends EventEmitter { ...@@ -137,7 +138,7 @@ export class Browser extends EventEmitter {
await this.init() await this.init()
} }
public async quit(): Promise<any> { public async quit(): Promise<void> {
log.verbose('PuppetWebBrowser', 'quit()') log.verbose('PuppetWebBrowser', 'quit()')
// if (this.currentState() === 'closing') { // if (this.currentState() === 'closing') {
......
...@@ -90,10 +90,10 @@ async function onBrowserDead(this: PuppetWeb, e): Promise<void> { ...@@ -90,10 +90,10 @@ async function onBrowserDead(this: PuppetWeb, e): Promise<void> {
return return
} }
this.browser = await this.initBrowser() await this.initBrowser()
log.verbose('PuppetWebEvent', 'onBrowserDead() new browser inited') log.verbose('PuppetWebEvent', 'onBrowserDead() new browser inited')
this.bridge = await this.initBridge() await this.initBridge()
log.verbose('PuppetWebEvent', 'onBrowserDead() bridge re-inited') log.verbose('PuppetWebEvent', 'onBrowserDead() bridge re-inited')
const dong = await this.ding() const dong = await this.ding()
......
...@@ -109,7 +109,7 @@ export class PuppetWeb extends Puppet { ...@@ -109,7 +109,7 @@ export class PuppetWeb extends Puppet {
} }
} }
public async quit(): Promise<any> { public async quit(): Promise<void> {
log.verbose('PuppetWeb', 'quit()') log.verbose('PuppetWeb', 'quit()')
// this.targetState('dead') // this.targetState('dead')
...@@ -177,11 +177,10 @@ export class PuppetWeb extends Puppet { ...@@ -177,11 +177,10 @@ export class PuppetWeb extends Puppet {
log.verbose('PuppetWeb', 'quit() done') log.verbose('PuppetWeb', 'quit() done')
// this.currentState('dead') // this.currentState('dead')
this.state.current('dead') this.state.current('dead')
return this // for Chaining
// }) // })
} }
public async initBrowser(): Promise<Browser> { public async initBrowser(): Promise<void> {
log.verbose('PuppetWeb', 'initBrowser()') log.verbose('PuppetWeb', 'initBrowser()')
const browser = new Browser({ const browser = new Browser({
head: <HeadName>this.setting.head head: <HeadName>this.setting.head
...@@ -194,7 +193,7 @@ export class PuppetWeb extends Puppet { ...@@ -194,7 +193,7 @@ export class PuppetWeb extends Puppet {
// if (this.targetState() !== 'live') { // if (this.targetState() !== 'live') {
if (this.state.target() !== 'live') { if (this.state.target() !== 'live') {
log.warn('PuppetWeb', 'initBrowser() found targetState != live, no init anymore') log.warn('PuppetWeb', 'initBrowser() found state.target()) != live, no init anymore')
// return Promise.resolve('skipped') // return Promise.resolve('skipped')
return Promise.reject('skipped') return Promise.reject('skipped')
} }
...@@ -207,10 +206,10 @@ export class PuppetWeb extends Puppet { ...@@ -207,10 +206,10 @@ export class PuppetWeb extends Puppet {
log.error('PuppetWeb', 'initBrowser() exception: %s', e.message) log.error('PuppetWeb', 'initBrowser() exception: %s', e.message)
throw e throw e
} }
return browser // follow func name meaning return
} }
public initBridge(): Promise<Bridge> { public async initBridge(): Promise<void> {
log.verbose('PuppetWeb', 'initBridge()') log.verbose('PuppetWeb', 'initBridge()')
const bridge = new Bridge( const bridge = new Bridge(
this // use puppet instead of browser, is because browser might change(die) duaring run time this // use puppet instead of browser, is because browser might change(die) duaring run time
...@@ -226,7 +225,7 @@ export class PuppetWeb extends Puppet { ...@@ -226,7 +225,7 @@ export class PuppetWeb extends Puppet {
return Promise.reject(errMsg) return Promise.reject(errMsg)
} }
return bridge.init() await bridge.init()
.catch(e => { .catch(e => {
if (!this.browser) { if (!this.browser) {
log.warn('PuppetWeb', 'initBridge() without browser?') log.warn('PuppetWeb', 'initBridge() without browser?')
...@@ -237,9 +236,10 @@ export class PuppetWeb extends Puppet { ...@@ -237,9 +236,10 @@ export class PuppetWeb extends Puppet {
throw e throw e
} }
}) })
return
} }
private initServer(): Promise<Server> { private async initServer(): Promise<void> {
log.verbose('PuppetWeb', 'initServer()') log.verbose('PuppetWeb', 'initServer()')
const server = new Server(this.port) const server = new Server(this.port)
...@@ -264,16 +264,17 @@ export class PuppetWeb extends Puppet { ...@@ -264,16 +264,17 @@ export class PuppetWeb extends Puppet {
// if (this.targetState() !== 'live') { // if (this.targetState() !== 'live') {
if (this.state.target() !== 'live') { if (this.state.target() !== 'live') {
const errMsg = 'initServer() found targetState != live, no init anymore' const errMsg = 'initServer() found state.target() != live, no init anymore'
log.warn('PuppetWeb', errMsg) log.warn('PuppetWeb', errMsg)
return Promise.reject(errMsg) return Promise.reject(errMsg)
} }
return server.init() await server.init()
.catch(e => { .catch(e => {
log.error('PuppetWeb', 'initServer() exception: %s', e.message) log.error('PuppetWeb', 'initServer() exception: %s', e.message)
throw e throw e
}) })
return
} }
public reset(reason?: string): void { public reset(reason?: string): void {
...@@ -291,7 +292,7 @@ export class PuppetWeb extends Puppet { ...@@ -291,7 +292,7 @@ export class PuppetWeb extends Puppet {
* use Message.self() instead * use Message.self() instead
*/ */
public self(message: Message): boolean { public self(message: Message): boolean {
log.warn('PuppetWeb', 'self() method deprecated. use Message.self() instead') log.warn('PuppetWeb', 'DEPRECATED self() method. use Message.self() instead')
if (!this.userId) { if (!this.userId) {
log.warn('PuppetWeb', 'self() got no this.userId') log.warn('PuppetWeb', 'self() got no this.userId')
...@@ -358,12 +359,13 @@ export class PuppetWeb extends Puppet { ...@@ -358,12 +359,13 @@ export class PuppetWeb extends Puppet {
/** /**
* logout from browser, then server will emit `logout` event * logout from browser, then server will emit `logout` event
*/ */
public logout() { public async logout(): Promise<void> {
return this.bridge.logout() await this.bridge.logout()
.catch(e => { .catch(e => {
log.error('PuppetWeb', 'logout() exception: %s', e.message) log.error('PuppetWeb', 'logout() exception: %s', e.message)
throw e throw e
}) })
return
} }
public getContact(id: string): Promise<any> { public getContact(id: string): Promise<any> {
......
...@@ -16,7 +16,6 @@ import { log } from './config' ...@@ -16,7 +16,6 @@ import { log } from './config'
* A - State A * A - State A
* B - State B * B - State B
*/ */
export class StateMonitor <A, B>{ export class StateMonitor <A, B>{
private _target: A|B private _target: A|B
private _current: A|B private _current: A|B
...@@ -25,45 +24,70 @@ export class StateMonitor <A, B>{ ...@@ -25,45 +24,70 @@ export class StateMonitor <A, B>{
constructor(private client: string, initState: A|B) { constructor(private client: string, initState: A|B) {
log.verbose('StateMonitor', 'constructor(%s, %s)', client, initState) log.verbose('StateMonitor', 'constructor(%s, %s)', client, initState)
this.target(initState) this._target = initState
this.current(initState, true) this._current = initState
this._stable = true
} }
/**
* set/get target state
*/
public target(newState?: A|B): A|B { public target(newState?: A|B): A|B {
if (newState) { if (newState) {
log.verbose('StateMonitor', 'target(%s) %s state change from %s to %s' log.verbose('StateMonitor', '%s.state.target(%s) from %s'
, this.client, newState , this.client
, this._target, newState , newState
) , this._target
)
this._target = newState this._target = newState
} else { } else {
log.verbose('StateMonitor', 'target() %s state is %s', this.client, this._target) log.silly('StateMonitor', '%s.state.target() is %s', this.client, this._target)
} }
return this._target return this._target
} }
/**
* set/get current state
* @param stable boolean true for stable, false for inprocess
*/
public current(newState?: A|B, stable = true): A|B { public current(newState?: A|B, stable = true): A|B {
if (newState) { if (newState) {
log.verbose('StateMonitor', 'current(%s, %s) %s state change from %s:%s to %s:%s' log.verbose('StateMonitor', '%s.state.current(%s, %s) from (%s, %s)'
, newState, stable
, this.client , this.client
, this._current, this._stable
, newState, stable , newState, stable
, this._current, this._stable
) )
if (this._current === newState && this._stable === stable
&& stable === false // warn for inprocess current state change twice, mostly like a logic bug outside
) {
log.warn('StateMonitor', '%s.state.current(%s, %s) called but there are already in the same state'
, this.client
, newState, stable
)
const e = new Error('current unchange')
log.verbose('StateMonitor', e.stack)
}
this._current = newState this._current = newState
this._stable = stable this._stable = stable
} else { } else {
log.verbose('StateMonitor', 'current() %s state is %s', this.client, this._current) log.silly('StateMonitor', '%s.state.current() is %s', this.client, this._current)
} }
return this._current return this._current
} }
/**
* does the current state be stable(not inprocess)?
*/
public stable() { public stable() {
log.verbose('StateMonitor', 'stable() %s state is %s', this.client, this._stable) log.silly('StateMonitor', '%s.state.stable() is %s', this.client, this._stable)
return this._stable return this._stable
} }
/**
* does the current state be inprocess(not stable)?
*/
public inprocess() { public inprocess() {
log.silly('StateMonitor', '%s.state.inprocess() is %s', this.client, !this._stable)
return !this._stable return !this._stable
} }
} }
......
...@@ -327,6 +327,12 @@ export class Wechaty extends EventEmitter implements Sayable { ...@@ -327,6 +327,12 @@ export class Wechaty extends EventEmitter implements Sayable {
return return
} }
public sleep(millisecond: number): Promise<void> {
return new Promise(resolve => {
setTimeout(resolve, millisecond)
})
}
/** /**
* @deprecated * @deprecated
*/ */
......
...@@ -9,7 +9,7 @@ import { ...@@ -9,7 +9,7 @@ import {
import { spy } from 'sinon' import { spy } from 'sinon'
test('Bridge retry-promise testing', async t => { test('Bridge retry-promise test', async t => {
// co(function* () { // co(function* () {
const EXPECTED_RESOLVE = 'Okey' const EXPECTED_RESOLVE = 'Okey'
const EXPECTED_REJECT = 'NotTheTime' const EXPECTED_REJECT = 'NotTheTime'
...@@ -33,10 +33,10 @@ test('Bridge retry-promise testing', async t => { ...@@ -33,10 +33,10 @@ test('Bridge retry-promise testing', async t => {
await retryPromise({ max: 1, backoff: 1 }, function() { await retryPromise({ max: 1, backoff: 1 }, function() {
return delay500() return delay500()
}) })
.then(r => { // .then(r => {
thenSpy(r) // thenSpy(r)
// t.fail('should not resolved retry-promise here') // // t.fail('should not resolved retry-promise here')
}) // })
.catch(e => { .catch(e => {
thenSpy(e) thenSpy(e)
// t.is(e, EXPECTED_REJECT, `retry-promise got ${EXPECTED_REJECT} when wait not enough`) // t.is(e, EXPECTED_REJECT, `retry-promise got ${EXPECTED_REJECT} when wait not enough`)
...@@ -52,22 +52,11 @@ test('Bridge retry-promise testing', async t => { ...@@ -52,22 +52,11 @@ test('Bridge retry-promise testing', async t => {
thenSpy(r) thenSpy(r)
// t.is(r, EXPECTED_RESOLVE, `retryPromise got "${EXPECTED_RESOLVE}" when wait enough`) // t.is(r, EXPECTED_RESOLVE, `retryPromise got "${EXPECTED_RESOLVE}" when wait enough`)
}) })
.catch(e => { // .catch(e => {
thenSpy(e) // thenSpy(e)
// t.fail(`should not be rejected(with ${e}) when there is enough wait`) // // t.fail(`should not be rejected(with ${e}) when there is enough wait`)
}) // })
t.true(thenSpy.withArgs(EXPECTED_RESOLVE).calledOnce, 'should got EXPECTED_RESOLVE when wait enough') t.true(thenSpy.withArgs(EXPECTED_RESOLVE).calledOnce, 'should got EXPECTED_RESOLVE when wait enough')
// })
// .catch(e => { // REJECTED
// t.fail(e)
// })
// .then(r => { // FINALLY
// t.end()
// })
// .catch(e => { // EXCEPTION
// t.fail(e)
// })
}) })
test('Bridge smoking test', async t => { test('Bridge smoking test', async t => {
...@@ -80,47 +69,27 @@ test('Bridge smoking test', async t => { ...@@ -80,47 +69,27 @@ test('Bridge smoking test', async t => {
const b = new Bridge(mockPuppet as PuppetWeb, PORT) const b = new Bridge(mockPuppet as PuppetWeb, PORT)
t.truthy(b, 'should instanciated a bridge with mocked puppet') t.truthy(b, 'should instanciated a bridge with mocked puppet')
// co(function* () { await browser.init()
await browser.init() t.pass('should instanciated a browser')
t.pass('should instanciated a browser')
await browser.open()
await browser.open() t.pass('should open success')
t.pass('should open success')
await b.inject()
await b.inject() t.pass('should injected WechatyBro')
t.pass('should injected WechatyBro')
const retDing = await b.execute('return WechatyBro.ding()')
const retDing = await b.execute('return WechatyBro.ding()') t.is(retDing, 'dong', 'should got dong after execute WechatyBro.ding()')
t.is(retDing, 'dong', 'should got dong after execute WechatyBro.ding()')
// @deprecated
// @deprecated // const retReady = await b.execute('return WechatyBro.isReady()')
// const retReady = await b.execute('return WechatyBro.isReady()') // t.is(typeof retReady, 'boolean', 'should got a boolean return after execute WechatyBro.isReady()')
// t.is(typeof retReady, 'boolean', 'should got a boolean return after execute WechatyBro.isReady()')
const retCode = await b.proxyWechaty('isLogin')
const retCode = await b.proxyWechaty('isLogin') t.is(typeof retCode, 'boolean', 'should got a boolean after call proxyWechaty(isLogin)')
t.is(typeof retCode, 'boolean', 'should got a boolean after call proxyWechaty(isLogin)')
await b.quit()
await b.quit() t.pass('b.quit()')
t.pass('b.quit()') await browser.quit()
await browser.quit() t.pass('browser.quit()')
t.pass('browser.quit()')
// })
// .catch(e => { // Rejected
// t.fail('co promise rejected:' + e)
// })
// .then(r => { // Finally
// return co(function* () {
// await b.quit()
// t.pass('b.quit()')
// await browser.quit()
// t.pass('browser.quit()')
// t.end()
// })
// })
// .catch(e => { // Exception
// t.fail('Test Exception:' + e)
// t.end()
// })
}) })
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
const PROFILE = Config.DEFAULT_PROFILE + '-' + process.pid + '-' const PROFILE = Config.DEFAULT_PROFILE + '-' + process.pid + '-'
let profileCounter = 1 let profileCounter = 1
test('Browser class cookie smoking tests', async t => { test('Browser Cookie smoking test', async t => {
const b = new Browser() const b = new Browser()
t.truthy(b, 'should instanciate a browser instance') t.truthy(b, 'should instanciate a browser instance')
...@@ -78,7 +78,7 @@ test('Browser class cookie smoking tests', async t => { ...@@ -78,7 +78,7 @@ test('Browser class cookie smoking tests', async t => {
await b.quit() await b.quit()
}) })
test('Browser session save before quit, and load after restart', async t => { test('Browser Cookie save/load test', async t => {
const profileName = PROFILE + profileCounter++ const profileName = PROFILE + profileCounter++
let b = new Browser({ let b = new Browser({
...@@ -90,7 +90,7 @@ test('Browser session save before quit, and load after restart', async t => { ...@@ -90,7 +90,7 @@ test('Browser session save before quit, and load after restart', async t => {
* use exception to call b.quit() to clean up * use exception to call b.quit() to clean up
*/ */
try { try {
t.truthy(b, 'new Browser') t.truthy(b, 'should get a new Browser')
// b.targetState('open') // b.targetState('open')
b.state.target('open') b.state.target('open')
......
...@@ -67,8 +67,12 @@ test.serial('PuppetWeb server/browser communication', async t => { ...@@ -67,8 +67,12 @@ test.serial('PuppetWeb server/browser communication', async t => {
await pw.init() await pw.init()
t.pass('should be inited') t.pass('should be inited')
const ret = await dingSocket(pw.server) try {
t.is(ret, EXPECTED_DING_DATA, 'should got EXPECTED_DING_DATA after resolved dingSocket()') const ret = await dingSocket(pw.server)
t.is(ret, EXPECTED_DING_DATA, 'should got EXPECTED_DING_DATA after resolved dingSocket()')
} catch (e) {
t.fail(e.message)
}
await pw.quit() await pw.quit()
......
...@@ -18,32 +18,32 @@ import { ...@@ -18,32 +18,32 @@ import {
* if 2 tests run parallel in the same process, * if 2 tests run parallel in the same process,
* there will have race conditions for the conflict of `getBrowserPids()` * there will have race conditions for the conflict of `getBrowserPids()`
*/ */
test.serial('WebDriver process create & quit test', async t => { test('WebDriver process create & quit test', async t => {
const b = new PuppetWebBrowser() const b = new PuppetWebBrowser()
t.truthy(b, 'should instanciate a browser') t.truthy(b, 'should instanciate a browser')
await b.init() await b.init()
t.pass('should be inited successful') t.pass('should be inited successful')
await b.open() await b.open()
t.pass('should open successful') t.pass('should open successful')
let pids = await b.getBrowserPids() let pids = await b.getBrowserPids()
t.truthy(pids.length > 0, 'should exist browser process after b.open()') t.truthy(pids.length > 0, 'should exist browser process after b.open()')
// console.log(b.driver.getSession()) // console.log(b.driver.getSession())
await b.quit() await b.quit()
t.pass('quited') t.pass('quited')
const useAva = false const useAva = false
if (!useAva) { // ava will run tests concurency... if (!useAva) { // ava will run tests concurency...
pids = await b.getBrowserPids() pids = await b.getBrowserPids()
t.is(pids.length, 0, 'no driver process after quit') t.is(pids.length, 0, 'no driver process after quit')
} }
}) })
test.serial('WebDriver smoke testing', async t => { test('WebDriver smoke testing', async t => {
const wb = new PuppetWebBrowser() const wb = new PuppetWebBrowser()
t.truthy(wb, 'Browser instnace') t.truthy(wb, 'Browser instnace')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册