Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
.www.
wechaty
提交
b0c84ccb
W
wechaty
项目概览
.www.
/
wechaty
与 Fork 源项目一致
Fork自
wechaty / wechaty
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
W
wechaty
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b0c84ccb
编写于
5月 09, 2016
作者:
Huan (李卓桓)
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
runable v0.0.2
上级
2b0e3b8c
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
529 addition
and
478 deletion
+529
-478
package.json
package.json
+2
-2
src/contact.js
src/contact.js
+3
-1
src/group.js
src/group.js
+8
-5
src/message.js
src/message.js
+25
-8
src/puppet-web-browser.js
src/puppet-web-browser.js
+94
-84
src/puppet-web-injectio.js
src/puppet-web-injectio.js
+27
-32
src/puppet-web-server.js
src/puppet-web-server.js
+199
-280
src/puppet-web.js
src/puppet-web.js
+43
-23
src/puppet.js
src/puppet.js
+25
-21
src/ssl-key-cert.js
src/ssl-key-cert.js
+67
-0
src/wechaty.js
src/wechaty.js
+11
-7
tests/message-tests.js
tests/message-tests.js
+2
-2
tests/puppet-web-browser-tests.js
tests/puppet-web-browser-tests.js
+1
-1
tests/puppet-web-server-tests.js
tests/puppet-web-server-tests.js
+15
-10
tests/webdriver-tests.js
tests/webdriver-tests.js
+7
-2
未找到文件。
package.json
浏览文件 @
b0c84ccb
...
...
@@ -5,8 +5,8 @@
"main"
:
"index.js"
,
"scripts"
:
{
"test"
:
"tape tests/*.js"
,
"build"
:
"src -d
lib
"
,
"lint"
:
"eslint
lib
"
"build"
:
"src -d
src
"
,
"lint"
:
"eslint
src
"
},
"repository"
:
{
"type"
:
"git"
,
...
...
src/contact.js
浏览文件 @
b0c84ccb
...
...
@@ -2,8 +2,10 @@
class
Contact
{
constructor
(
id
)
{
this
.
id
=
id
}
toString
()
{
return
`Class Contact({id:
${
this
.
id
}
)`
}
getId
()
{
return
this
.
id
}
...
...
src/group.js
浏览文件 @
b0c84ccb
/* jshint node:true, unused:true */
class
Group
{
constructor
()
{
constructor
(
id
)
{
this
.
id
=
id
}
find
()
{
toString
()
{
return
`Class Group({id=
${
this
.
id
}
})`
}
getId
()
{
return
this
.
id
}
static
find
()
{
}
findAll
()
{
static
findAll
()
{
}
}
module
.
exports
=
Group
src/message.js
浏览文件 @
b0c84ccb
//const EventEmitter = require('events')
const
Contact
=
require
(
'
./contact
'
)
const
Group
=
require
(
'
./group
'
)
class
Message
{
constructor
(
rawObj
)
{
this
.
rawObj
=
rawObj
this
.
rawObj
=
rawObj
=
rawObj
||
{}
// Transform rawObj to local m
this
.
m
=
{
id
:
rawObj
.
MsgId
,
type
:
rawObj
.
MsgType
,
from
:
rawObj
.
MMActualSender
,
from
:
new
Contact
(
rawObj
.
MMActualSender
)
,
to
:
new
Contact
(
rawObj
.
MMPeerUserName
)
,
group
:
rawObj
.
MMIsChatRoom
?
new
Group
(
rawObj
.
FromUserName
)
:
null
,
content
:
rawObj
.
MMActualContent
,
status
:
rawObj
.
Status
,
digest
:
rawObj
.
MMDigest
,
to
:
rawObj
.
MMPeerUserName
,
actual_content
:
rawObj
.
MMActualContent
,
group
:
rawObj
.
MMIsChatRoom
?
rawObj
.
FromUserName
:
null
,
date
:
new
Date
(
rawObj
.
MMDisplayTime
*
1000
)
}
}
toString
()
{
const
id
=
this
.
m
.
id
// Contact
const
from
=
this
.
m
.
from
.
getId
()
const
to
=
this
.
m
.
to
.
getId
()
//return `Class Message({id:${id}, from:${from}, to:${to})`
const
content
=
this
.
m
.
content
if
(
content
.
length
>
20
)
content
=
content
.
substring
(
0
,
17
)
+
'
...
'
;
return
`Class Message("
${
content
}
")`
}
get
(
prop
)
{
if
(
!
prop
||
!
(
prop
in
this
.
m
))
{
const
s
=
'
[
'
+
Object
.
keys
(
this
.
m
).
join
(
'
,
'
)
+
'
]
'
...
...
@@ -28,13 +41,17 @@ class Message {
return
this
.
m
[
prop
]
}
set
(
prop
,
value
)
{
this
.
m
[
prop
]
=
value
}
dump
()
{
console
.
log
(
'
======= dump message =======
'
)
Object
.
keys
(
this
.
m
).
forEach
(
k
=>
console
.
log
(
`
${
k
}
:
${
this
.
m
[
k
]}
`
))
console
.
error
(
'
======= dump message =======
'
)
Object
.
keys
(
this
.
m
).
forEach
(
k
=>
console
.
error
(
`
${
k
}
:
${
this
.
m
[
k
]}
`
))
}
dumpRaw
()
{
console
.
log
(
'
======= dump raw message =======
'
)
Object
.
keys
(
this
.
rawObj
).
forEach
(
k
=>
console
.
log
(
`
${
k
}
:
${
this
.
rawObj
[
k
]}
`
))
console
.
error
(
'
======= dump raw message =======
'
)
Object
.
keys
(
this
.
rawObj
).
forEach
(
k
=>
console
.
error
(
`
${
k
}
:
${
this
.
rawObj
[
k
]}
`
))
}
static
find
(
selector
,
option
)
{
...
...
src/puppet-web-browser.js
浏览文件 @
b0c84ccb
/****************************************
*
* Class Browser
*
header cookie
BaseRequest
Uin
Sid
Skey
DeviceId
***************************************/
const
fs
=
require
(
'
fs
'
)
const
path
=
require
(
'
path
'
)
const
WebDriver
=
require
(
'
selenium-webdriver
'
)
class
Browser
{
constructor
(
options
)
{
options
=
options
||
{}
this
.
browser
=
options
.
browser
||
'
phantomjs
'
this
.
port
=
options
.
port
||
8788
// 'W' 'X' Ascii Code
}
toString
()
{
return
`Class Wechaty.Puppet.Browser(
${
this
.
browser
}
,
${
this
.
port
}
)`
}
init
()
{
return
this
.
open
()
.
then
(
this
.
inject
.
bind
(
this
))
}
open
()
{
const
WX_URL
=
'
https://wx.qq.com
'
console
.
error
(
`browser init
${
this
.
browser
}
:
${
this
.
port
}
`
)
this
.
driver
=
new
WebDriver
.
Builder
().
forBrowser
(
this
.
browser
).
build
()
return
this
.
driver
.
get
(
WX_URL
)
}
getInjectio
()
{
return
fs
.
readFileSync
(
path
.
join
(
path
.
dirname
(
__filename
),
'
puppet-web-injectio.js
'
)
,
'
utf8
'
)
}
inject
()
{
const
injectio
=
this
.
getInjectio
()
console
.
error
(
'
injecting
'
)
return
this
.
execute
(
injectio
,
this
.
port
)
.
then
(()
=>
{
console
.
error
(
'
injected / call Wechaty.init()
'
)
return
this
.
execute
(
'
return Wechaty.init()
'
)
}).
then
((
data
)
=>
{
console
.
error
(
'
Wechaty.init() return:
'
+
data
)
return
new
Promise
((
resolve
,
reject
)
=>
resolve
(
data
))
})
}
quit
()
{
console
.
error
(
'
Browser.quit
'
)
if
(
!
this
.
driver
)
{
console
.
error
(
'
no need to quite because no driver
'
)
return
new
Promise
((
resolve
,
reject
)
=>
resolve
(
'
no driver
'
))
}
console
.
error
(
'
Browser.driver.quit
'
)
this
.
execute
(
'
return (typeof Wechaty)!=="undefined" && Wechaty.quit()
'
).
then
(()
=>
{
this
.
driver
.
quit
(
true
)
delete
this
.
driver
return
new
Promise
((
resolve
,
reject
)
=>
resolve
())
})
}
execute
(
script
,
...
args
)
{
// console.error(`Browser.execute(${script})`)
if
(
!
this
.
driver
)
throw
new
Error
(
'
driver not found
'
)
// a promise
return
this
.
driver
.
executeScript
.
apply
(
this
.
driver
,
arguments
)
}
}
module
.
exports
=
Browser
/****************************************
*
* Class Browser
*
header cookie
BaseRequest
Uin
Sid
Skey
DeviceId
***************************************/
const
fs
=
require
(
'
fs
'
)
const
path
=
require
(
'
path
'
)
const
WebDriver
=
require
(
'
selenium-webdriver
'
)
const
log
=
require
(
'
npmlog
'
)
//log.disableColor()
class
Browser
{
constructor
(
options
)
{
options
=
options
||
{}
this
.
browser
=
options
.
browser
||
'
chrome
'
//'phantomjs'
this
.
port
=
options
.
port
||
8788
// 'W' 'X' Ascii Code
}
toString
()
{
return
`Class Wechaty.Puppet.Browser(
${
this
.
browser
}
,
${
this
.
port
}
)`
}
init
()
{
return
this
.
open
()
.
then
(
this
.
inject
.
bind
(
this
))
}
open
()
{
const
WX_URL
=
'
https://wx.qq.com
'
log
.
verbose
(
'
Browser
'
,
`init
${
this
.
browser
}
:
${
this
.
port
}
`
)
this
.
driver
=
new
WebDriver
.
Builder
().
forBrowser
(
this
.
browser
).
build
()
/*
this.driver = new WebDriver.Builder()//.forBrowser(this.browser).build()
.withCapabilities(
WebDriver.Capabilities.phantomjs()
.set('phantomjs.binary.path', 'D:\\cygwin64\\home\\zixia\\git\\wechaty\\node_modules\\phantomjs-prebuilt\\lib\\phantom\\bin\\phantomjs.exe')
).build()
*/
return
this
.
driver
.
get
(
WX_URL
)
}
getInjectio
()
{
return
fs
.
readFileSync
(
path
.
join
(
path
.
dirname
(
__filename
),
'
puppet-web-injectio.js
'
)
,
'
utf8
'
)
}
inject
()
{
const
injectio
=
this
.
getInjectio
()
log
.
verbose
(
'
Browser
'
,
'
injecting
'
)
return
this
.
execute
(
injectio
,
this
.
port
)
.
then
(()
=>
{
log
.
verbose
(
'
Browser
'
,
'
injected / try Wechaty.init()
'
)
return
this
.
execute
(
'
return (typeof Wechaty)==="undefined" ? false : Wechaty.init()
'
)
}).
then
((
data
)
=>
{
log
.
verbose
(
'
Browser
'
,
'
Wechaty.init() return:
'
+
data
)
return
new
Promise
((
resolve
,
reject
)
=>
resolve
(
data
))
})
}
quit
()
{
log
.
verbose
(
'
Browser
'
,
'
Browser.quit
'
)
if
(
!
this
.
driver
)
{
log
.
verbose
(
'
Browser
'
,
'
no need to quite because no driver
'
)
return
new
Promise
((
resolve
,
reject
)
=>
resolve
(
'
no driver
'
))
}
log
.
verbose
(
'
Browser
'
,
'
Browser.driver.quit
'
)
return
this
.
execute
(
'
return (typeof Wechaty)!=="undefined" && Wechaty.quit()
'
).
then
(()
=>
{
this
.
driver
.
quit
()
this
.
driver
=
null
return
new
Promise
((
resolve
,
reject
)
=>
resolve
())
})
}
execute
(
script
,
...
args
)
{
//log.verbose('Browser', `Browser.execute(${script})`)
if
(
!
this
.
driver
)
throw
new
Error
(
'
driver not found
'
)
// return promise
return
this
.
driver
.
executeScript
.
apply
(
this
.
driver
,
arguments
)
}
}
module
.
exports
=
Browser
src/puppet-web-injectio.js
浏览文件 @
b0c84ccb
...
...
@@ -19,6 +19,8 @@
408: 未确认
*/
if
(
typeof
Wechaty
!==
'
undefined
'
)
return
'
Wechaty already injected?
'
;
;
return
(
function
(
port
)
{
port
=
port
||
8788
...
...
@@ -38,7 +40,7 @@
}
var
Wechaty
=
{
glue
:
{}
//
see
glueAngular() function
glue
:
{}
//
will be initialized by
glueAngular() function
// glue funcs
,
getLoginStatusCode
:
function
()
{
return
Wechaty
.
glue
.
loginScope
.
code
}
,
getLoginQrImgUrl
:
function
()
{
return
Wechaty
.
glue
.
loginScope
.
qrcodeUrl
}
...
...
@@ -52,7 +54,7 @@
,
init
:
init
,
send
:
send
,
clog
:
clog
// Console log
,
slog
:
slog
//
Socket IO log
,
slog
:
slog
//
log throw Socket IO
,
ding
:
ding
,
quit
:
quit
}
...
...
@@ -110,22 +112,21 @@
function
slog
(
data
)
{
return
Wechaty
.
socket
&&
Wechaty
.
socket
.
emit
(
'
log
'
,
data
)
}
function
ding
()
{
return
'
dong
'
}
function
send
(
ToUserName
,
Content
)
{
var
c
=
Wechaty
.
glue
.
chatFactory
var
m
=
c
.
createMessage
({
var
chat
=
Wechaty
.
glue
.
chatFactory
var
conf
=
Wechaty
.
glue
.
confFactory
var
m
=
chat
.
createMessage
({
ToUserName
:
ToUserName
,
Content
:
Content
,
MsgType
:
conf
.
MSGTYPE_TEXT
})
c
.
appendMessage
(
m
)
return
c
.
sendMessage
(
m
)
c
hat
.
appendMessage
(
m
)
return
c
hat
.
sendMessage
(
m
)
}
function
hookMessage
()
{
var
rootScope
=
Wechaty
.
glue
.
rootScope
rootScope
.
$on
(
"
message:add:success
"
,
function
(
event
,
data
)
{
Wechaty
.
socket
.
emit
(
'
message
'
,
data
)
.
catch
(
function
(
e
)
{
clog
(
'
socket.emit(message, data) fail:
'
)
clog
(
e
)
})
if
(
Wechaty
.
socket
)
Wechaty
.
socket
.
emit
(
'
message
'
,
data
);
else
clog
(
'
Wechaty.socket not ready
'
);
})
}
function
hookUnload
()
{
...
...
@@ -151,28 +152,22 @@
// Wechaty global variable: socket
var
socket
=
Wechaty
.
socket
=
io
.
connect
(
'
https://127.0.0.1:
'
+
port
)
socket
.
on
(
'
connect
'
,
function
()
{
clog
(
'
on connect entried
'
)
// new message
Wechaty
.
glue
.
rootScope
.
$on
(
"
message:add:success
"
,
function
(
event
,
data
)
{
socket
.
emit
(
'
message
'
,
data
)
})
// ding -> dong. for test & live check purpose
// ping/pong are reserved by socket.io https://github.com/socketio/socket.io/issues/2414
socket
.
on
(
'
ding
'
,
function
(
e
)
{
clog
(
'
received socket io event: ding. emit dong...
'
)
socket
.
emit
(
'
dong
'
,
'
dong
'
)
})
// re-connect XXX will socketio library auto re-connect by itself???
// socket.on('disconnect', function(e) {
// clog('event: socket disconnect')
// // Reconnect...
// setTimeout(function () {
// clog('starting initSocket after disconnect')
// initSocket()
// }, 1000)
// })
// ding -> dong. for test & live check purpose
// ping/pong are reserved by socket.io https://github.com/socketio/socket.io/issues/2414
socket
.
on
(
'
ding
'
,
function
(
e
)
{
clog
(
'
received socket io event: ding. emit dong...
'
)
socket
.
emit
(
'
dong
'
,
'
dong
'
)
})
socket
.
on
(
'
connect
'
,
function
(
e
)
{
clog
(
'
connected to server:
'
+
e
)
})
socket
.
on
(
'
disconnect
'
,
function
(
e
)
{
clog
(
'
socket disconnect:
'
+
e
)
})
// // Reconnect...
// setTimeout(function () {
// clog('starting initSocket after disconnect')
// initSocket()
// }, 1000)
// })
}
window
.
Wechaty
=
Wechaty
...
...
src/puppet-web-server.js
浏览文件 @
b0c84ccb
const
Browser
=
require
(
'
./puppet-web-browser
'
)
const
co
=
require
(
'
co
'
)
/****************************************
*
* Class Server
*
***************************************/
const
fs
=
require
(
'
fs
'
)
const
io
=
require
(
'
socket.io
'
)
const
path
=
require
(
'
path
'
)
const
https
=
require
(
'
https
'
)
const
bodyParser
=
require
(
'
body-parser
'
)
const
Express
=
require
(
'
express
'
)
const
EventEmitter
=
require
(
'
events
'
)
class
Server
extends
EventEmitter
{
constructor
(
port
)
{
super
()
this
.
port
=
port
||
8788
// W(87) X(88), ascii char code ;-]
this
.
logined
=
false
this
.
on
(
'
login
'
,
()
=>
this
.
logined
=
true
)
this
.
on
(
'
logout
'
,
()
=>
this
.
logined
=
false
)
}
init
()
{
this
.
express
=
this
.
createExpress
()
this
.
server
=
this
.
createHttpsServer
(
this
.
express
,
this
.
port
)
this
.
socketio
=
this
.
createSocketIo
(
this
.
server
)
this
.
browser
=
this
.
createBrowser
()
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
browser
.
init
()
.
then
(()
=>
{
console
.
error
(
'
browser init finished with port:
'
+
this
.
port
+
'
.
'
)
resolve
()
// after init success
})
})
}
createBrowser
()
{
const
b
=
new
Browser
({
port
:
this
.
port
})
/**
* `unload` event is sent from js@browser to webserver via socketio
* after received `unload`, we re-inject the Wechaty js code into browser.
*/
this
.
on
(
'
unload
'
,
()
=>
{
console
.
error
(
'
server received unload event
'
)
this
.
browser
.
inject
()
.
then
(()
=>
console
.
error
(
'
re-injected
'
))
})
return
b
}
/*
* Ssl Key & Cert files.
* No need to re-config & Hardcoded here,
* because there will only be visit from 127.0.0.1
*/
getSsl
()
{
// http://blog.mgechev.com/2014/02/19/create-https-tls-ssl-application-with-express-nodejs/
// openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
// openssl rsa -in key.pem -out newkey.pem && mv newkey.pem key.pem
return
{
key
:
`
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAt1c10tCbJG5ydWPjBV5c4gA3f1/8ubhNnYj98dtFPR8a4VPk
ORCyst157tLq5uPgmlZLedAm08VFiDUwn8iGQI/RegQSuRjxaS2MccfP9jpzDazy
eMBi0mLg25z/4v9y/8N9nLSqbHrPrye+hzpSkSkyQ/zf/P85ZCdTGwCnFX6WlBQX
I/3o5wWWRv4DaZTaLhChHjAa6+HJdYFvDvI6QUxggj3Vq64HsJv2xGvG7pZWjxXp
FS0Mg8MQbHME1J92OwPNaqsNUY3JfPkaeYmfQi5Qy53ULGLxVgV0eyIFf6s4NSCr
FI4PjJXyBWYCAlxVIUm1WdylIAl4MVvGADA1mQIDAQABAoIBAEOFUsU5HmnkYzLo
fotTnVF+UvIOH70mKy+BbETOREmmUvf5NWvuwmEtP+K8utYdxnIQpetOxX3ogRsQ
u7+c0hSk4rjVFzAkB4R8yeR9ehFspUK8FvBxqfNhhv5aa8Ll4SxgirpTrxAUirgv
IvQafp4HVgPD9ZnvROulr+2Z5+7596qif4F1HrrxN6tl+cGNZFIZ7vk7uGsF8k4G
LQ8xik8QABcTE4pKpRtNlesRpojSGI8cnu/z8MgDIPMHu6wgdz+OR1rZwNMuREZi
zejf5gg82B1KxeFNEmtMI1GM+whKVkPBxwASJTOaiN2Oh7SdSO5SHxFv2bAxjJ6z
SC4mwqECgYEA7YSIINzOTCkUGGcJrg14P0m1KxuoPFSoAXk61F6kwW1FQVPmfk4i
n/MO8+2/CSAZiFEFNTUvWj5xM955wDVgSY8Z7l/aYxn11gGzV0XypsK77edTRrfp
6AlvIepclSX5ocmhizHe4mrm8KaZ014qMtO3RUaoDA9h7zqQOK5OyxcCgYEAxZty
Dy7IxOBk3QfGdVqto/oDX2fQ6PTAIYwuOAh6rrQDkSXShPWI3bUJegylQeVOYG40
3ti/fd/247OkFwPsPODNisWQTsdX5Kr4KWjmfTSpSDm1AkDvnuPk/tcyFhijxZ48
6Q0ZL529oy7cwel3p3uzDIFbAMEdATKIRp9css8CgYAkJNfmUFOgaVvifsONVgVn
dBr6rWHDlIpgdwdJzAE8Yhl44ICh1dgVCRLMcfBxPg5EnTeyqh5DmF73qrJSWo0F
hJ5IlRORoyCy6V1WOZG8aMPaZypYB6KzqcPcoGJoW/gJ87n+iZ9GS0hLdL7R2HGJ
fIhWJXNrKmgX1Iyf436gDwKBgQC57ekEICEIHZrJ3eb9xLRc9YD249fNWXzuE9fp
IRFOEFLK36uVLvH4qb6g+AUGW5vDX+6fP5Ht/i1vUjey8B33qg275OhDN42busKF
NA6rAEHHk4Sc+jx8ZDGzFwgpgkWWS61EGu73vpQQVqegTOwoyltOCOh3bTy9Q661
xHyUQQKBgA1vFFy09wJmQNCoo2kLvghkyPHrBXQlzoRW3cafw+vwoYZFukxst0dd
2mQ3CyRJ7buoDdj0cFVlScB7KSQtIvLMtAn6tkL6ecooep346OSoLlsQd/F5ODep
bBdRj0Orj7xQDeIicM7ASTYPAivh9NTu4yJL0r/YOX3OvXxaBSGf
-----END RSA PRIVATE KEY-----
`
,
cert
:
`
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKMz7h5gRwqgMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTYwNTAxMTUyNzM5WhcNMTcwNTAxMTUyNzM5WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAt1c10tCbJG5ydWPjBV5c4gA3f1/8ubhNnYj98dtFPR8a4VPkORCyst15
7tLq5uPgmlZLedAm08VFiDUwn8iGQI/RegQSuRjxaS2MccfP9jpzDazyeMBi0mLg
25z/4v9y/8N9nLSqbHrPrye+hzpSkSkyQ/zf/P85ZCdTGwCnFX6WlBQXI/3o5wWW
Rv4DaZTaLhChHjAa6+HJdYFvDvI6QUxggj3Vq64HsJv2xGvG7pZWjxXpFS0Mg8MQ
bHME1J92OwPNaqsNUY3JfPkaeYmfQi5Qy53ULGLxVgV0eyIFf6s4NSCrFI4PjJXy
BWYCAlxVIUm1WdylIAl4MVvGADA1mQIDAQABo1AwTjAdBgNVHQ4EFgQU/Sed0ljf
HEpQsmReiphJnSsPTFowHwYDVR0jBBgwFoAU/Sed0ljfHEpQsmReiphJnSsPTFow
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXjqJfXSEwVktRmeB+tW0
F837NEfzyedP82gSCCC+pbs+4E6DbDANupxP8vqIfqTe03YScZHVR/ha/f/WPLpc
HvDuyOSXrms9x0OHxsH70Ajx5/JBWyBbtFdox6yCEoeydOXl+MQDXgnGGv8VFXdN
dd2RP6/Ovx88hYGWcwf4RekTrbsM40n7BkkCCEedZPy7ouRmAs2FXpd+cm3zD9jt
Bas7b0wEOA7H2HejkbFOUierE40Kzh72vDD7M6DqUZFSvClY0O0+EYefB5TiRsN0
g+Xdc4Ag/St5eqgrp95KOlVeepSlb35LAD1Cc91LddTXCYS7+dc4ndQYpgrLU0ru
Sw==
-----END CERTIFICATE-----
`
}
}
/**
*
* Https Server
*
*/
createHttpsServer
(
express
)
{
const
key
=
this
.
getSsl
().
key
const
cert
=
this
.
getSsl
().
cert
return
https
.
createServer
({
key
:
key
,
cert
:
cert
},
express
).
listen
(
this
.
port
,
()
=>
{
console
.
error
(
`createHttpsServer listening on port
${
this
.
port
}
!`
)
})
}
/**
*
* Express Middleware
*
*/
createExpress
()
{
const
app
=
new
Express
()
app
.
use
(
bodyParser
.
json
())
app
.
use
(
function
(
req
,
res
,
next
)
{
res
.
header
(
"
Access-Control-Allow-Origin
"
,
"
*
"
)
res
.
header
(
"
Access-Control-Allow-Headers
"
,
"
Origin, X-Requested-With, Content-Type, Accept
"
)
next
()
})
app
.
get
(
'
/ding
'
,
function
(
req
,
res
)
{
console
.
error
(
new
Date
()
+
'
GET /ding
'
)
res
.
send
(
'
dong
'
)
})
// app.post('/', function (req, res) {
// console.log('post ' + new Date())
// console.log(req.body)
// res.send(req.body)
// })
return
app
}
/**
*
* Socket IO
*
*/
createSocketIo
(
server
)
{
const
socketServer
=
io
.
listen
(
server
,
{
log
:
true
})
socketServer
.
sockets
.
on
(
'
connection
'
,
(
s
)
=>
{
console
.
log
(
'
socket.on connection entried
'
)
// save to instance: socketClient
this
.
socketClient
=
s
s
.
on
(
'
disconnect
'
,
function
()
{
console
.
error
(
'
socket.io disconnected
'
)
/**
* Possible conditions:
* 1. Browser reload
* 2. Lost connection(Bad network
* 3.
*/
this
.
socketClient
=
null
})
// Events from Wechaty@Broswer --to--> Server
const
events
=
[
'
message
'
,
'
login
'
,
'
logout
'
,
'
unload
'
]
events
.
map
(
e
=>
{
s
.
on
(
e
,
data
=>
{
console
.
log
(
`recv event[
${
e
}
] from browser`
)
this
.
emit
(
e
,
data
)
})
})
/**
* prevent lost event: buffer new event received when socket disconnected
while (buff.length) {
let e = buff.shift()
socket.emit(e.event, e.data)
}
*/
})
return
socketServer
}
isLogined
()
{
return
this
.
logined
}
quit
()
{
if
(
this
.
browser
)
{
this
.
browser
.
quit
()
delete
this
.
browser
}
if
(
this
.
socketServer
)
{
socketServer
.
httpsServer
.
close
()
socketServer
.
close
()
delete
this
.
socketServer
}
if
(
this
.
socketClient
)
{
this
.
socketClient
.
disconnect
()
delete
this
.
socketClient
}
if
(
this
.
server
)
{
this
.
server
.
close
()
delete
this
.
server
}
}
/**
*
* Proxy Call to Wechaty in Browser
*
*/
browserExecute
(
script
)
{
if
(
!
this
.
browser
)
throw
new
Error
(
'
no browser!
'
)
return
this
.
browser
.
execute
(
script
)
}
proxyWechaty
(
wechatyFunc
)
{
const
args
=
Array
.
prototype
.
slice
.
call
(
arguments
,
1
)
const
argsJson
=
JSON
.
stringify
(
args
)
const
wechatyScript
=
`return (Wechaty && Wechaty.
${
wechatyFunc
}
.apply(undefined, JSON.parse('
${
argsJson
}
')))`
console
.
error
(
'
proxyWechaty:
'
+
wechatyScript
)
return
this
.
browserExecute
(
wechatyScript
)
}
Wechaty_getLoginStatusCode
()
{
return
this
.
proxyWechaty
(
'
getLoginStatusCode
'
)
}
Wechaty_getLoginQrImgUrl
()
{
return
this
.
proxyWechaty
(
'
getLoginQrImgUrl
'
)
}
// Wechaty_CARPEDIEM() { return this.proxyWechaty('call') }
debugLoop
()
{
this
.
Wechaty_getLoginStatusCode
().
then
((
c
)
=>
{
console
.
error
(
`login status code:
${
c
}
`
)
setTimeout
(
this
.
debugLoop
.
bind
(
this
),
3000
)
})
}
}
module
.
exports
=
Server
const
Browser
=
require
(
'
./puppet-web-browser
'
)
/****************************************
*
* Class Server
*
***************************************/
const
fs
=
require
(
'
fs
'
)
const
io
=
require
(
'
socket.io
'
)
const
path
=
require
(
'
path
'
)
const
https
=
require
(
'
https
'
)
const
bodyParser
=
require
(
'
body-parser
'
)
const
Express
=
require
(
'
express
'
)
const
EventEmitter
=
require
(
'
events
'
)
const
log
=
require
(
'
npmlog
'
)
//const co = require('co')
class
Server
extends
EventEmitter
{
constructor
(
options
)
{
super
()
options
=
options
||
{}
this
.
port
=
options
.
port
||
8788
// W(87) X(88), ascii char code ;-]
this
.
logined
=
false
this
.
on
(
'
login
'
,
()
=>
this
.
logined
=
true
)
this
.
on
(
'
logout
'
,
()
=>
this
.
logined
=
false
)
}
init
()
{
this
.
express
=
this
.
createExpress
()
this
.
server
=
this
.
createHttpsServer
(
this
.
express
,
this
.
port
)
this
.
socketio
=
this
.
createSocketIo
(
this
.
server
)
this
.
browser
=
this
.
createBrowser
()
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
browser
.
init
()
.
then
(()
=>
{
log
.
verbose
(
'
Server
'
,
`browser init finished with port:
${
this
.
port
}
`
)
resolve
()
// after init success
})
})
}
createBrowser
()
{
const
b
=
new
Browser
({
port
:
this
.
port
})
/**
* `unload` event is sent from js@browser to webserver via socketio
* after received `unload`, we re-inject the Wechaty js code into browser.
*/
this
.
on
(
'
unload
'
,
()
=>
{
log
.
verbose
(
'
Server
'
,
'
server received unload event
'
)
this
.
browser
.
inject
()
.
then
(()
=>
log
.
verbose
(
'
Server
'
,
'
re-injected
'
))
})
return
b
}
/**
*
* Https Server
*
*/
createHttpsServer
(
express
)
{
return
https
.
createServer
({
key
:
require
(
'
./ssl-key-cert
'
).
key
,
cert
:
require
(
'
./ssl-key-cert
'
).
cert
},
express
).
listen
(
this
.
port
,
()
=>
{
log
.
verbose
(
'
Server
'
,
`createHttpsServer listening on port
${
this
.
port
}
!`
)
})
}
/**
*
* Express Middleware
*
*/
createExpress
()
{
const
app
=
new
Express
()
app
.
use
(
bodyParser
.
json
())
app
.
use
(
function
(
req
,
res
,
next
)
{
res
.
header
(
"
Access-Control-Allow-Origin
"
,
"
*
"
)
res
.
header
(
"
Access-Control-Allow-Headers
"
,
"
Origin, X-Requested-With, Content-Type, Accept
"
)
next
()
})
app
.
get
(
'
/ding
'
,
function
(
req
,
res
)
{
log
.
verbose
(
'
Server
'
,
'
%s GET /ding
'
,
new
Date
())
res
.
end
(
'
dong
'
)
})
return
app
}
/**
*
* Socket IO
*
*/
createSocketIo
(
server
)
{
const
socketServer
=
io
.
listen
(
server
,
{
log
:
true
})
socketServer
.
sockets
.
on
(
'
connection
'
,
(
s
)
=>
{
log
.
verbose
(
'
Server
'
,
'
socket.on connection entried
'
)
// save to instance: socketClient
this
.
socketClient
=
s
s
.
on
(
'
disconnect
'
,
function
()
{
log
.
verbose
(
'
Server
'
,
'
socket.io disconnected
'
)
/**
* Possible conditions:
* 1. Browser reload
* 2. Lost connection(Bad network
* 3.
*/
this
.
socketClient
=
null
})
// Events from Wechaty@Broswer --to--> Server
;[
'
message
'
,
'
login
'
,
'
logout
'
,
'
unload
'
].
map
(
e
=>
{
s
.
on
(
e
,
data
=>
{
log
.
verbose
(
'
Server
'
,
`recv event[
${
e
}
] from browser`
)
this
.
emit
(
e
,
data
)
})
})
s
.
on
(
'
error
'
,
e
=>
log
.
error
(
'
Server
'
,
'
socket error: %s
'
,
e
))
/**
* prevent lost event: buffer new event received when socket disconnected
while (buff.length) {
let e = buff.shift()
socket.emit(e.event, e.data)
}
*/
})
return
socketServer
}
isLogined
()
{
return
this
.
logined
}
quit
()
{
if
(
this
.
browser
)
{
this
.
browser
.
quit
()
delete
this
.
browser
}
if
(
this
.
socketServer
)
{
socketServer
.
httpsServer
.
close
()
socketServer
.
close
()
delete
this
.
socketServer
}
if
(
this
.
socketClient
)
{
this
.
socketClient
.
disconnect
()
delete
this
.
socketClient
}
if
(
this
.
server
)
{
this
.
server
.
close
()
delete
this
.
server
}
}
/**
*
* Proxy Call to Wechaty in Browser
*
*/
browserExecute
(
script
)
{
if
(
!
this
.
browser
)
throw
new
Error
(
'
no browser!
'
)
return
this
.
browser
.
execute
(
script
)
}
proxyWechaty
(
wechatyFunc
,
...
args
)
{
//const args = Array.prototype.slice.call(arguments, 1)
const
argsJson
=
JSON
.
stringify
(
args
)
const
wechatyScript
=
`return (Wechaty && Wechaty.
${
wechatyFunc
}
.apply(undefined, JSON.parse('
${
argsJson
}
')))`
log
.
verbose
(
'
Server
'
,
'
proxyWechaty:
'
+
wechatyScript
)
return
this
.
browserExecute
(
wechatyScript
)
}
}
module
.
exports
=
Server
src/puppet-web.js
浏览文件 @
b0c84ccb
/**
*
* wechaty
-lib: Wechat for Bot. and for human who can talk with
bot/robot
* wechaty
: Wechat for Bot. and for human who talk to
bot/robot
*
* Web
Soul of
Puppet
* Web Puppet
* use to control wechat web.
*
* Licenst:
MIT
* https://github.com/zixia/wechaty
-lib
* Licenst:
ISC
* https://github.com/zixia/wechaty
*
*/
...
...
@@ -17,43 +17,59 @@
*
***************************************/
const
Puppet
=
require
(
'
./puppet
'
)
const
Message
=
require
(
'
./message
'
)
const
WebServer
=
require
(
'
./puppet-web-server
'
)
class
PuppetWeb
extends
Puppet
{
constructor
(
port
)
{
constructor
(
options
)
{
super
()
this
.
port
=
port
||
8788
// W(87) X(88), ascii char code ;-]
options
=
options
||
{}
this
.
port
=
options
.
port
||
8788
// W(87) X(88), ascii char code ;-]
}
toString
()
{
return
`Class PuppetWeb({port:
${
this
.
port
}
})`
}
init
()
{
this
.
server
=
new
WebServer
(
this
.
port
)
this
.
server
=
new
WebServer
(
{
port
:
this
.
port
}
)
const
EVENTS_IN
=
[
'
message
'
,
'
login
'
;[
// events. ';' for seprate from the last code line
'
login
'
,
'
logout
'
]
EVENTS_IN
.
map
(
event
=>
].
map
(
event
=>
this
.
server
.
on
(
event
,
data
=>
this
.
emit
(
event
,
data
)
)
)
return
this
.
server
.
init
(
this
.
port
)
this
.
server
.
on
(
'
message
'
,
data
=>
{
const
m
=
new
Message
(
data
)
this
.
emit
(
'
message
'
,
m
)
})
return
this
.
server
.
init
()
}
send
(
message
)
{
if
(
!
this
.
browser
)
throw
new
Error
(
'
browser not exist!
'
);
const
ToUserName
=
message
.
get
(
'
to
'
)
const
Content
=
message
.
get
(
'
content
'
)
const
toContact
=
message
.
get
(
'
to
'
)
const
content
=
message
.
get
(
'
content
'
)
const
script
=
`return Wechaty.send('
${
ToUserName
}
', '
${
Content
}
')`
return
this
.
browser
.
execte
(
script
)
return
this
.
server
.
proxyWechaty
(
'
send
'
,
toContact
.
getId
(),
content
)
}
logout
()
{
if
(
!
this
.
browser
)
throw
new
Error
(
'
browser not exist!
'
);
return
this
.
browser
.
execte
(
'
return Wechaty.logout()
'
)
return
this
.
server
.
proxyWechaty
(
'
logout
'
)
}
getLoginStatusCode
()
{
log
.
verbose
(
'
PuppetWeb
'
,
'
getLoginStatusCode
'
)
return
this
.
server
.
proxyWechaty
(
'
getLoginStatusCode
'
)
}
getLoginQrImgUrl
()
{
return
this
.
server
.
proxyWechaty
(
'
getLoginQrImgUrl
'
)
}
debugLoop
()
{
this
.
getLoginStatusCode
().
then
((
c
)
=>
{
log
.
verbose
(
'
PuppetWeb
'
,
`login status code:
${
c
}
`
)
setTimeout
(
this
.
debugLoop
.
bind
(
this
),
3000
)
})
}
/*
...
...
@@ -80,8 +96,12 @@ class PuppetWeb extends Puppet {
* Public Methods
*
*/
getLoginQrImgUrl
()
{
return
this
.
server
.
Wechaty_getLoginQrImgUrl
()
}
getLoginStatusCode
()
{
return
this
.
server
.
Wechaty_getLoginStatusCode
()
}
getLoginQrImgUrl
()
{
return
this
.
server
.
proxyWechaty
(
'
getLoginQrImgUrl
'
)
}
getLoginStatusCode
()
{
return
this
.
server
.
proxyWechaty
(
'
getLoginStatusCode
'
)
}
}
module
.
exports
=
PuppetWeb
src/puppet.js
浏览文件 @
b0c84ccb
/**
* Wechat for Bot. and for human who can talk with bot/robot
*
* Interface for puppet
*
*/
* Wechat for Bot. and for human who can talk with bot/robot
*
* Interface for puppet
*
* Licenst: ISC
* https://github.com/zixia/wechaty
*
*/
const
EventEmitter
=
require
(
'
events
'
)
...
...
@@ -13,32 +16,33 @@ class Puppet extends EventEmitter {
}
/**
* Get current logined user
* @return <Contact>
*/
* Get current logined user
* @return <Contact>
*/
currentUser
()
{
throw
new
Error
(
'
To Be Implemented
'
)
}
/**
* let puppet send message
*
* @param <Message> message - the message to be sent
* @return <Promise>
*/
* let puppet send message
*
* @param <Message> message - the message to be sent
* @return <Promise>
*/
send
(
message
)
{
throw
new
Error
(
'
To Be Implemented
'
)
}
logout
()
{
throw
new
Error
(
'
To Be Implementsd
'
)
}
alive
()
{
throw
new
Error
(
'
To Be Implementsd
'
)
}
// () { throw new Error('To Be Implemented') }
/**
*
* Events .on(...)
*
* login -
* logout -
*
*
*/
*
* Events .on(...)
*
* login -
* logout -
*
*
*/
debug
(
cb
)
{
// List of all events
[
'
message
'
// event data should carry a instance of Message
...
...
src/ssl-key-cert.js
0 → 100644
浏览文件 @
b0c84ccb
/**
* Ssl Key & Cert files.
* No need to re-config & Hardcoded here,
* because there will only be visit from 127.0.0.1
*
* http://blog.mgechev.com/2014/02/19/create-https-tls-ssl-application-with-express-nodejs/
* openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
* openssl rsa -in key.pem -out newkey.pem && mv newkey.pem key.pem
*/
const
key
=
`
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAt1c10tCbJG5ydWPjBV5c4gA3f1/8ubhNnYj98dtFPR8a4VPk
ORCyst157tLq5uPgmlZLedAm08VFiDUwn8iGQI/RegQSuRjxaS2MccfP9jpzDazy
eMBi0mLg25z/4v9y/8N9nLSqbHrPrye+hzpSkSkyQ/zf/P85ZCdTGwCnFX6WlBQX
I/3o5wWWRv4DaZTaLhChHjAa6+HJdYFvDvI6QUxggj3Vq64HsJv2xGvG7pZWjxXp
FS0Mg8MQbHME1J92OwPNaqsNUY3JfPkaeYmfQi5Qy53ULGLxVgV0eyIFf6s4NSCr
FI4PjJXyBWYCAlxVIUm1WdylIAl4MVvGADA1mQIDAQABAoIBAEOFUsU5HmnkYzLo
fotTnVF+UvIOH70mKy+BbETOREmmUvf5NWvuwmEtP+K8utYdxnIQpetOxX3ogRsQ
u7+c0hSk4rjVFzAkB4R8yeR9ehFspUK8FvBxqfNhhv5aa8Ll4SxgirpTrxAUirgv
IvQafp4HVgPD9ZnvROulr+2Z5+7596qif4F1HrrxN6tl+cGNZFIZ7vk7uGsF8k4G
LQ8xik8QABcTE4pKpRtNlesRpojSGI8cnu/z8MgDIPMHu6wgdz+OR1rZwNMuREZi
zejf5gg82B1KxeFNEmtMI1GM+whKVkPBxwASJTOaiN2Oh7SdSO5SHxFv2bAxjJ6z
SC4mwqECgYEA7YSIINzOTCkUGGcJrg14P0m1KxuoPFSoAXk61F6kwW1FQVPmfk4i
n/MO8+2/CSAZiFEFNTUvWj5xM955wDVgSY8Z7l/aYxn11gGzV0XypsK77edTRrfp
6AlvIepclSX5ocmhizHe4mrm8KaZ014qMtO3RUaoDA9h7zqQOK5OyxcCgYEAxZty
Dy7IxOBk3QfGdVqto/oDX2fQ6PTAIYwuOAh6rrQDkSXShPWI3bUJegylQeVOYG40
3ti/fd/247OkFwPsPODNisWQTsdX5Kr4KWjmfTSpSDm1AkDvnuPk/tcyFhijxZ48
6Q0ZL529oy7cwel3p3uzDIFbAMEdATKIRp9css8CgYAkJNfmUFOgaVvifsONVgVn
dBr6rWHDlIpgdwdJzAE8Yhl44ICh1dgVCRLMcfBxPg5EnTeyqh5DmF73qrJSWo0F
hJ5IlRORoyCy6V1WOZG8aMPaZypYB6KzqcPcoGJoW/gJ87n+iZ9GS0hLdL7R2HGJ
fIhWJXNrKmgX1Iyf436gDwKBgQC57ekEICEIHZrJ3eb9xLRc9YD249fNWXzuE9fp
IRFOEFLK36uVLvH4qb6g+AUGW5vDX+6fP5Ht/i1vUjey8B33qg275OhDN42busKF
NA6rAEHHk4Sc+jx8ZDGzFwgpgkWWS61EGu73vpQQVqegTOwoyltOCOh3bTy9Q661
xHyUQQKBgA1vFFy09wJmQNCoo2kLvghkyPHrBXQlzoRW3cafw+vwoYZFukxst0dd
2mQ3CyRJ7buoDdj0cFVlScB7KSQtIvLMtAn6tkL6ecooep346OSoLlsQd/F5ODep
bBdRj0Orj7xQDeIicM7ASTYPAivh9NTu4yJL0r/YOX3OvXxaBSGf
-----END RSA PRIVATE KEY-----
`
const
cert
=
`
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKMz7h5gRwqgMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTYwNTAxMTUyNzM5WhcNMTcwNTAxMTUyNzM5WjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAt1c10tCbJG5ydWPjBV5c4gA3f1/8ubhNnYj98dtFPR8a4VPkORCyst15
7tLq5uPgmlZLedAm08VFiDUwn8iGQI/RegQSuRjxaS2MccfP9jpzDazyeMBi0mLg
25z/4v9y/8N9nLSqbHrPrye+hzpSkSkyQ/zf/P85ZCdTGwCnFX6WlBQXI/3o5wWW
Rv4DaZTaLhChHjAa6+HJdYFvDvI6QUxggj3Vq64HsJv2xGvG7pZWjxXpFS0Mg8MQ
bHME1J92OwPNaqsNUY3JfPkaeYmfQi5Qy53ULGLxVgV0eyIFf6s4NSCrFI4PjJXy
BWYCAlxVIUm1WdylIAl4MVvGADA1mQIDAQABo1AwTjAdBgNVHQ4EFgQU/Sed0ljf
HEpQsmReiphJnSsPTFowHwYDVR0jBBgwFoAU/Sed0ljfHEpQsmReiphJnSsPTFow
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXjqJfXSEwVktRmeB+tW0
F837NEfzyedP82gSCCC+pbs+4E6DbDANupxP8vqIfqTe03YScZHVR/ha/f/WPLpc
HvDuyOSXrms9x0OHxsH70Ajx5/JBWyBbtFdox6yCEoeydOXl+MQDXgnGGv8VFXdN
dd2RP6/Ovx88hYGWcwf4RekTrbsM40n7BkkCCEedZPy7ouRmAs2FXpd+cm3zD9jt
Bas7b0wEOA7H2HejkbFOUierE40Kzh72vDD7M6DqUZFSvClY0O0+EYefB5TiRsN0
g+Xdc4Ag/St5eqgrp95KOlVeepSlb35LAD1Cc91LddTXCYS7+dc4ndQYpgrLU0ru
Sw==
-----END CERTIFICATE-----
`
module
.
exports
=
{
cert
:
cert
,
key
:
key
}
src/wechaty.js
浏览文件 @
b0c84ccb
...
...
@@ -11,14 +11,18 @@ const Group = require('./group')
class
Wechaty
extends
EventEmitter
{
// cookie,Uin, Sid,SKey
constructor
()
{
constructor
(
puppet
)
{
super
()
this
.
puppet
=
new
Puppet
.
Web
()
/*
this.contact = new Contact(this.puppet)
this.group = new Group(this.puppet)
this.message = new Message(this.puppet)
*/
puppet
=
puppet
||
'
web
'
switch
(
puppet
)
{
case
'
web
'
:
this
.
puppet
=
new
Puppet
.
Web
()
break
default
:
throw
new
Error
(
'
Puppet unknown:
'
+
puppet
)
break
}
this
.
puppet
.
on
(
'
message
'
,
(
e
)
=>
{
this
.
emit
(
'
message
'
,
e
)
...
...
tests/message-tests.js
浏览文件 @
b0c84ccb
...
...
@@ -10,8 +10,8 @@ test('Message constructor parser test', t => {
}
const
m
=
new
Message
(
rawData
)
t
.
equal
(
m
.
get
(
'
id
'
)
,
EXPECTED
.
id
,
'
id right
'
)
t
.
equal
(
m
.
get
(
'
from
'
)
,
EXPECTED
.
from
,
'
from right
'
)
t
.
equal
(
m
.
get
(
'
id
'
)
,
EXPECTED
.
id
,
'
id right
'
)
t
.
equal
(
m
.
get
(
'
from
'
)
.
getId
()
,
EXPECTED
.
from
,
'
from right
'
)
t
.
end
()
})
...
...
tests/puppet-web-browser-tests.js
浏览文件 @
b0c84ccb
...
...
@@ -4,7 +4,7 @@ const Browser = require('../src/puppet-web-browser')
test
(
'
Browser class smoking tests
'
,
function
(
t
)
{
//t.plan(5)
const
PORT
=
58788
const
b
=
new
Browser
(
'
chrome
'
,
PORT
)
const
b
=
new
Browser
(
{
browser
:
'
chrome
'
,
port
:
PORT
}
)
t
.
ok
(
b
,
'
Browser instance created
'
)
b
.
open
()
...
...
tests/puppet-web-server-tests.js
浏览文件 @
b0c84ccb
const
https
=
require
(
'
https
'
)
const
test
=
require
(
'
tape
'
)
const
log
=
require
(
'
npmlog
'
)
const
test
=
require
(
'
tape
'
)
const
Server
=
require
(
'
../src/puppet-web-server
'
)
test
(
'
Server basic tests
'
,
function
(
t
)
{
//t.plan(9)
const
PORT
=
58788
const
s
=
new
Server
(
PORT
)
const
s
=
new
Server
(
{
port
:
PORT
}
)
t
.
equal
(
typeof
s
,
'
object
'
,
'
Server instance created
'
)
const
express
=
s
.
createExpress
()
t
.
equal
(
typeof
express
,
'
function
'
,
'
create express
'
)
delete
express
const
server
=
s
.
createHttpsServer
(
express
,
PORT
)
const
server
=
s
.
createHttpsServer
(
express
)
t
.
equal
(
typeof
server
,
'
object
'
,
'
create server
'
)
server
.
on
(
'
close
'
,
()
=>
t
.
ok
(
true
,
'
HttpsServer quited
'
))
server
.
close
(()
=>
t
.
ok
(
true
,
'
HttpsServer closed
'
))
...
...
@@ -33,9 +33,9 @@ test('Server basic tests', function (t) {
s
.
quit
()
+
t
.
end
()
})
test
(
'
Server smok
ing tests
'
,
function
(
t
)
{
test
(
'
Server smok
e testing
'
,
function
(
t
)
{
const
PORT
=
58788
const
server
=
new
Server
(
PORT
)
const
server
=
new
Server
(
{
port
:
PORT
}
)
server
.
init
()
.
then
(()
=>
{
...
...
@@ -59,6 +59,7 @@ test('Server smoking tests', function (t) {
t
.
equal
(
retBrowser
,
'
dong
'
,
'
ding browser got dong
'
)
t
.
equal
(
retProxy
,
'
dong
'
,
'
ding proxy got dong
'
)
// XXX sometimes object? 201605
t
.
equal
(
typeof
retStatus
,
'
number
'
,
'
status is number
'
)
t
.
end
()
+
server
.
quit
()
...
...
@@ -74,7 +75,7 @@ test('Server smoking tests', function (t) {
return
new
Promise
((
resolve
,
reject
)
=>
{
https
.
get
(
options
,
res
=>
{
res
.
on
(
'
data
'
,
chunk
=>
{
console
.
log
(
'
https on data got:
'
+
chunk
.
toString
())
log
.
info
(
'
TestingServer
'
,
'
https on data got:
'
+
chunk
.
toString
())
resolve
(
chunk
.
toString
())
})
}).
on
(
'
error
'
,
e
=>
reject
(
'
https get error:
'
+
e
))
...
...
@@ -89,20 +90,24 @@ test('Server smoking tests', function (t) {
setTimeout
(
testDing
,
waitTime
)
function
testDing
()
{
//log.info('TestingServer', server.socketio)
if
(
!
server
.
socketClient
)
{
totalTime
+=
waitTime
if
(
totalTime
>
maxTime
)
return
reject
(
'
timeout after
'
+
totalTime
+
'
ms
'
);
console
.
error
(
'
waiting socketClient to connect for
'
+
totalTime
+
'
/
'
+
maxTime
+
'
ms...
'
)
log
.
info
(
'
TestingServer
'
,
'
waiting socketClient to connect for
'
+
totalTime
+
'
/
'
+
maxTime
+
'
ms...
'
)
setTimeout
(
testDing
,
waitTime
)
return
}
//log.info('TestingServer', server.socketClient)
server
.
socketClient
.
on
(
'
dong
'
,
data
=>
{
console
.
log
(
'
socket on dong got:
'
+
data
)
log
.
info
(
'
TestingServer
'
,
'
socket on dong got:
'
+
data
)
resolve
(
data
)
})
server
.
socketClient
.
emit
(
'
ding
'
)
server
.
socketClient
.
emit
(
'
ding
'
)
server
.
socketClient
.
emit
(
'
ding
'
)
}
})
}
...
...
@@ -116,7 +121,7 @@ test('Server smoking tests', function (t) {
}
function
getLoginStatusCode
()
{
return
server
.
Wechaty_getLoginStatusCode
(
)
return
server
.
proxyWechaty
(
'
getLoginStatusCode
'
)
}
}).
catch
((
e
)
=>
{
...
...
tests/webdriver-tests.js
浏览文件 @
b0c84ccb
...
...
@@ -9,8 +9,13 @@ const WebBrowser = require('../src/puppet-web-browser')
test
(
'
WebDriver smoke testing
'
,
function
(
t
)
{
const
driver
=
new
WebDriver
.
Builder
()
//.withCapabilities(WebDriver.Capabilities.chrome()).build()
.
withCapabilities
(
WebDriver
.
Capabilities
.
phantomjs
()).
build
()
.
withCapabilities
(
WebDriver
.
Capabilities
.
chrome
()).
build
()
/*
.withCapabilities(
WebDriver.Capabilities.phantomjs()
//.set('phantomjs.binary.path', 'D:\\cygwin64\\home\\zixia\\git\\wechaty\\node_modules\\phantomjs-prebuilt\\lib\\phantom\\bin\\phantomjs.exe')
).build()
*/
// .set('webdriver.load.strategy', 'unstable')
// https://stackoverflow.com/questions/37071807/how-to-executescript-before-page-load-by-webdriver-in-selenium
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录