Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lzb_79
uni-app
提交
feaf1646
U
uni-app
项目概览
lzb_79
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
feaf1646
编写于
9月 24, 2021
作者:
fxy060608
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(automator): support safari,firefox
上级
9bd8db1d
变更
13
展开全部
隐藏空白更改
内联
并排
Showing
13 changed file
with
1870 addition
and
6274 deletion
+1870
-6274
.prettierignore
.prettierignore
+8
-1
packages/uni-app-plus/lib/automator.js
packages/uni-app-plus/lib/automator.js
+724
-990
packages/uni-app-plus/lib/uni.automator.js
packages/uni-app-plus/lib/uni.automator.js
+238
-316
packages/uni-app-vite/lib/template/__uniappautomator.js
packages/uni-app-vite/lib/template/__uniappautomator.js
+15
-530
packages/uni-automator/dist/environment.js
packages/uni-automator/dist/environment.js
+1
-44
packages/uni-automator/dist/index.js
packages/uni-automator/dist/index.js
+16
-1467
packages/uni-automator/dist/teardown.js
packages/uni-automator/dist/teardown.js
+1
-13
packages/uni-h5/lib/automator.js
packages/uni-h5/lib/automator.js
+718
-912
packages/uni-h5/lib/uni.automator.js
packages/uni-h5/lib/uni.automator.js
+145
-107
packages/uni-mp-baidu/lib/automator.js
packages/uni-mp-baidu/lib/automator.js
+1
-488
packages/uni-mp-baidu/lib/uni.automator.js
packages/uni-mp-baidu/lib/uni.automator.js
+1
-556
packages/uni-mp-weixin/lib/automator.js
packages/uni-mp-weixin/lib/automator.js
+1
-489
packages/uni-mp-weixin/lib/uni.automator.js
packages/uni-mp-weixin/lib/uni.automator.js
+1
-361
未找到文件。
.prettierignore
浏览文件 @
feaf1646
...
...
@@ -5,5 +5,12 @@ packages/uni-automator/lib
packages/uni-cli-nvue/lib
packages/uni-cli-shared/lib
packages/uni-components/lib
packages/uni-cloud/lib
packages/uni-mp-alipay/lib
packages/uni-mp-baidu/lib
packages/uni-mp-kuaishou/lib
packages/uni-mp-qq/lib
packages/uni-mp-toutiao/lib
packages/uni-mp-vue/lib
packages/uni-cloud/lib
\ No newline at end of file
packages/uni-mp-weixin/lib
packages/uni-mp-quickapp-webview/lib
\ No newline at end of file
packages/uni-app-plus/lib/automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-app-plus/lib/uni.automator.js
浏览文件 @
feaf1646
'
use strict
'
function
_interopDefault
(
ex
)
{
return
ex
&&
typeof
ex
===
'
object
'
&&
'
default
'
in
ex
?
ex
[
'
default
'
]
:
ex
function
t
(
t
)
{
return
t
&&
'
object
'
==
typeof
t
&&
'
default
'
in
t
?
t
.
default
:
t
}
var
fs
=
_interopDefault
(
require
(
'
fs
'
))
var
debug
=
_interopDefault
(
require
(
'
debug
'
))
var
parser
=
_interopDefault
(
require
(
'
postcss-selector-parser
'
))
var
fs$1
=
_interopDefault
(
require
(
'
fs-extra
'
))
var
dateFormat
=
_interopDefault
(
require
(
'
licia/dateFormat
'
))
var
path
=
require
(
'
path
'
)
var
util
=
require
(
'
util
'
)
require
(
'
address
'
)
require
(
'
default-gateway
'
)
require
(
'
licia/isStr
'
)
require
(
'
licia/getPort
'
)
function
transform
(
selectors
)
{
selectors
.
walk
((
selector
)
=>
{
if
(
selector
.
type
===
'
tag
'
)
{
const
value
=
selector
.
value
if
(
value
===
'
page
'
)
{
//@ts-ignore
{
selector
.
value
=
'
body
'
}
}
else
{
selector
.
value
=
'
uni-
'
+
value
}
var
e
=
t
(
require
(
'
fs
'
)),
s
=
t
(
require
(
'
debug
'
)),
i
=
t
(
require
(
'
postcss-selector-parser
'
)),
r
=
t
(
require
(
'
fs-extra
'
)),
a
=
t
(
require
(
'
licia/dateFormat
'
)),
n
=
require
(
'
path
'
),
o
=
require
(
'
util
'
)
require
(
'
address
'
),
require
(
'
default-gateway
'
),
require
(
'
licia/isStr
'
),
require
(
'
licia/getPort
'
)
s
(
'
automator:devtool
'
)
function
l
(
t
)
{
t
.
walk
((
t
)
=>
{
if
(
'
tag
'
===
t
.
type
)
{
const
e
=
t
.
value
t
.
value
=
'
page
'
===
e
?
'
body
'
:
'
uni-
'
+
e
}
})
}
function
transSelector
(
method
)
{
return
{
reflect
:
async
(
send
,
params
)
=>
send
(
method
,
params
,
false
),
params
(
params
)
{
if
(
params
.
selector
)
{
params
.
selector
=
parser
(
transform
).
processSync
(
params
.
selector
)
}
return
params
},
}
}
const
methods
=
[
const
c
=
[
'
Page.getElement
'
,
'
Page.getElements
'
,
'
Element.getElement
'
,
'
Element.getElements
'
,
]
function
initAdapter
(
adapter
)
{
methods
.
forEach
((
method
)
=>
{
adapter
[
method
]
=
transSelector
(
method
)
})
}
const
qrCodeTerminal
=
require
(
'
qrcode-terminal
'
)
const
QrCodeReader
=
require
(
'
qrcode-reader
'
)
const
isWin
=
/^win/
.
test
(
process
.
platform
)
const
normalizePath
=
(
path
)
=>
(
isWin
?
path
.
replace
(
/
\\
/g
,
'
/
'
)
:
path
)
const
debugLauncher
=
debug
(
'
automator:launcher
'
)
const
APPID
=
'
HBuilder
'
const
PACKAGE
=
'
io.dcloud.HBuilder
'
const
readdir
=
util
.
promisify
(
fs
.
readdir
)
const
stat
=
util
.
promisify
(
fs
.
stat
)
async
function
getFiles
(
dir
)
{
const
subdirs
=
await
readdir
(
dir
)
const
files
=
await
Promise
.
all
(
subdirs
.
map
(
async
(
subdir
)
=>
{
const
res
=
path
.
resolve
(
dir
,
subdir
)
return
(
await
stat
(
res
)).
isDirectory
()
?
getFiles
(
res
)
:
res
})
)
return
files
.
reduce
((
a
,
f
)
=>
a
.
concat
(
f
),
[])
}
class
Launcher
{
constructor
(
options
)
{
this
.
id
=
options
.
id
this
.
app
=
options
.
executablePath
this
.
appid
=
options
.
appid
||
APPID
this
.
package
=
options
.
package
||
PACKAGE
require
(
'
qrcode-terminal
'
),
require
(
'
qrcode-reader
'
)
const
h
=
/^win/
.
test
(
process
.
platform
),
u
=
s
(
'
automator:launcher
'
),
d
=
o
.
promisify
(
e
.
readdir
),
p
=
o
.
promisify
(
e
.
stat
)
class
m
{
constructor
(
t
)
{
;(
this
.
id
=
t
.
id
),
(
this
.
app
=
t
.
executablePath
),
(
this
.
appid
=
t
.
appid
||
'
HBuilder
'
),
(
this
.
package
=
t
.
package
||
'
io.dcloud.HBuilder
'
)
}
shouldPush
()
{
return
this
.
exists
(
this
.
FILE_APP_SERVICE
)
.
then
(()
=>
{
debugLauncher
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
this
.
FILE_APP_SERVICE
}
exists`
.
then
(
()
=>
(
u
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
this
.
FILE_APP_SERVICE
}
exists`
),
!
1
)
return
false
})
.
catch
(()
=>
{
debugLauncher
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
this
.
FILE_APP_SERVICE
}
not exists`
)
.
catch
(
()
=>
(
u
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
this
.
FILE_APP_SERVICE
}
not exists`
),
!
0
)
return
true
})
)
}
push
(
from
)
{
return
getFiles
(
from
)
.
then
((
files
)
=>
{
const
pushs
=
files
.
map
((
file
)
=>
{
const
to
=
normalizePath
(
path
.
join
(
this
.
DIR_WWW
,
path
.
relative
(
from
,
file
))
push
(
t
)
{
return
(
async
function
t
(
e
)
{
const
s
=
await
d
(
e
)
return
(
await
Promise
.
all
(
s
.
map
(
async
(
s
)
=>
{
const
i
=
n
.
resolve
(
e
,
s
)
return
(
await
p
(
i
)).
isDirectory
()
?
t
(
i
)
:
i
})
)
).
reduce
((
t
,
e
)
=>
t
.
concat
(
e
),
[])
})(
t
)
.
then
((
e
)
=>
{
const
s
=
e
.
map
((
e
)
=>
{
const
s
=
((
t
)
=>
(
h
?
t
.
replace
(
/
\\
/g
,
'
/
'
)
:
t
))(
n
.
join
(
this
.
DIR_WWW
,
n
.
relative
(
t
,
e
))
)
debugLauncher
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
push
${
file
}
${
to
}
`
return
(
u
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
push
${
e
}
${
s
}
`
),
this
.
pushFile
(
e
,
s
)
)
return
this
.
pushFile
(
file
,
to
)
})
return
Promise
.
all
(
push
s
)
return
Promise
.
all
(
s
)
})
.
then
((
res
)
=>
true
)
.
then
((
t
)
=>
!
0
)
}
get
FILE_APP_SERVICE
()
{
return
`
${
this
.
DIR_WWW
}
/app-service.js`
return
this
.
DIR_WWW
+
'
/app-service.js
'
}
}
const
debugClient
=
debug
(
'
automator:simctl
'
)
function
padZero
(
str
)
{
const
num
=
parseInt
(
str
)
return
num
>
9
?
String
(
num
)
:
'
0
'
+
num
const
y
=
s
(
'
automator:simctl
'
)
function
f
(
t
)
{
const
e
=
parseInt
(
t
)
return
e
>
9
?
String
(
e
)
:
'
0
'
+
e
}
class
IOS
extends
Launcher
{
class
g
extends
m
{
constructor
()
{
super
(...
arguments
)
this
.
bundleVersion
=
''
super
(...
arguments
),
(
this
.
bundleVersion
=
''
)
}
async
init
()
{
const
Simctl
=
require
(
'
node-simctl
'
).
Simctl
this
.
tool
=
new
Simctl
({
udid
:
this
.
id
})
const
t
=
require
(
'
node-simctl
'
).
Simctl
this
.
tool
=
new
t
({
udid
:
this
.
id
})
try
{
await
this
.
tool
.
bootDevice
()
}
catch
(
e
)
{}
await
this
.
initSDCard
()
debugClient
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
init
${
this
.
id
}
`
)
}
catch
(
t
)
{}
await
this
.
initSDCard
(),
y
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
init
${
this
.
id
}
`
)
}
async
initSDCard
()
{
const
appInfo
=
await
this
.
tool
.
appInfo
(
this
.
package
)
debugClient
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
appInfo
${
appInfo
}
`
)
const
matches
=
appInfo
.
match
(
/DataContainer
\s
+=
\s
+"
(
.*
)
"/
)
if
(
!
matches
)
{
return
Promise
.
resolve
(
''
)
}
const
versionMatches
=
appInfo
.
match
(
/CFBundleVersion
\s
+=
\s
+
(
.*
)
;/
)
if
(
!
versionMatches
)
{
return
Promise
.
resolve
(
''
)
}
this
.
sdcard
=
matches
[
1
].
replace
(
'
file:
'
,
''
)
this
.
bundleVersion
=
versionMatches
[
1
]
debugClient
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
sdcard
}
`
)
const
t
=
await
this
.
tool
.
appInfo
(
this
.
package
)
y
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
appInfo
${
t
}
`
)
const
e
=
t
.
match
(
/DataContainer
\s
+=
\s
+"
(
.*
)
"/
)
if
(
!
e
)
return
Promise
.
resolve
(
''
)
const
s
=
t
.
match
(
/CFBundleVersion
\s
+=
\s
+
(
.*
)
;/
)
if
(
!
s
)
return
Promise
.
resolve
(
''
)
;(
this
.
sdcard
=
e
[
1
].
replace
(
'
file:
'
,
''
)),
(
this
.
bundleVersion
=
s
[
1
]),
y
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
sdcard
}
`
)
}
async
version
()
{
return
Promise
.
resolve
(
this
.
bundleVersion
)
}
formatVersion
(
version
)
{
const
versions
=
version
.
split
(
'
.
'
)
if
(
versions
.
length
!==
3
)
{
return
version
}
return
versions
[
0
]
+
padZero
(
versions
[
1
])
+
padZero
(
versions
[
2
])
formatVersion
(
t
)
{
const
e
=
t
.
split
(
'
.
'
)
return
3
!==
e
.
length
?
t
:
e
[
0
]
+
f
(
e
[
1
])
+
f
(
e
[
2
])
}
async
install
()
{
debugClient
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
app
}
`
)
await
this
.
tool
.
installApp
(
this
.
app
)
await
this
.
tool
.
grantPermission
(
this
.
package
,
'
all
'
)
await
this
.
initSDCard
()
return
Promise
.
resolve
(
true
)
return
(
y
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
app
}
`
),
await
this
.
tool
.
installApp
(
this
.
app
),
await
this
.
tool
.
grantPermission
(
this
.
package
,
'
all
'
),
await
this
.
initSDCard
(),
Promise
.
resolve
(
!
0
)
)
}
async
start
()
{
try
{
await
this
.
tool
.
terminateApp
(
this
.
package
)
await
this
.
tool
.
launchApp
(
this
.
package
)
}
catch
(
e
)
{}
return
Promise
.
resolve
(
true
)
await
this
.
tool
.
terminateApp
(
this
.
package
)
,
await
this
.
tool
.
launchApp
(
this
.
package
)
}
catch
(
t
)
{}
return
Promise
.
resolve
(
!
0
)
}
async
exit
()
{
await
this
.
tool
.
terminateApp
(
this
.
package
)
await
this
.
tool
.
shutdownDevice
()
return
Promise
.
resolve
(
true
)
return
(
await
this
.
tool
.
terminateApp
(
this
.
package
),
await
this
.
tool
.
shutdownDevice
(),
Promise
.
resolve
(
!
0
)
)
}
async
captureScreenshot
()
{
return
Promise
.
resolve
(
await
this
.
tool
.
getScreenshot
())
}
exists
(
file
)
{
return
fs$1
.
existsSync
(
file
)
?
Promise
.
resolve
(
true
)
:
Promise
.
reject
(
Error
(
`
${
file
}
not exists`
))
exists
(
t
)
{
return
r
.
existsSync
(
t
)
?
Promise
.
resolve
(
!
0
)
:
Promise
.
reject
(
Error
(
t
+
'
not exists
'
))
}
pushFile
(
from
,
to
)
{
return
Promise
.
resolve
(
fs$1
.
copySync
(
from
,
to
))
pushFile
(
t
,
e
)
{
return
Promise
.
resolve
(
r
.
copySync
(
t
,
e
))
}
get
DIR_WWW
()
{
return
`
${
this
.
sdcard
}
/Documents/Pandora/apps/
${
this
.
appid
}
/www/`
}
}
const
adb
=
require
(
'
adbkit
'
)
const
debugClient$1
=
debug
(
'
automator:adb
'
)
const
$EXTERNAL_STORAGE
=
'
$EXTERNAL_STORAGE
'
class
Android
extends
Launcher
{
const
w
=
require
(
'
adbkit
'
),
M
=
s
(
'
automator:adb
'
)
class
P
extends
m
{
async
init
()
{
// adbkit 异常时,可能不会关闭 socket
this
.
tool
=
adb
.
createClient
()
if
(
!
this
.
id
)
{
const
devices
=
await
this
.
tool
.
listDevices
()
if
(
!
devices
.
length
)
{
throw
Error
(
`Device not found`
)
}
this
.
id
=
devices
[
0
].
id
if
(((
this
.
tool
=
w
.
createClient
()),
!
this
.
id
))
{
const
t
=
await
this
.
tool
.
listDevices
()
if
(
!
t
.
length
)
throw
Error
(
'
Device not found
'
)
this
.
id
=
t
[
0
].
id
}
this
.
sdcard
=
(
await
this
.
shell
(
this
.
COMMAND_EXTERNAL
)).
trim
()
debugClient$1
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
init
${
this
.
id
}
${
this
.
sdcard
}
`
)
;(
this
.
sdcard
=
(
await
this
.
shell
(
this
.
COMMAND_EXTERNAL
)).
trim
()),
M
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
init
${
this
.
id
}
${
this
.
sdcard
}
`
)
}
version
()
{
return
this
.
shell
(
this
.
COMMAND_VERSION
).
then
((
output
)
=>
{
const
matches
=
output
.
match
(
/versionName=
(
.*
)
/
)
if
(
matches
&&
matches
.
length
>
1
)
{
return
matches
[
1
]
}
return
''
return
this
.
shell
(
this
.
COMMAND_VERSION
).
then
((
t
)
=>
{
const
e
=
t
.
match
(
/versionName=
(
.*
)
/
)
return
e
&&
e
.
length
>
1
?
e
[
1
]
:
''
})
}
formatVersion
(
version
)
{
return
version
formatVersion
(
t
)
{
return
t
}
async
install
()
{
let
grant
=
true
let
t
=
!
0
try
{
const
props
=
await
this
.
tool
.
getProperties
(
this
.
id
)
const
version
=
props
[
'
ro.build.version.release
'
].
split
(
'
.
'
)[
0
]
if
(
parseInt
(
version
)
<
6
)
{
grant
=
false
}
}
catch
(
e
)
{}
debugClient$1
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
app
}
permission=
${
grant
}
`
)
if
(
grant
)
{
const
Command
=
require
(
'
adbkit/lib/adb/command.js
'
)
const
oldSend
=
Command
.
prototype
.
_send
Command
.
prototype
.
_send
=
function
send
(
data
)
{
if
(
data
.
indexOf
(
'
shell:pm install -r
'
)
===
0
)
{
data
=
data
.
replace
(
'
shell:pm install -r
'
,
'
shell:pm install -r -g
'
)
debugClient$1
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
data
}
`
)
}
return
oldSend
.
call
(
this
,
data
)
const
e
=
(
await
this
.
tool
.
getProperties
(
this
.
id
))[
'
ro.build.version.release
'
].
split
(
'
.
'
)[
0
]
parseInt
(
e
)
<
6
&&
(
t
=
!
1
)
}
catch
(
t
)
{}
if
(
(
M
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
install
${
this
.
app
}
permission=
${
t
}
`
),
t
)
)
{
const
t
=
require
(
'
adbkit/lib/adb/command.js
'
),
e
=
t
.
prototype
.
_send
t
.
prototype
.
_send
=
function
(
t
)
{
return
(
0
===
t
.
indexOf
(
'
shell:pm install -r
'
)
&&
((
t
=
t
.
replace
(
'
shell:pm install -r
'
,
'
shell:pm install -r -g
'
)),
M
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
${
t
}
`
)),
e
.
call
(
this
,
t
)
)
}
}
return
this
.
tool
.
install
(
this
.
id
,
this
.
app
).
then
(()
=>
this
.
init
())
...
...
@@ -265,151 +212,126 @@ class Android extends Launcher {
return
this
.
shell
(
this
.
COMMAND_STOP
)
}
captureScreenshot
()
{
return
this
.
tool
.
screencap
(
this
.
id
).
then
((
stream
)
=>
{
return
new
Promise
((
resolve
)
=>
{
const
chunks
=
[]
stream
.
on
(
'
data
'
,
function
(
chunk
)
{
chunks
.
push
(
chunk
)
})
stream
.
on
(
'
end
'
,
function
()
{
resolve
(
Buffer
.
concat
(
chunks
).
toString
(
'
base64
'
))
return
this
.
tool
.
screencap
(
this
.
id
).
then
(
(
t
)
=>
new
Promise
((
e
)
=>
{
const
s
=
[]
t
.
on
(
'
data
'
,
function
(
t
)
{
s
.
push
(
t
)
}),
t
.
on
(
'
end
'
,
function
()
{
e
(
Buffer
.
concat
(
s
).
toString
(
'
base64
'
))
})
})
})
})
}
exists
(
file
)
{
return
this
.
tool
.
stat
(
this
.
id
,
file
)
}
pushFile
(
from
,
to
)
{
return
this
.
tool
.
push
(
this
.
id
,
from
,
to
)
)
}
shell
(
command
)
{
debugClient$1
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
SEND ►
${
command
}
`
)
return
this
.
tool
.
shell
(
this
.
id
,
command
)
.
then
(
adb
.
util
.
readAll
)
.
then
((
output
)
=>
{
const
res
=
output
.
toString
()
debugClient$1
(
`
${
dateFormat
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
◀ RECV
${
res
}
`
)
return
res
})
exists
(
t
)
{
return
this
.
tool
.
stat
(
this
.
id
,
t
)
}
pushFile
(
t
,
e
)
{
return
this
.
tool
.
push
(
this
.
id
,
t
,
e
)
}
shell
(
t
)
{
return
(
M
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
SEND ►
${
t
}
`
),
this
.
tool
.
shell
(
this
.
id
,
t
)
.
then
(
w
.
util
.
readAll
)
.
then
((
t
)
=>
{
const
e
=
t
.
toString
()
return
M
(
`
${
a
(
'
yyyy-mm-dd HH:MM:ss:l
'
)}
◀ RECV
${
e
}
`
),
e
})
)
}
get
DIR_WWW
()
{
return
`
${
this
.
sdcard
}
/Android/data/
${
this
.
package
}
/apps/
${
this
.
appid
}
/www`
}
get
COMMAND_EXTERNAL
()
{
return
`echo
${
$EXTERNAL_STORAGE
}
`
return
'
echo $EXTERNAL_STORAGE
'
}
get
COMMAND_VERSION
()
{
return
`dumpsys package
${
this
.
package
}
`
return
'
dumpsys package
'
+
this
.
package
}
get
COMMAND_STOP
()
{
return
`am force-stop
${
this
.
package
}
`
return
'
am force-stop
'
+
this
.
package
}
get
COMMAND_START
()
{
return
`am start -n
${
this
.
package
}
/io.dcloud.PandoraEntry --es
${
this
.
appid
}
--ez needUpdateApp false --ez reload true`
}
}
const
debugDevtools
=
debug
(
'
automator:devtool
'
)
let
launcher
let
install
=
false
function
createLauncher
(
platform
,
options
)
{
if
(
platform
===
'
ios
'
)
{
return
new
IOS
(
options
)
}
return
new
Android
(
options
)
}
const
VERSIONS_RE
=
{
android
:
/android_version=
(
.*
)
/
,
ios
:
/iphone_version=
(
.*
)
/
,
}
function
getVersion
(
version
,
platform
)
{
if
(
version
.
endsWith
(
'
.txt
'
))
{
try
{
const
versionStr
=
fs
.
readFileSync
(
version
).
toString
()
const
matches
=
versionStr
.
match
(
VERSIONS_RE
[
platform
])
if
(
matches
)
{
return
matches
[
1
]
}
}
catch
(
e
)
{
console
.
error
(
e
)
}
}
return
version
}
async
function
validateDevtools
(
options
,
puppet
)
{
options
.
platform
=
(
options
.
platform
||
process
.
env
.
UNI_OS_NAME
).
toLocaleLowerCase
()
Object
.
assign
(
options
,
options
[
options
.
platform
])
launcher
=
createLauncher
(
options
.
platform
,
options
)
await
launcher
.
init
()
// check device
const
version
=
await
launcher
.
version
()
if
(
!
version
)
{
install
=
true
}
else
if
(
options
.
version
)
{
const
newVersion
=
launcher
.
formatVersion
(
getVersion
(
options
.
version
,
options
.
platform
)
)
debugDevtools
(
`version:
${
version
}
`
)
debugDevtools
(
`newVersion:
${
newVersion
}
`
)
if
(
newVersion
!==
version
)
{
install
=
true
}
}
if
(
install
)
{
if
(
!
options
.
executablePath
)
{
throw
Error
(
`app-plus->
${
options
.
platform
}
->executablePath is not provided`
)
}
if
(
!
fs
.
existsSync
(
options
.
executablePath
))
{
throw
Error
(
`
${
options
.
executablePath
}
not exists`
)
}
}
return
options
}
async
function
createDevtools
(
projectPath
,
options
,
puppet
)
{
if
(
install
)
{
//install
await
launcher
.
install
()
}
if
(
install
||
puppet
.
compiled
||
(
await
launcher
.
shouldPush
()))
{
await
launcher
.
push
(
projectPath
)
}
await
launcher
.
start
()
}
const
adapter
=
{
'
Tool.close
'
:
{
reflect
:
async
()
=>
{},
},
'
App.exit
'
:
{
reflect
:
async
()
=>
launcher
.
exit
(),
},
'
App.enableLog
'
:
{
reflect
:
()
=>
Promise
.
resolve
(),
},
const
v
=
s
(
'
automator:devtool
'
)
let
E
,
$
=
!
1
const
S
=
{
android
:
/android_version=
(
.*
)
/
,
ios
:
/iphone_version=
(
.*
)
/
}
const
A
=
{
'
Tool.close
'
:
{
reflect
:
async
()
=>
{}
},
'
App.exit
'
:
{
reflect
:
async
()
=>
E
.
exit
()
},
'
App.enableLog
'
:
{
reflect
:
()
=>
Promise
.
resolve
()
},
'
App.captureScreenshot
'
:
{
reflect
:
async
(
send
,
params
)
=>
{
const
data
=
await
launcher
.
captureScreenshot
(
params
)
debugDevtools
(
`App.captureScreenshot
${
data
.
length
}
`
)
return
{
data
,
}
reflect
:
async
(
t
,
e
)
=>
{
const
s
=
await
E
.
captureScreenshot
(
e
)
return
v
(
'
App.captureScreenshot
'
+
s
.
length
),
{
data
:
s
}
},
},
}
initAdapter
(
adapter
)
const
puppet
=
{
!
(
function
(
t
)
{
c
.
forEach
((
e
)
=>
{
t
[
e
]
=
(
function
(
t
)
{
return
{
reflect
:
async
(
e
,
s
)
=>
e
(
t
,
s
,
!
1
),
params
:
(
t
)
=>
(
t
.
selector
&&
(
t
.
selector
=
i
(
l
).
processSync
(
t
.
selector
)),
t
),
}
})(
e
)
})
})(
A
)
const
_
=
{
devtools
:
{
name
:
'
App
'
,
paths
:
[],
required
:
[
'
manifest.json
'
,
'
app-service.js
'
],
validate
:
validateDevtools
,
create
:
createDevtools
,
validate
:
async
function
(
t
,
s
)
{
;(
t
.
platform
=
(
t
.
platform
||
process
.
env
.
UNI_OS_NAME
).
toLocaleLowerCase
()),
Object
.
assign
(
t
,
t
[
t
.
platform
]),
(
E
=
(
function
(
t
,
e
)
{
return
'
ios
'
===
t
?
new
g
(
e
)
:
new
P
(
e
)
})(
t
.
platform
,
t
)),
await
E
.
init
()
const
i
=
await
E
.
version
()
if
(
i
)
{
if
(
t
.
version
)
{
const
s
=
E
.
formatVersion
(
(
function
(
t
,
s
)
{
if
(
t
.
endsWith
(
'
.txt
'
))
try
{
const
i
=
e
.
readFileSync
(
t
).
toString
().
match
(
S
[
s
])
if
(
i
)
return
i
[
1
]
}
catch
(
t
)
{
console
.
error
(
t
)
}
return
t
})(
t
.
version
,
t
.
platform
)
)
v
(
'
version:
'
+
i
),
v
(
'
newVersion:
'
+
s
),
s
!==
i
&&
(
$
=
!
0
)
}
}
else
$
=
!
0
if
(
$
)
{
if
(
!
t
.
executablePath
)
throw
Error
(
`app-plus->
${
t
.
platform
}
->executablePath is not provided`
)
if
(
!
e
.
existsSync
(
t
.
executablePath
))
throw
Error
(
t
.
executablePath
+
'
not exists
'
)
}
return
t
},
create
:
async
function
(
t
,
e
,
s
)
{
$
&&
(
await
E
.
install
()),
(
$
||
s
.
compiled
||
(
await
E
.
shouldPush
()))
&&
(
await
E
.
push
(
t
)),
await
E
.
start
()
},
},
adapter
,
adapter
:
A
,
}
module
.
exports
=
puppet
module
.
exports
=
_
packages/uni-app-vite/lib/template/__uniappautomator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-automator/dist/environment.js
浏览文件 @
feaf1646
'
use strict
'
;
function
_interopDefault
(
ex
)
{
return
(
ex
&&
(
typeof
ex
===
'
object
'
)
&&
'
default
'
in
ex
)
?
ex
[
'
default
'
]
:
ex
;
}
var
NodeEnvironment
=
_interopDefault
(
require
(
'
jest-environment-node
'
));
var
Automator
=
_interopDefault
(
require
(
'
./index.js
'
));
const
automator
=
new
Automator
();
class
UniAutomatorEnvironment
extends
NodeEnvironment
{
constructor
(
config
,
context
)
{
super
(
config
);
if
(
process
.
env
.
UNI_AUTOMATOR_CONFIG
)
{
this
.
launchOptions
=
require
(
process
.
env
.
UNI_AUTOMATOR_CONFIG
);
}
else
{
this
.
launchOptions
=
config
.
testEnvironmentOptions
;
}
}
async
setup
()
{
await
super
.
setup
();
const
globalThis
=
global
;
if
(
!
globalThis
.
__init__
)
{
globalThis
.
__init__
=
true
;
// 必须启用runInBand,否则会launch多次
this
.
launchOptions
.
platform
=
this
.
launchOptions
.
platform
||
process
.
env
.
UNI_PLATFORM
;
globalThis
.
program
=
await
automator
.
launch
(
this
.
launchOptions
);
if
(
this
.
launchOptions
.
devtools
&&
this
.
launchOptions
.
devtools
.
remote
)
{
await
globalThis
.
program
.
remote
(
true
);
}
}
else
{
if
(
!
globalThis
.
program
)
{
throw
Error
(
`Program init failed`
);
}
}
this
.
global
.
program
=
globalThis
.
program
;
}
async
teardown
()
{
await
super
.
teardown
();
}
}
module
.
exports
=
UniAutomatorEnvironment
;
"
use strict
"
;
function
t
(
t
){
return
t
&&
"
object
"
==
typeof
t
&&
"
default
"
in
t
?
t
.
default
:
t
}
var
e
=
t
(
require
(
"
jest-environment-node
"
));
const
s
=
new
(
t
(
require
(
"
./index.js
"
)));
module
.
exports
=
class
extends
e
{
constructor
(
t
,
e
){
super
(
t
),
process
.
env
.
UNI_AUTOMATOR_CONFIG
?
this
.
launchOptions
=
require
(
process
.
env
.
UNI_AUTOMATOR_CONFIG
):
this
.
launchOptions
=
t
.
testEnvironmentOptions
}
async
setup
(){
await
super
.
setup
();
const
t
=
global
;
if
(
t
.
__init__
){
if
(
!
t
.
program
)
throw
Error
(
"
Program init failed
"
)}
else
t
.
__init__
=!
0
,
this
.
launchOptions
.
platform
=
this
.
launchOptions
.
platform
||
process
.
env
.
UNI_PLATFORM
,
t
.
program
=
await
s
.
launch
(
this
.
launchOptions
),
this
.
launchOptions
.
devtools
&&
this
.
launchOptions
.
devtools
.
remote
&&
await
t
.
program
.
remote
(
!
0
);
this
.
global
.
program
=
t
.
program
}
async
teardown
(){
await
super
.
teardown
()}};
packages/uni-automator/dist/index.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-automator/dist/teardown.js
浏览文件 @
feaf1646
'
use strict
'
;
async
function
teardown
()
{
const
program
=
global
.
program
;
program
&&
program
.
teardown
();
await
new
Promise
((
resolve
)
=>
{
setTimeout
(()
=>
{
resolve
();
},
3000
);
});
}
module
.
exports
=
teardown
;
"
use strict
"
;
module
.
exports
=
async
function
(){
const
o
=
global
.
program
;
o
&&
o
.
teardown
(),
await
new
Promise
(
o
=>
{
setTimeout
(()
=>
{
o
(
void
0
)},
3
e3
)})};
packages/uni-h5/lib/automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-h5/lib/uni.automator.js
浏览文件 @
feaf1646
'
use strict
'
function
_interopDefault
(
ex
)
{
return
ex
&&
typeof
ex
===
'
object
'
&&
'
default
'
in
ex
?
ex
[
'
default
'
]
:
ex
function
e
(
e
)
{
return
e
&&
'
object
'
==
typeof
e
&&
'
default
'
in
e
?
e
.
default
:
e
}
var
debug
=
_interopDefault
(
require
(
'
debug
'
))
var
puppeteer
=
_interopDefault
(
require
(
'
puppeteer
'
))
var
parser
=
_interopDefault
(
require
(
'
postcss-selector-parser
'
))
function
transform
(
selectors
)
{
selectors
.
walk
((
selector
)
=>
{
if
(
selector
.
type
===
'
tag
'
)
{
const
value
=
selector
.
value
if
(
value
===
'
page
'
)
{
//@ts-ignore
{
selector
.
value
=
'
uni-page-body
'
}
}
else
{
selector
.
value
=
'
uni-
'
+
value
}
var
t
=
e
(
require
(
'
debug
'
)),
o
=
e
(
require
(
'
postcss-selector-parser
'
))
const
n
=
t
(
'
automator:devtool
'
)
function
r
(
e
)
{
e
.
walk
((
e
)
=>
{
if
(
'
tag
'
===
e
.
type
)
{
const
t
=
e
.
value
e
.
value
=
'
page
'
===
t
?
'
uni-page-body
'
:
'
uni-
'
+
t
}
})
}
function
transSelector
(
method
)
{
return
{
reflect
:
async
(
send
,
params
)
=>
send
(
method
,
params
,
false
),
params
(
params
)
{
if
(
params
.
selector
)
{
params
.
selector
=
parser
(
transform
).
processSync
(
params
.
selector
)
}
return
params
},
}
}
const
methods
=
[
const
s
=
[
'
Page.getElement
'
,
'
Page.getElements
'
,
'
Element.getElement
'
,
'
Element.getElements
'
,
]
function
initAdapter
(
adapter
)
{
methods
.
forEach
((
method
)
=>
{
adapter
[
method
]
=
transSelector
(
method
)
})
}
const
debugDevtools
=
debug
(
'
automator:devtool
'
)
async
function
validateDevtools
(
options
)
{
options
.
options
=
options
.
options
||
{}
if
(
options
.
executablePath
&&
!
options
.
options
.
executablePath
)
{
options
.
options
.
executablePath
=
options
.
executablePath
}
options
.
options
.
defaultViewport
=
Object
.
assign
(
{
width
:
375
,
height
:
667
,
deviceScaleFactor
:
2
,
hasTouch
:
true
,
isMobile
:
true
,
},
options
.
options
.
defaultViewport
||
{}
const
i
=
[
'
chromium
'
,
'
firefox
'
,
'
webkit
'
]
let
a
=
!
1
try
{
a
=
!!
require
(
'
playwright
'
)
}
catch
(
e
)
{}
const
c
=
new
Map
()
function
p
(
e
=
'
chromium
'
)
{
const
t
=
e
&&
i
.
includes
(
e
)
?
e
:
i
[
0
]
let
o
=
c
.
get
(
t
)
return
(
o
||
((
o
=
(
function
(
e
)
{
if
(
'
webkit
'
===
e
)
return
l
(
'
webkit
'
)
if
(
'
firefox
'
===
e
)
return
l
(
'
firefox
'
)
return
a
?
l
(
'
chromium
'
)
:
(
function
()
{
const
e
=
require
(
'
puppeteer
'
)
let
t
,
o
return
{
type
:
'
chromium
'
,
provider
:
'
puppeteer
'
,
async
open
(
r
,
s
,
i
)
{
t
=
await
e
.
launch
(
s
.
options
)
const
a
=
t
.
process
()
a
?
n
(
'
%s %o
'
,
a
.
spawnfile
,
s
.
options
)
:
n
(
'
%o
'
,
s
.
options
),
(
o
=
await
t
.
newPage
()),
o
.
on
(
'
console
'
,
(
e
)
=>
{
i
.
emit
(
'
App.logAdded
'
,
{
type
:
e
.
type
(),
args
:
[
e
.
text
()],
})
}),
o
.
on
(
'
pageerror
'
,
(
e
)
=>
{
i
.
emit
(
'
App.exceptionThrown
'
,
e
)
}),
await
o
.
goto
(
s
.
url
||
r
),
await
o
.
waitFor
(
1
e3
)
},
close
:
()
=>
t
.
close
(),
screenshot
:
(
e
=
!
1
)
=>
o
.
screenshot
({
encoding
:
'
base64
'
,
fullPage
:
e
}),
}
})()
})(
t
)),
c
.
set
(
t
,
o
)),
o
)
if
(
!
options
.
teardown
)
{
options
.
teardown
=
options
.
options
.
headless
===
false
?
'
disconnect
'
:
'
close
'
}
return
options
}
let
browser
let
page
async
function
createDevtools
(
url
,
options
,
puppet
)
{
browser
=
await
puppeteer
.
launch
(
options
.
options
)
const
process
=
browser
.
process
()
if
(
process
)
{
debugDevtools
(
'
%s %o
'
,
process
.
spawnfile
,
options
.
options
)
}
else
{
debugDevtools
(
'
%o
'
,
options
.
options
)
function
l
(
e
)
{
const
t
=
require
(
'
playwright
'
)
let
o
,
r
return
{
type
:
e
,
provider
:
'
playwright
'
,
async
open
(
s
,
i
,
a
)
{
;(
o
=
await
t
[
e
].
launch
(
i
.
options
)),
'
firefox
'
===
e
&&
(
i
.
contextOptions
.
isMobile
=
!
1
),
n
(
'
browser.newContext
'
+
JSON
.
stringify
(
i
.
contextOptions
))
const
c
=
await
o
.
newContext
(
i
.
contextOptions
)
;(
r
=
await
c
.
newPage
()),
r
.
on
(
'
console
'
,
(
e
)
=>
{
a
.
emit
(
'
App.logAdded
'
,
{
type
:
e
.
type
(),
args
:
[
e
.
text
()]
})
}),
r
.
on
(
'
pageerror
'
,
(
e
)
=>
{
a
.
emit
(
'
App.exceptionThrown
'
,
e
)
}),
await
r
.
goto
(
i
.
url
||
s
),
await
r
.
waitForTimeout
(
1
e3
)
},
close
:
()
=>
o
.
close
(),
screenshot
:
(
e
=
!
1
)
=>
r
.
screenshot
({
fullPage
:
e
}).
then
((
e
)
=>
e
.
toString
(
'
base64
'
)),
}
page
=
await
browser
.
newPage
()
page
.
on
(
'
console
'
,
(
msg
)
=>
{
puppet
.
emit
(
'
App.logAdded
'
,
{
type
:
msg
.
type
(),
args
:
[
msg
.
text
()]
})
})
page
.
on
(
'
pageerror
'
,
(
err
)
=>
{
puppet
.
emit
(
'
App.exceptionThrown
'
,
err
)
})
await
page
.
goto
(
options
.
url
||
url
)
await
page
.
waitFor
(
1000
)
}
const
adapter
=
{
let
u
const
f
=
{
'
Tool.close
'
:
{
reflect
:
async
()
=>
{
await
browser
.
close
()
await
u
.
close
()
},
},
'
App.exit
'
:
{
reflect
:
async
()
=>
{},
},
'
App.enableLog
'
:
{
reflect
:
()
=>
Promise
.
resolve
(),
},
'
App.exit
'
:
{
reflect
:
async
()
=>
{}
},
'
App.enableLog
'
:
{
reflect
:
()
=>
Promise
.
resolve
()
},
'
App.captureScreenshot
'
:
{
reflect
:
async
(
send
,
params
)
=>
{
const
data
=
await
page
.
screenshot
({
encoding
:
'
base64
'
,
fullPage
:
!!
params
.
fullPage
,
})
debugDevtools
(
`App.captureScreenshot
${
data
.
length
}
`
)
return
{
data
,
}
reflect
:
async
(
e
,
t
)
=>
{
const
o
=
await
u
.
screenshot
(
!!
t
.
fullPage
)
return
n
(
'
App.captureScreenshot
'
+
o
.
length
),
{
data
:
o
}
},
},
}
initAdapter
(
adapter
)
const
puppet
=
{
!
(
function
(
e
)
{
s
.
forEach
((
t
)
=>
{
e
[
t
]
=
(
function
(
e
)
{
return
{
reflect
:
async
(
t
,
o
)
=>
t
(
e
,
o
,
!
1
),
params
:
(
e
)
=>
(
e
.
selector
&&
(
e
.
selector
=
o
(
r
).
processSync
(
e
.
selector
)),
e
),
}
})(
t
)
})
})(
f
)
const
h
=
{
devtools
:
{
name
:
'
google chrome
'
,
name
:
'
browser
'
,
paths
:
[],
validate
:
validateDevtools
,
create
:
createDevtools
,
},
shouldCompile
(
options
,
devtoolsOptions
)
{
if
(
devtoolsOptions
.
url
)
{
return
false
}
return
true
validate
:
async
function
(
e
)
{
return
(
(
e
.
options
=
e
.
options
||
{}),
e
.
executablePath
&&
!
e
.
options
.
executablePath
&&
(
e
.
options
.
executablePath
=
e
.
executablePath
),
(
e
.
contextOptions
=
{
viewport
:
Object
.
assign
(
{
width
:
375
,
height
:
667
},
e
.
options
.
defaultViewport
||
{}
),
hasTouch
:
!
0
,
isMobile
:
!
0
,
deviceScaleFactor
:
2
,
}),
(
e
.
options
.
defaultViewport
=
Object
.
assign
(
{
width
:
375
,
height
:
667
,
deviceScaleFactor
:
2
,
hasTouch
:
!
0
,
isMobile
:
!
0
,
},
e
.
options
.
defaultViewport
||
{}
)),
e
.
teardown
||
(
e
.
teardown
=
!
1
===
e
.
options
.
headless
?
'
disconnect
'
:
'
close
'
),
e
)
},
create
:
async
function
(
e
,
t
,
o
)
{
;(
u
=
p
(
process
.
env
.
BROWSER
)),
n
(
'
createDevtools
'
+
(
u
.
provider
+
'
'
+
u
.
type
+
'
'
+
JSON
.
stringify
(
t
))
),
await
u
.
open
(
e
,
t
,
o
)
},
},
adapter
,
shouldCompile
:
(
e
,
t
)
=>
!
t
.
url
,
adapter
:
f
,
}
module
.
exports
=
puppet
module
.
exports
=
h
packages/uni-mp-baidu/lib/automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-mp-baidu/lib/uni.automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-mp-weixin/lib/automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
packages/uni-mp-weixin/lib/uni.automator.js
浏览文件 @
feaf1646
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录