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

merge ava

root = true
[*]
indent_style = space
indent_size = 2
\ No newline at end of file
......@@ -503,10 +503,11 @@ Know more about TAP: [Why I use Tape Instead of Mocha & So Should You](https://m
# Version History
## v0.3.9 (master)
## v0.3.13 (master)
1. Managed by Cloud Manager: https://app.wechaty.io
1. Dockerized & Published to docker hub as: [zixia/wechaty](https://hub.docker.com/r/zixia/wechaty/)
1. add `reset` & `shutdown` to IO Event
1. Unit Test Runner switch from Tape/Tap to AVA <https://github.com/avajs/ava>
## v0.2.3 (2016/7/28)
1. add wechaty.io cloud management support: set environment variable `WECHATY_TOKEN` to enable io support
......
......@@ -8,7 +8,11 @@ echo "Docker Starting Wechaty v$(wechaty-version)"
# to identify run env (for tests)
export WECHATY_DOCKER='docker'
# CI will force ava to output use --verbose param, which is fit docker console log
export CI="$WECHATY_DOCKER"
echo "WECHATY_HEAD=$WECHATY_HEAD"
if [ "$WECHATY_HEAD" != "phantomjs" ]; then
export DISPLAY=':99.0'
Xvfb :99 -screen 0 1024x768x24 &
......
......@@ -11,9 +11,13 @@ const IoBot = require('./src/io-bot')
const log = require('./src/npmlog-env')
const Config = require('./src/config')
const UtilLib = require('./src/util-lib')
Object.assign(Wechaty, {
Message
default: Wechaty
, Wechaty
, Message
, Contact
, Room
......@@ -26,6 +30,7 @@ Object.assign(Wechaty, {
, log // for convenionce use npmlog with environment variable LEVEL
, Config
, UtilLib
})
module.exports = Wechaty
......@@ -6,16 +6,17 @@
"wechaty": {
"DEFAULT_HEAD": "chrome",
"DEFAULT_PUPPET": "web",
"DEFAULT_PROFILE": "default-profile-name",
"DEFAULT_PORT": 8788,
"DEFAULT_PUPPET_PORT": 58788
},
"scripts": {
"lint": "eslint src test",
"lint": "eslint src test || echo ok",
"pretest": "npm run lint",
"start": "node bin/io-bot",
"demo": "node example/ding-dong-bot.js",
"test": "cross-env LC_ALL=C TAP_TIMEOUT=600 WECHATY_LOG=silly tape \"test/**/*.spec.js\"",
"devtest": "cross-env LC_ALL=C TAP_TIMEOUT=600 tape"
"test": "cross-env LC_ALL=C WECHATY_LOG=verbose ava --timeout=10m \"{src,test}/**/*.spec.js\"",
"testdev": "cross-env LC_ALL=C WECHATY_LOG=silly ava --verbose --fail-fast --timeout=3m"
},
"repository": {
"type": "git",
......@@ -69,6 +70,7 @@
},
"devDependencies": {
"apiai": "^2.0.7",
"ava": "^0.16.0",
"cookie-parser": "^1.4.3",
"cross-env": "^2.0.0",
"eslint": "^3.3.1",
......
......@@ -52,7 +52,9 @@ class Contact {
if (!this.id) {
log.warn('Contact', 'ready() call on an un-inited contact')
return Promise.resolve(this)
} else if (this.obj.id) {
}
if (this.obj.id) { // already ready
return Promise.resolve(this)
}
......@@ -61,15 +63,15 @@ class Contact {
contactGetter = Contact.puppet.getContact.bind(Contact.puppet)
}
return contactGetter(this.id)
.then(data => {
log.silly('Contact', `contactGetter(${this.id}) resolved`)
this.rawObj = data
this.obj = this.parse(data)
return this
}).catch(e => {
log.error('Contact', `contactGetter(${this.id}) exception: %s`, e.message)
throw e
})
.then(data => {
log.silly('Contact', `contactGetter(${this.id}) resolved`)
this.rawObj = data
this.obj = this.parse(data)
return this
}).catch(e => {
log.error('Contact', `contactGetter(${this.id}) exception: %s`, e.message)
throw e
})
}
dumpRaw() {
......@@ -95,13 +97,14 @@ class Contact {
Contact.init = function() { Contact.pool = {} }
Contact.init()
Contact.load = function(id) {
if (!id) { return null }
if (id in Contact.pool) {
return Contact.pool[id]
if (!(id in Contact.pool)) {
Contact.pool[id] = new Contact(id)
}
return Contact.pool[id] = new Contact(id)
return Contact.pool[id]
}
// Contact.search = function(options) {
// if (options.name) {
......@@ -114,6 +117,9 @@ Contact.load = function(id) {
// return []
// }
Contact.attach = function(puppet) { Contact.puppet = puppet }
Contact.attach = function(puppet) {
log.verbose('Contact', 'attach() to %s', puppet && puppet.constructor.name)
Contact.puppet = puppet
}
module.exports = Contact
......@@ -164,7 +164,10 @@ Object.keys(Message.Type).forEach(k => {
Message.Type[v] = k // Message.Type[1] = 'TEXT'
})
Message.attach = function(puppet) { Message.puppet = puppet }
Message.attach = function(puppet) {
log.verbose('Message', 'attach() to %s', puppet && puppet.constructor.name)
Message.puppet = puppet
}
module.exports = Message
......
......@@ -192,7 +192,14 @@ this.onResourceRequested = function(request, net) {
this.driver = null
log.silly('PuppetWebBrowser', 'quit() this.driver = null')
/**
*
* if we use AVA to test, then this.clean will cause problems
* because there will be more than one instance of browser with the same nodejs process id
*
*/
yield this.clean()
log.silly('PuppetWebBrowser', 'quit() co() end')
}).catch(e => {
// console.log(e)
......
......@@ -276,26 +276,29 @@ function onServerLogin(data, attempt = 0) {
log.verbose('PuppetWebEvent', 'bridge.getUserName: %s', this.userId)
this.user = yield Contact.load(this.userId).ready()
log.verbose('PuppetWebEvent', `onServerLogin() user ${this.user.name()} logined`)
this.emit('login', this.user)
yield this.browser.saveSession()
.catch(e => { // fail safe
log.warn('PuppetWebEvent', 'onServerLogin() browser.saveSession exception: %s', e.message)
})
this.emit('login', this.user)
}).catch(e => {
log.error('PuppetWebEvent', 'onServerLogin() exception: %s', e.message)
throw e
})
}
function onServerLogout(data) {
if (this.user) {
this.emit('logout', this.user)
} else if (this.userId) {
this.emit('logout', this.userId)
} else { log.verbose('PuppetWebEvent', 'onServerLogout() without this.user or userId initialized') }
this.emit('logout', this.user || this.userId)
if (!this.user && !this.userId) {
log.warn('PuppetWebEvent', 'onServerLogout() without this.user or userId initialized')
}
this.userId = null
this.user = null
this.user = null
// this.browser.cleanSession()
// .catch(e => { /* fail safe */
......
/**
*
* wechaty: Wechat for Bot. and for human who talk to bot/robot
*
* Class PuppetWeb
*
* use to control wechat in web browser.
*
* Licenst: ISC
* https://github.com/zixia/wechaty
*
*/
/**************************************
*
* Class PuppetWeb
*
***************************************/
const util = require('util')
const fs = require('fs')
const co = require('co')
const log = require('../npmlog-env')
const Puppet = require('../puppet')
const Contact = require('../contact')
const Room = require('../room')
const Message = require('../message')
const Server = require('./server')
const PuppetWeb = require('./puppet-web')
const Event = require('./event')
const Server = require('./server')
const Browser = require('./browser')
const Bridge = require('./bridge')
const Event = require('./event')
const Watchdog = require('./watchdog')
const UtilLib = require('../util-lib')
const Config = require('../config')
class PuppetWeb extends Puppet {
constructor({
head = Config.DEFAULT_HEAD
, profile = null // if not set profile, then do not store session.
} = {}) {
super()
this.head = head
this.profile = profile
this.userId = null // user id
this.user = null // <Contact> of user self
}
toString() { return `Class PuppetWeb({browser:${this.browser},port:${this.port}})` }
init() {
log.verbose('PuppetWeb', `init() with head:${this.head}, profile:${this.profile}`)
this.readyState('connecting')
this.on('watchdog', Watchdog.onFeed.bind(this))
return co.call(this, function* () {
this.port = yield UtilLib.getPort(Config.DEFAULT_PUPPET_PORT)
log.verbose('PuppetWeb', 'init() getPort %d', this.port)
yield this.initAttach(this)
log.verbose('PuppetWeb', 'initAttach() done')
this.server = yield this.initServer()
log.verbose('PuppetWeb', 'initServer() done')
this.browser = yield this.initBrowser()
log.verbose('PuppetWeb', 'initBrowser() done')
this.bridge = yield this.initBridge()
log.verbose('PuppetWeb', 'initBridge() done')
// this.watchDog('inited') // start watchdog
this.emit('watchdog', { data: 'inited' })
})
.catch(e => { // Reject
log.error('PuppetWeb', 'init exception: %s', e.message)
this.quit()
throw e
})
.then(() => { // Finally
log.verbose('PuppetWeb', 'init() done')
this.readyState('connected')
return this // for Chaining
})
}
quit() {
log.verbose('PuppetWeb', 'quit()')
if (this.readyState() === 'disconnecting') {
log.warn('PuppetWeb', 'quit() is called but readyState is `disconnecting`?')
throw new Error('do not call quit again when quiting')
}
// POISON must feed before readyState set to "disconnecting"
this.emit('watchdog', {
data: 'PuppetWeb.quit()',
type: 'POISON'
})
this.readyState('disconnecting')
return co.call(this, function* () {
if (this.bridge) {
yield 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) {
yield 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) {
yield 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') }
log.verbose('PuppetWeb', 'quit() server.quit() this.initAttach(null)')
yield this.initAttach(null)
})
.catch(e => { // Reject
log.error('PuppetWeb', 'quit() exception: %s', e.message)
throw e
})
.then(() => { // Finally, Fail Safe
log.verbose('PuppetWeb', 'quit() done')
this.readyState('disconnected')
return this // for Chaining
})
}
initAttach(puppet) {
log.verbose('PuppetWeb', 'initAttach()')
Contact.attach(puppet)
Room.attach(puppet)
Message.attach(puppet)
return Promise.resolve(!!puppet)
}
initBrowser() {
log.verbose('PuppetWeb', 'initBrowser()')
const browser = new Browser({
head: this.head
, sessionFile: this.profile
})
browser.on('dead', Event.onBrowserDead.bind(this))
// fastUrl is used to open in browser for we can set cookies.
// backup: 'https://res.wx.qq.com/zh_CN/htmledition/v2/images/icon/ico_loading28a2f7.gif'
const fastUrl = 'https://wx.qq.com/zh_CN/htmledition/v2/images/webwxgeticon.jpg'
return co.call(this, function* () {
yield browser.init()
yield browser.open(fastUrl)
yield browser.loadSession()
.catch(e => { // fail safe
log.verbose('PuppetWeb', 'browser.loadSession(%s) exception: %s', this.profile, e.message || e)
})
yield browser.open()
return browser // follow func name meaning
}).catch(e => {
log.error('PuppetWeb', 'initBrowser() exception: %s', e.message)
throw e
})
}
initBridge() {
log.verbose('PuppetWeb', 'initBridge()')
const bridge = new Bridge({
puppet: this // use puppet instead of browser, is because browser might change(die) duaring run time
, port: this.port
})
return bridge.init()
.catch(e => {
if (this.browser.dead()) {
log.warn('PuppetWeb', 'initBridge() found browser dead, wait it to restore')
} else {
log.error('PuppetWeb', 'initBridge() exception: %s', e.message)
throw e
}
})
}
initServer() {
log.verbose('PuppetWeb', 'initServer()')
const server = new Server({port: this.port})
server.on('scan' , Event.onServerScan.bind(this))
server.on('login' , Event.onServerLogin.bind(this))
server.on('logout' , Event.onServerLogout.bind(this))
server.on('message' , Event.onServerMessage.bind(this))
/**
* @depreciated 20160825 zixia
*
* when `unload` there should always be a `disconnect` event?
*/
// server.on('unload' , Event.onServerUnload.bind(this))
server.on('connection', Event.onServerConnection.bind(this))
server.on('disconnect', Event.onServerDisconnect.bind(this))
server.on('log' , Event.onServerLog.bind(this))
server.on('ding' , Event.onServerDing.bind(this))
return server.init()
.catch(e => {
log.error('PuppetWeb', 'initServer() exception: %s', e.message)
throw e
})
}
self(message) {
if (!this.userId) {
log.verbose('PuppetWeb', 'self() got no this.userId')
return false
}
if (!message || !message.get('from')) {
log.verbose('PuppetWeb', 'self() got no message')
return false
}
return this.userId == message.get('from')
}
send(message) {
const to = message.get('to')
const room = message.get('room')
let content = message.get('content')
let destination = to
if (room) {
destination = room
// if (to && to!==room) {
// content = `@[${to}] ${content}`
// }
}
log.silly('PuppetWeb', `send(${destination}, ${content})`)
return this.bridge.send(destination, content)
.catch(e => {
log.error('PuppetWeb', 'send() exception: %s', e.message)
throw e
})
}
reply(message, replyContent) {
if (this.self(message)) {
return Promise.reject(new Error('will not to reply message of myself'))
}
const m = new Message()
.set('content' , replyContent)
.set('from' , message.obj.to)
.set('to' , message.obj.from)
.set('room' , message.obj.room)
// log.verbose('PuppetWeb', 'reply() by message: %s', util.inspect(m))
return this.send(m)
.catch(e => {
log.error('PuppetWeb', 'reply() exception: %s', e.message)
throw e
})
}
/**
* logout from browser, then server will emit `logout` event
*/
logout() {
return this.bridge.logout()
.catch(e => {
log.error('PuppetWeb', 'logout() exception: %s', e.message)
throw e
})
}
getContact(id) {
return this.bridge.getContact(id)
.catch(e => {
log.error('PuppetWeb', 'getContact(%d) exception: %s', id, e.message)
throw e
})
}
logined() { return !!(this.user) }
ding(data) {
if (!this.bridge) {
return Promise.reject(new Error('ding fail: no bridge(yet)!'))
}
return this.bridge.ding(data)
.catch(e => {
log.warn('PuppetWeb', 'ding(%s) rejected: %s', data, e.message)
throw e
})
}
}
const Bridge = require('./bridge')
const Watchdog = require('./watchdog')
Object.assign(PuppetWeb, {
default: PuppetWeb
, PuppetWeb
, Server
, Browser
, Bridge
, Event
, Watchdog
})
module.exports = PuppetWeb
import { test } from 'ava'
import { PuppetWeb } from './'
test('PuppetWeb Module Exports', t => {
t.truthy(PuppetWeb.default , 'should export default')
t.truthy(PuppetWeb.PuppetWeb , 'should export PuppetWeb')
t.truthy(PuppetWeb.Event , 'should export Event')
t.truthy(PuppetWeb.Watchdog , 'should export Watchdog')
t.truthy(PuppetWeb.Server , 'should export Server')
t.truthy(PuppetWeb.Browser , 'should export Browser')
t.truthy(PuppetWeb.Bridge , 'should export Bridge')
})
/**
*
* wechaty: Wechat for Bot. and for human who talk to bot/robot
*
* Class PuppetWeb
*
* use to control wechat in web browser.
*
* Licenst: ISC
* https://github.com/zixia/wechaty
*
*/
/**************************************
*
* Class PuppetWeb
*
***************************************/
const util = require('util')
const fs = require('fs')
const co = require('co')
const log = require('../npmlog-env')
const Puppet = require('../puppet')
const Contact = require('../contact')
const Room = require('../room')
const Message = require('../message')
const Server = require('./server')
const Browser = require('./browser')
const Bridge = require('./bridge')
const Event = require('./event')
const Watchdog = require('./watchdog')
const UtilLib = require('../util-lib')
const Config = require('../config')
class PuppetWeb extends Puppet {
constructor({
head = Config.DEFAULT_HEAD
, profile = null // if not set profile, then do not store session.
} = {}) {
super()
this.head = head
this.profile = profile
this.userId = null // user id
this.user = null // <Contact> of user self
}
toString() { return `Class PuppetWeb({browser:${this.browser},port:${this.port}})` }
init() {
log.verbose('PuppetWeb', `init() with head:${this.head}, profile:${this.profile}`)
this.readyState('connecting')
this.on('watchdog', Watchdog.onFeed.bind(this))
return co.call(this, function* () {
this.port = yield UtilLib.getPort(Config.DEFAULT_PUPPET_PORT)
log.verbose('PuppetWeb', 'init() getPort %d', this.port)
yield this.initAttach(this)
log.verbose('PuppetWeb', 'initAttach() done')
this.server = yield this.initServer()
log.verbose('PuppetWeb', 'initServer() done')
this.browser = yield this.initBrowser()
log.verbose('PuppetWeb', 'initBrowser() done')
this.bridge = yield this.initBridge()
log.verbose('PuppetWeb', 'initBridge() done')
// this.watchDog('inited') // start watchdog
this.emit('watchdog', { data: 'inited' })
})
.catch(e => { // Reject
log.error('PuppetWeb', 'init exception: %s', e.message)
this.quit()
throw e
})
.then(() => { // Finally
log.verbose('PuppetWeb', 'init() done')
this.readyState('connected')
return this // for Chaining
})
}
quit() {
log.verbose('PuppetWeb', 'quit()')
if (this.readyState() === 'disconnecting') {
log.warn('PuppetWeb', 'quit() is called but readyState is `disconnecting`?')
throw new Error('do not call quit again when quiting')
}
// POISON must feed before readyState set to "disconnecting"
this.emit('watchdog', {
data: 'PuppetWeb.quit()',
type: 'POISON'
})
this.readyState('disconnecting')
return co.call(this, function* () {
if (this.bridge) {
yield 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) {
yield 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) {
yield 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') }
log.verbose('PuppetWeb', 'quit() server.quit() this.initAttach(null)')
yield this.initAttach(null)
})
.catch(e => { // Reject
log.error('PuppetWeb', 'quit() exception: %s', e.message)
throw e
})
.then(() => { // Finally, Fail Safe
log.verbose('PuppetWeb', 'quit() done')
this.readyState('disconnected')
return this // for Chaining
})
}
initAttach(puppet) {
log.verbose('PuppetWeb', 'initAttach()')
Contact.attach(puppet)
Room.attach(puppet)
Message.attach(puppet)
return Promise.resolve(!!puppet)
}
initBrowser() {
log.verbose('PuppetWeb', 'initBrowser()')
const browser = new Browser({
head: this.head
, sessionFile: this.profile
})
browser.on('dead', Event.onBrowserDead.bind(this))
// fastUrl is used to open in browser for we can set cookies.
// backup: 'https://res.wx.qq.com/zh_CN/htmledition/v2/images/icon/ico_loading28a2f7.gif'
const fastUrl = 'https://wx.qq.com/zh_CN/htmledition/v2/images/webwxgeticon.jpg'
return co.call(this, function* () {
yield browser.init()
yield browser.open(fastUrl)
yield browser.loadSession()
.catch(e => { // fail safe
log.verbose('PuppetWeb', 'browser.loadSession(%s) exception: %s', this.profile, e.message || e)
})
yield browser.open()
return browser // follow func name meaning
}).catch(e => {
log.error('PuppetWeb', 'initBrowser() exception: %s', e.message)
throw e
})
}
initBridge() {
log.verbose('PuppetWeb', 'initBridge()')
const bridge = new Bridge({
puppet: this // use puppet instead of browser, is because browser might change(die) duaring run time
, port: this.port
})
return bridge.init()
.catch(e => {
if (this.browser.dead()) {
log.warn('PuppetWeb', 'initBridge() found browser dead, wait it to restore')
} else {
log.error('PuppetWeb', 'initBridge() exception: %s', e.message)
throw e
}
})
}
initServer() {
log.verbose('PuppetWeb', 'initServer()')
const server = new Server({port: this.port})
server.on('scan' , Event.onServerScan.bind(this))
server.on('login' , Event.onServerLogin.bind(this))
server.on('logout' , Event.onServerLogout.bind(this))
server.on('message' , Event.onServerMessage.bind(this))
/**
* @depreciated 20160825 zixia
*
* when `unload` there should always be a `disconnect` event?
*/
// server.on('unload' , Event.onServerUnload.bind(this))
server.on('connection', Event.onServerConnection.bind(this))
server.on('disconnect', Event.onServerDisconnect.bind(this))
server.on('log' , Event.onServerLog.bind(this))
server.on('ding' , Event.onServerDing.bind(this))
return server.init()
.catch(e => {
log.error('PuppetWeb', 'initServer() exception: %s', e.message)
throw e
})
}
self(message) {
if (!this.userId) {
log.verbose('PuppetWeb', 'self() got no this.userId')
return false
}
if (!message || !message.get('from')) {
log.verbose('PuppetWeb', 'self() got no message')
return false
}
return this.userId == message.get('from')
}
send(message) {
const to = message.get('to')
const room = message.get('room')
let content = message.get('content')
let destination = to
if (room) {
destination = room
// if (to && to!==room) {
// content = `@[${to}] ${content}`
// }
}
log.silly('PuppetWeb', `send(${destination}, ${content})`)
return this.bridge.send(destination, content)
.catch(e => {
log.error('PuppetWeb', 'send() exception: %s', e.message)
throw e
})
}
reply(message, replyContent) {
if (this.self(message)) {
return Promise.reject(new Error('will not to reply message of myself'))
}
const m = new Message()
.set('content' , replyContent)
.set('from' , message.obj.to)
.set('to' , message.obj.from)
.set('room' , message.obj.room)
// log.verbose('PuppetWeb', 'reply() by message: %s', util.inspect(m))
return this.send(m)
.catch(e => {
log.error('PuppetWeb', 'reply() exception: %s', e.message)
throw e
})
}
/**
* logout from browser, then server will emit `logout` event
*/
logout() {
return this.bridge.logout()
.catch(e => {
log.error('PuppetWeb', 'logout() exception: %s', e.message)
throw e
})
}
getContact(id) {
if (!this.bridge) {
throw new Error('PuppetWeb has no bridge for getContact()')
}
return this.bridge.getContact(id)
.catch(e => {
log.error('PuppetWeb', 'getContact(%d) exception: %s', id, e.message)
throw e
})
}
logined() { return !!(this.user) }
ding(data) {
if (!this.bridge) {
return Promise.reject(new Error('ding fail: no bridge(yet)!'))
}
return this.bridge.ding(data)
.catch(e => {
log.warn('PuppetWeb', 'ding(%s) rejected: %s', data, e.message)
throw e
})
}
}
Object.assign(PuppetWeb, {
default: PuppetWeb
, PuppetWeb
, Server
, Browser
, Bridge
})
module.exports = PuppetWeb
......@@ -47,7 +47,8 @@ class Puppet extends EventEmitter {
getContact(id) { // for unit testing
log.verbose('Puppet', `Interface method getContact(${id})`)
return Promise.resolve({UserName: 'WeChaty', NickName: 'Puppet'})
throw new Error('Absolute Interface Method should never to be called')
// return Promise.resolve({UserName: 'WeChaty', NickName: 'Puppet'})
}
// () { throw new Error('To Be Implemented') }
......
......@@ -87,18 +87,22 @@ function guid() {
})
}
/**
*
* @param port is just a suggestion.
* there's no grantuee for the number
*/
function getPort(port) {
port = port || 8788
log.verbose('UtilLib', 'getPort(%d)', port)
let tryPort = nextPort(port || 8788)
return new Promise((resolve, reject) => {
let tryPort = port
// https://gist.github.com/mikeal/1840641
function _getPort(cb) {
var server = require('net').createServer()
server.on('error', function(err) {
if (err) {}
tryPort++
tryPort = nextPort(port)
_getPort(cb)
})
server.listen(tryPort, function(err) {
......@@ -117,6 +121,12 @@ function getPort(port) {
resolve(okPort)
})
})
function nextPort(port) {
RANDOM_RANGE = 1024
const n = Math.floor(Math.random() * RANDOM_RANGE)
return port + n
}
}
module.exports = UtilLib
const test = require('tape')
const Contact = require('../src/contact')
const Puppet = require('../src/puppet')
const log = require('../src/npmlog-env')
import { test } from 'ava'
import {
Contact
, Puppet
, log
} from '../'
// const test = require('tape')
// const Contact = require('../src/contact')
// const Puppet = require('../src/puppet')
// const log = require('../src/npmlog-env')
Contact.attach(new Puppet())
test('Contact smoke testing', t => {
test('Contact smoke testing', async t => {
const UserName = '@0bb3e4dd746fdbd4a80546aef66f4085'
const NickName = 'Nick Name Test'
......@@ -25,15 +30,15 @@ test('Contact smoke testing', t => {
const c = new Contact(UserName)
t.equal(c.id, UserName, 'id/UserName right')
c.ready(mockContactGetter)
.then(r => {
t.equal(r.get('id') , UserName, 'UserName set')
t.equal(r.get('name') , NickName, 'NickName set')
t.is(c.id, UserName, 'id/UserName right')
const r = await c.ready(mockContactGetter)
// .then(r => {
t.is(r.get('id') , UserName, 'UserName set')
t.is(r.get('name') , NickName, 'NickName set')
const s = r.toString()
t.equal(typeof s, 'string', 'toString()')
})
.catch(e => t.fail('ready() rejected: ' + e))
.then(_ => t.end()) // test end
const s = r.toString()
t.is(typeof s, 'string', 'toString()')
// })
// .catch(e => t.fail('ready() rejected: ' + e))
// .then(_ => t.end()) // test end
})
import { test } from 'ava'
test('Electron smoke testing', async t => {
t.true(true, 'test')
})
test.todo('Electron open wx')
const test = require('tape')
const Message = require('../src/message')
const Contact = require('../src/contact')
const Puppet = require('../src/puppet')
const log = require('../src/npmlog-env')
import { test } from 'ava'
import {
Contact
, Message
, Puppet
, log
} from '../'
// const test = require('tape')
// const Message = require('../src/message')
// const Contact = require('../src/contact')
// const Puppet = require('../src/puppet')
// const log = require('../src/npmlog-env')
const puppet = new Puppet()
Contact.attach(puppet)
Message.attach(puppet)
test('Message constructor parser test', t => {
Contact.attach(new Puppet())
Message.attach(new Puppet())
// Contact.attach(new Puppet())
// Message.attach(new Puppet())
const rawData = JSON.parse('{"MsgId":"179242112323992762","FromUserName":"@0bb3e4dd746fdbd4a80546aef66f4085","ToUserName":"@16d20edf23a3bf3bc71bb4140e91619f3ff33b4e33f7fcd25e65c1b02c7861ab","MsgType":1,"Content":"test123","Status":3,"ImgStatus":1,"CreateTime":1461652670,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":179242112323992770,"MMPeerUserName":"@0bb3e4dd746fdbd4a80546aef66f4085","MMDigest":"test123","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":true,"LocalID":"179242112323992762","ClientMsgId":"179242112323992762","MMActualContent":"test123","MMActualSender":"@0bb3e4dd746fdbd4a80546aef66f4085","MMDigestTime":"14:37","MMDisplayTime":1461652670,"MMTime":"14:37"}')
......@@ -17,32 +28,37 @@ test('Message constructor parser test', t => {
}
const m = new Message(rawData)
t.equal(m.id , EXPECTED.id , 'id right')
t.equal(m.get('from') , EXPECTED.from , 'from right')
t.is(m.id , EXPECTED.id , 'id right')
t.is(m.get('from') , EXPECTED.from , 'from right')
const s = m.toString()
t.equal(typeof s, 'string', 'toString()')
t.is(typeof s, 'string', 'toString()')
t.end()
// t.end()
})
test('Message ready() promise testing', t => {
Contact.attach(new Puppet())
Message.attach(new Puppet())
test('Message ready() promise testing', async t => {
// must different with other rawData, because Contact class with load() will cache the result. or use Contact.resetPool()
const rawData = JSON.parse('{"MsgId":"3009511950433684462","FromUserName":"@0748ee480711bf20af91c298a0d7dcc77c30a680c1004157386b81cf13474823","ToUserName":"@b58f91e0c5c9e841e290d862ddb63c14","MsgType":1,"Content":"哈哈","Status":3,"ImgStatus":1,"CreateTime":1462887888,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":3009511950433684500,"MMPeerUserName":"@0748ee480711bf20af91c298a0d7dcc77c30a680c1004157386b81cf13474823","MMDigest":"哈哈","MMIsSend":false,"MMIsChatRoom":false,"MMUnread":false,"LocalID":"3009511950433684462","ClientMsgId":"3009511950433684462","MMActualContent":"哈哈","MMActualSender":"@0748ee480711bf20af91c298a0d7dcc77c30a680c1004157386b81cf13474823","MMDigestTime":"21:44","MMDisplayTime":1462887888,"MMTime":"21:44","_h":104,"_index":0,"_offsetTop":0,"$$hashKey":"098"}')
const expectedFromUserName = '@0748ee480711bf20af91c298a0d7dcc77c30a680c1004157386b81cf13474823'
const expectedToUserName = '@b58f91e0c5c9e841e290d862ddb63c14'
const expectedFromNickName = 'From Nick Name Test'
const expectedToNickName = 'To Nick Name Test'
const expectedFromNickName = 'From Nick Name@Test'
const expectedToNickName = 'To Nick Name@Test'
const expectedMsgId = '3009511950433684462'
// const puppet = new Puppet()
puppet.getContact = mockGetContact
// const puppet = new Puppet()
// Contact.attach(puppet)
// Message.attach(puppet)
Contact.init()
// Mock
Contact.puppet.getContact = function (id) {
function mockGetContact(id) {
log.silly('TestMessage', `mocked getContact(${id})`)
return new Promise((resolve,reject) => {
let obj = {}
......@@ -61,36 +77,34 @@ test('Message ready() promise testing', t => {
break
default:
log.error('TestMessage', `mocked getContact(${id}) unknown`)
t.fail('mocked getContact(${id}) unknown')
break
}
log.silly('TestMessage', 'setTimeout mocked getContact')
setTimeout(r => {
log.silly('TestMessage', 'mocked getContact resolved')
return resolve(obj)
}, 200)
}, 100)
})
}
const m = new Message(rawData)
t.equal(m.id, expectedMsgId, 'id/MsgId right')
t.is(m.id, expectedMsgId, 'id/MsgId right')
const p = m.ready()
p.then(r => {
const fc = Contact.load(m.get('from'))
const tc = Contact.load(m.get('to'))
t.equal(fc.get('id') , expectedFromUserName, 'contact ready for FromUserName')
t.equal(fc.get('name') , expectedFromNickName, 'contact ready for FromNickName')
t.equal(tc.get('id') , expectedToUserName , 'contact ready for ToUserName')
t.equal(tc.get('name') , expectedToNickName , 'contact ready for ToNickName')
})
.catch(e => t.fail('m.ready() rejected: ' + e))
.then(_ => t.end()) // test end
await m.ready()
const fc = Contact.load(m.get('from'))
const tc = Contact.load(m.get('to'))
t.is(fc.get('id') , expectedFromUserName, 'contact ready for FromUserName')
t.is(fc.get('name') , expectedFromNickName, 'contact ready for FromNickName')
t.is(tc.get('id') , expectedToUserName , 'contact ready for ToUserName')
t.is(tc.get('name') , expectedToNickName , 'contact ready for ToNickName')
})
test('TBW: Message static method', t => {
Contact.attach(new Puppet())
Message.attach(new Puppet())
// Contact.attach(new Puppet())
// Message.attach(new Puppet())
const m = Message.find({
id: 'xxx'
......@@ -98,7 +112,7 @@ test('TBW: Message static method', t => {
limit: 1
})
t.ok(m.get('id'), 'Message.find')
t.truthy(m.get('id'), 'Message.find')
const ms = Message.findAll({
from: 'yyy'
......@@ -106,7 +120,7 @@ test('TBW: Message static method', t => {
limit: 2
})
t.equal(ms.length, 2, 'Message.findAll with limit 2')
t.is(ms.length, 2, 'Message.findAll with limit 2')
t.end()
// t.end()
})
'use strict'
import { test } from 'ava'
import { log } from '../'
const sinon = require('sinon')
const test = require('tape')
import { spy } from 'sinon'
const log = require('../src/npmlog-env')
// 'use strict'
// const sinon = require('sinon')
// const test = require('tape')
// const log = require('../src/npmlog-env')
test('Node.js function params destructuring behaviour test', function(t) {
const DEFAULT_N = 1
const DEFAULT_S = 't'
const spy = sinon.spy()
const paramSpy = spy()
function paramTest({
n = DEFAULT_N
, s = DEFAULT_S
} = {}) {
spy(n, s)
paramSpy(n, s)
}
spy.reset()
paramSpy.reset()
paramTest()
t.deepEqual(spy.args[0], [DEFAULT_N, DEFAULT_S], 'should be equal to default args')
t.deepEqual(paramSpy.args[0], [DEFAULT_N, DEFAULT_S], 'should be equal to default args')
spy.reset()
paramSpy.reset()
paramTest({n: 42})
t.deepEqual(spy.args[0], [42, DEFAULT_S], 'should be equal to default s args')
t.deepEqual(paramSpy.args[0], [42, DEFAULT_S], 'should be equal to default s args')
spy.reset()
paramSpy.reset()
paramTest({s: 'life'})
t.deepEqual(spy.args[0], [DEFAULT_N, 'life'], 'should be equal to default n args')
t.deepEqual(paramSpy.args[0], [DEFAULT_N, 'life'], 'should be equal to default n args')
t.end()
// t.end()
})
const co = require('co')
const test = require('tape')
import { test } from 'ava'
const Browser = require('../../src/puppet-web/browser')
const Bridge = require('../../src/puppet-web/bridge')
import {
PuppetWeb
, log
} from '../../'
// const co = require('co')
// const test = require('tape')
const Browser = PuppetWeb.Browser
const Bridge = PuppetWeb.Bridge
const PORT = 58788
const log = require('../../src/npmlog-env')
// const log = require('../../src/npmlog-env')
test('Bridge retry-promise testing', function(t) {
co(function* () {
test('Bridge retry-promise testing', async t => {
// co(function* () {
const EXPECTED_RESOLVE = 'Okey'
const EXPECTED_REJECT = 'NotTheTime'
function delayedFactory(timeout) {
......@@ -25,82 +32,88 @@ test('Bridge retry-promise testing', function(t) {
const retryPromise = require('retry-promise').default
var delay50 = delayedFactory(50)
yield retryPromise({max:1, backoff: 10}, function() {
await retryPromise({max:1, backoff: 10}, function() {
return delay50()
})
.then(r => {
t.fail('should not resolved retry-promise here')
})
.catch(e => {
t.equal(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`)
})
var anotherDelay50 = delayedFactory(50)
yield retryPromise({max:6, backoff: 10}, function() {
await retryPromise({max:6, backoff: 10}, function() {
return anotherDelay50()
})
.then(r => {
t.equal(r, EXPECTED_RESOLVE, `retryPromise got "${EXPECTED_RESOLVE}" when wait enough`)
t.is(r, EXPECTED_RESOLVE, `retryPromise got "${EXPECTED_RESOLVE}" when wait enough`)
})
.catch(e => {
t.fail(`should not be rejected(with ${e}) when there is enough wait`)
})
})
.catch(e => { // REJECTED
t.fail(e)
})
.then(r => { // FINALLY
t.end()
})
.catch(e => { // EXCEPTION
t.fail(e)
})
// })
// .catch(e => { // REJECTED
// t.fail(e)
// })
// .then(r => { // FINALLY
// t.end()
// })
// .catch(e => { // EXCEPTION
// t.fail(e)
// })
})
test('Bridge smoking test', function(t) {
test('Bridge smoking test', async t => {
const browser = new Browser({port: PORT})
t.ok(browser, 'should instanciated a browser')
t.truthy(browser, 'should instanciated a browser')
const mockPuppet = {browser: browser}
const b = new Bridge({puppet: mockPuppet})
t.ok(b, 'should instanciated a bridge with mocked puppet')
const b = new Bridge({puppet: mockPuppet, port: PORT})
t.truthy(b, 'should instanciated a bridge with mocked puppet')
co(function* () {
yield browser.init()
// co(function* () {
await browser.init()
t.pass('should instanciated a browser')
yield browser.open()
await browser.open()
t.pass('should open success')
yield b.inject()
await b.inject()
t.pass('should injected wechaty')
const retDing = yield b.execute('return Wechaty.ding()')
t.equal(retDing, 'dong', 'should got dong after execute Wechaty.ding()')
const retDing = await b.execute('return Wechaty.ding()')
t.is(retDing, 'dong', 'should got dong after execute Wechaty.ding()')
// @deprecated
// const retReady = yield b.execute('return Wechaty.isReady()')
// t.equal(typeof retReady, 'boolean', 'should got a boolean return after execute Wechaty.isReady()')
const retCode = yield b.proxyWechaty('isLogin')
t.equal(typeof retCode, 'boolean', 'should got a boolean after call proxyWechaty(isLogin)')
})
.catch(e => { // Rejected
t.fail('co promise rejected:' + e)
})
.then(r => { // Finally
return co(function* () {
yield b.quit()
t.pass('b.quit()')
yield browser.quit()
t.pass('browser.quit()')
t.end()
})
})
.catch(e => { // Exception
t.fail('Test Exception:' + e)
t.end()
})
// const retReady = await b.execute('return Wechaty.isReady()')
// t.is(typeof retReady, 'boolean', 'should got a boolean return after execute Wechaty.isReady()')
const retCode = await b.proxyWechaty('isLogin')
t.is(typeof retCode, 'boolean', 'should got a boolean after call proxyWechaty(isLogin)')
await b.quit()
t.pass('b.quit()')
await 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()
// })
})
const co = require('co')
const test = require('tape')
import { test } from 'ava'
const log = require('../../src/npmlog-env')
import {
PuppetWeb
, Config
, log
} from '../../'
const Browser = require('../../src/puppet-web/browser')
const PROFILE = 'unit-test-session.wechaty.json'
test('Browser class cookie smoking tests', function(t) {
// const co = require('co')
// const test = require('tape')
// const log = require('../../src/npmlog-env')
const Browser = PuppetWeb.Browser
const PROFILE = Config.DEFAULT_PROFILE + '-' + process.pid + '-'
let profileCounter = 1
test('Browser class cookie smoking tests', async t => {
const b = new Browser()
t.ok(b, 'should instanciate a browser instance')
t.truthy(b, 'should instanciate a browser instance')
co(function* () {
yield b.init()
// co(function* () {
await b.init()
t.pass('should inited')
yield b.open()
await b.open()
t.pass('should opened')
const two = yield b.execute('return 1+1')
t.equal(two, 2, 'should got 2 after execute script 1+1')
const two = await b.execute('return 1+1')
t.is(two, 2, 'should got 2 after execute script 1+1')
let cookies = yield b.driver.manage().getCookies()
t.ok(cookies.length, 'should got plenty of cookies')
let cookies = await b.driver.manage().getCookies()
t.truthy(cookies.length, 'should got plenty of cookies')
yield b.driver.manage().deleteAllCookies()
cookies = yield b.driver.manage().getCookies()
t.equal(cookies.length, 0, 'should no cookie anymore after deleteAllCookies()')
await b.driver.manage().deleteAllCookies()
cookies = await b.driver.manage().getCookies()
t.is(cookies.length, 0, 'should no cookie anymore after deleteAllCookies()')
const EXPECTED_COOKIES = [{
name: 'wechaty0'
......@@ -44,48 +54,40 @@ test('Browser class cookie smoking tests', function(t) {
, expiry: 99999999999999
}]
yield b.addCookies(EXPECTED_COOKIES)
await b.addCookies(EXPECTED_COOKIES)
cookies = yield b.driver.manage().getCookies()
cookies = await b.driver.manage().getCookies()
const cookies0 = cookies.filter(c => { return RegExp(EXPECTED_COOKIES[0].name).test(c.name) })
t.equal(cookies0[0].name, EXPECTED_COOKIES[0].name, 'getCookies() should filter out the cookie named wechaty0')
t.is(cookies0[0].name, EXPECTED_COOKIES[0].name, 'getCookies() should filter out the cookie named wechaty0')
const cookies1 = cookies.filter(c => { return RegExp(EXPECTED_COOKIES[1].name).test(c.name) })
t.equal(cookies1[0].name, EXPECTED_COOKIES[1].name, 'getCookies() should filter out the cookie named wechaty1')
t.is(cookies1[0].name, EXPECTED_COOKIES[1].name, 'getCookies() should filter out the cookie named wechaty1')
yield b.open()
await b.open()
t.pass('re-opened url')
const cookieAfterOpen = yield b.driver.manage().getCookie(EXPECTED_COOKIES[0].name)
t.equal(cookieAfterOpen.name, EXPECTED_COOKIES[0].name, 'getCookie() should get expected cookie named after re-open url')
const cookieAfterOpen = await b.driver.manage().getCookie(EXPECTED_COOKIES[0].name)
t.is(cookieAfterOpen.name, EXPECTED_COOKIES[0].name, 'getCookie() should get expected cookie named after re-open url')
const dead = b.dead()
t.equal(dead, false, 'should be a not dead browser')
t.is(dead, false, 'should be a not dead browser')
const live = yield b.readyLive()
t.equal(live, true, 'should be a live browser')
})
.catch((e) => { // Rejected
t.fail('co promise rejected:' + e)
})
.then(r => { // Finally
b.quit()
.then(_ => t.end())
})
.catch(e => { // Exception
t.fail('Exception:' + e)
})
const live = await b.readyLive()
t.is(live, true, 'should be a live browser')
await b.quit()
})
test('Browser session save & load', function(t) {
test('Browser session save & load', async t => {
const profileName = PROFILE + profileCounter++
let b = new Browser({
sessionFile: PROFILE
sessionFile: profileName
})
t.ok(b, 'new Browser')
t.truthy(b, 'new Browser')
co(function* () {
yield b.init()
// co(function* () {
await b.init()
t.pass('inited')
yield b.open()
await b.open()
t.pass('opened')
const EXPECTED_COOKIE = {
......@@ -98,72 +100,65 @@ test('Browser session save & load', function(t) {
}
const EXPECTED_NAME_REGEX = new RegExp('^' + EXPECTED_COOKIE.name + '$')
yield b.driver.manage().deleteAllCookies()
let cookies = yield b.driver.manage().getCookies()
t.equal(cookies.length, 0, 'should no cookie after deleteAllCookies()')
await b.driver.manage().deleteAllCookies()
let cookies = await b.driver.manage().getCookies()
t.is(cookies.length, 0, 'should no cookie after deleteAllCookies()')
yield b.addCookies(EXPECTED_COOKIE)
const cookieFromBrowser = yield b.driver.manage().getCookie(EXPECTED_COOKIE.name)
t.equal(cookieFromBrowser.name, EXPECTED_COOKIE.name, 'cookie from getCookie() should be same as we just set')
await b.addCookies(EXPECTED_COOKIE)
const cookieFromBrowser = await b.driver.manage().getCookie(EXPECTED_COOKIE.name)
t.is(cookieFromBrowser.name, EXPECTED_COOKIE.name, 'cookie from getCookie() should be same as we just set')
let cookiesFromCheck = yield b.checkSession()
t.ok(cookiesFromCheck.length, 'should get cookies from checkSession() after addCookies()')
let cookiesFromCheck = await b.checkSession()
t.truthy(cookiesFromCheck.length, 'should get cookies from checkSession() after addCookies()')
let cookieFromCheck = cookiesFromCheck.filter(c => EXPECTED_NAME_REGEX.test(c.name))
t.equal(cookieFromCheck[0].name, EXPECTED_COOKIE.name, 'cookie from checkSession() return should be same as we just set by addCookies()')
t.is(cookieFromCheck[0].name, EXPECTED_COOKIE.name, 'cookie from checkSession() return should be same as we just set by addCookies()')
const cookiesFromSave = yield b.saveSession()
t.ok(cookiesFromSave.length, 'should get cookies from saveSession()')
const cookiesFromSave = await b.saveSession()
t.truthy(cookiesFromSave.length, 'should get cookies from saveSession()')
const cookieFromSave = cookiesFromSave.filter(c => EXPECTED_NAME_REGEX.test(c.name))
t.equal(cookieFromSave.length, 1, 'should has the cookie we just set')
t.equal(cookieFromSave[0].name, EXPECTED_COOKIE.name, 'cookie from saveSession() return should be same as we just set')
t.is(cookieFromSave.length, 1, 'should has the cookie we just set')
t.is(cookieFromSave[0].name, EXPECTED_COOKIE.name, 'cookie from saveSession() return should be same as we just set')
yield b.driver.manage().deleteAllCookies()
cookiesFromCheck = yield b.checkSession()
t.equal(cookiesFromCheck.length, 0, 'should no cookie from checkSession() after deleteAllCookies()')
await b.driver.manage().deleteAllCookies()
cookiesFromCheck = await b.checkSession()
t.is(cookiesFromCheck.length, 0, 'should no cookie from checkSession() after deleteAllCookies()')
const cookiesFromLoad = yield b.loadSession().catch(() => {}) // fall safe
t.ok(cookiesFromLoad.length, 'should get cookies after loadSession()')
const cookiesFromLoad = await b.loadSession().catch(() => {}) // fall safe
t.truthy(cookiesFromLoad.length, 'should get cookies after loadSession()')
const cookieFromLoad = cookiesFromLoad.filter(c => EXPECTED_NAME_REGEX.test(c.name))
t.equal(cookieFromLoad[0].name, EXPECTED_COOKIE.name, 'cookie from loadSession() should has expected cookie')
t.is(cookieFromLoad[0].name, EXPECTED_COOKIE.name, 'cookie from loadSession() should has expected cookie')
cookiesFromCheck = yield b.checkSession()
t.ok(cookiesFromCheck.length, 'should get cookies from checkSession() after loadSession()')
cookiesFromCheck = await b.checkSession()
t.truthy(cookiesFromCheck.length, 'should get cookies from checkSession() after loadSession()')
cookieFromCheck = cookiesFromCheck.filter(c => EXPECTED_NAME_REGEX.test(c.name))
t.ok(cookieFromCheck.length, 'should has cookie after filtered after loadSession()')
t.equal(cookieFromCheck[0].name, EXPECTED_COOKIE.name, 'cookie from checkSession() return should has expected cookie after loadSession')
t.truthy(cookieFromCheck.length, 'should has cookie after filtered after loadSession()')
t.is(cookieFromCheck[0].name, EXPECTED_COOKIE.name, 'cookie from checkSession() return should has expected cookie after loadSession')
yield b.quit()
await b.quit()
t.pass('quited')
b = new Browser({
sessionFile: PROFILE
sessionFile: profileName
})
t.pass('re-new Browser')
yield b.init()
await b.init()
t.pass('re-init Browser')
yield b.open()
await b.open()
t.pass('re-open Browser')
yield b.loadSession()
await b.loadSession()
t.pass('loadSession for new instance of Browser')
const cookieAfterQuit = yield b.driver.manage().getCookie(EXPECTED_COOKIE.name)
t.equal(cookieAfterQuit.name, EXPECTED_COOKIE.name, 'cookie from getCookie() after browser quit, should load the right cookie back')
const cookieAfterQuit = await b.driver.manage().getCookie(EXPECTED_COOKIE.name)
t.truthy(cookieAfterQuit, 'should get cookie from getCookie()')
t.is(cookieAfterQuit.name, EXPECTED_COOKIE.name, 'cookie from getCookie() after browser quit, should load the right cookie back')
// clean
require('fs').unlink(PROFILE, err => {
require('fs').unlink(profileName, err => {
if (err) {
log.warn('Browser', 'unlink session file %s fail: %s', PROFILE, err)
}
})
})
.catch(e => { // Reject
log.warn('TestBrowser', 'error: %s', e)
t.fail(e)
})
.then(r => { // Finally
b.quit()
.then(_ => t.end())
})
.catch(e => { t.fail(e) }) // Exception
await b.quit()
})
const co = require('co')
const util = require('util')
const test = require('tape')
const retryPromise = require('retry-promise').default
import { test } from 'ava'
const log = require('../../src/npmlog-env')
import {
PuppetWeb
, log
} from '../../'
import util from 'util'
// const co = require('co')
// const util = require('util')
// const test = require('tape')
// const retryPromise = require('retry-promise').default
// const log = require('../../src/npmlog-env')
const PORT = process.env.WECHATY_PORT || 58788
const PROFILE = 'unit-test-session.wechaty.json'
const PuppetWeb = require('../../src/puppet-web')
const PuppetWebEvent = require('../../src/puppet-web/event')
// const PuppetWeb = require('../../src/puppet-web')
const PuppetWebEvent = PuppetWeb.Event // require('../../src/puppet-web/event')
test('Puppet Web Event smoking test', function(t) {
test('Puppet Web Event smoking test', async t => {
let pw = new PuppetWeb({profile: PROFILE})
t.ok(pw, 'should instantiated a PuppetWeb')
t.truthy(pw, 'should instantiated a PuppetWeb')
co(function* () {
yield pw.init()
// co(function* () {
await pw.init()
t.pass('should be inited')
yield PuppetWebEvent.onBrowserDead.call(pw, 'event unit test')
await PuppetWebEvent.onBrowserDead.call(pw, 'event unit test')
t.pass('should finish onBrowserDead event process')
})
.catch(e => t.fail(e)) // Reject
.then(r => { // Finally
pw.quit()
.then(_ => t.end())
})
.catch(e => t.fail(e)) // Exception
await pw.quit()
// })
// .catch(e => t.fail(e)) // Reject
// .then(r => { // Finally
// pw.quit()
// .then(_ => t.end())
// })
// .catch(e => t.fail(e)) // Exception
})
const co = require('co')
const util = require('util')
const test = require('tape')
const retryPromise = require('retry-promise').default
import { test } from 'ava'
const log = require('../../src/npmlog-env')
import {
PuppetWeb
, Message
, log
} from '../../'
const PROFILE = 'unit-test-session.wechaty.json'
import util from 'util'
import retryPormise from 'retry-promise'
import EventEmitter from 'events'
const PuppetWeb = require('../../src/puppet-web')
const Message = require('../../src/message')
import { spy } from 'sinon'
test('Puppet Web Self Message Identification', function(t) {
const p = new PuppetWeb({profile: PROFILE})
t.ok(p, 'should instantiated a PuppetWeb')
test('Puppet Web Self Message Identification', t => {
const p = new PuppetWeb()
t.truthy(p, 'should instantiated a PuppetWeb')
const EXPECTED_USER_ID = 'zixia'
const m = new Message()
m.set('from', EXPECTED_USER_ID)
p.userId = EXPECTED_USER_ID
t.ok(p.self(m), 'should identified self for message which from is self')
t.end()
t.truthy(p.self(m), 'should identified self for message which from is self')
})
test('PuppetWeb smoke testing', function(t) {
let pw = new PuppetWeb({profile: PROFILE})
t.ok(pw, 'should instantiated a PuppetWeb')
test.serial('PuppetWeb login/logout events', async t => {
let pw = new PuppetWeb()
t.truthy(pw, 'should instantiated a PuppetWeb')
co(function* () {
yield pw.init()
t.pass('should be inited')
t.equal(pw.logined() , false , 'should be not logined')
await pw.init()
t.pass('should be inited')
t.is(pw.logined() , false , 'should be not logined')
// XXX find a better way to mock...
pw.bridge.getUserName = function() { return Promise.resolve('mockedUserName') }
pw.getContact = function() { return Promise.resolve('dummy') }
// XXX find a better way to mock...
pw.bridge.getUserName = function() { return Promise.resolve('mockedUserName') }
pw.getContact = function() { return Promise.resolve('dummy') }
const p1 = new Promise((resolve) => {
pw.once('login', r => {
t.equal(pw.logined() , true , 'should be logined after emit login event')
resolve()
})
})
pw.server.emit('login')
yield p1
const p2 = new Promise((resolve) => {
pw.once('logout', r => process.nextTick(() => { // wait to next tick for pw clean logined user status
// log.verbose('TestPuppetWeb', 'on(logout) received %s, islogined: %s', r, pw.logined())
t.equal(pw.logined() , false , 'should be logouted after logout event')
resolve()
}))
})
pw.server.emit('logout')
yield p2
})
.catch(e => t.fail(e)) // Reject
.then(r => { // Finally
// log.warn('TestPuppetWeb', 'finally()')
pw.quit()
.then(_ => t.end())
})
.catch(e => t.fail(e)) // Exception
const loginPromise = new Promise((res,rej) => pw.once('login', _ => res('loginFired')))
pw.server.emit('login')
t.is(await loginPromise, 'loginFired', 'should fired login event')
t.is(pw.logined(), true , 'should be logined')
const logoutPromise = new Promise((res,rej) => pw.once('logout', _ => res('logoutFired')))
pw.server.emit('logout')
t.is(await logoutPromise, 'logoutFired', 'should fire logout event')
t.is(pw.logined(), false, 'should be logouted')
await pw.quit()
})
test('PuppetWeb server/browser communication', function(t) {
let pw = new PuppetWeb({profile: PROFILE})
t.ok(pw, 'should instantiated a PuppetWeb')
test.serial('PuppetWeb server/browser communication', async t => {
let pw = new PuppetWeb()
t.truthy(pw, 'should instantiated a PuppetWeb')
const EXPECTED_DING_DATA = 'dingdong'
co(function* () {
yield pw.init()
t.pass('should be inited')
const ret = yield dingSocket(pw.server)
t.equal(ret, EXPECTED_DING_DATA, 'should got EXPECTED_DING_DATA after resolved dingSocket()')
})
.catch(e => { // Reject
log.warn('TestPuppetWeb', 'error: %s', e)
t.fail(e)
})
.then(r => { // Finally
pw.quit()
.then(_ => t.end())
})
.catch(e => t.fail(e)) // Exception
await pw.init()
t.pass('should be inited')
const ret = await dingSocket(pw.server)
t.is(ret, EXPECTED_DING_DATA, 'should got EXPECTED_DING_DATA after resolved dingSocket()')
await pw.quit()
return
/////////////////////////////////////////////////////////////////////////////
......
const https = require('https')
const test = require('tape')
const sinon = require('sinon')
const co = require('co')
import { test } from 'ava'
const log = require('../../src/npmlog-env')
import https from 'https'
import sinon from 'sinon'
const PuppetWebServer = require('../../src/puppet-web/server')
import {
PuppetWeb
, Message
, log
} from '../../'
// const https = require('https')
// const test = require('tape')
// const sinon = require('sinon')
// const co = require('co')
// const log = require('../../src/npmlog-env')
const PuppetWebServer = PuppetWeb.Server //require('../../src/puppet-web/server')
const PORT = 48788
test('PuppetWebServer basic tests', function(t) {
test('PuppetWebServer basic tests', async t => {
const s = new PuppetWebServer({port: PORT})
t.equal(typeof s, 'object', 'PuppetWebServer instance created')
t.is(typeof s, 'object', 'PuppetWebServer instance created')
let httpsServer = null
co(function* () {
// co(function* () {
const spy = sinon.spy()
const express = s.createExpress()
t.equal(typeof express, 'function', 'create express')
t.is(typeof express, 'function', 'create express')
httpsServer = s.createHttpsServer(express)
t.equal(typeof httpsServer, 'object', 'create https server')
t.is(typeof httpsServer, 'object', 'create https server')
httpsServer.on('close', _ => spy('onClose'))
const socketio = s.createSocketIo(httpsServer)
t.equal(typeof socketio, 'object', 'should created socket io instance')
t.is(typeof socketio, 'object', 'should created socket io instance')
const retClose = yield new Promise((resolve, reject) => {
const retClose = await new Promise((resolve, reject) => {
httpsServer.close(_ => {
spy('closed')
resolve('closed')
})
})
t.equal(retClose, 'closed', 'HttpsServer closed')
t.is(retClose, 'closed', 'HttpsServer closed')
t.ok(spy.calledTwice, 'spy should be called twice after close HttpsServer')
t.truthy(spy.calledTwice, 'spy should be called twice after close HttpsServer')
t.deepEqual(spy.args[0], ['onClose'], 'should fire event `close` when close HttpsServer')
t.deepEqual(spy.args[1], ['closed'] , 'should run callback when close HttpsServer')
})
.catch(e => { // Reject
t.fail('co promise rejected:' + e)
})
.then(() => { // Finally
s.quit()
.then(_ => t.end())
})
.catch(e => { // Exception
t.fail('Exception:' + e)
})
await s.quit()
// })
// .catch(e => { // Reject
// t.fail('co promise rejected:' + e)
// })
// .then(() => { // Finally
// s.quit()
// .then(_ => t.end())
// })
// .catch(e => { // Exception
// t.fail('Exception:' + e)
// })
})
test('PuppetWebServer smoke testing', function(t) {
test('PuppetWebServer smoke testing', async t => {
const server = new PuppetWebServer({port: PORT})
t.ok(server, 'new server instance')
co(function* () {
const retInit = yield server.init()
t.ok(retInit, 'server:' + PORT + ' inited')
const retHttps = yield dingHttps()
t.equal(retHttps , 'dong', 'ding https got dong')
}).catch(e => { // Reject
t.fail('co rejected:' + e)
}).then(() => { // Finally
server.quit()
t.end()
})
.catch(e => { // Exception
t.fail('Exception:' + e)
})
t.truthy(server, 'new server instance')
// co(function* () {
const retInit = await server.init()
t.truthy(retInit, 'server:' + PORT + ' inited')
const retHttps = await dingHttps()
t.is(retHttps , 'dong', 'ding https got dong')
await server.quit()
// }).catch(e => { // Reject
// t.fail('co rejected:' + e)
// }).then(() => { // Finally
// server.quit()
// t.end()
// })
// .catch(e => { // Exception
// t.fail('Exception:' + e)
// })
return // The following is help functions only
......
const co = require('co')
const util = require('util')
const test = require('tape')
const retryPromise = require('retry-promise').default
import { test } from 'ava'
const log = require('../../src/npmlog-env')
import util from 'util'
import retryPromise from 'retry-promise'
import {
PuppetWeb
, log
} from '../../'
// const co = require('co')
// const util = require('util')
// const test = require('tape')
// const retryPromise = require('retry-promise').default
// const log = require('../../src/npmlog-env')
const PROFILE = 'unit-test-session.wechaty.json'
const PuppetWeb = require('../../src/puppet-web')
const Watchdog = require('../../src/puppet-web/watchdog.js')
// const PuppetWeb = require('../../src/puppet-web')
const Watchdog = PuppetWeb.Watchdog // require('../../src/puppet-web/watchdog.js')
test('Puppet Web watchdog timer', function(t) {
test('Puppet Web watchdog timer', async t => {
const pw = new PuppetWeb({profile: PROFILE})
t.ok(pw, 'should instantiate a PuppetWeb')
t.truthy(pw, 'should instantiate a PuppetWeb')
Watchdog.onFeed.call(pw, { data: 'initing directly' })
t.pass('should ok with default food type')
co(function* () {
// co(function* () {
const origLogLevel = log.level
if (log.level === 'info') {
......@@ -25,11 +35,11 @@ test('Puppet Web watchdog timer', function(t) {
t.pass('set log.level = silent to mute log when watchDog reset wechaty temporary')
}
yield pw.init()
yield pw.quit()
// yield pw.bridge.quit()
await pw.init()
await pw.quit()
// await pw.bridge.quit()
// pw.bridge = null
// yield pw.browser.quit()
// await pw.browser.quit()
// pw.browser = null
let errorCounter = 0
......@@ -38,27 +48,28 @@ test('Puppet Web watchdog timer', function(t) {
data: 'active_for_timeout_1ms'
, timeout: 1
})
yield new Promise(resolve => setTimeout(resolve, 10)) // wait untill reset
t.equal(errorCounter, 1, 'should get event[error] after watchdog timeout')
await new Promise(resolve => setTimeout(resolve, 10)) // wait untill reset
t.is(errorCounter, 1, 'should get event[error] after watchdog timeout')
pw.once('error', e => t.fail('waitDing() triggered watchDogReset()'))
const EXPECTED_DING_DATA = 'dingdong'
pw.emit('watchdog', { data: 'feed to extend the dog life' })
const dong = yield waitDing(EXPECTED_DING_DATA)
t.equal(dong, EXPECTED_DING_DATA, 'should get EXPECTED_DING_DATA from ding after watchdog reset, and restored log level')
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
})
.catch(e => { // Exception
t.fail('co exception: ' + e.message)
})
.then(() => { // Finally
pw.quit()
.then(_ => t.end())
})
await pw.quit()
// })
// .catch(e => { // Exception
// t.fail('co exception: ' + e.message)
// })
// .then(() => { // Finally
// pw.quit()
// .then(_ => t.end())
// })
return
/////////////////////////////////////////////////////////////////////////////
......
const test = require('tape')
const Wechaty = require('../')
const Puppet = Wechaty.Puppet
import { test } from 'ava'
import { Wechaty, Puppet } from '../'
// const test = require('tape')
// const Wechaty = require('../')
// const Puppet = Wechaty.Puppet
test('Puppet smoking test', t => {
const p = new Puppet()
t.equal(p.readyState(), 'disconnected', 'should be disconnected state after instanciate')
t.is(p.readyState(), 'disconnected', 'should be disconnected state after instanciate')
p.readyState('connecting')
t.equal(p.readyState(), 'connecting', 'should be connecting state after set')
t.is(p.readyState(), 'connecting', 'should be connecting state after set')
t.end()
// t.end()
})
const test = require('tape')
const Message = require('../src/message')
const Room = require('../src/room')
const Contact = require('../src/contact')
const Puppet = require('../src/puppet')
const log = require('../src/npmlog-env')
import { test } from 'ava'
import {
Message
, Room
, Contact
, Puppet
, log
} from '../'
Room.attach(new Puppet())
test('Room smoke testing', t => {
Room.attach(new Puppet())
// const test = require('tape')
// const Message = require('../src/message')
// const Room = require('../src/room')
// const Contact = require('../src/contact')
// const Puppet = require('../src/puppet')
// const log = require('../src/npmlog-env')
test('Room smoke testing', async t => {
const UserName = '@0bb3e4dd746fdbd4a80546aef66f4085'
const NickName = 'Nick Name Test'
......@@ -27,20 +37,22 @@ test('Room smoke testing', t => {
})
}
const g = new Room(UserName)
const r = new Room(UserName)
t.is(r.id, UserName, 'id/UserName right')
await r.ready(mockContactGetter)
t.equal(g.id, UserName, 'id/UserName right')
g.ready(mockContactGetter)
.then(r => {
t.equal(r.get('id') , UserName, 'UserName set')
t.equal(r.get('name') , NickName, 'NickName set')
t.equal(r.get('encryId') , EncryChatRoomId, 'EncryChatRoomId set')
// .then(r => {
t.is(r.get('id') , UserName, 'UserName set')
t.is(r.get('name') , NickName, 'NickName set')
t.is(r.get('encryId') , EncryChatRoomId, 'EncryChatRoomId set')
const s = r.toString()
t.equal(typeof s, 'string', 'toString()')
})
.catch(e => t.fail('ready() rejected: ' + e))
.then(_ => t.end()) // test end
t.is(typeof s, 'string', 'toString()')
// })
// .catch(e => t.fail('ready() rejected: ' + e))
// .then(_ => t.end()) // test end
})
/*
const rawData = JSON.parse('{"MsgId":"1120003476579027592","FromUserName":"@@4aa0ae1e1ebc568b613fa43ce93b478df0339f73340d87083822c2016d2e53d9","ToUserName":"@94e4b0db79ccc844d7bb4a2b1efac3ff","MsgType":1,"Content":"@9ad4ba13fac52c55d323521b67f7cc39:<br/>[Strong]","Status":3,"ImgStatus":1,"CreateTime":1462889712,"VoiceLength":0,"PlayLength":0,"FileName":"","FileSize":"","MediaId":"","Url":"","AppMsgType":0,"StatusNotifyCode":0,"StatusNotifyUserName":"","RecommendInfo":{"UserName":"","NickName":"","QQNum":0,"Province":"","City":"","Content":"","Signature":"","Alias":"","Scene":0,"VerifyFlag":0,"AttrStatus":0,"Sex":0,"Ticket":"","OpCode":0},"ForwardFlag":0,"AppInfo":{"AppID":"","Type":0},"HasProductId":0,"Ticket":"","ImgHeight":0,"ImgWidth":0,"SubMsgType":0,"NewMsgId":1120003476579027600,"MMPeerUserName":"@@4aa0ae1e1ebc568b613fa43ce93b478df0339f73340d87083822c2016d2e53d9","MMDigest":"感恩的心 ","MMIsSend":false,"MMIsChatRoom":true,"MMUnread":false,"LocalID":"1120003476579027592","ClientMsgId":"1120003476579027592","MMActualContent":"HTML-CODE","MMActualSender":"@9ad4ba13fac52c55d323521b67f7cc39","MMDigestTime":"22:15","MMDisplayTime":1462889712,"MMTime":"22:15","_h":126,"_index":0,"_offsetTop":0,"$$hashKey":"0QK", "MemberList": [{"Uin":0,"UserName":"@94e4b0db79ccc844d7bb4a2b1efac3ff","NickName":"李卓桓","AttrStatus":37996631,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"北京阿布","KeyWord":"liz"},{"Uin":0,"UserName":"@34887973779b7dd827366a31772cd83df223e6f71d9a79e44fe619aafe2901a4","NickName":"Tiger","AttrStatus":4292711,"PYInitial":"","PYQuanPin":"","RemarkPYInitial":"","RemarkPYQuanPin":"","MemberStatus":0,"DisplayName":"DisplayNameTiger","KeyWord":"","HeadImgUrl":"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=0&username=@34887973779b7dd827366a31772cd83df223e6f71d9a79e44fe619aafe2901a4&skey=@crypt_f9cec94b_8517b7f9fec85f5a78a804c4f45f5536&chatroomid=@7b3dcd218431d79045cda3493c3179ae"}]}')
......@@ -51,26 +63,24 @@ test('Room smoke testing', t => {
}
const g = new Room(rawData)
t.equal(g.id , EXPECTED.id , 'id right')
t.equal(g.from.id , EXPECTED.from , 'from right')
t.is(g.id , EXPECTED.id , 'id right')
t.is(g.from.id , EXPECTED.from , 'from right')
const s = g.toString()
t.equal(typeof s, 'string', 'toString()')
t.is(typeof s, 'string', 'toString()')
t.end()
})
*/
test('TBW: Room static method', t => {
Room.attach(new Puppet())
const r = Room.find({
id: 'xxx'
}, {
limit: 1
})
t.ok(r.id, 'Room.find')
t.truthy(r.id, 'Room.find')
const rs = Room.findAll({
from: 'yyy'
......@@ -78,7 +88,7 @@ test('TBW: Room static method', t => {
limit: 2
})
t.equal(rs.length, 2, 'Room.findAll with limit 2')
t.is(rs.length, 2, 'Room.findAll with limit 2')
t.end()
// t.end()
})
'use strict'
import { test } from 'ava'
import {
UtilLib
, log
} from '../'
const co = require('co')
const test = require('tape')
const Express = require('express')
const http = require('http')
import express from 'express'
import http from 'http'
const log = require('../src/npmlog-env')
const UtilLib = require('../src/util-lib')
// 'use strict'
// const co = require('co')
// const test = require('tape')
// const Express = require('express')
// const http = require('http')
// const log = require('../src/npmlog-env')
// const UtilLib = require('../src/util-lib')
test('Html smoking test', t => {
const HTML_BEFORE_STRIP = 'Outer<html>Inner</html>'
......@@ -28,28 +37,28 @@ test('Html smoking test', t => {
const PLAIN_AFTER = '&&&[流汗]'
const strippedHtml = UtilLib.stripHtml(HTML_BEFORE_STRIP)
t.equal(strippedHtml, HTML_AFTER_STRIP, 'should strip html as expected')
t.is(strippedHtml, HTML_AFTER_STRIP, 'should strip html as expected')
const unescapedHtml = UtilLib.unescapeHtml(HTML_BEFORE_UNESCAPE)
t.equal(unescapedHtml, HTML_AFTER_UNESCAPE, 'should unescape html as expected')
t.is(unescapedHtml, HTML_AFTER_UNESCAPE, 'should unescape html as expected')
for (let i=0; i<EMOJI_BEFORE_DIGEST.length; i++) {
const emojiDigest = UtilLib.digestEmoji(EMOJI_BEFORE_DIGEST[i])
t.equal(emojiDigest, EMOJI_AFTER_DIGEST[i], 'should digest emoji string ' + i + ' as expected')
t.is(emojiDigest, EMOJI_AFTER_DIGEST[i], 'should digest emoji string ' + i + ' as expected')
}
const plainText = UtilLib.plainText(PLAIN_BEFORE)
t.equal(plainText, PLAIN_AFTER, 'should convert plain text as expected')
t.is(plainText, PLAIN_AFTER, 'should convert plain text as expected')
t.end()
// t.end()
})
test('Media download smoking test', t => {
const app = new require('express')()
const app = express()
app.use(require('cookie-parser')())
app.get('/ding', function(req, res) {
// console.log(req.cookies)
t.ok(req.cookies, 'should has cookies in req')
t.equal(req.cookies.life, '42', 'should has a cookie named life value 42')
t.truthy(req.cookies, 'should has cookies in req')
t.is(req.cookies.life, '42', 'should has a cookie named life value 42')
res.end('dong')
})
......@@ -64,9 +73,9 @@ test('Media download smoking test', t => {
.then(s => {
s.on('data', (chunk) => {
// console.log(`BODY: ${chunk}`)
t.equal(chunk.toString(), 'dong', 'should success download dong from downloadStream()')
t.is(chunk.toString(), 'dong', 'should success download dong from downloadStream()')
server.close()
t.end()
// t.end()
})
})
.catch(e => {
......@@ -74,23 +83,23 @@ test('Media download smoking test', t => {
})
})
test('getPort', t => {
test('getPort with free & busy port', async t => {
const PORT = 8788
co(function* () {
let port = yield UtilLib.getPort(PORT)
t.equal(port, PORT, 'should equal exactly PORT when it is available')
// co(function* () {
let port = await UtilLib.getPort(PORT)
t.notSame(port, PORT, 'should not be same port even it is available(to provent conflict between concurrency tests in AVA)')
const app = new Express()
const app = express()
const server = app.listen(PORT)
port = yield UtilLib.getPort(PORT)
port = await UtilLib.getPort(PORT)
server.close()
t.equal(port, PORT+1, 'should bigger then PORT when it is not availble')
t.true(port > PORT, 'should bigger then PORT when it is not availble')
}).catch(e => {
t.fail(e)
}).then(_ => {
t.end()
})
// }).catch(e => {
// t.fail(e)
// }).then(_ => {
// t.end()
// })
})
'use strict'
import WebDriver from 'selenium-webdriver'
import express from 'express'
import * as http from 'http'
import * as url from 'url'
const WebDriver = require('selenium-webdriver')
const Express = require('express')
const http = require('http')
const url = require('url')
const co = require('co')
import { test } from 'ava'
const test = require('tape')
const UtilLib = require('../src/util-lib')
const log = require('../src/npmlog-env')
import { UtilLib, log } from '../'
test('Phantomjs smoking test', t => {
const phantomjsExe = require('phantomjs-prebuilt').path
......@@ -76,17 +72,17 @@ this.onResourceRequested = function(request, net) {
`)
driver.get('https://wx.qq.com')
t.end()
// t.end()
})
test('Phantomjs http header', t => {
co(function* () {
const port = yield UtilLib.getPort(8080)
const app = new Express()
test('Phantomjs http header', async t => {
// co(function* () {
const port = await UtilLib.getPort(8080)
// console.log(express)
const app = express()
app.use((req, res, done) => {
//console.log(req.headers)
t.equal(req.headers.referer, 'https://wx.qq.com/')
t.is(req.headers.referer, 'https://wx.qq.com/')
done()
})
......@@ -99,10 +95,10 @@ test('Phantomjs http header', t => {
options.headers = {
Accept: 'image/webp,image/*,*/*;q=0.8'
, 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
, Referer: 'https://wx.qq.com/'
, 'Accept-Encoding': 'gzip, deflate, sdch'
, 'Accept-Language': 'zh-CN,zh;q=0.8'
, 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'
, Referer: 'https://wx.qq.com/'
, 'Accept-Encoding': 'gzip, deflate, sdch'
, 'Accept-Language': 'zh-CN,zh;q=0.8'
}
options.agent = http.globalAgent
......@@ -119,9 +115,9 @@ test('Phantomjs http header', t => {
})
req.end()
}).catch(e => {
t.fail(e)
}).then(_ => {
t.end()
})
// }).catch(e => {
// t.fail(e)
// }).then(_ => {
// t.end()
// })
})
'use strict'
import path from 'path'
const path = require('path')
const co = require('co')
const test = require('tape')
import { test } from 'ava'
const log = require('../src/npmlog-env')
import {
Browser
, By
} from 'selenium-webdriver'
const WebDriver = require('selenium-webdriver')
const Browser = WebDriver.Browser
const By = WebDriver.By
import {
PuppetWeb
, log
} from '../'
const PuppetWebBrowser = require('../src/puppet-web/browser')
const PuppetWebBridge = require('../src/puppet-web/bridge')
// 'use strict'
test('WebDriver process create & quit test', t => {
co(function* () {
const b = new PuppetWebBrowser()
t.ok(b, 'should instanciate a browser')
// const path = require('path')
// const co = require('co')
// const test = require('tape')
yield b.init()
// const log = require('../src/npmlog-env')
// const WebDriver = require('selenium-webdriver')
// const Browser = WebDriver.Browser
// const By = WebDriver.By
// const PuppetWebBrowser = require('../src/puppet-web/browser')
// const PuppetWebBridge = require('../src/puppet-web/bridge')
test('WebDriver process create & quit test', async t => {
// co(function* () {
const b = new PuppetWeb.Browser()
t.truthy(b, 'should instanciate a browser')
await b.init()
t.pass('should be inited successful')
yield b.open()
await b.open()
t.pass('should open successful')
let pids = yield b.getBrowserPids()
t.ok(pids.length > 0, 'should exist browser process after b.open()')
let pids = await b.getBrowserPids()
t.truthy(pids.length > 0, 'should exist browser process after b.open()')
// console.log(b.driver.getSession())
yield b.quit()
await b.quit()
t.pass('quited')
pids = yield b.getBrowserPids()
t.equal(pids.length, 0, 'no driver process after quit')
})
.catch(e => t.fail(e))
.then(_ => t.end())
const useAva = true
if (!useAva) { // ava will run tests concurency...
pids = await b.getBrowserPids()
t.is(pids.length, 0, 'no driver process after quit')
}
return
// })
// .catch(e => t.fail(e))
// .then(_ => t.end())
// return
})
test('WebDriver smoke testing', function(t) {
const wb = new PuppetWebBrowser()
t.ok(wb, 'Browser instnace')
test('WebDriver smoke testing', async t => {
const wb = new PuppetWeb.Browser()
t.truthy(wb, 'Browser instnace')
const mockPuppet = {browser: wb}
const bridge = new PuppetWebBridge({puppet: mockPuppet})
t.ok(bridge, 'Bridge instnace')
const bridge = new PuppetWeb.Bridge({puppet: mockPuppet})
t.truthy(bridge, 'Bridge instnace')
var driver // for help function `execute`
co(function* () {
const m = (yield wb.getBrowserPids()).length
t.equal(m, 0, 'should has no browser process before get()')
// co(function* () {
const m = (await wb.getBrowserPids()).length
t.is(m, 0, 'should has no browser process before get()')
driver = yield wb.initDriver()
t.ok(driver, 'should init driver success')
driver = await wb.initDriver()
t.truthy(driver, 'should init driver success')
const injectio = bridge.getInjectio()
t.ok(injectio.length > 10, 'should got injectio script')
t.truthy(injectio.length > 10, 'should got injectio script')
// XXX: if get rid of this dummy,
// driver.get() will fail due to cant start phantomjs process
yield Promise.resolve()
// 20160828 fixed in new version of selenium webdriver
// await Promise.resolve()
yield driver.get('https://wx.qq.com/')
await driver.get('https://wx.qq.com/')
t.pass('should open wx.qq.com')
const n = (yield wb.getBrowserPids()).length
const n = (await wb.getBrowserPids()).length
// console.log(n)
// yield new Promise((resolve) => {
// await new Promise((resolve) => {
// setTimeout(() => {
// resolve()
// }, 3000)
// })
t.ok(n > 0, 'should exist browser process after get()')
const retAdd = yield driverExecute('return 1+1')
t.equal(retAdd, 2, 'should return 2 for execute 1+1 in browser')
const retInject = yield driverExecute(injectio, 8788)
t.ok(retInject, 'should return a object contains status of inject operation')
t.equal(retInject.code, 200, 'should got code 200 for a success wechaty inject')
})
.catch(e => t.fail('promise rejected. e:' + e)) // Rejected
.then(_ => { // Finally
wb.quit()
.then(_ => t.end())
})
.catch(e => t.fail(e)) // Exception
t.truthy(n > 0, 'should exist browser process after get()')
const retAdd = await driverExecute('return 1+1')
t.is(retAdd, 2, 'should return 2 for execute 1+1 in browser')
const retInject = await driverExecute(injectio, 8788)
t.truthy(retInject, 'should return a object contains status of inject operation')
t.is(retInject.code, 200, 'should got code 200 for a success wechaty inject')
await wb.quit()
// })
// .catch(e => t.fail('promise rejected. e:' + e)) // Rejected
// .then(_ => { // Finally
// wb.quit()
// .then(_ => t.end())
// })
// .catch(e => t.fail(e)) // Exception
return
......
const test = require('tape')
const Wechaty = require('../')
import { test } from 'ava'
import { Wechaty } from '../'
test('Wechaty Framework', t => {
t.ok(Wechaty , 'should export Wechaty')
t.ok(Wechaty.Message , 'should export Wechaty.Message')
t.ok(Wechaty.Contact , 'should export Wechaty.Contact')
t.ok(Wechaty.Room , 'should export Wechaty.Room')
t.truthy(Wechaty , 'should export Wechaty')
t.truthy(Wechaty.Message , 'should export Wechaty.Message')
t.truthy(Wechaty.Contact , 'should export Wechaty.Contact')
t.truthy(Wechaty.Room , 'should export Wechaty.Room')
t.ok(Wechaty.IoBot , 'should export Wechaty.IoBot')
t.truthy(Wechaty.IoBot , 'should export Wechaty.IoBot')
t.ok(Wechaty.log , 'should export Wechaty.log')
t.truthy(Wechaty.log , 'should export Wechaty.log')
t.ok(Wechaty.Puppet , 'should export Wechaty.Puppet')
t.ok(Wechaty.PuppetWeb , 'should export Wechaty.PuppetWeb')
t.truthy(Wechaty.Puppet , 'should export Wechaty.Puppet')
t.truthy(Wechaty.PuppetWeb , 'should export Wechaty.PuppetWeb')
const bot = new Wechaty()
t.equal(bot.version(true), Wechaty.version, 'should export version in package.json')
t.end()
t.is(bot.version(true), Wechaty.version, 'should export version in package.json')
})
test('Wechaty Config setting', t => {
const Config = Wechaty.Config
t.ok(Config , 'should export Wechaty.Config')
t.ok(Config.DEFAULT_HEAD , 'should has DEFAULT_HEAD')
t.ok(Config.DEFAULT_PUPPET , 'should has DEFAULT_PUPPET')
t.ok(Config.DEFAULT_PORT , 'should has DEFAULT_PORT')
t.ok(Config.DEFAULT_PUPPET_PORT, 'should has DEFAULT_PUPPET_PORT')
t.end()
t.truthy(Config , 'should export Wechaty.Config')
t.truthy(Config.DEFAULT_HEAD , 'should has DEFAULT_HEAD')
t.truthy(Config.DEFAULT_PUPPET , 'should has DEFAULT_PUPPET')
t.truthy(Config.DEFAULT_PORT , 'should has DEFAULT_PORT')
t.truthy(Config.DEFAULT_PUPPET_PORT, 'should has DEFAULT_PUPPET_PORT')
})
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册