提交 feaf1646 编写于 作者: fxy060608's avatar fxy060608

feat(automator): support safari,firefox

上级 9bd8db1d
......@@ -5,5 +5,12 @@ packages/uni-automator/lib
packages/uni-cli-nvue/lib
packages/uni-cli-shared/lib
packages/uni-components/lib
packages/uni-mp-vue/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-mp-weixin/lib
packages/uni-mp-quickapp-webview/lib
\ No newline at end of file
var hasOwnProperty = Object.prototype.hasOwnProperty
var hasOwn = function (val, key) {
return hasOwnProperty.call(val, key)
}
var isUndef = function (v) {
return v === undefined || v === null
}
var isArray = Array.isArray
var isPromise = function (obj) {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
)
}
var cacheStringFunction = function (fn) {
var cache = Object.create(null)
return function (str) {
var hit = cache[str]
return hit || (cache[str] = fn(str))
var e,
t = Object.prototype.hasOwnProperty,
n = function (e) {
return null == e
},
r = Array.isArray,
o = function (e) {
var t = Object.create(null)
return function (n) {
return t[n] || (t[n] = e(n))
}
}
var hyphenateRE = /\B([A-Z])/g
var hyphenate = cacheStringFunction(function (str) {
return str.replace(hyphenateRE, '-$1').toLowerCase()
})
var camelizeRE = /-(\w)/g
var camelize = cacheStringFunction(function (str) {
return str.replace(camelizeRE, function (_, c) {
return c ? c.toUpperCase() : ''
},
u = /\B([A-Z])/g,
i = o(function (e) {
return e.replace(u, '-$1').toLowerCase()
}),
c = /-(\w)/g,
a = o(function (e) {
return e.replace(c, function (e, t) {
return t ? t.toUpperCase() : ''
})
})
var capitalize = cacheStringFunction(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
})
var PATH_RE =
}),
s = o(function (e) {
return e.charAt(0).toUpperCase() + e.slice(1)
}),
f =
/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g
function getPaths(path, data) {
if (isArray(path)) {
return path
}
if (data && hasOwn(data, path)) {
return [path]
}
var res = []
path.replace(PATH_RE, function (match, p1, offset, string) {
res.push(offset ? string.replace(/\\(\\)?/g, '$1') : p1 || match)
return string
})
return res
}
function getDataByPath(data, path) {
var paths = getPaths(path, data)
var dataPath
for (dataPath = paths.shift(); !isUndef(dataPath); ) {
if (null == (data = data[dataPath])) {
return
}
dataPath = paths.shift()
}
return data
function l(e, n) {
if (r(e)) return e
if (n && ((o = n), (u = e), t.call(o, u))) return [e]
var o,
u,
i = []
return (
e.replace(f, function (e, t, n, r) {
return i.push(n ? r.replace(/\\(\\)?/g, '$1') : t || e), r
}),
i
)
}
function findParent(vm) {
var parent = vm.$parent
while (parent) {
if (parent._$id) {
return parent
}
parent = parent.$parent
function d(e, t) {
var r,
o = l(t, e)
for (r = o.shift(); !n(r); ) {
if (null == (e = e[r])) return
r = o.shift()
}
return e
}
function getVmNodeId(vm) {
//@ts-ignore
{
if (vm._$weex) {
return vm._uid
}
if (vm._$id) {
return vm._$id
}
var parent_1 = findParent(vm)
if (!vm.$parent) {
return '-1'
}
var vnode = vm.$vnode
var context = vnode.context
// slot 内的组件,需要补充 context 的 id,否则可能与内部组件索引值一致,导致 id 冲突
if (context && context !== parent_1 && context._$id) {
return context._$id + ';' + parent_1._$id + ',' + vnode.data.attrs._i
}
return parent_1._$id + ',' + vnode.data.attrs._i
}
}
function getPageId(page) {
if (page.__wxWebviewId__) {
//mp-weixin
return page.__wxWebviewId__
}
if (page.privateProperties) {
//mp-baidu
return page.privateProperties.slaveId
}
if (page.$page) {
//h5 and app-plus
return page.$page.id
}
function p(e) {
return e.__wxWebviewId__
? e.__wxWebviewId__
: e.privateProperties
? e.privateProperties.slaveId
: e.$page
? e.$page.id
: void 0
}
function getPagePath(page) {
return page.route || page.uri
function g(e) {
return e.route || e.uri
}
function getPageQuery(page) {
return page.options || (page.$page && page.$page.options) || {}
function m(e) {
return e.options || (e.$page && e.$page.options) || {}
}
function parsePage(page) {
return {
id: getPageId(page),
path: getPagePath(page),
query: getPageQuery(page),
}
function v(e) {
return { id: p(e), path: g(e), query: m(e) }
}
function getPageById(id) {
return getCurrentPages().find(function (page) {
return getPageId(page) === id
function _(e) {
var t = (function (e) {
return getCurrentPages().find(function (t) {
return p(t) === e
})
})(e)
return t && t.$vm
}
function getPageVm(id) {
var page = getPageById(id)
return page && page.$vm
}
function matchNodeId(vm, nodeId) {
//@ts-ignore
{
return getVmNodeId(vm) === nodeId
}
}
function findComponentVm(vm, nodeId) {
var res
if (vm) {
if (matchNodeId(vm, nodeId)) {
res = vm
} else {
vm.$children.find(function (child) {
res = findComponentVm(child, nodeId)
return res
function h(e, t) {
var n = _(e)
return (
n &&
(function e(t, n) {
var r
return (
t &&
(!(function (e, t) {
return (
(function (e) {
if (e._$weex) return e._uid
if (e._$id) return e._$id
var t = (function (e) {
for (var t = e.$parent; t; ) {
if (t._$id) return t
t = t.$parent
}
})(e)
if (!e.$parent) return '-1'
var n = e.$vnode,
r = n.context
return r && r !== t && r._$id
? r._$id + ';' + t._$id + ',' + n.data.attrs._i
: t._$id + ',' + n.data.attrs._i
})(e) === t
)
})(t, n)
? t.$children.find(function (t) {
return (r = e(t, n))
})
}
}
return res
}
function getComponentVm(pageId, nodeId) {
var pageVm = getPageVm(pageId)
return pageVm && findComponentVm(pageVm, nodeId)
}
function getData(vm, path) {
var data
if (vm) {
data = path ? getDataByPath(vm.$data, path) : Object.assign({}, vm.$data)
}
return Promise.resolve({ data: data })
: (r = t)),
r
)
})(n, t)
)
}
function setData(vm, data) {
if (vm) {
Object.keys(data).forEach(function (name) {
vm[name] = data[name]
})
}
return Promise.resolve()
function E(e, t) {
var n
return (
e && (n = t ? d(e.$data, t) : Object.assign({}, e.$data)),
Promise.resolve({ data: n })
)
}
var CALL_METHOD_ERROR
;(function (CALL_METHOD_ERROR) {
CALL_METHOD_ERROR['VM_NOT_EXISTS'] = 'VM_NOT_EXISTS'
CALL_METHOD_ERROR['METHOD_NOT_EXISTS'] = 'METHOD_NOT_EXISTS'
})(CALL_METHOD_ERROR || (CALL_METHOD_ERROR = {}))
function callMethod(vm, method, args) {
return new Promise(function (resolve, reject) {
if (!vm) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
if (!vm[method]) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
var ret = vm[method].apply(vm, args)
isPromise(ret)
? ret.then(function (res) {
resolve({ result: res })
})
: resolve({ result: ret })
})
function y(e, t) {
return (
e &&
Object.keys(t).forEach(function (n) {
e[n] = t[n]
}),
Promise.resolve()
)
}
var SYNC_APIS = [
function w(t, n, r) {
return new Promise(function (o, u) {
if (!t) return u(e.VM_NOT_EXISTS)
if (!t[n]) return u(e.VM_NOT_EXISTS)
var i,
c = t[n].apply(t, r)
!(i = c) ||
('object' != typeof i && 'function' != typeof i) ||
'function' != typeof i.then
? o({ result: c })
: c.then(function (e) {
o({ result: e })
})
})
}
!(function (e) {
;(e.VM_NOT_EXISTS = 'VM_NOT_EXISTS'),
(e.METHOD_NOT_EXISTS = 'METHOD_NOT_EXISTS')
})(e || (e = {}))
var T = [
'stopRecord',
'getRecorderManager',
'pauseVoice',
......@@ -222,257 +178,131 @@ var SYNC_APIS = [
'stopPullDownRefresh',
'arrayBufferToBase64',
'base64ToArrayBuffer',
]
var originUni = {}
var SYNC_API_RE = /Sync$/
var MOCK_API_BLACKLIST_RE = /^on|^off/
function isSyncApi(method) {
return SYNC_API_RE.test(method) || SYNC_APIS.indexOf(method) !== -1
}
function canIMock(method) {
return !MOCK_API_BLACKLIST_RE.test(method)
}
var App = {
],
x = {},
P = /Sync$/,
S = /^on|^off/
function O(e) {
return P.test(e) || -1 !== T.indexOf(e)
}
var $ = {
getPageStack: function () {
return Promise.resolve({
pageStack: getCurrentPages().map(function (page) {
return parsePage(page)
pageStack: getCurrentPages().map(function (e) {
return v(e)
}),
})
},
getCurrentPage: function () {
var pages = getCurrentPages()
var len = pages.length
return new Promise(function (resolve, reject) {
if (!len) {
reject(Error('getCurrentPages().length=0'))
} else {
resolve(parsePage(pages[len - 1]))
}
})
},
callUniMethod: function (params) {
var method = params.method
var args = params.args
return new Promise(function (resolve, reject) {
if (!uni[method]) {
return reject(Error('uni.' + method + ' not exists'))
}
if (isSyncApi(method)) {
return resolve({
result: uni[method].apply(uni, args),
})
}
var params = [
Object.assign({}, args[0] || {}, {
success: function (result) {
var timeout = method === 'pageScrollTo' ? 350 : 0
setTimeout(function () {
resolve({ result: result })
}, timeout)
var e = getCurrentPages(),
t = e.length
return new Promise(function (n, r) {
t ? n(v(e[t - 1])) : r(Error('getCurrentPages().length=0'))
})
},
callUniMethod: function (e) {
var t = e.method,
n = e.args
return new Promise(function (e, r) {
if (!uni[t]) return r(Error('uni.' + t + ' not exists'))
if (O(t)) return e({ result: uni[t].apply(uni, n) })
var o = [
Object.assign({}, n[0] || {}, {
success: function (n) {
setTimeout(
function () {
e({ result: n })
},
'pageScrollTo' === t ? 350 : 0
)
},
fail: function (res) {
reject(Error(res.errMsg.replace(method + ':fail ', '')))
fail: function (e) {
r(Error(e.errMsg.replace(t + ':fail ', '')))
},
}),
]
uni[method].apply(uni, params)
uni[t].apply(uni, o)
})
},
mockUniMethod: function (params) {
var method = params.method
if (!uni[method]) {
throw Error('uni.' + method + ' not exists')
}
if (!canIMock(method)) {
throw Error("You can't mock uni." + method)
}
// TODO getOwnPropertyDescriptor?
var result = params.result
if (isUndef(result)) {
// restoreUniMethod
if (originUni[method]) {
uni[method] = originUni[method]
delete originUni[method]
}
return Promise.resolve()
}
var mockFn = isSyncApi(method)
mockUniMethod: function (e) {
var t = e.method
if (!uni[t]) throw Error('uni.' + t + ' not exists')
if (
!(function (e) {
return !S.test(e)
})(t)
)
throw Error("You can't mock uni." + t)
var r = e.result
if (n(r)) return x[t] && ((uni[t] = x[t]), delete x[t]), Promise.resolve()
var o = O(t)
? function () {
return result
return r
}
: function (params) {
: function (e) {
setTimeout(function () {
var isFail = result.errMsg && result.errMsg.indexOf(':fail') !== -1
if (isFail) {
params.fail && params.fail(result)
} else {
params.success && params.success(result)
}
params.complete && params.complete(result)
r.errMsg && -1 !== r.errMsg.indexOf(':fail')
? e.fail && e.fail(r)
: e.success && e.success(r),
e.complete && e.complete(r)
}, 4)
}
// mockFn.origin = originUni[method] || uni[method];
if (!originUni[method]) {
originUni[method] = uni[method]
}
uni[method] = mockFn
return Promise.resolve()
return x[t] || (x[t] = uni[t]), (uni[t] = o), Promise.resolve()
},
}
var Page = {
getData: function (params) {
return getData(getPageVm(params.pageId), params.path)
},
setData: function (params) {
return setData(getPageVm(params.pageId), params.data)
},
callMethod: function (params) {
var _a
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Page[' + params.pageId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'page.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(getPageVm(params.pageId), params.method, params.args)
.then(function (res) {
return resolve(res)
})
.catch(function (type) {
reject(Error(err[type]))
})
})
},
}
function getNodeId(params) {
return params.nodeId || params.elementId
}
var Element = {
getData: function (params) {
return getData(
getComponentVm(params.pageId, getNodeId(params)),
params.path
)
b = {
getData: function (e) {
return E(_(e.pageId), e.path)
},
setData: function (params) {
return setData(
getComponentVm(params.pageId, getNodeId(params)),
params.data
)
setData: function (e) {
return y(_(e.pageId), e.data)
},
callMethod: function (params) {
var _a
var nodeId = getNodeId(params)
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Component[' + params.pageId + ':' + nodeId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'component.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(
getComponentVm(params.pageId, nodeId),
params.method,
params.args
)
.then(function (res) {
return resolve(res)
callMethod: function (t) {
var n,
r =
(((n = {})[e.VM_NOT_EXISTS] = 'Page[' + t.pageId + '] not exists'),
(n[e.METHOD_NOT_EXISTS] = 'page.' + t.method + ' not exists'),
n)
return new Promise(function (e, n) {
w(_(t.pageId), t.method, t.args)
.then(function (t) {
return e(t)
})
.catch(function (type) {
reject(Error(err[type]))
.catch(function (e) {
n(Error(r[e]))
})
})
},
}
function initPage(adapter) {
return {
'Page.getElement': function (params) {
return adapter.querySelector(
adapter.getDocument(params.pageId),
params.selector
)
},
'Page.getElements': function (params) {
return adapter.querySelectorAll(
adapter.getDocument(params.pageId),
params.selector
)
},
'Page.getWindowProperties': function (params) {
return adapter.queryProperties(
adapter.getWindow(params.pageId),
params.names
)
},
}
function I(e) {
return e.nodeId || e.elementId
}
function initElement(adapter) {
var getEl = function (params) {
return adapter.getEl(params.elementId, params.pageId)
}
return {
'Element.getElement': function (params) {
return adapter.querySelector(getEl(params), params.selector)
},
'Element.getElements': function (params) {
return adapter.querySelectorAll(getEl(params), params.selector)
},
'Element.getDOMProperties': function (params) {
return adapter.queryProperties(getEl(params), params.names)
},
'Element.getProperties': function (params) {
var el = getEl(params)
var ctx = el.__vue__ || el.attr || {}
return adapter.queryProperties(ctx, params.names)
},
'Element.getOffset': function (params) {
return adapter.getOffset(getEl(params))
},
'Element.getAttributes': function (params) {
return adapter.queryAttributes(getEl(params), params.names)
},
'Element.getStyles': function (params) {
return adapter.queryStyles(getEl(params), params.names)
},
'Element.getHTML': function (params) {
return adapter.queryHTML(getEl(params), params.type)
var C = {
getData: function (e) {
return E(h(e.pageId, I(e)), e.path)
},
'Element.tap': function (params) {
return adapter.dispatchTapEvent(getEl(params))
setData: function (e) {
return y(h(e.pageId, I(e)), e.data)
},
'Element.longpress': function (params) {
return adapter.dispatchLongpressEvent(getEl(params))
},
'Element.touchstart': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchstart', params)
},
'Element.touchmove': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchmove', params)
},
'Element.touchend': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchend', params)
},
'Element.callFunction': function (params) {
return adapter.callFunction(
getEl(params),
params.functionName,
params.args
)
},
'Element.triggerEvent': function (params) {
return adapter.triggerEvent(getEl(params), params.type, params.detail)
callMethod: function (t) {
var n,
r = I(t),
o =
(((n = {})[e.VM_NOT_EXISTS] =
'Component[' + t.pageId + ':' + r + '] not exists'),
(n[e.METHOD_NOT_EXISTS] = 'component.' + t.method + ' not exists'),
n)
return new Promise(function (e, n) {
w(h(t.pageId, r), t.method, t.args)
.then(function (t) {
return e(t)
})
.catch(function (e) {
n(Error(o[e]))
})
})
},
}
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
......@@ -487,61 +317,38 @@ MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++)
s += arguments[i].length
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j]
function M() {
for (var e = 0, t = 0, n = arguments.length; t < n; t++)
e += arguments[t].length
var r = Array(e),
o = 0
for (t = 0; t < n; t++)
for (var u = arguments[t], i = 0, c = u.length; i < c; i++, o++) r[o] = u[i]
return r
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
var getRandomValues =
(typeof crypto != 'undefined' &&
;('undefined' != typeof crypto &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
(typeof msCrypto != 'undefined' &&
typeof msCrypto.getRandomValues == 'function' &&
('undefined' != typeof msCrypto &&
'function' == typeof msCrypto.getRandomValues &&
msCrypto.getRandomValues.bind(msCrypto))
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = []
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1)
}
function getDocument(pageId) {
var page = getCurrentPages().find(function (page) {
return page.$page.id === pageId
for (var A = [], D = 0; D < 256; ++D) A[D] = (D + 256).toString(16).substr(1)
function N(e) {
var t = getCurrentPages().find(function (t) {
return t.$page.id === e
})
if (!page) {
throw Error('page[' + pageId + '] not found')
}
var weex = page.$vm._$weex
if (!weex.document.__$weex__) {
weex.document.__$weex__ = weex
}
return weex.document
if (!t) throw Error('page[' + e + '] not found')
var n = t.$vm._$weex
return n.document.__$weex__ || (n.document.__$weex__ = n), n.document
}
var TAGS = {}
var U_TAGS = {}
var k = {},
q = {}
;['text', 'image', 'input', 'textarea', 'video', 'web-view', 'slider'].forEach(
function (tag) {
TAGS[tag] = true
U_TAGS['u-' + tag] = true
function (e) {
;(k[e] = !0), (q['u-' + e] = !0)
}
)
var BUILITIN = [
var j = [
'movable-view',
'picker',
'ad',
......@@ -563,569 +370,496 @@ var BUILITIN = [
'swiper-item',
'swiper',
'switch',
]
var BUILITIN_ALIAS = BUILITIN.map(function (tag) {
return capitalize(camelize(tag))
})
function transTagName(el) {
var tagName = el.type
if (U_TAGS[tagName]) {
return tagName.replace('u-', '')
}
var componentName = el.__vue__ && el.__vue__.$options.name
if (componentName === 'USlider') {
return 'slider'
}
if (componentName && BUILITIN_ALIAS.indexOf(componentName) !== -1) {
return hyphenate(componentName)
}
return tagName
}
function transEl(el) {
var elem = {
elementId: el.nodeId,
tagName: transTagName(el),
nvue: true,
}
var vm = el.__vue__
if (vm && !vm.$options.isReserved) {
elem.nodeId = vm._uid
}
if (elem.tagName === 'video') {
elem.videoId = elem.nodeId
}
return elem
}
function querySelectorByFn(node, match, result) {
var children = node.children
for (var i = 0; i < children.length; i++) {
var childNode = children[i]
if (match(childNode)) {
if (result) {
result.push(childNode)
} else {
return childNode
}
}
if (result) {
querySelectorByFn(childNode, match, result)
} else {
var res = querySelectorByFn(childNode, match, result)
if (res) {
return res
}
}
}
return result
}
function querySelector(context, selector, result) {
var matchSelector
var match
if (selector.indexOf('#') === 0) {
matchSelector = selector.substr(1)
match = function (node) {
return node.attr && node.attr.id === matchSelector
}
} else if (selector.indexOf('.') === 0) {
matchSelector = selector.substr(1)
match = function (node) {
return node.classList && node.classList.indexOf(matchSelector) !== -1
}
}
if (match) {
var ret_1 = querySelectorByFn(context, match, result)
if (!ret_1) {
throw Error('Node(' + selector + ') not exists')
}
return ret_1
}
if (selector === 'body') {
return Object.assign({}, context, { type: 'page' })
}
if (selector.indexOf('uni-') === 0) {
selector = selector.replace('uni-', '')
}
var tagName = TAGS[selector] ? 'u-' + selector : selector
var aliasTagName =
BUILITIN.indexOf(tagName) !== -1 ? capitalize(camelize(tagName)) : ''
var ret = querySelectorByFn(
context,
function (node) {
],
R = j.map(function (e) {
return s(a(e))
})
function V(e) {
var t = e.type
if (q[t]) return t.replace('u-', '')
var n = e.__vue__ && e.__vue__.$options.name
return 'USlider' === n ? 'slider' : n && -1 !== R.indexOf(n) ? i(n) : t
}
function L(e) {
var t = { elementId: e.nodeId, tagName: V(e), nvue: !0 },
n = e.__vue__
return (
node.type === tagName ||
(aliasTagName &&
node.__vue__ &&
node.__vue__.$options.name === aliasTagName)
n && !n.$options.isReserved && (t.nodeId = n._uid),
'video' === t.tagName && (t.videoId = t.nodeId),
t
)
},
result
}
function B(e, t, n) {
for (var r = e.children, o = 0; o < r.length; o++) {
var u = r[o]
if (t(u)) {
if (!n) return u
n.push(u)
}
if (n) B(u, t, n)
else {
var i = B(u, t, n)
if (i) return i
}
}
return n
}
function H(e, t, n) {
var r, o
if (
(0 === t.indexOf('#')
? ((r = t.substr(1)),
(o = function (e) {
return e.attr && e.attr.id === r
}))
: 0 === t.indexOf('.') &&
((r = t.substr(1)),
(o = function (e) {
return e.classList && -1 !== e.classList.indexOf(r)
})),
o)
) {
var u = B(e, o, n)
if (!u) throw Error('Node(' + t + ') not exists')
return u
}
if ('body' === t) return Object.assign({}, e, { type: 'page' })
0 === t.indexOf('uni-') && (t = t.replace('uni-', ''))
var i = k[t] ? 'u-' + t : t,
c = -1 !== j.indexOf(i) ? s(a(i)) : '',
f = B(
e,
function (e) {
return e.type === i || (c && e.__vue__ && e.__vue__.$options.name === c)
},
n
)
if (!ret) {
throw Error('Node(' + selector + ') not exists')
}
return ret
if (!f) throw Error('Node(' + t + ') not exists')
return f
}
var DOM_PROPERTIES = [
var U = [
{
test: function (names) {
test: function (e) {
return (
names.length === 2 &&
names.indexOf('document.documentElement.scrollWidth') !== -1 &&
names.indexOf('document.documentElement.scrollHeight') !== -1
2 === e.length &&
-1 !== e.indexOf('document.documentElement.scrollWidth') &&
-1 !== e.indexOf('document.documentElement.scrollHeight')
)
},
call: function (node) {
var weex = node.__$weex__ || node.ownerDocument.__$weex__
return new Promise(function (resolve) {
if (node.type === 'scroll-view' && node.children.length === 1) {
node = node.children[0]
}
weex.requireModule('dom').getComponentRect(node.ref, function (res) {
if (res.result) {
resolve([res.size.width, res.size.height])
} else {
resolve([0, 0])
}
call: function (e) {
var t = e.__$weex__ || e.ownerDocument.__$weex__
return new Promise(function (n) {
'scroll-view' === e.type &&
1 === e.children.length &&
(e = e.children[0]),
t.requireModule('dom').getComponentRect(e.ref, function (e) {
e.result ? n([e.size.width, e.size.height]) : n([0, 0])
})
})
},
},
{
test: function (names) {
return (
names.length === 1 && names[0] === 'document.documentElement.scrollTop'
)
test: function (e) {
return 1 === e.length && 'document.documentElement.scrollTop' === e[0]
},
call: function (node) {
var weex = node.__$weex__ || node.ownerDocument.__$weex__
return new Promise(function (resolve) {
if (node.type === 'scroll-view' && node.children.length === 1) {
node = node.children[0]
}
weex.requireModule('dom').getComponentRect(node.ref, function (res) {
resolve([(res.size && Math.abs(res.size.top)) || 0])
call: function (e) {
var t = e.__$weex__ || e.ownerDocument.__$weex__
return new Promise(function (n) {
'scroll-view' === e.type &&
1 === e.children.length &&
(e = e.children[0]),
t.requireModule('dom').getComponentRect(e.ref, function (e) {
n([(e.size && Math.abs(e.size.top)) || 0])
})
})
},
},
{
test: function (names) {
test: function (e) {
return (
names.length === 2 &&
names.indexOf('offsetWidth') !== -1 &&
names.indexOf('offsetHeight') !== -1
2 === e.length &&
-1 !== e.indexOf('offsetWidth') &&
-1 !== e.indexOf('offsetHeight')
)
},
call: function (node) {
var weex = node.__$weex__ || node.ownerDocument.__$weex__
return new Promise(function (resolve) {
weex.requireModule('dom').getComponentRect(node.ref, function (res) {
if (res.result) {
resolve([res.size.width, res.size.height])
} else {
resolve([0, 0])
}
call: function (e) {
var t = e.__$weex__ || e.ownerDocument.__$weex__
return new Promise(function (n) {
t.requireModule('dom').getComponentRect(e.ref, function (e) {
e.result ? n([e.size.width, e.size.height]) : n([0, 0])
})
})
},
},
{
test: function (names, node) {
return names.length === 1 && names[0] === 'innerText'
test: function (e, t) {
return 1 === e.length && 'innerText' === e[0]
},
call: function (node) {
return Promise.resolve([toText(node, []).join('')])
call: function (e) {
return Promise.resolve([X(e, []).join('')])
},
},
]
function toText(node, res) {
if (node.type === 'u-text') {
res.push(node.attr.value)
} else {
node.pureChildren.map(function (child) {
return toText(child, res)
})
}
return res
function X(e, t) {
return (
'u-text' === e.type
? t.push(e.attr.value)
: e.pureChildren.map(function (e) {
return X(e, t)
}),
t
)
}
function formatHTML(html) {
return html.replace(/\n/g, '').replace(/<u-/g, '<').replace(/<\/u-/g, '</')
function W(e) {
return e.replace(/\n/g, '').replace(/<u-/g, '<').replace(/<\/u-/g, '</')
}
function toHTML(node, type) {
if (type === 'outer') {
if (node.role === 'body' && node.type === 'scroll-view') {
return '<page>' + formatHTML(toHTML(node, 'inner')) + '</page>'
}
return formatHTML(node.toString())
}
return formatHTML(
node.pureChildren
.map(function (child) {
return child.toString()
function z(e, t) {
return 'outer' === t
? 'body' === e.role && 'scroll-view' === e.type
? '<page>' + W(z(e, 'inner')) + '</page>'
: W(e.toString())
: W(
e.pureChildren
.map(function (e) {
return e.toString()
})
.join('')
)
}
var FUNCTIONS = {
var J = {
input: {
input: function (el, value) {
el.setValue(value)
input: function (e, t) {
e.setValue(t)
},
},
textarea: {
input: function (el, value) {
el.setValue(value)
input: function (e, t) {
e.setValue(t)
},
},
'scroll-view': {
scrollTo: function (el, x, y) {
// TODO
el.scrollTo(y)
scrollTo: function (e, t, n) {
e.scrollTo(n)
},
scrollTop: function (el) {
// TODO
scrollTop: function (e) {
return 0
},
scrollLeft: function (el) {
// TODO
scrollLeft: function (e) {
return 0
},
scrollWidth: function (el) {
// TODO
scrollWidth: function (e) {
return 0
},
scrollHeight: function (el) {
// TODO
scrollHeight: function (e) {
return 0
},
},
swiper: {
swipeTo: function (el, index) {
el.__vue__.current = index
swipeTo: function (e, t) {
e.__vue__.current = t
},
},
'movable-view': {
moveTo: function (el, x, y) {
var vm = el.__vue__
vm.x = x
vm.y = y
moveTo: function (e, t, n) {
var r = e.__vue__
;(r.x = t), (r.y = n)
},
},
switch: {
tap: function (el) {
var vm = el.__vue__
vm.checked = !vm.checked
tap: function (e) {
var t = e.__vue__
t.checked = !t.checked
},
},
slider: {
slideTo: function (el, value) {
el.__vue__.value = value
slideTo: function (e, t) {
e.__vue__.value = t
},
},
}
function getRoot(pageId) {
var doc = getDocument(pageId)
return doc.body
function F(e) {
return N(e).body
}
var adapter = {
getWindow: function (pageId) {
return getRoot(pageId)
},
getDocument: function (pageId) {
return getRoot(pageId)
},
getEl: function (elementId, pageId) {
var doc = getDocument(pageId)
var element = doc.getRef(elementId)
if (!element) {
throw Error('element destroyed')
}
return element
},
getOffset: function (node) {
var weex = node.__$weex__ || node.ownerDocument.__$weex__
return new Promise(function (resolve) {
weex.requireModule('dom').getComponentRect(node.ref, function (res) {
if (res.result) {
resolve({
left: res.size.left,
top: res.size.top,
})
} else {
resolve({
left: 0,
top: 0,
})
}
var K = {
getWindow: function (e) {
return F(e)
},
getDocument: function (e) {
return F(e)
},
getEl: function (e, t) {
var n = N(t).getRef(e)
if (!n) throw Error('element destroyed')
return n
},
getOffset: function (e) {
var t = e.__$weex__ || e.ownerDocument.__$weex__
return new Promise(function (n) {
t.requireModule('dom').getComponentRect(e.ref, function (e) {
e.result
? n({ left: e.size.left, top: e.size.top })
: n({ left: 0, top: 0 })
})
})
},
querySelector: function (context, selector) {
return Promise.resolve(transEl(querySelector(context, selector)))
querySelector: function (e, t) {
return Promise.resolve(L(H(e, t)))
},
querySelectorAll: function (context, selector) {
querySelectorAll: function (e, t) {
return Promise.resolve({
elements: querySelector(context, selector, []).map(function (el) {
return transEl(el)
elements: H(e, t, []).map(function (e) {
return L(e)
}),
})
},
queryProperties: function (context, names) {
var options = DOM_PROPERTIES.find(function (options) {
return options.test(names, context)
queryProperties: function (e, t) {
var n = U.find(function (n) {
return n.test(t, e)
})
if (options) {
return options.call(context).then(function (properties) {
return {
properties: properties,
}
return n
? n.call(e).then(function (e) {
return { properties: e }
})
}
return Promise.resolve({
properties: names.map(function (name) {
return getDataByPath(context, name)
: Promise.resolve({
properties: t.map(function (t) {
return d(e, t)
}),
})
},
queryAttributes: function (context, names) {
var attr = context.attr
queryAttributes: function (e, t) {
var n = e.attr
return Promise.resolve({
attributes: names.map(function (name) {
if (name === 'class') {
return (context.classList || []).join(' ')
}
return String(attr[name] || attr[camelize(name)] || '')
attributes: t.map(function (t) {
return 'class' === t
? (e.classList || []).join(' ')
: String(n[t] || n[a(t)] || '')
}),
})
},
queryStyles: function (context, names) {
var style = context.style
queryStyles: function (e, t) {
var n = e.style
return Promise.resolve({
styles: names.map(function (name) {
return style[name]
styles: t.map(function (e) {
return n[e]
}),
})
},
queryHTML: function (context, type) {
return Promise.resolve({
html: toHTML(context, type),
})
queryHTML: function (e, t) {
return Promise.resolve({ html: z(e, t) })
},
dispatchTapEvent: function (el) {
el.fireEvent(
dispatchTapEvent: function (e) {
return (
e.fireEvent(
'click',
{
timeStamp: Date.now(),
target: el,
currentTarget: el,
},
true
{ timeStamp: Date.now(), target: e, currentTarget: e },
!0
),
Promise.resolve()
)
return Promise.resolve()
},
dispatchLongpressEvent: function (el) {
el.fireEvent(
dispatchLongpressEvent: function (e) {
return (
e.fireEvent(
'longpress',
{
timeStamp: Date.now(),
target: el,
currentTarget: el,
},
true
{ timeStamp: Date.now(), target: e, currentTarget: e },
!0
),
Promise.resolve()
)
return Promise.resolve()
},
dispatchTouchEvent: function (el, type, eventInitDict) {
if (!eventInitDict) {
eventInitDict = {}
}
if (!eventInitDict.touches) {
eventInitDict.touches = []
}
if (!eventInitDict.changedTouches) {
eventInitDict.changedTouches = []
}
if (!eventInitDict.touches.length) {
eventInitDict.touches.push({
identifier: Date.now(),
target: el,
})
}
el.fireEvent(
type,
dispatchTouchEvent: function (e, t, n) {
return (
n || (n = {}),
n.touches || (n.touches = []),
n.changedTouches || (n.changedTouches = []),
n.touches.length || n.touches.push({ identifier: Date.now(), target: e }),
e.fireEvent(
t,
Object.assign(
{
timeStamp: Date.now(),
target: el,
currentTarget: el,
},
eventInitDict
{ timeStamp: Date.now(), target: e, currentTarget: e },
n
),
true
!0
),
Promise.resolve()
)
return Promise.resolve()
},
callFunction: function (el, functionName, args) {
var fn = getDataByPath(FUNCTIONS, functionName)
if (!fn) {
return Promise.reject(Error(functionName + ' not exists'))
}
return Promise.resolve({
result: fn.apply(null, __spreadArrays([el], args)),
})
},
triggerEvent: function (el, type, detail) {
var vm = el.__vue__
if (vm) {
vm.$trigger && vm.$trigger(type, {}, detail)
} else {
el.fireEvent(
type,
{
timeStamp: Date.now(),
target: el,
currentTarget: el,
callFunction: function (e, t, n) {
var r = d(J, t)
return r
? Promise.resolve({ result: r.apply(null, M([e], n)) })
: Promise.reject(Error(t + ' not exists'))
},
false,
{ params: [{ detail: detail }] }
triggerEvent: function (e, t, n) {
var r = e.__vue__
return (
r
? r.$trigger && r.$trigger(t, {}, n)
: e.fireEvent(
t,
{ timeStamp: Date.now(), target: e, currentTarget: e },
!1,
{ params: [{ detail: n }] }
),
Promise.resolve()
)
}
return Promise.resolve()
},
}
function initNativeApi() {
return Object.assign({}, initPage(adapter), initElement(adapter))
}
var Api = {}
Object.keys(App).forEach(function (method) {
Api['App.' + method] = App[method]
})
Object.keys(Page).forEach(function (method) {
Api['Page.' + method] = Page[method]
})
Object.keys(Element).forEach(function (method) {
Api['Element.' + method] = Element[method]
})
var wsEndpoint = process.env.UNI_AUTOMATOR_WS_ENDPOINT
var NVueApi
var fallback
var socketTask
//@ts-ignore
{
fallback = function (id, method, params, data) {
var pageId = params.pageId
var page = findPageByPageId(pageId)
if (!page) {
data.error = {
message: 'page[' + pageId + '] not exists',
}
send(data)
return true
}
var isNVue = !!page.$page.meta.isNVue
//@ts-ignore
if (!isNVue) {
UniServiceJSBridge.publishHandler(
'sendAutoMessage',
{
id: id,
method: method,
params: params,
},
pageId
)
return true
}
if (!NVueApi) {
NVueApi = initNativeApi()
}
return NVueApi[method]
}
UniServiceJSBridge.subscribe('onAutoMessageReceive', function (res) {
send(res)
})
}
function send(data) {
socketTask.send({ data: JSON.stringify(data) })
}
function findPageByPageId(pageId) {
var pages = getCurrentPages()
if (!pageId) {
return pages[pages.length - 1]
}
return pages.find(function (page) {
return page.$page.id === pageId
})
}
function onMessage(res) {
var _a = JSON.parse(res.data),
id = _a.id,
method = _a.method,
params = _a.params
var data = { id: id }
var fn = Api[method]
if (!fn) {
if (fallback) {
var result = fallback(id, method, params, data)
if (result === true) {
return
}
fn = result
}
if (!fn) {
data.error = {
message: method + ' unimplemented',
}
return send(data)
}
var Q = {}
Object.keys($).forEach(function (e) {
Q['App.' + e] = $[e]
}),
Object.keys(b).forEach(function (e) {
Q['Page.' + e] = b[e]
}),
Object.keys(C).forEach(function (e) {
Q['Element.' + e] = C[e]
})
var Y,
Z,
G,
ee = process.env.UNI_AUTOMATOR_WS_ENDPOINT
function te(e) {
G.send({ data: JSON.stringify(e) })
}
function ne(e) {
var t = JSON.parse(e.data),
n = t.id,
r = t.method,
o = t.params,
u = { id: n },
i = Q[r]
if (!i) {
if (Z) {
var c = Z(n, r, o, u)
if (!0 === c) return
i = c
}
if (!i) return (u.error = { message: r + ' unimplemented' }), te(u)
}
try {
fn(params)
.then(function (res) {
res && (data.result = res)
i(o)
.then(function (e) {
e && (u.result = e)
})
.catch(function (err) {
data.error = {
message: err.message,
}
.catch(function (e) {
u.error = { message: e.message }
})
.finally(function () {
send(data)
te(u)
})
} catch (err) {
data.error = {
message: err.message,
}
send(data)
} catch (e) {
;(u.error = { message: e.message }), te(u)
}
}
function initRuntimeAutomator(options) {
if (options === void 0) {
options = {}
}
socketTask = uni.connectSocket({
url: wsEndpoint,
complete: function () {},
})
socketTask.onMessage(onMessage)
socketTask.onOpen(function (res) {
options.success && options.success()
console.log('已开启自动化测试...')
})
socketTask.onError(function (res) {
console.log('automator.onError', res)
;(Z = function (e, t, n, r) {
var o = n.pageId,
u = (function (e) {
var t = getCurrentPages()
if (!e) return t[t.length - 1]
return t.find(function (t) {
return t.$page.id === e
})
socketTask.onClose(function () {
options.fail && options.fail({ errMsg: '$$initRuntimeAutomator:fail' })
})(o)
return u
? !u.$page.meta.isNVue
? (UniServiceJSBridge.publishHandler(
'sendAutoMessage',
{ id: e, method: t, params: n },
o
),
!0)
: (Y ||
(Y = Object.assign(
{},
(function (e) {
return {
'Page.getElement': function (t) {
return e.querySelector(e.getDocument(t.pageId), t.selector)
},
'Page.getElements': function (t) {
return e.querySelectorAll(e.getDocument(t.pageId), t.selector)
},
'Page.getWindowProperties': function (t) {
return e.queryProperties(e.getWindow(t.pageId), t.names)
},
}
})(K),
(function (e) {
var t = function (t) {
return e.getEl(t.elementId, t.pageId)
}
return {
'Element.getElement': function (n) {
return e.querySelector(t(n), n.selector)
},
'Element.getElements': function (n) {
return e.querySelectorAll(t(n), n.selector)
},
'Element.getDOMProperties': function (n) {
return e.queryProperties(t(n), n.names)
},
'Element.getProperties': function (n) {
var r = t(n),
o = r.__vue__ || r.attr || {}
return e.queryProperties(o, n.names)
},
'Element.getOffset': function (n) {
return e.getOffset(t(n))
},
'Element.getAttributes': function (n) {
return e.queryAttributes(t(n), n.names)
},
'Element.getStyles': function (n) {
return e.queryStyles(t(n), n.names)
},
'Element.getHTML': function (n) {
return e.queryHTML(t(n), n.type)
},
'Element.tap': function (n) {
return e.dispatchTapEvent(t(n))
},
'Element.longpress': function (n) {
return e.dispatchLongpressEvent(t(n))
},
'Element.touchstart': function (n) {
return e.dispatchTouchEvent(t(n), 'touchstart', n)
},
'Element.touchmove': function (n) {
return e.dispatchTouchEvent(t(n), 'touchmove', n)
},
'Element.touchend': function (n) {
return e.dispatchTouchEvent(t(n), 'touchend', n)
},
'Element.callFunction': function (n) {
return e.callFunction(t(n), n.functionName, n.args)
},
'Element.triggerEvent': function (n) {
return e.triggerEvent(t(n), n.type, n.detail)
},
}
})(K)
)),
Y[t])
: ((r.error = { message: 'page[' + o + '] not exists' }), te(r), !0)
}),
UniServiceJSBridge.subscribe('onAutoMessageReceive', function (e) {
te(e)
}),
setTimeout(function () {
var e
void 0 === e && (e = {}),
(G = uni.connectSocket({ url: ee, complete: function () {} })).onMessage(
ne
),
G.onOpen(function (t) {
e.success && e.success(), console.log('已开启自动化测试...')
}),
G.onError(function (e) {
console.log('automator.onError', e)
}),
G.onClose(function () {
e.fail && e.fail({ errMsg: '$$initRuntimeAutomator:fail' }),
console.log('automator.onClose')
})
}
//@ts-ignore
{
setTimeout(function () {
// (global as any).testMessage = onMessage;
initRuntimeAutomator()
}, 500)
}
'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
)
)
.catch(
() => (
u(
`${a('yyyy-mm-dd HH:MM:ss:l')} ${this.FILE_APP_SERVICE} not exists`
),
!0
)
return false
})
.catch(() => {
debugLauncher(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} ${
this.FILE_APP_SERVICE
} not exists`
)
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
})
)
debugLauncher(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} push ${file} ${to}`
).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))
)
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(pushs)
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.terminateApp(this.package),
await this.tool.launchApp(this.package)
} catch (e) {}
return Promise.resolve(true)
} 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
}
this.sdcard = (await this.shell(this.COMMAND_EXTERNAL)).trim()
debugClient$1(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} init ${this.id} ${this.sdcard}`
)
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
}
version() {
return this.shell(this.COMMAND_VERSION).then((output) => {
const matches = output.match(/versionName=(.*)/)
if (matches && matches.length > 1) {
return matches[1]
;(this.sdcard = (await this.shell(this.COMMAND_EXTERNAL)).trim()),
M(`${a('yyyy-mm-dd HH:MM:ss:l')} init ${this.id} ${this.sdcard}`)
}
return ''
version() {
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}`
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)
)
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)
}
}
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 = _
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n():"function"==typeof define&&define.amd?define(n):n()}(0,function(){"use strict";function e(e){var n=this.constructor;return this.then(function(t){return n.resolve(e()).then(function(){return t})},function(t){return n.resolve(e()).then(function(){return n.reject(t)})})}function n(e){return!(!e||"undefined"==typeof e.length)}function t(){}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=undefined,this._deferreds=[],c(e,this)}function r(e,n){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,o._immediateFn(function(){var t=1===e._state?n.onFulfilled:n.onRejected;if(null!==t){var o;try{o=t(e._value)}catch(r){return void f(n.promise,r)}i(n.promise,o)}else(1===e._state?i:f)(n.promise,e._value)})):e._deferreds.push(n)}function i(e,n){try{if(n===e)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"==typeof n||"function"==typeof n)){var t=n.then;if(n instanceof o)return e._state=3,e._value=n,void u(e);if("function"==typeof t)return void c(function(e,n){return function(){e.apply(n,arguments)}}(t,n),e)}e._state=1,e._value=n,u(e)}catch(r){f(e,r)}}function f(e,n){e._state=2,e._value=n,u(e)}function u(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var n=0,t=e._deferreds.length;t>n;n++)r(e,e._deferreds[n]);e._deferreds=null}function c(e,n){var t=!1;try{e(function(e){t||(t=!0,i(n,e))},function(e){t||(t=!0,f(n,e))})}catch(o){if(t)return;t=!0,f(n,o)}}var a=setTimeout;o.prototype["catch"]=function(e){return this.then(null,e)},o.prototype.then=function(e,n){var o=new this.constructor(t);return r(this,new function(e,n,t){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof n?n:null,this.promise=t}(e,n,o)),o},o.prototype["finally"]=e,o.all=function(e){return new o(function(t,o){function r(e,n){try{if(n&&("object"==typeof n||"function"==typeof n)){var u=n.then;if("function"==typeof u)return void u.call(n,function(n){r(e,n)},o)}i[e]=n,0==--f&&t(i)}catch(c){o(c)}}if(!n(e))return o(new TypeError("Promise.all accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return t([]);for(var f=i.length,u=0;i.length>u;u++)r(u,i[u])})},o.resolve=function(e){return e&&"object"==typeof e&&e.constructor===o?e:new o(function(n){n(e)})},o.reject=function(e){return new o(function(n,t){t(e)})},o.race=function(e){return new o(function(t,r){if(!n(e))return r(new TypeError("Promise.race accepts an array"));for(var i=0,f=e.length;f>i;i++)o.resolve(e[i]).then(t,r)})},o._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){a(e,0)},o._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var l=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if("undefined"!=typeof global)return global;throw Error("unable to locate global object")}();"Promise"in l?l.Promise.prototype["finally"]||(l.Promise.prototype["finally"]=e):l.Promise=o});
function initPage(adapter) {
return {
"Page.getElement": function (params) {
return adapter.querySelector(adapter.getDocument(params.pageId), params.selector);
},
"Page.getElements": function (params) {
return adapter.querySelectorAll(adapter.getDocument(params.pageId), params.selector);
},
"Page.getWindowProperties": function (params) {
return adapter.queryProperties(adapter.getWindow(params.pageId), params.names);
},
};
}
function initElement(adapter) {
var getEl = function (params) { return adapter.getEl(params.elementId, params.pageId); };
return {
"Element.getElement": function (params) {
return adapter.querySelector(getEl(params), params.selector);
},
"Element.getElements": function (params) {
return adapter.querySelectorAll(getEl(params), params.selector);
},
"Element.getDOMProperties": function (params) {
return adapter.queryProperties(getEl(params), params.names);
},
"Element.getProperties": function (params) {
var el = getEl(params);
var ctx = el.__vue__ || el.attr || {};
return adapter.queryProperties(ctx, params.names);
},
"Element.getOffset": function (params) {
return adapter.getOffset(getEl(params));
},
"Element.getAttributes": function (params) {
return adapter.queryAttributes(getEl(params), params.names);
},
"Element.getStyles": function (params) {
return adapter.queryStyles(getEl(params), params.names);
},
"Element.getHTML": function (params) {
return adapter.queryHTML(getEl(params), params.type);
},
"Element.tap": function (params) {
return adapter.dispatchTapEvent(getEl(params));
},
"Element.longpress": function (params) {
return adapter.dispatchLongpressEvent(getEl(params));
},
"Element.touchstart": function (params) {
return adapter.dispatchTouchEvent(getEl(params), "touchstart", params);
},
"Element.touchmove": function (params) {
return adapter.dispatchTouchEvent(getEl(params), "touchmove", params);
},
"Element.touchend": function (params) {
return adapter.dispatchTouchEvent(getEl(params), "touchend", params);
},
"Element.callFunction": function (params) {
return adapter.callFunction(getEl(params), params.functionName, params.args);
},
"Element.triggerEvent": function (params) {
return adapter.triggerEvent(getEl(params), params.type, params.detail);
},
};
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
......@@ -81,450 +12,4 @@ MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
var getRandomValues = typeof crypto != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto != 'undefined' && typeof msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto);
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
function rng() {
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
return getRandomValues(rnds8);
}
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}
function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex; // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
return [bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], '-', bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]], bth[buf[i++]]].join('');
}
function v4(options, buf, offset) {
var i = buf && offset || 0;
if (typeof options == 'string') {
buf = options === 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};
var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}
return buf || bytesToUuid(rnds);
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasOwn = function (val, key) { return hasOwnProperty.call(val, key); };
var isUndef = function (v) {
return v === undefined || v === null;
};
var isArray = Array.isArray;
var cacheStringFunction = function (fn) {
var cache = Object.create(null);
return (function (str) {
var hit = cache[str];
return hit || (cache[str] = fn(str));
});
};
var camelizeRE = /-(\w)/g;
var camelize = cacheStringFunction(function (str) {
return str.replace(camelizeRE, function (_, c) { return (c ? c.toUpperCase() : ""); });
});
var capitalize = cacheStringFunction(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1);
});
var PATH_RE = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
function getPaths(path, data) {
if (isArray(path)) {
return path;
}
if (data && hasOwn(data, path)) {
return [path];
}
var res = [];
path.replace(PATH_RE, function (match, p1, offset, string) {
res.push(offset ? string.replace(/\\(\\)?/g, "$1") : p1 || match);
return string;
});
return res;
}
function getDataByPath(data, path) {
var paths = getPaths(path, data);
var dataPath;
for (dataPath = paths.shift(); !isUndef(dataPath);) {
if (null == (data = data[dataPath])) {
return;
}
dataPath = paths.shift();
}
return data;
}
function findParent(vm) {
var parent = vm.$parent;
while (parent) {
if (parent._$id) {
return parent;
}
parent = parent.$parent;
}
}
function getVmNodeId(vm) {
//@ts-ignore
{
if (vm._$weex) {
return vm._uid;
}
if (vm._$id) {
return vm._$id;
}
var parent_1 = findParent(vm);
if (!vm.$parent) {
return "-1";
}
var vnode = vm.$vnode;
var context = vnode.context;
// slot 内的组件,需要补充 context 的 id,否则可能与内部组件索引值一致,导致 id 冲突
if (context && context !== parent_1 && context._$id) {
return context._$id + ";" + parent_1._$id + "," + vnode.data.attrs._i;
}
return parent_1._$id + "," + vnode.data.attrs._i;
}
}
var elementMap = new Map();
function getElId(element) {
var elementId = element._id;
if (!elementId) {
elementId = v4();
element._id = elementId;
elementMap.set(elementId, { id: elementId, element: element });
}
return elementId;
}
function isValidEl(el) {
if (el) {
var tagName = el.tagName;
return tagName.indexOf("UNI-") === 0 || tagName === "BODY";
}
return false;
}
function transEl(el) {
if (!isValidEl(el)) {
throw Error("no such element");
}
var elem = {
elementId: getElId(el),
tagName: el.tagName.toLocaleLowerCase().replace("uni-", ""),
};
var vm = el.__vue__;
if (vm) {
if (vm.$parent && vm.$parent.$el === el) {
vm = vm.$parent;
}
if (vm && !vm.$options.isReserved) {
elem.nodeId = getVmNodeId(vm);
}
}
if (elem.tagName === "video") {
elem.videoId = elem.nodeId;
}
return elem;
}
function formatHTML(html) {
return html
.replace(/\n/g, "")
.replace(/(<uni-text[^>]*>)(<span[^>]*>[^<]*<\/span>)(.*?<\/uni-text>)/g, "$1$3")
.replace(/<\/?[^>]*>/g, function (replacement) {
if (-1 < replacement.indexOf("<body")) {
return "<page>";
}
else if ("</body>" === replacement) {
return "</page>";
}
else if (0 !== replacement.indexOf("<uni-") &&
0 !== replacement.indexOf("</uni-")) {
return "";
}
return replacement
.replace(/uni-/g, "")
.replace(/ role=""/g, "")
.replace(/ aria-label=""/g, "");
});
}
var FUNCTIONS = {
input: {
input: function (el, value) {
var vm = el.__vue__;
vm.valueSync = value;
vm.$triggerInput({}, { value: value });
},
},
textarea: {
input: function (el, value) {
var vm = el.__vue__;
vm.valueSync = value;
vm.$triggerInput({}, { value: value });
},
},
"scroll-view": {
scrollTo: function (el, x, y) {
var main = el.__vue__.$refs.main;
main.scrollLeft = x;
main.scrollTop = y;
},
scrollTop: function (el) {
return el.__vue__.$refs.main.scrollTop;
},
scrollLeft: function (el) {
return el.__vue__.$refs.main.scrollLeft;
},
scrollWidth: function (el) {
return el.__vue__.$refs.main.scrollWidth;
},
scrollHeight: function (el) {
return el.__vue__.$refs.main.scrollHeight;
},
},
swiper: {
swipeTo: function (el, index) {
el.__vue__.current = index;
},
},
"movable-view": {
moveTo: function (el, x, y) {
el.__vue__._animationTo(x, y);
},
},
switch: {
tap: function (el) {
el.click();
},
},
slider: {
slideTo: function (el, value) {
var vm = el.__vue__;
var slider = vm.$refs["uni-slider"];
var offsetWidth = slider.offsetWidth;
var boxLeft = slider.getBoundingClientRect().left;
vm.value = value;
vm._onClick({
x: ((value - vm.min) * offsetWidth) / (vm.max - vm.min) + boxLeft,
});
},
},
};
var adapter = {
getWindow: function (pageId) {
return window;
},
getDocument: function (pageId) {
return document;
},
getEl: function (elementId) {
var element = elementMap.get(elementId);
if (!element) {
throw Error("element destroyed");
}
return element.element;
},
getOffset: function (node) {
var rect = node.getBoundingClientRect();
return Promise.resolve({
left: rect.left + window.pageXOffset,
top: rect.top + window.pageYOffset,
});
},
querySelector: function (context, selector) {
if (selector === "page") {
//TODO h5平台?
selector = "body";
}
return Promise.resolve(transEl(context.querySelector(selector)));
},
querySelectorAll: function (context, selector) {
var elements = [];
var nodeList = document.querySelectorAll(selector);
[].forEach.call(nodeList, function (node) {
try {
elements.push(transEl(node));
}
catch (e) { }
});
return Promise.resolve({ elements: elements });
},
queryProperties: function (context, names) {
return Promise.resolve({
properties: names.map(function (name) {
var value = getDataByPath(context, name);
if (name === "document.documentElement.scrollTop" && value === 0) {
value = getDataByPath(context, "document.body.scrollTop");
}
return value;
}),
});
},
queryAttributes: function (context, names) {
return Promise.resolve({
attributes: names.map(function (name) {
return String(context.getAttribute(name));
}),
});
},
queryStyles: function (context, names) {
var style = getComputedStyle(context);
return Promise.resolve({
styles: names.map(function (name) { return style[name]; }),
});
},
queryHTML: function (context, type) {
return Promise.resolve({
html: formatHTML(type === "outer" ? context.outerHTML : context.innerHTML),
});
},
dispatchTapEvent: function (el) {
el.click();
return Promise.resolve();
},
dispatchLongpressEvent: function (el) {
return Promise.resolve();
},
dispatchTouchEvent: function (el, type, eventInitDict) {
if (!eventInitDict) {
eventInitDict = {};
}
if (!eventInitDict.touches) {
eventInitDict.touches = [];
}
if (!eventInitDict.changedTouches) {
eventInitDict.changedTouches = [];
}
if (!eventInitDict.touches.length) {
eventInitDict.touches.push({
identifier: Date.now(),
target: el,
});
}
var touches = eventInitDict.touches.map(function (touch) { return new Touch(touch); });
var changedTouches = eventInitDict.changedTouches.map(function (touch) { return new Touch(touch); });
el.dispatchEvent(new TouchEvent(type, {
cancelable: true,
bubbles: true,
touches: touches,
targetTouches: [],
changedTouches: changedTouches,
}));
return Promise.resolve();
},
callFunction: function (el, functionName, args) {
var fn = getDataByPath(FUNCTIONS, functionName);
if (!fn) {
return Promise.reject(Error(functionName + " not exists"));
}
return Promise.resolve({
result: fn.apply(null, __spreadArrays([el], args)),
});
},
triggerEvent: function (el, type, detail) {
var vm = el.__vue__;
vm.$trigger && vm.$trigger(type, {}, detail);
return Promise.resolve();
},
};
var BUILITIN = [
"movable-view",
"picker",
"ad",
"button",
"checkbox-group",
"checkbox",
"form",
"icon",
"label",
"movable-area",
"navigator",
"picker-view-column",
"picker-view",
"progress",
"radio-group",
"radio",
"rich-text",
"u-slider",
"swiper-item",
"swiper",
"switch",
];
var BUILITIN_ALIAS = BUILITIN.map(function (tag) { return capitalize(camelize(tag)); });
function initWebApi() {
return Object.assign({}, initPage(adapter), initElement(adapter));
}
var Api = initWebApi();
function send(data) {
return UniViewJSBridge.publishHandler("onAutoMessageReceive", data);
}
UniViewJSBridge.subscribe("sendAutoMessage", function (_a) {
var id = _a.id, method = _a.method, params = _a.params;
var data = { id: id };
var fn = Api[method];
if (!fn) {
data.error = {
message: method + " unimplemented",
};
return send(data);
}
try {
fn(params)
.then(function (res) {
res && (data.result = res);
})
.catch(function (err) {
data.error = {
message: err.message,
};
})
.finally(function () {
send(data);
});
}
catch (err) {
data.error = {
message: err.message,
};
send(data);
}
});
function e(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var i=arguments[t],u=0,c=i.length;u<c;u++,o++)r[o]=i[u];return r}!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t():"function"==typeof define&&define.amd?define(t):t()}(0,(function(){function e(e){var t=this.constructor;return this.then((function(n){return t.resolve(e()).then((function(){return n}))}),(function(n){return t.resolve(e()).then((function(){return t.reject(n)}))}))}function t(e){return!(!e||void 0===e.length)}function n(){}function r(e){if(!(this instanceof r))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],a(e,this)}function o(e,t){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,r._immediateFn((function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null!==n){var r;try{r=n(e._value)}catch(e){return void u(t.promise,e)}i(t.promise,r)}else(1===e._state?i:u)(t.promise,e._value)}))):e._deferreds.push(t)}function i(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof r)return e._state=3,e._value=t,void c(e);if("function"==typeof n)return void a(function(e,t){return function(){e.apply(t,arguments)}}(n,t),e)}e._state=1,e._value=t,c(e)}catch(t){u(e,t)}}function u(e,t){e._state=2,e._value=t,c(e)}function c(e){2===e._state&&0===e._deferreds.length&&r._immediateFn((function(){e._handled||r._unhandledRejectionFn(e._value)}));for(var t=0,n=e._deferreds.length;n>t;t++)o(e,e._deferreds[t]);e._deferreds=null}function a(e,t){var n=!1;try{e((function(e){n||(n=!0,i(t,e))}),(function(e){n||(n=!0,u(t,e))}))}catch(e){if(n)return;n=!0,u(t,e)}}var s=setTimeout;r.prototype.catch=function(e){return this.then(null,e)},r.prototype.then=function(e,t){var r=new this.constructor(n);return o(this,new function(e,t,n){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof t?t:null,this.promise=n}(e,t,r)),r},r.prototype.finally=e,r.all=function(e){return new r((function(n,r){function o(e,t){try{if(t&&("object"==typeof t||"function"==typeof t)){var c=t.then;if("function"==typeof c)return void c.call(t,(function(t){o(e,t)}),r)}i[e]=t,0==--u&&n(i)}catch(e){r(e)}}if(!t(e))return r(new TypeError("Promise.all accepts an array"));var i=Array.prototype.slice.call(e);if(0===i.length)return n([]);for(var u=i.length,c=0;i.length>c;c++)o(c,i[c])}))},r.resolve=function(e){return e&&"object"==typeof e&&e.constructor===r?e:new r((function(t){t(e)}))},r.reject=function(e){return new r((function(t,n){n(e)}))},r.race=function(e){return new r((function(n,o){if(!t(e))return o(new TypeError("Promise.race accepts an array"));for(var i=0,u=e.length;u>i;i++)r.resolve(e[i]).then(n,o)}))},r._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){s(e,0)},r._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var l=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if("undefined"!=typeof global)return global;throw Error("unable to locate global object")}();"Promise"in l?l.Promise.prototype.finally||(l.Promise.prototype.finally=e):l.Promise=r}));var t="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),n=new Uint8Array(16);function r(){if(!t)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return t(n)}for(var o=[],i=0;i<256;++i)o[i]=(i+256).toString(16).substr(1);function u(e,t,n){var i=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var u=(e=e||{}).random||(e.rng||r)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,t)for(var c=0;c<16;++c)t[i+c]=u[c];return t||function(e,t){var n=t||0,r=o;return[r[e[n++]],r[e[n++]],r[e[n++]],r[e[n++]],"-",r[e[n++]],r[e[n++]],"-",r[e[n++]],r[e[n++]],"-",r[e[n++]],r[e[n++]],"-",r[e[n++]],r[e[n++]],r[e[n++]],r[e[n++]],r[e[n++]],r[e[n++]]].join("")}(u)}var c=Object.prototype.hasOwnProperty,a=Array.isArray,s=function(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}},l=/-(\w)/g,f=s((function(e){return e.replace(l,(function(e,t){return t?t.toUpperCase():""}))})),d=s((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),p=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;function m(e,t){if(a(e))return e;if(t&&(n=t,r=e,c.call(n,r)))return[e];var n,r,o=[];return e.replace(p,(function(e,t,n,r){return o.push(n?r.replace(/\\(\\)?/g,"$1"):t||e),r})),o}function v(e,t){var n,r=m(t,e);for(n=r.shift();null!=n;){if(null==(e=e[n]))return;n=r.shift()}return e}var h=new Map;function g(e){if(!function(e){if(e){var t=e.tagName;return 0===t.indexOf("UNI-")||"BODY"===t}return!1}(e))throw Error("no such element");var t,n,r={elementId:(t=e,n=t._id,n||(n=u(),t._id=n,h.set(n,{id:n,element:t})),n),tagName:e.tagName.toLocaleLowerCase().replace("uni-","")},o=e.__vue__;return o&&(o.$parent&&o.$parent.$el===e&&(o=o.$parent),o&&!o.$options.isReserved&&(r.nodeId=function(e){if(e._$weex)return e._uid;if(e._$id)return e._$id;var t=function(e){for(var t=e.$parent;t;){if(t._$id)return t;t=t.$parent}}(e);if(!e.$parent)return"-1";var n=e.$vnode,r=n.context;return r&&r!==t&&r._$id?r._$id+";"+t._$id+","+n.data.attrs._i:t._$id+","+n.data.attrs._i}(o))),"video"===r.tagName&&(r.videoId=r.nodeId),r}var _={input:{input:function(e,t){var n=e.__vue__;n.valueSync=t,n.$triggerInput({},{value:t})}},textarea:{input:function(e,t){var n=e.__vue__;n.valueSync=t,n.$triggerInput({},{value:t})}},"scroll-view":{scrollTo:function(e,t,n){var r=e.__vue__.$refs.main;r.scrollLeft=t,r.scrollTop=n},scrollTop:function(e){return e.__vue__.$refs.main.scrollTop},scrollLeft:function(e){return e.__vue__.$refs.main.scrollLeft},scrollWidth:function(e){return e.__vue__.$refs.main.scrollWidth},scrollHeight:function(e){return e.__vue__.$refs.main.scrollHeight}},swiper:{swipeTo:function(e,t){e.__vue__.current=t}},"movable-view":{moveTo:function(e,t,n){e.__vue__._animationTo(t,n)}},switch:{tap:function(e){e.click()}},slider:{slideTo:function(e,t){var n=e.__vue__,r=n.$refs["uni-slider"],o=r.offsetWidth,i=r.getBoundingClientRect().left;n.value=t,n._onClick({x:(t-n.min)*o/(n.max-n.min)+i})}}},y={getWindow:function(e){return window},getDocument:function(e){return document},getEl:function(e){var t=h.get(e);if(!t)throw Error("element destroyed");return t.element},getOffset:function(e){var t=e.getBoundingClientRect();return Promise.resolve({left:t.left+window.pageXOffset,top:t.top+window.pageYOffset})},querySelector:function(e,t){return"page"===t&&(t="body"),Promise.resolve(g(e.querySelector(t)))},querySelectorAll:function(e,t){var n=[],r=document.querySelectorAll(t);return[].forEach.call(r,(function(e){try{n.push(g(e))}catch(e){}})),Promise.resolve({elements:n})},queryProperties:function(e,t){return Promise.resolve({properties:t.map((function(t){var n=v(e,t);return"document.documentElement.scrollTop"===t&&0===n&&(n=v(e,"document.body.scrollTop")),n}))})},queryAttributes:function(e,t){return Promise.resolve({attributes:t.map((function(t){return String(e.getAttribute(t))}))})},queryStyles:function(e,t){var n=getComputedStyle(e);return Promise.resolve({styles:t.map((function(e){return n[e]}))})},queryHTML:function(e,t){return Promise.resolve({html:(n="outer"===t?e.outerHTML:e.innerHTML,n.replace(/\n/g,"").replace(/(<uni-text[^>]*>)(<span[^>]*>[^<]*<\/span>)(.*?<\/uni-text>)/g,"$1$3").replace(/<\/?[^>]*>/g,(function(e){return-1<e.indexOf("<body")?"<page>":"</body>"===e?"</page>":0!==e.indexOf("<uni-")&&0!==e.indexOf("</uni-")?"":e.replace(/uni-/g,"").replace(/ role=""/g,"").replace(/ aria-label=""/g,"")})))});var n},dispatchTapEvent:function(e){return e.click(),Promise.resolve()},dispatchLongpressEvent:function(e){return Promise.resolve()},dispatchTouchEvent:function(e,t,n){n||(n={}),n.touches||(n.touches=[]),n.changedTouches||(n.changedTouches=[]),n.touches.length||n.touches.push({identifier:Date.now(),target:e});var r=w(n.touches),o=w(n.changedTouches),i=w([]);return e.dispatchEvent(new TouchEvent(t,{cancelable:!0,bubbles:!0,touches:r,targetTouches:i,changedTouches:o})),Promise.resolve()},callFunction:function(t,n,r){var o=v(_,n);return o?Promise.resolve({result:o.apply(null,e([t],r))}):Promise.reject(Error(n+" not exists"))},triggerEvent:function(e,t,n){var r=e.__vue__;return r.$trigger&&r.$trigger(t,{},n),Promise.resolve()}};function w(e){var t,n=e.map((function(e){return function(e){if(document.createTouch)return document.createTouch(window,e.target,e.identifier,e.pageX,e.pageY,e.screenX,e.screenY);return new Touch(e)}(e)}));return document.createTouchList?(t=document).createTouchList.apply(t,n):n}["movable-view","picker","ad","button","checkbox-group","checkbox","form","icon","label","movable-area","navigator","picker-view-column","picker-view","progress","radio-group","radio","rich-text","u-slider","swiper-item","swiper","switch"].map((function(e){return d(f(e))}));var E=Object.assign({},function(e){return{"Page.getElement":function(t){return e.querySelector(e.getDocument(t.pageId),t.selector)},"Page.getElements":function(t){return e.querySelectorAll(e.getDocument(t.pageId),t.selector)},"Page.getWindowProperties":function(t){return e.queryProperties(e.getWindow(t.pageId),t.names)}}}(y),function(e){var t=function(t){return e.getEl(t.elementId,t.pageId)};return{"Element.getElement":function(n){return e.querySelector(t(n),n.selector)},"Element.getElements":function(n){return e.querySelectorAll(t(n),n.selector)},"Element.getDOMProperties":function(n){return e.queryProperties(t(n),n.names)},"Element.getProperties":function(n){var r=t(n),o=r.__vue__||r.attr||{};return e.queryProperties(o,n.names)},"Element.getOffset":function(n){return e.getOffset(t(n))},"Element.getAttributes":function(n){return e.queryAttributes(t(n),n.names)},"Element.getStyles":function(n){return e.queryStyles(t(n),n.names)},"Element.getHTML":function(n){return e.queryHTML(t(n),n.type)},"Element.tap":function(n){return e.dispatchTapEvent(t(n))},"Element.longpress":function(n){return e.dispatchLongpressEvent(t(n))},"Element.touchstart":function(n){return e.dispatchTouchEvent(t(n),"touchstart",n)},"Element.touchmove":function(n){return e.dispatchTouchEvent(t(n),"touchmove",n)},"Element.touchend":function(n){return e.dispatchTouchEvent(t(n),"touchend",n)},"Element.callFunction":function(n){return e.callFunction(t(n),n.functionName,n.args)},"Element.triggerEvent":function(n){return e.triggerEvent(t(n),n.type,n.detail)}}}(y));function b(e){return UniViewJSBridge.publishHandler("onAutoMessageReceive",e)}UniViewJSBridge.subscribe("sendAutoMessage",(function(e){var t=e.id,n=e.method,r=e.params,o={id:t},i=E[n];if(!i)return o.error={message:n+" unimplemented"},b(o);try{i(r).then((function(e){e&&(o.result=e)})).catch((function(e){o.error={message:e.message}})).finally((function(){b(o)}))}catch(e){o.error={message:e.message},b(o)}}));
'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()}};
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var fs = _interopDefault(require('fs'));
var path = _interopDefault(require('path'));
var debug = _interopDefault(require('debug'));
var isRelative = _interopDefault(require('licia/isRelative'));
var WebSocket = _interopDefault(require('ws'));
var events = require('events');
var uuid = _interopDefault(require('licia/uuid'));
var stringify = _interopDefault(require('licia/stringify'));
var dateFormat = _interopDefault(require('licia/dateFormat'));
var waitUntil = _interopDefault(require('licia/waitUntil'));
var fs$1 = _interopDefault(require('licia/fs'));
var isFn = _interopDefault(require('licia/isFn'));
var trim = _interopDefault(require('licia/trim'));
var isStr = _interopDefault(require('licia/isStr'));
var startWith = _interopDefault(require('licia/startWith'));
var isNum = _interopDefault(require('licia/isNum'));
var sleep$1 = _interopDefault(require('licia/sleep'));
var isUndef = _interopDefault(require('licia/isUndef'));
var address = _interopDefault(require('address'));
var defaultGateway = _interopDefault(require('default-gateway'));
var getPort = _interopDefault(require('licia/getPort'));
var child_process = require('child_process');
var toStr = _interopDefault(require('licia/toStr'));
class Transport extends events.EventEmitter {
constructor(ws) {
super();
this.ws = ws;
this.ws.addEventListener("message", (event) => {
this.emit("message", event.data);
});
this.ws.addEventListener("close", () => {
this.emit("close");
});
}
send(message) {
this.ws.send(message);
}
close() {
this.ws.close();
}
}
const CLOSE_ERR_TIP = "Connection closed";
class Connection extends events.EventEmitter {
constructor(transport, puppet, namespace) {
super();
this.puppet = puppet;
this.namespace = namespace;
this.callbacks = new Map();
this.transport = transport;
this.debug = debug("automator:protocol:" + this.namespace);
this.onMessage = (msg) => {
this.debug(`${dateFormat("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${msg}`);
const { id, method, error, result, params } = JSON.parse(msg);
if (!id) {
return this.puppet.emit(method, params);
}
const { callbacks } = this;
if (id && callbacks.has(id)) {
const promise = callbacks.get(id);
callbacks.delete(id);
error ? promise.reject(Error(error.message)) : promise.resolve(result);
}
};
this.onClose = () => {
this.callbacks.forEach((promise) => {
promise.reject(Error(CLOSE_ERR_TIP));
});
};
this.transport.on("message", this.onMessage);
this.transport.on("close", this.onClose);
}
send(method, params = {}, reflect = true) {
if (reflect && this.puppet.adapter.has(method)) {
return this.puppet.adapter.send(this, method, params);
}
const id = uuid();
const data = stringify({
id,
method,
params,
});
this.debug(`${dateFormat("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${data}`);
return new Promise((resolve, reject) => {
try {
this.transport.send(data);
}
catch (e) {
reject(Error(CLOSE_ERR_TIP));
}
this.callbacks.set(id, {
resolve,
reject,
});
});
}
dispose() {
this.transport.close();
}
static createDevtoolConnection(url, puppet) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(url);
ws.addEventListener("open", () => {
resolve(new Connection(new Transport(ws), puppet, "devtool"));
});
ws.addEventListener("error", reject);
});
}
static createRuntimeConnection(port, puppet, timeout) {
return new Promise((resolve, reject) => {
debug("automator:runtime")(`${dateFormat("yyyy-mm-dd HH:MM:ss:l")} port=${port}`);
const wss = new WebSocket.Server({
port,
});
waitUntil(async () => {
if (puppet.runtimeConnection) {
return true;
}
}, timeout, 1e3).catch(() => {
wss.close();
reject("Failed to connect to runtime, please make sure the project is running");
});
wss.on("connection", function connection(ws) {
debug("automator:runtime")(`${dateFormat("yyyy-mm-dd HH:MM:ss:l")} connected`);
const connection = new Connection(new Transport(ws), puppet, "runtime");
// 可能会被重新连接,刷新成最新的
puppet.setRuntimeConnection(connection);
resolve(connection);
});
puppet.setRuntimeServer(wss);
});
}
}
const qrCodeTerminal = require("qrcode-terminal");
const QrCodeReader = require("qrcode-reader");
const isWin = /^win/.test(process.platform);
function printQrCode(content) {
return new Promise((resolve) => {
qrCodeTerminal.generate(content, {
small: true,
}, (qrcode) => {
process.stdout.write(qrcode);
resolve();
});
});
}
function toArray(str) {
if (isStr(str)) {
return [true, [str]];
}
return [false, str];
}
async function invokeManyToMany(fn, str) {
const [isSingle, strArr] = toArray(str);
const result = await fn(strArr);
return isSingle ? result[0] : result;
}
async function resolvePort(port, defaultPort) {
const newPort = await getPort(port || defaultPort);
if (port && newPort !== port) {
throw Error(`Port ${port} is in use, please specify another port`);
}
return newPort;
}
function getWsEndpoint(port) {
let host;
try {
// This can only return an IPv4 address
const result = defaultGateway.v4.sync();
host = address.ip(result && result.interface);
if (host) {
// Check if the address is a private ip
// https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
if (!/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(host)) {
// Address is not private, so we will discard it
host = undefined;
}
}
}
catch (_e) {
// ignored
}
return "ws://" + (host || "localhost") + ":" + port;
}
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}var e=t(require("fs")),n=t(require("path")),s=t(require("debug")),i=t(require("licia/isRelative")),o=t(require("ws")),r=require("events"),a=t(require("licia/uuid")),c=t(require("licia/stringify")),p=t(require("licia/dateFormat")),l=t(require("licia/waitUntil")),u=t(require("licia/fs")),h=t(require("licia/isFn")),d=t(require("licia/trim")),m=t(require("licia/isStr")),g=t(require("licia/startWith")),y=t(require("licia/isNum")),v=t(require("licia/sleep")),w=t(require("licia/isUndef")),f=t(require("address")),P=t(require("default-gateway")),M=t(require("licia/getPort")),k=require("child_process"),E=t(require("licia/toStr"));class b extends r.EventEmitter{constructor(t){super(),this.ws=t,this.ws.addEventListener("message",t=>{this.emit("message",t.data)}),this.ws.addEventListener("close",()=>{this.emit("close")})}send(t){this.ws.send(t)}close(){this.ws.close()}}class I extends r.EventEmitter{constructor(t,e,n){super(),this.puppet=e,this.namespace=n,this.callbacks=new Map,this.transport=t,this.debug=s("automator:protocol:"+this.namespace),this.onMessage=t=>{this.debug(`${p("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${t}`);const{id:e,method:n,error:s,result:i,params:o}=JSON.parse(t);if(!e)return this.puppet.emit(n,o);const{callbacks:r}=this;if(e&&r.has(e)){const t=r.get(e);r.delete(e),s?t.reject(Error(s.message)):t.resolve(i)}},this.onClose=()=>{this.callbacks.forEach(t=>{t.reject(Error("Connection closed"))})},this.transport.on("message",this.onMessage),this.transport.on("close",this.onClose)}send(t,e={},n=!0){if(n&&this.puppet.adapter.has(t))return this.puppet.adapter.send(this,t,e);const s=a(),i=c({id:s,method:t,params:e});return this.debug(`${p("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${i}`),new Promise((t,e)=>{try{this.transport.send(i)}catch(t){e(Error("Connection closed"))}this.callbacks.set(s,{resolve:t,reject:e})})}dispose(){this.transport.close()}static createDevtoolConnection(t,e){return new Promise((n,s)=>{const i=new o(t);i.addEventListener("open",()=>{n(new I(new b(i),e,"devtool"))}),i.addEventListener("error",s)})}static createRuntimeConnection(t,e,n){return new Promise((i,r)=>{s("automator:runtime")(`${p("yyyy-mm-dd HH:MM:ss:l")} port=${t}`);const a=new o.Server({port:t});l(async()=>{if(e.runtimeConnection)return!0},n,1e3).catch(()=>{a.close(),r("Failed to connect to runtime, please make sure the project is running")}),a.on("connection",(function(t){s("automator:runtime")(p("yyyy-mm-dd HH:MM:ss:l")+" connected");const n=new I(new b(t),e,"runtime");e.setRuntimeConnection(n),i(n)})),e.setRuntimeServer(a)})}}const C=require("qrcode-terminal");require("qrcode-reader"),/^win/.test(process.platform);async function T(t,e){const[n,s]=function(t){return m(t)?[!0,[t]]:[!1,t]}(e),i=await t(s);return n?i[0]:i}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
......@@ -203,1265 +13,4 @@ MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
var TYPES;
(function (TYPES) {
TYPES["RUNTIME"] = "runtime";
TYPES["DEVTOOL"] = "devtool";
})(TYPES || (TYPES = {}));
function wrapper(type, descriptor) {
const method = descriptor.value;
descriptor.value = async function (params) {
const fn = await (method === null || method === void 0 ? void 0 : method.call(this, params));
return fn(type);
};
return descriptor;
}
function runtime(target, propertyName, descriptor) {
return wrapper(TYPES.RUNTIME, descriptor);
}
function devtool(target, propertyName, descriptor) {
return wrapper(TYPES.DEVTOOL, descriptor);
}
class Base {
constructor(puppet) {
this.puppet = puppet;
}
invoke(method, params) {
return async (type) => {
if (!this.puppet.devtoolConnection) {
return this.puppet.runtimeConnection.send(method, params);
}
return (type === TYPES.DEVTOOL
? this.puppet.devtoolConnection
: this.puppet.runtimeConnection).send(method, params);
};
}
on(method, listener) {
this.puppet.on(method, listener);
}
}
class Element extends Base {
constructor(puppet, options) {
super(puppet);
this.id = options.elementId;
this.pageId = options.pageId;
this.nodeId = options.nodeId;
this.videoId = options.videoId;
}
async getData(params) {
return this.invokeMethod("Element.getData", params);
}
async setData(params) {
return this.invokeMethod("Element.setData", params);
}
async callMethod(params) {
return this.invokeMethod("Element.callMethod", params);
}
async getElement(params) {
return this.invokeMethod("Element.getElement", params);
}
async getElements(params) {
return this.invokeMethod("Element.getElements", params);
}
async getOffset() {
return this.invokeMethod("Element.getOffset");
}
async getHTML(params) {
return this.invokeMethod("Element.getHTML", params);
}
async getAttributes(params) {
return this.invokeMethod("Element.getAttributes", params);
}
async getStyles(params) {
return this.invokeMethod("Element.getStyles", params);
}
async getDOMProperties(params) {
return this.invokeMethod("Element.getDOMProperties", params);
}
async getProperties(params) {
return this.invokeMethod("Element.getProperties", params);
}
async tap() {
return this.invokeMethod("Element.tap");
}
async longpress() {
return this.invokeMethod("Element.longpress");
}
async touchstart(params) {
return this.invokeMethod("Element.touchstart", params);
}
async touchmove(params) {
return this.invokeMethod("Element.touchmove", params);
}
async touchend(params) {
return this.invokeMethod("Element.touchend", params);
}
async triggerEvent(params) {
return this.invokeMethod("Element.triggerEvent", params);
}
async callFunction(params) {
return this.invokeMethod("Element.callFunction", params);
}
async callContextMethod(params) {
return this.invokeMethod("Element.callContextMethod", params);
}
invokeMethod(method, params = {}) {
params.elementId = this.id;
params.pageId = this.pageId;
this.nodeId && (params.nodeId = this.nodeId);
this.videoId && (params.videoId = this.videoId);
return this.invoke(method, params);
}
}
__decorate([
runtime
], Element.prototype, "getData", null);
__decorate([
runtime
], Element.prototype, "setData", null);
__decorate([
runtime
], Element.prototype, "callMethod", null);
__decorate([
devtool
], Element.prototype, "getElement", null);
__decorate([
devtool
], Element.prototype, "getElements", null);
__decorate([
devtool
], Element.prototype, "getOffset", null);
__decorate([
devtool
], Element.prototype, "getHTML", null);
__decorate([
devtool
], Element.prototype, "getAttributes", null);
__decorate([
devtool
], Element.prototype, "getStyles", null);
__decorate([
devtool
], Element.prototype, "getDOMProperties", null);
__decorate([
devtool
], Element.prototype, "getProperties", null);
__decorate([
devtool
], Element.prototype, "tap", null);
__decorate([
devtool
], Element.prototype, "longpress", null);
__decorate([
devtool
], Element.prototype, "touchstart", null);
__decorate([
devtool
], Element.prototype, "touchmove", null);
__decorate([
devtool
], Element.prototype, "touchend", null);
__decorate([
devtool
], Element.prototype, "triggerEvent", null);
__decorate([
devtool
], Element.prototype, "callFunction", null);
__decorate([
devtool
], Element.prototype, "callContextMethod", null);
const util = require("util");
class Element$1 {
constructor(puppet, options, elementMap) {
this.puppet = puppet;
this.id = options.elementId;
this.pageId = options.pageId;
this.nodeId = options.nodeId || null;
this.videoId = options.videoId || null;
this.tagName = options.tagName;
this.nvue = options.nvue;
this.elementMap = elementMap;
// 统一格式化为 page
if (this.tagName === "body" || this.tagName === "page-body") {
this.tagName = "page";
}
this.api = new Element(puppet, options);
}
toJSON() {
return JSON.stringify({
id: this.id,
tagName: this.tagName,
pageId: this.pageId,
nodeId: this.nodeId,
videoId: this.videoId,
});
}
toString() {
return this.toJSON();
}
[util.inspect.custom]() {
return this.toJSON();
}
async $(selector) {
try {
const element = await this.api.getElement({ selector });
return Element$1.create(this.puppet, Object.assign({}, element, {
pageId: this.pageId,
}), this.elementMap);
}
catch (e) {
return null;
}
}
async $$(selector) {
const { elements } = await this.api.getElements({ selector });
return elements.map((elem) => Element$1.create(this.puppet, Object.assign({}, elem, {
pageId: this.pageId,
}), this.elementMap));
}
async size() {
const [width, height] = await this.domProperty([
"offsetWidth",
"offsetHeight",
]);
return {
width,
height,
};
}
async offset() {
const { left, top } = await this.api.getOffset();
return {
left,
top,
};
}
async text() {
return this.domProperty("innerText");
}
async attribute(name) {
if (!isStr(name)) {
throw Error("name must be a string");
}
return (await this.api.getAttributes({ names: [name] })).attributes[0];
}
async value() {
return this.property("value");
}
async property(name) {
if (!isStr(name)) {
throw Error("name must be a string");
}
if (this.puppet.checkProperty) {
let props = this.publicProps;
if (!props) {
this.publicProps = props = await this._property("__propPublic");
}
if (!props[name]) {
throw Error(`${this.tagName}.${name} not exists`);
}
}
return this._property(name);
}
async html() {
return (await this.api.getHTML({ type: "inner" })).html;
}
async outerHtml() {
return (await this.api.getHTML({ type: "outer" })).html;
}
async style(name) {
if (!isStr(name)) {
throw Error("name must be a string");
}
return (await this.api.getStyles({ names: [name] })).styles[0];
}
async tap() {
return this.api.tap();
}
async longpress() {
if (this.nvue) {
return this.api.longpress();
}
await this.touchstart();
await sleep$1(350);
return this.touchend();
}
async trigger(type, detail) {
const event = {
type,
};
if (!isUndef(detail)) {
event.detail = detail;
}
return this.api.triggerEvent(event);
}
async touchstart(options) {
return this.api.touchstart(options);
}
async touchmove(options) {
return this.api.touchmove(options);
}
async touchend(options) {
return this.api.touchend(options);
}
async domProperty(name) {
return invokeManyToMany(async (names) => (await this.api.getDOMProperties({ names })).properties, name);
}
_property(name) {
return invokeManyToMany(async (names) => (await this.api.getProperties({ names })).properties, name);
}
send(method, params) {
params.elementId = this.id;
params.pageId = this.pageId;
this.nodeId && (params.nodeId = this.nodeId);
this.videoId && (params.videoId = this.videoId);
return this.puppet.send(method, params);
}
async callFunction(functionName, ...args) {
return (await this.api.callFunction({
functionName,
args,
})).result;
}
static create(puppet, options, elementMap) {
let element = elementMap.get(options.elementId);
if (element) {
return element;
}
let ElementClass;
if (options.nodeId) {
ElementClass = CustomElement;
}
else {
switch (options.tagName) {
case "input":
ElementClass = InputElement;
break;
case "textarea":
ElementClass = TextareaElement;
break;
case "scroll-view":
ElementClass = ScrollViewElement;
break;
case "swiper":
ElementClass = SwiperElement;
break;
case "movable-view":
ElementClass = MovableViewElement;
break;
case "switch":
ElementClass = SwitchElement;
break;
case "slider":
ElementClass = SliderElement;
break;
case "video":
ElementClass = ContextElement;
break;
default:
ElementClass = Element$1;
}
}
element = new ElementClass(puppet, options, elementMap);
elementMap.set(options.elementId, element);
return element;
}
}
class CustomElement extends Element$1 {
async setData(data) {
return this.api.setData({ data });
}
async data(path) {
const data = {};
if (path) {
data.path = path;
}
return (await this.api.getData(data)).data;
}
async callMethod(method, ...args) {
return (await this.api.callMethod({
method,
args,
})).result;
}
}
class InputElement extends Element$1 {
async input(value) {
return this.callFunction("input.input", value);
}
}
class TextareaElement extends Element$1 {
async input(value) {
return this.callFunction("textarea.input", value);
}
}
class ScrollViewElement extends Element$1 {
async scrollTo(x, y) {
return this.callFunction("scroll-view.scrollTo", x, y);
}
async property(name) {
if (name === "scrollTop") {
return this.callFunction("scroll-view.scrollTop");
}
else if (name === "scrollLeft") {
return this.callFunction("scroll-view.scrollLeft");
}
return super.property(name);
}
async scrollWidth() {
return this.callFunction("scroll-view.scrollWidth");
}
async scrollHeight() {
return this.callFunction("scroll-view.scrollHeight");
}
}
class SwiperElement extends Element$1 {
async swipeTo(index) {
return this.callFunction("swiper.swipeTo", index);
}
}
class MovableViewElement extends Element$1 {
async moveTo(x, y) {
return this.callFunction("movable-view.moveTo", x, y);
}
async property(name) {
if (name === "x") {
return this._property("_translateX");
}
else if (name === "y") {
return this._property("_translateY");
}
return super.property(name);
}
}
class SwitchElement extends Element$1 {
async tap() {
return this.callFunction("switch.tap");
}
}
class SliderElement extends Element$1 {
async slideTo(value) {
return this.callFunction("slider.slideTo", value);
}
}
class ContextElement extends Element$1 {
async callContextMethod(method, ...args) {
const result = await this.api.callContextMethod({
method,
args,
});
return result;
}
}
class Page extends Base {
constructor(puppet, options) {
super(puppet);
this.id = options.id;
}
async getData(params) {
return this.invokeMethod("Page.getData", params);
}
async setData(params) {
return this.invokeMethod("Page.setData", params);
}
async callMethod(params) {
return this.invokeMethod("Page.callMethod", params);
}
async getElement(params) {
return this.invokeMethod("Page.getElement", params);
}
async getElements(params) {
return this.invokeMethod("Page.getElements", params);
}
async getWindowProperties(params) {
return this.invokeMethod("Page.getWindowProperties", params);
}
invokeMethod(method, params = {}) {
params.pageId = this.id;
return this.invoke(method, params);
}
}
__decorate([
runtime
], Page.prototype, "getData", null);
__decorate([
runtime
], Page.prototype, "setData", null);
__decorate([
runtime
], Page.prototype, "callMethod", null);
__decorate([
devtool
], Page.prototype, "getElement", null);
__decorate([
devtool
], Page.prototype, "getElements", null);
__decorate([
devtool
], Page.prototype, "getWindowProperties", null);
const util$1 = require("util");
class Page$1 {
constructor(puppet, options) {
this.puppet = puppet;
this.id = options.id;
this.path = options.path;
this.query = options.query;
this.elementMap = new Map();
this.api = new Page(puppet, options);
}
toJSON() {
return JSON.stringify({ id: this.id, path: this.path, query: this.query });
}
toString() {
return this.toJSON();
}
[util$1.inspect.custom]() {
return this.toJSON();
}
async waitFor(condition) {
if (isNum(condition)) {
return await sleep$1(condition);
}
else if (isFn(condition)) {
return waitUntil(condition);
}
else if (isStr(condition)) {
return waitUntil(async () => {
const elms = await this.$$(condition);
return elms.length > 0;
});
}
}
async $(selector) {
try {
const page = await this.api.getElement({ selector });
return Element$1.create(this.puppet, Object.assign({
selector,
}, page, {
pageId: this.id,
}), this.elementMap);
}
catch (t) {
return null;
}
}
async $$(selector) {
const { elements } = await this.api.getElements({ selector });
return elements.map((elem) => Element$1.create(this.puppet, Object.assign({
selector,
}, elem, {
pageId: this.id,
}), this.elementMap));
}
async data(path) {
const payload = {};
if (path) {
payload.path = path;
}
return (await this.api.getData(payload)).data;
}
async setData(data) {
return this.api.setData({ data });
}
async size() {
const [width, height] = await this.windowProperty([
"document.documentElement.scrollWidth",
"document.documentElement.scrollHeight",
]);
return {
width,
height,
};
}
async callMethod(method, ...args) {
return (await this.api.callMethod({
method,
args,
})).result;
}
async scrollTop() {
return this.windowProperty("document.documentElement.scrollTop");
}
async windowProperty(names) {
const isSingle = isStr(names);
if (isSingle) {
names = [names];
}
const { properties } = await this.api.getWindowProperties({
names: names,
});
return isSingle ? properties[0] : properties;
}
static create(puppet, options, pageMap) {
let page = pageMap.get(options.id);
if (page) {
//update query (部分页面id被锁定,如tabBar页面)
page.query = options.query;
return page;
}
page = new Page$1(puppet, options);
pageMap.set(options.id, page);
return page;
}
}
class App extends Base {
async getPageStack() {
return this.invoke("App.getPageStack");
}
async callUniMethod(params) {
return this.invoke("App.callUniMethod", params);
}
async getCurrentPage() {
return this.invoke("App.getCurrentPage");
}
async mockUniMethod(params) {
return this.invoke("App.mockUniMethod", params);
}
async callFunction(params) {
return this.invoke("App.callFunction", params);
}
async captureScreenshot(params) {
return this.invoke("App.captureScreenshot", params);
}
async exit() {
return this.invoke("App.exit");
}
async addBinding(params) {
return this.invoke("App.addBinding", params);
}
async enableLog() {
return this.invoke("App.enableLog");
}
onLogAdded(listener) {
return this.on("App.logAdded", listener);
}
onBindingCalled(listener) {
return this.on("App.bindingCalled", listener);
}
onExceptionThrown(listener) {
return this.on("App.exceptionThrown", listener);
}
}
__decorate([
runtime
], App.prototype, "getPageStack", null);
__decorate([
runtime
], App.prototype, "callUniMethod", null);
__decorate([
runtime
], App.prototype, "getCurrentPage", null);
__decorate([
runtime
], App.prototype, "mockUniMethod", null);
__decorate([
devtool
], App.prototype, "callFunction", null);
__decorate([
devtool
], App.prototype, "captureScreenshot", null);
__decorate([
devtool
], App.prototype, "exit", null);
__decorate([
devtool
], App.prototype, "addBinding", null);
__decorate([
devtool
], App.prototype, "enableLog", null);
class Tool extends Base {
async getInfo() {
return this.invoke("Tool.getInfo");
}
async enableRemoteDebug(params) {
return this.invoke("Tool.enableRemoteDebug");
}
async close() {
return this.invoke("Tool.close");
}
async getTestAccounts() {
return this.invoke("Tool.getTestAccounts");
}
onRemoteDebugConnected(listener) {
this.puppet.once("Tool.onRemoteDebugConnected", listener);
// mp-baidu
this.puppet.once("Tool.onPreviewConnected", listener);
}
}
__decorate([
devtool
], Tool.prototype, "getInfo", null);
__decorate([
devtool
], Tool.prototype, "enableRemoteDebug", null);
__decorate([
devtool
], Tool.prototype, "close", null);
__decorate([
devtool
], Tool.prototype, "getTestAccounts", null);
function sleep(timeout) {
return new Promise((e) => setTimeout(e, timeout));
}
function isFnStr(str) {
return (isStr(str) &&
((str = trim(str)), startWith(str, "function") || startWith(str, "() =>")));
}
class Program extends events.EventEmitter {
constructor(puppet, options) {
super();
this.puppet = puppet;
this.options = options;
this.pageMap = new Map();
this.appBindings = new Map();
this.appApi = new App(puppet);
this.toolApi = new Tool(puppet);
this.appApi.onLogAdded((msg) => {
this.emit("console", msg);
});
this.appApi.onBindingCalled(({ name, args }) => {
try {
const fn = this.appBindings.get(name);
fn && fn(...args);
}
catch (t) { }
});
this.appApi.onExceptionThrown((error) => {
this.emit("exception", error);
});
}
async pageStack() {
return (await this.appApi.getPageStack()).pageStack.map((page) => Page$1.create(this.puppet, page, this.pageMap));
}
async navigateTo(url) {
return this.changeRoute("navigateTo", url);
}
async redirectTo(url) {
return this.changeRoute("redirectTo", url);
}
async navigateBack() {
return this.changeRoute("navigateBack");
}
async reLaunch(url) {
return this.changeRoute("reLaunch", url);
}
async switchTab(url) {
return this.changeRoute("switchTab", url);
}
async currentPage() {
const { id, path, query } = await this.appApi.getCurrentPage();
return Page$1.create(this.puppet, { id, path, query }, this.pageMap);
}
async systemInfo() {
return this.callUniMethod("getSystemInfoSync");
}
async callUniMethod(method, ...args) {
return (await this.appApi.callUniMethod({ method, args })).result;
}
async mockUniMethod(method, result, ...args) {
if (isFn(result) || isFnStr(result)) {
return this.appApi.mockUniMethod({
method,
functionDeclaration: result.toString(),
args,
});
}
return this.appApi.mockUniMethod({ method, result });
}
async restoreUniMethod(method) {
return this.appApi.mockUniMethod({ method });
}
async evaluate(appFunction, // tslint:disable-line
...args) {
return (await this.appApi.callFunction({
functionDeclaration: appFunction.toString(),
args,
})).result;
}
async pageScrollTo(scrollTop) {
await this.callUniMethod("pageScrollTo", {
scrollTop,
duration: 0,
});
}
async close() {
try {
await this.appApi.exit();
}
catch (t) { }
await sleep(1e3);
this.puppet.disposeRuntimeServer();
await this.toolApi.close();
this.disconnect();
}
async teardown() {
return this[this.options.teardown === "disconnect" ? "disconnect" : "close"]();
}
async remote(auto) {
if (!this.puppet.devtools.remote) {
return console.warn(`Failed to enable remote, ${this.puppet.devtools.name} is unimplemented`);
}
const { qrCode } = await this.toolApi.enableRemoteDebug({ auto });
qrCode && (await printQrCode(qrCode));
const connectedPromise = new Promise((resolve) => {
this.toolApi.onRemoteDebugConnected(async () => {
await sleep(1e3);
resolve();
});
});
const runtimePromise = new Promise((resolve) => {
this.puppet.setRemoteRuntimeConnectionCallback(() => {
resolve();
});
});
return Promise.all([connectedPromise, runtimePromise]);
}
disconnect() {
this.puppet.dispose();
}
on(event, listener) {
if (event === "console") {
this.appApi.enableLog();
}
super.on(event, listener);
return this;
}
async exposeFunction(name, bindingFunction) {
if (this.appBindings.has(name)) {
throw Error(`Failed to expose function with name ${name}: already exists!`);
}
this.appBindings.set(name, bindingFunction);
await this.appApi.addBinding({ name });
}
async checkVersion() { }
async screenshot(options) {
const { data } = await this.appApi.captureScreenshot({
fullPage: options === null || options === void 0 ? void 0 : options.fullPage,
});
if (!(options === null || options === void 0 ? void 0 : options.path))
return data;
await fs$1.writeFile(options.path, data, "base64");
}
async testAccounts() {
return (await this.toolApi.getTestAccounts()).accounts;
}
async changeRoute(method, url) {
await this.callUniMethod(method, {
url,
});
await sleep(3e3);
return this.currentPage();
}
}
class Adapter {
constructor(options) {
this.options = options;
}
has(method) {
return !!this.options[method];
}
send(connection, method, params) {
const option = this.options[method];
if (!option) {
return Promise.reject(Error(`adapter for ${method} not found`));
}
const reflect = option.reflect;
if (!reflect) {
return Promise.reject(Error(`${method}'s reflect is required`));
}
if (option.params) {
params = option.params(params);
}
if (typeof reflect === "function") {
return reflect(connection.send.bind(connection), params);
}
else {
method = reflect;
}
return connection.send(method, params);
}
}
const debugPuppet = debug("automator:puppet");
const AUTOMATOR_JSON_FILE = ".automator.json";
function tryRequire(path) {
try {
return require(path);
}
catch (e) { }
}
function resolveAutomatorJson(projectPath, platform, mode) {
let json;
let jsonPath;
if (process.env.UNI_OUTPUT_DIR) {
jsonPath = path.join(process.env.UNI_OUTPUT_DIR, `../.automator/${platform}`, AUTOMATOR_JSON_FILE);
json = tryRequire(jsonPath);
}
else {
jsonPath = path.join(projectPath, `dist/${mode}/.automator/${platform}`, AUTOMATOR_JSON_FILE);
json = tryRequire(jsonPath);
if (!json) {
jsonPath = path.join(projectPath, `unpackage/dist/${mode}/.automator/${platform}`, AUTOMATOR_JSON_FILE);
json = tryRequire(jsonPath);
}
}
debugPuppet(`${jsonPath}=>${JSON.stringify(json)}`);
return json;
}
function equalWsEndpoint(projectPath, port, platform, mode) {
const json = resolveAutomatorJson(projectPath, platform, mode);
if (!json || !json.wsEndpoint) {
return false;
}
const version = require("../package.json").version;
if (json.version !== version) {
debugPuppet(`unmet=>${json.version}!==${version}`);
return false;
}
const wsEndpoint = getWsEndpoint(port);
debugPuppet(`wsEndpoint=>${wsEndpoint}`);
return json.wsEndpoint === wsEndpoint;
}
class Puppet extends events.EventEmitter {
constructor(platform, target) {
super();
if (target) {
this.target = target;
}
else {
this.target = require(`@dcloudio/uni-${platform === "app" ? "app-plus" : platform}/lib/uni.automator.js`);
}
if (!this.target) {
throw Error("puppet is not provided");
}
this.platform = platform;
this.adapter = new Adapter(this.target.adapter || {});
}
setCompiler(compiler) {
this.compiler = compiler;
}
setRuntimeServer(wss) {
this.wss = wss;
}
setRemoteRuntimeConnectionCallback(callback) {
this.remoteRuntimeConnectionCallback = callback;
}
setRuntimeConnection(connection) {
this.runtimeConnection = connection;
if (this.remoteRuntimeConnectionCallback) {
this.remoteRuntimeConnectionCallback();
this.remoteRuntimeConnectionCallback = null;
}
}
setDevtoolConnection(connection) {
this.devtoolConnection = connection;
}
disposeRuntimeServer() {
this.wss && this.wss.close();
}
disposeRuntime() {
this.runtimeConnection.dispose();
}
disposeDevtool() {
this.compiler && this.compiler.stop();
this.devtoolConnection && this.devtoolConnection.dispose();
}
dispose() {
this.disposeRuntime();
this.disposeDevtool();
this.disposeRuntimeServer();
}
send(method, params) {
return this.runtimeConnection.send(method, params);
}
validateProject(projectPath) {
const required = this.target.devtools.required;
if (!required) {
return true;
}
return !required.find((file) => !fs.existsSync(path.join(projectPath, file)));
}
validateDevtools(opions) {
const validate = this.target.devtools.validate;
if (validate) {
return validate(opions, this);
}
return Promise.resolve(opions);
}
createDevtools(devtoolsProjectPath, options, timeout) {
const create = this.target.devtools.create;
if (create) {
options.timeout = timeout;
return create(devtoolsProjectPath, options, this);
}
return Promise.resolve();
}
shouldCompile(projectPath, port, options, devtoolsOptions) {
this.compiled = true;
const shouldCompile = this.target.shouldCompile;
if (shouldCompile) {
this.compiled = shouldCompile(options, devtoolsOptions);
}
else {
if (options.compile === true) {
this.compiled = true;
}
else {
//自动检测
this.compiled = !equalWsEndpoint(projectPath, port, this.platform, this.mode);
}
}
return this.compiled;
}
get checkProperty() {
return this.platform === "mp-weixin";
}
get devtools() {
return this.target.devtools;
}
get mode() {
const mode = this.target.mode;
if (mode) {
return mode;
}
return process.env.NODE_ENV === "production" ? "build" : "dev";
}
}
const debugCompiler = debug("automator:compiler");
const SIGNAL_DONE = "DONE Build complete";
const SIGNAL_DONE_H5 = "- Network";
const SIGNAL_DONE_VITE_H5 = "> Network";
const PATH_RE = /The\s+(.*)\s+directory is ready/;
class Compiler {
constructor(puppet) {
this.puppet = puppet;
this.puppet.setCompiler(this);
}
compile(options) {
const mode = this.puppet.mode;
const platform = this.puppet.platform;
let silent = options.silent;
const autoPort = options.port;
const autoHost = options.host;
const npmScript = `${mode}:${platform}`;
const projectPath = options.projectPath;
const [command, cliArgs] = this.getSpawnArgs(options, npmScript);
cliArgs.push("--auto-port");
cliArgs.push(toStr(autoPort));
if (autoHost) {
cliArgs.push("--auto-host");
cliArgs.push(autoHost);
}
const cliOptions = {
cwd: options.cliPath,
env: Object.assign(Object.assign({}, process.env), { NODE_ENV: mode === "build" ? "production" : "development" }),
};
return new Promise((resolve, reject) => {
const onError = (err) => {
reject(err);
};
const onStdoutData = (data) => {
const msg = data.toString().trim();
!silent && console.log(msg);
if (msg.includes(SIGNAL_DONE_H5) || msg.includes(SIGNAL_DONE_VITE_H5)) {
const networkUrl = msg.match(/Network:(.*)/)[1].trim();
// H5 DONE
debugCompiler(`url: ${networkUrl}`);
resolve({ path: networkUrl });
}
else if (msg.includes(SIGNAL_DONE)) {
const matches = msg.match(PATH_RE);
let outputDir = "";
if (matches && matches.length > 1) {
outputDir = path.join(projectPath, matches[1]);
}
else {
outputDir = path.join(projectPath, `dist/${mode}/${platform}`);
if (!fs.existsSync(outputDir)) {
outputDir = path.join(projectPath, `unpackage/dist/${mode}/${platform}`);
}
}
silent = true; // 编译已完成
this.stop();
resolve({
path: outputDir,
});
}
};
debugCompiler(`${command} ${cliArgs.join(" ")} %o`, cliOptions);
this.cliProcess = child_process.spawn(command, cliArgs, cliOptions);
this.cliProcess.on("error", onError);
this.cliProcess.stdout.on("data", onStdoutData);
this.cliProcess.stderr.on("data", onStdoutData);
});
}
stop() {
this.cliProcess && this.cliProcess.kill("SIGTERM");
}
getSpawnArgs(options, npmScript) {
let pkg;
const cliPath = options.cliPath;
try {
pkg = require(path.join(cliPath, "package.json"));
}
catch (e) { }
if (pkg && pkg.scripts && pkg.scripts[npmScript]) {
return [
process.env.UNI_NPM_PATH ||
(/^win/.test(process.platform) ? "npm.cmd" : "npm"),
["run", npmScript, "--"],
];
}
process.env.UNI_INPUT_DIR = options.projectPath;
process.env.UNI_OUTPUT_DIR = path.join(options.projectPath, `unpackage/dist/${this.puppet.mode}/${this.puppet.platform}`);
return [
process.env.UNI_NODE_PATH || "node",
[path.join(cliPath, "bin/uniapp-cli.js")],
];
}
}
const PORT = 9520;
const TIMEOUT = 6e4;
function exit(msg) {
throw Error(msg);
}
class Launcher {
async launch(options) {
let devtools = (options.platform === "app"
? options.app || options["app-plus"]
: options[options.platform]) || {};
this.puppet = new Puppet(options.platform, devtools.puppet);
// 1.校验参数
const { port, cliPath, timeout, projectPath } = await this.validate(options);
devtools = await this.puppet.validateDevtools(devtools);
// 2.编译
let shouldCompile = this.puppet.shouldCompile(projectPath, port, options, devtools);
let devtoolsProjectPath = process.env.UNI_OUTPUT_DIR || projectPath;
if (!shouldCompile) {
if (!this.puppet.validateProject(devtoolsProjectPath)) {
devtoolsProjectPath = path.join(projectPath, "dist/" + this.puppet.mode + "/" + this.puppet.platform);
if (!this.puppet.validateProject(devtoolsProjectPath)) {
devtoolsProjectPath = path.join(projectPath, "unpackage/dist/" + this.puppet.mode + "/" + this.puppet.platform);
if (!this.puppet.validateProject(devtoolsProjectPath)) {
shouldCompile = true;
}
}
}
}
if (shouldCompile) {
this.puppet.compiled = options.compile = true;
this.compiler = new Compiler(this.puppet);
const compilerResult = await this.compiler.compile({
host: options.host,
port,
cliPath,
projectPath,
silent: !!options.silent,
});
if (compilerResult.path) {
devtoolsProjectPath = compilerResult.path;
}
}
const promises = [];
// 3.runtime
promises.push(this.createRuntimeConnection(port, timeout));
// 4.devtool
promises.push(this.puppet.createDevtools(devtoolsProjectPath, devtools, timeout));
return new Promise((resolve, reject) => {
Promise.all(promises)
.then(([runtimeConnection, devtoolConnection]) => {
runtimeConnection &&
this.puppet.setRuntimeConnection(runtimeConnection);
devtoolConnection &&
this.puppet.setDevtoolConnection(devtoolConnection);
debug("automator:program")("ready");
const teardown = devtools.teardown || "disconnect";
resolve(new Program(this.puppet, { teardown, port }));
})
.catch((err) => reject(err));
});
}
resolveCliPath(cliPath) {
if (!cliPath) {
return cliPath;
}
try {
const { dependencies, devDependencies } = require(path.join(cliPath, "package.json"));
if (hasCliDeps(devDependencies) || hasCliDeps(dependencies)) {
return cliPath;
}
}
catch (e) { }
}
resolveProjectPath(projectPath, options) {
if (!projectPath) {
projectPath = process.env.UNI_INPUT_DIR || process.cwd();
}
if (isRelative(projectPath)) {
projectPath = path.resolve(projectPath);
}
if (!fs.existsSync(projectPath)) {
exit(`Project path ${projectPath} doesn't exist`);
}
return projectPath;
}
async validate(options) {
const projectPath = this.resolveProjectPath(options.projectPath, options);
let cliPath = process.env.UNI_CLI_PATH || options.cliPath;
cliPath = this.resolveCliPath(cliPath || "");
!cliPath && (cliPath = this.resolveCliPath(process.cwd()));
!cliPath && (cliPath = this.resolveCliPath(projectPath));
if (!cliPath) {
throw Error("cliPath is not provided");
}
const port = await resolvePort(options.port || PORT);
const timeout = options.timeout || TIMEOUT;
return {
port,
cliPath,
timeout,
projectPath,
};
}
async createRuntimeConnection(port, timeout) {
return Connection.createRuntimeConnection(port, this.puppet, timeout);
}
}
function hasCliDeps(deps) {
if (!deps) {
return false;
}
return !!(deps["@dcloudio/vue-cli-plugin-uni"] || deps["@dcloudio/vite-plugin-uni"]);
}
class Automator {
constructor() {
this.launcher = new Launcher();
}
// async connect(options: IConnectOptions) {
// return this.launcher.connect(options);
// }
async launch(options) {
return this.launcher.launch(options);
}
}
module.exports = Automator;
function D(t,e,n,s){var i,o=arguments.length,r=o<3?e:null===s?s=Object.getOwnPropertyDescriptor(e,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,n,s);else for(var a=t.length-1;a>=0;a--)(i=t[a])&&(r=(o<3?i(r):o>3?i(e,n,r):i(e,n))||r);return o>3&&r&&Object.defineProperty(e,n,r),r}var j;function A(t,e){const n=e.value;return e.value=async function(e){return(await(null==n?void 0:n.call(this,e)))(t)},e}function R(t,e,n){return A(j.RUNTIME,n)}function S(t,e,n){return A(j.DEVTOOL,n)}!function(t){t.RUNTIME="runtime",t.DEVTOOL="devtool"}(j||(j={}));class q{constructor(t){this.puppet=t}invoke(t,e){return async n=>this.puppet.devtoolConnection?(n===j.DEVTOOL?this.puppet.devtoolConnection:this.puppet.runtimeConnection).send(t,e):this.puppet.runtimeConnection.send(t,e)}on(t,e){this.puppet.on(t,e)}}class x extends q{constructor(t,e){super(t),this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId,this.videoId=e.videoId}async getData(t){return this.invokeMethod("Element.getData",t)}async setData(t){return this.invokeMethod("Element.setData",t)}async callMethod(t){return this.invokeMethod("Element.callMethod",t)}async getElement(t){return this.invokeMethod("Element.getElement",t)}async getElements(t){return this.invokeMethod("Element.getElements",t)}async getOffset(){return this.invokeMethod("Element.getOffset")}async getHTML(t){return this.invokeMethod("Element.getHTML",t)}async getAttributes(t){return this.invokeMethod("Element.getAttributes",t)}async getStyles(t){return this.invokeMethod("Element.getStyles",t)}async getDOMProperties(t){return this.invokeMethod("Element.getDOMProperties",t)}async getProperties(t){return this.invokeMethod("Element.getProperties",t)}async tap(){return this.invokeMethod("Element.tap")}async longpress(){return this.invokeMethod("Element.longpress")}async touchstart(t){return this.invokeMethod("Element.touchstart",t)}async touchmove(t){return this.invokeMethod("Element.touchmove",t)}async touchend(t){return this.invokeMethod("Element.touchend",t)}async triggerEvent(t){return this.invokeMethod("Element.triggerEvent",t)}async callFunction(t){return this.invokeMethod("Element.callFunction",t)}async callContextMethod(t){return this.invokeMethod("Element.callContextMethod",t)}invokeMethod(t,e={}){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.invoke(t,e)}}D([R],x.prototype,"getData",null),D([R],x.prototype,"setData",null),D([R],x.prototype,"callMethod",null),D([S],x.prototype,"getElement",null),D([S],x.prototype,"getElements",null),D([S],x.prototype,"getOffset",null),D([S],x.prototype,"getHTML",null),D([S],x.prototype,"getAttributes",null),D([S],x.prototype,"getStyles",null),D([S],x.prototype,"getDOMProperties",null),D([S],x.prototype,"getProperties",null),D([S],x.prototype,"tap",null),D([S],x.prototype,"longpress",null),D([S],x.prototype,"touchstart",null),D([S],x.prototype,"touchmove",null),D([S],x.prototype,"touchend",null),D([S],x.prototype,"triggerEvent",null),D([S],x.prototype,"callFunction",null),D([S],x.prototype,"callContextMethod",null);const N=require("util");class O{constructor(t,e,n){this.puppet=t,this.id=e.elementId,this.pageId=e.pageId,this.nodeId=e.nodeId||null,this.videoId=e.videoId||null,this.tagName=e.tagName,this.nvue=e.nvue,this.elementMap=n,"body"!==this.tagName&&"page-body"!==this.tagName||(this.tagName="page"),this.api=new x(t,e)}toJSON(){return JSON.stringify({id:this.id,tagName:this.tagName,pageId:this.pageId,nodeId:this.nodeId,videoId:this.videoId})}toString(){return this.toJSON()}[N.inspect.custom](){return this.toJSON()}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({},e,{pageId:this.pageId}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(t=>O.create(this.puppet,Object.assign({},t,{pageId:this.pageId}),this.elementMap))}async size(){const[t,e]=await this.domProperty(["offsetWidth","offsetHeight"]);return{width:t,height:e}}async offset(){const{left:t,top:e}=await this.api.getOffset();return{left:t,top:e}}async text(){return this.domProperty("innerText")}async attribute(t){if(!m(t))throw Error("name must be a string");return(await this.api.getAttributes({names:[t]})).attributes[0]}async value(){return this.property("value")}async property(t){if(!m(t))throw Error("name must be a string");if(this.puppet.checkProperty){let e=this.publicProps;if(e||(this.publicProps=e=await this._property("__propPublic")),!e[t])throw Error(`${this.tagName}.${t} not exists`)}return this._property(t)}async html(){return(await this.api.getHTML({type:"inner"})).html}async outerHtml(){return(await this.api.getHTML({type:"outer"})).html}async style(t){if(!m(t))throw Error("name must be a string");return(await this.api.getStyles({names:[t]})).styles[0]}async tap(){return this.api.tap()}async longpress(){return this.nvue?this.api.longpress():(await this.touchstart(),await v(350),this.touchend())}async trigger(t,e){const n={type:t};return w(e)||(n.detail=e),this.api.triggerEvent(n)}async touchstart(t){return this.api.touchstart(t)}async touchmove(t){return this.api.touchmove(t)}async touchend(t){return this.api.touchend(t)}async domProperty(t){return T(async t=>(await this.api.getDOMProperties({names:t})).properties,t)}_property(t){return T(async t=>(await this.api.getProperties({names:t})).properties,t)}send(t,e){return e.elementId=this.id,e.pageId=this.pageId,this.nodeId&&(e.nodeId=this.nodeId),this.videoId&&(e.videoId=this.videoId),this.puppet.send(t,e)}async callFunction(t,...e){return(await this.api.callFunction({functionName:t,args:e})).result}static create(t,e,n){let s,i=n.get(e.elementId);if(i)return i;if(e.nodeId)s=$;else switch(e.tagName){case"input":s=U;break;case"textarea":s=_;break;case"scroll-view":s=F;break;case"swiper":s=L;break;case"movable-view":s=H;break;case"switch":s=B;break;case"slider":s=J;break;case"video":s=W;break;default:s=O}return i=new s(t,e,n),n.set(e.elementId,i),i}}class $ extends O{async setData(t){return this.api.setData({data:t})}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}}class U extends O{async input(t){return this.callFunction("input.input",t)}}class _ extends O{async input(t){return this.callFunction("textarea.input",t)}}class F extends O{async scrollTo(t,e){return this.callFunction("scroll-view.scrollTo",t,e)}async property(t){return"scrollTop"===t?this.callFunction("scroll-view.scrollTop"):"scrollLeft"===t?this.callFunction("scroll-view.scrollLeft"):super.property(t)}async scrollWidth(){return this.callFunction("scroll-view.scrollWidth")}async scrollHeight(){return this.callFunction("scroll-view.scrollHeight")}}class L extends O{async swipeTo(t){return this.callFunction("swiper.swipeTo",t)}}class H extends O{async moveTo(t,e){return this.callFunction("movable-view.moveTo",t,e)}async property(t){return"x"===t?this._property("_translateX"):"y"===t?this._property("_translateY"):super.property(t)}}class B extends O{async tap(){return this.callFunction("switch.tap")}}class J extends O{async slideTo(t){return this.callFunction("slider.slideTo",t)}}class W extends O{async callContextMethod(t,...e){return await this.api.callContextMethod({method:t,args:e})}}class V extends q{constructor(t,e){super(t),this.id=e.id}async getData(t){return this.invokeMethod("Page.getData",t)}async setData(t){return this.invokeMethod("Page.setData",t)}async callMethod(t){return this.invokeMethod("Page.callMethod",t)}async getElement(t){return this.invokeMethod("Page.getElement",t)}async getElements(t){return this.invokeMethod("Page.getElements",t)}async getWindowProperties(t){return this.invokeMethod("Page.getWindowProperties",t)}invokeMethod(t,e={}){return e.pageId=this.id,this.invoke(t,e)}}D([R],V.prototype,"getData",null),D([R],V.prototype,"setData",null),D([R],V.prototype,"callMethod",null),D([S],V.prototype,"getElement",null),D([S],V.prototype,"getElements",null),D([S],V.prototype,"getWindowProperties",null);const z=require("util");class G{constructor(t,e){this.puppet=t,this.id=e.id,this.path=e.path,this.query=e.query,this.elementMap=new Map,this.api=new V(t,e)}toJSON(){return JSON.stringify({id:this.id,path:this.path,query:this.query})}toString(){return this.toJSON()}[z.inspect.custom](){return this.toJSON()}async waitFor(t){return y(t)?await v(t):h(t)?l(t):m(t)?l(async()=>(await this.$$(t)).length>0):void 0}async $(t){try{const e=await this.api.getElement({selector:t});return O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap)}catch(t){return null}}async $$(t){const{elements:e}=await this.api.getElements({selector:t});return e.map(e=>O.create(this.puppet,Object.assign({selector:t},e,{pageId:this.id}),this.elementMap))}async data(t){const e={};return t&&(e.path=t),(await this.api.getData(e)).data}async setData(t){return this.api.setData({data:t})}async size(){const[t,e]=await this.windowProperty(["document.documentElement.scrollWidth","document.documentElement.scrollHeight"]);return{width:t,height:e}}async callMethod(t,...e){return(await this.api.callMethod({method:t,args:e})).result}async scrollTop(){return this.windowProperty("document.documentElement.scrollTop")}async windowProperty(t){const e=m(t);e&&(t=[t]);const{properties:n}=await this.api.getWindowProperties({names:t});return e?n[0]:n}static create(t,e,n){let s=n.get(e.id);return s?(s.query=e.query,s):(s=new G(t,e),n.set(e.id,s),s)}}class X extends q{async getPageStack(){return this.invoke("App.getPageStack")}async callUniMethod(t){return this.invoke("App.callUniMethod",t)}async getCurrentPage(){return this.invoke("App.getCurrentPage")}async mockUniMethod(t){return this.invoke("App.mockUniMethod",t)}async callFunction(t){return this.invoke("App.callFunction",t)}async captureScreenshot(t){return this.invoke("App.captureScreenshot",t)}async exit(){return this.invoke("App.exit")}async addBinding(t){return this.invoke("App.addBinding",t)}async enableLog(){return this.invoke("App.enableLog")}onLogAdded(t){return this.on("App.logAdded",t)}onBindingCalled(t){return this.on("App.bindingCalled",t)}onExceptionThrown(t){return this.on("App.exceptionThrown",t)}}D([R],X.prototype,"getPageStack",null),D([R],X.prototype,"callUniMethod",null),D([R],X.prototype,"getCurrentPage",null),D([R],X.prototype,"mockUniMethod",null),D([S],X.prototype,"callFunction",null),D([S],X.prototype,"captureScreenshot",null),D([S],X.prototype,"exit",null),D([S],X.prototype,"addBinding",null),D([S],X.prototype,"enableLog",null);class Y extends q{async getInfo(){return this.invoke("Tool.getInfo")}async enableRemoteDebug(t){return this.invoke("Tool.enableRemoteDebug")}async close(){return this.invoke("Tool.close")}async getTestAccounts(){return this.invoke("Tool.getTestAccounts")}onRemoteDebugConnected(t){this.puppet.once("Tool.onRemoteDebugConnected",t),this.puppet.once("Tool.onPreviewConnected",t)}}function K(t){return new Promise(e=>setTimeout(e,t))}D([S],Y.prototype,"getInfo",null),D([S],Y.prototype,"enableRemoteDebug",null),D([S],Y.prototype,"close",null),D([S],Y.prototype,"getTestAccounts",null);class Q extends r.EventEmitter{constructor(t,e){super(),this.puppet=t,this.options=e,this.pageMap=new Map,this.appBindings=new Map,this.appApi=new X(t),this.toolApi=new Y(t),this.appApi.onLogAdded(t=>{this.emit("console",t)}),this.appApi.onBindingCalled(({name:t,args:e})=>{try{const n=this.appBindings.get(t);n&&n(...e)}catch(t){}}),this.appApi.onExceptionThrown(t=>{this.emit("exception",t)})}async pageStack(){return(await this.appApi.getPageStack()).pageStack.map(t=>G.create(this.puppet,t,this.pageMap))}async navigateTo(t){return this.changeRoute("navigateTo",t)}async redirectTo(t){return this.changeRoute("redirectTo",t)}async navigateBack(){return this.changeRoute("navigateBack")}async reLaunch(t){return this.changeRoute("reLaunch",t)}async switchTab(t){return this.changeRoute("switchTab",t)}async currentPage(){const{id:t,path:e,query:n}=await this.appApi.getCurrentPage();return G.create(this.puppet,{id:t,path:e,query:n},this.pageMap)}async systemInfo(){return this.callUniMethod("getSystemInfoSync")}async callUniMethod(t,...e){return(await this.appApi.callUniMethod({method:t,args:e})).result}async mockUniMethod(t,e,...n){return h(e)||m(s=e)&&(s=d(s),g(s,"function")||g(s,"() =>"))?this.appApi.mockUniMethod({method:t,functionDeclaration:e.toString(),args:n}):this.appApi.mockUniMethod({method:t,result:e});var s}async restoreUniMethod(t){return this.appApi.mockUniMethod({method:t})}async evaluate(t,...e){return(await this.appApi.callFunction({functionDeclaration:t.toString(),args:e})).result}async pageScrollTo(t){await this.callUniMethod("pageScrollTo",{scrollTop:t,duration:0})}async close(){try{await this.appApi.exit()}catch(t){}await K(1e3),this.puppet.disposeRuntimeServer(),await this.toolApi.close(),this.disconnect()}async teardown(){return this["disconnect"===this.options.teardown?"disconnect":"close"]()}async remote(t){if(!this.puppet.devtools.remote)return console.warn(`Failed to enable remote, ${this.puppet.devtools.name} is unimplemented`);const{qrCode:e}=await this.toolApi.enableRemoteDebug({auto:t});var n;e&&await(n=e,new Promise(t=>{C.generate(n,{small:!0},e=>{process.stdout.write(e),t(void 0)})}));const s=new Promise(t=>{this.toolApi.onRemoteDebugConnected(async()=>{await K(1e3),t(void 0)})}),i=new Promise(t=>{this.puppet.setRemoteRuntimeConnectionCallback(()=>{t(void 0)})});return Promise.all([s,i])}disconnect(){this.puppet.dispose()}on(t,e){return"console"===t&&this.appApi.enableLog(),super.on(t,e),this}async exposeFunction(t,e){if(this.appBindings.has(t))throw Error(`Failed to expose function with name ${t}: already exists!`);this.appBindings.set(t,e),await this.appApi.addBinding({name:t})}async checkVersion(){}async screenshot(t){const{data:e}=await this.appApi.captureScreenshot({fullPage:null==t?void 0:t.fullPage});if(!(null==t?void 0:t.path))return e;await u.writeFile(t.path,e,"base64")}async testAccounts(){return(await this.toolApi.getTestAccounts()).accounts}async changeRoute(t,e){return await this.callUniMethod(t,{url:e}),await K(3e3),this.currentPage()}}class Z{constructor(t){this.options=t}has(t){return!!this.options[t]}send(t,e,n){const s=this.options[e];if(!s)return Promise.reject(Error(`adapter for ${e} not found`));const i=s.reflect;return i?(s.params&&(n=s.params(n)),"function"==typeof i?i(t.send.bind(t),n):(e=i,t.send(e,n))):Promise.reject(Error(e+"'s reflect is required"))}}const tt=s("automator:puppet");function et(t){try{return require(t)}catch(t){}}function nt(t,e,s,i){const o=function(t,e,s){let i,o;return process.env.UNI_OUTPUT_DIR?(o=n.join(process.env.UNI_OUTPUT_DIR,"../.automator/"+e,".automator.json"),i=et(o)):(o=n.join(t,`dist/${s}/.automator/${e}`,".automator.json"),i=et(o),i||(o=n.join(t,`unpackage/dist/${s}/.automator/${e}`,".automator.json"),i=et(o))),tt(`${o}=>${JSON.stringify(i)}`),i}(t,s,i);if(!o||!o.wsEndpoint)return!1;const r=require("../package.json").version;if(o.version!==r)return tt(`unmet=>${o.version}!==${r}`),!1;const a=function(t){let e;try{const t=P.v4.sync();e=f.ip(t&&t.interface),e&&(/^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(e)||(e=void 0))}catch(t){}return"ws://"+(e||"localhost")+":"+t}(e);return tt("wsEndpoint=>"+a),o.wsEndpoint===a}class st extends r.EventEmitter{constructor(t,e){if(super(),e)this.target=e;else{if(this.target=null,"h5"===t)try{this.target=require("@dcloudio/uni-h5/lib/h5/uni.automator.js")}catch(t){}this.target||(this.target=require(`@dcloudio/uni-${"app"===t?"app-plus":t}/lib/uni.automator.js`))}if(!this.target)throw Error("puppet is not provided");this.platform=t,this.adapter=new Z(this.target.adapter||{})}setCompiler(t){this.compiler=t}setRuntimeServer(t){this.wss=t}setRemoteRuntimeConnectionCallback(t){this.remoteRuntimeConnectionCallback=t}setRuntimeConnection(t){this.runtimeConnection=t,this.remoteRuntimeConnectionCallback&&(this.remoteRuntimeConnectionCallback(),this.remoteRuntimeConnectionCallback=null)}setDevtoolConnection(t){this.devtoolConnection=t}disposeRuntimeServer(){this.wss&&this.wss.close()}disposeRuntime(){this.runtimeConnection.dispose()}disposeDevtool(){this.compiler&&this.compiler.stop(),this.devtoolConnection&&this.devtoolConnection.dispose()}dispose(){this.disposeRuntime(),this.disposeDevtool(),this.disposeRuntimeServer()}send(t,e){return this.runtimeConnection.send(t,e)}validateProject(t){const s=this.target.devtools.required;return!s||!s.find(s=>!e.existsSync(n.join(t,s)))}validateDevtools(t){const e=this.target.devtools.validate;return e?e(t,this):Promise.resolve(t)}createDevtools(t,e,n){const s=this.target.devtools.create;return s?(e.timeout=n,s(t,e,this)):Promise.resolve()}shouldCompile(t,e,n,s){this.compiled=!0;const i=this.target.shouldCompile;return i?this.compiled=i(n,s):!0===n.compile?this.compiled=!0:this.compiled=!nt(t,e,this.platform,this.mode),this.compiled}get checkProperty(){return"mp-weixin"===this.platform}get devtools(){return this.target.devtools}get mode(){const t=this.target.mode;return t||("production"===process.env.NODE_ENV?"build":"dev")}}const it=s("automator:compiler"),ot=/The\s+(.*)\s+directory is ready/;class rt{constructor(t){this.puppet=t,this.puppet.setCompiler(this)}compile(t){const s=this.puppet.mode,i=this.puppet.platform;let o=t.silent;const r=t.port,a=t.host,c=`${s}:${i}`,p=t.projectPath,[l,u]=this.getSpawnArgs(t,c);u.push("--auto-port"),u.push(E(r)),a&&(u.push("--auto-host"),u.push(a));const h={cwd:t.cliPath,env:Object.assign(Object.assign({},process.env),{NODE_ENV:"build"===s?"production":"development"})};return new Promise((t,r)=>{const a=r=>{const a=r.toString().trim();if(!o&&console.log(a),a.includes("- Network")||a.includes("> Network")){const e=a.match(/Network:(.*)/)[1].trim();it("url: "+e),t({path:e})}else if(a.includes("DONE Build complete")){const r=a.match(ot);let c="";r&&r.length>1?c=n.join(p,r[1]):(c=n.join(p,`dist/${s}/${i}`),e.existsSync(c)||(c=n.join(p,`unpackage/dist/${s}/${i}`))),o=!0,this.stop(),t({path:c})}};it(`${l} ${u.join(" ")} %o`,h),this.cliProcess=k.spawn(l,u,h),this.cliProcess.on("error",t=>{r(t)}),this.cliProcess.stdout.on("data",a),this.cliProcess.stderr.on("data",a)})}stop(){this.cliProcess&&this.cliProcess.kill("SIGTERM")}getSpawnArgs(t,e){let s;const i=t.cliPath;try{s=require(n.join(i,"package.json"))}catch(t){}return s&&s.scripts&&s.scripts[e]?[process.env.UNI_NPM_PATH||(/^win/.test(process.platform)?"npm.cmd":"npm"),["run",e,"--"]]:(process.env.UNI_INPUT_DIR=t.projectPath,process.env.UNI_OUTPUT_DIR=n.join(t.projectPath,`unpackage/dist/${this.puppet.mode}/${this.puppet.platform}`),[process.env.UNI_NODE_PATH||"node",[n.join(i,"bin/uniapp-cli.js")]])}}class at{async launch(t){let e=("app"===t.platform?t.app||t["app-plus"]:t[t.platform])||{};this.puppet=new st(t.platform,e.puppet);const{port:i,cliPath:o,timeout:r,projectPath:a}=await this.validate(t);e=await this.puppet.validateDevtools(e);let c=this.puppet.shouldCompile(a,i,t,e),p=process.env.UNI_OUTPUT_DIR||a;if(c||this.puppet.validateProject(p)||(p=n.join(a,"dist/"+this.puppet.mode+"/"+this.puppet.platform),this.puppet.validateProject(p)||(p=n.join(a,"unpackage/dist/"+this.puppet.mode+"/"+this.puppet.platform),this.puppet.validateProject(p)||(c=!0))),c){this.puppet.compiled=t.compile=!0,this.compiler=new rt(this.puppet);const e=await this.compiler.compile({host:t.host,port:i,cliPath:o,projectPath:a,silent:!!t.silent});e.path&&(p=e.path)}const l=[];return l.push(this.createRuntimeConnection(i,r)),l.push(this.puppet.createDevtools(p,e,r)),new Promise((t,n)=>{Promise.all(l).then(([n,o])=>{n&&this.puppet.setRuntimeConnection(n),o&&this.puppet.setDevtoolConnection(o),s("automator:program")("ready");const r=e.teardown||"disconnect";t(new Q(this.puppet,{teardown:r,port:i}))}).catch(t=>n(t))})}resolveCliPath(t){if(!t)return t;try{const{dependencies:e,devDependencies:s}=require(n.join(t,"package.json"));if(ct(s)||ct(e))return t}catch(t){}}resolveProjectPath(t,s){return t||(t=process.env.UNI_INPUT_DIR||process.cwd()),i(t)&&(t=n.resolve(t)),e.existsSync(t)||function(t){throw Error(t)}(`Project path ${t} doesn't exist`),t}async validate(t){const e=this.resolveProjectPath(t.projectPath,t);let n=process.env.UNI_CLI_PATH||t.cliPath;if(n=this.resolveCliPath(n||""),!n&&(n=this.resolveCliPath(process.cwd())),!n&&(n=this.resolveCliPath(e)),!n)throw Error("cliPath is not provided");return{port:await async function(t,e){const n=await M(t||e);if(t&&n!==t)throw Error(`Port ${t} is in use, please specify another port`);return n}(t.port||9520),cliPath:n,timeout:t.timeout||6e4,projectPath:e}}async createRuntimeConnection(t,e){return I.createRuntimeConnection(t,this.puppet,e)}}function ct(t){return!!t&&!(!t["@dcloudio/vue-cli-plugin-uni"]&&!t["@dcloudio/vite-plugin-uni"])}module.exports=class{constructor(){this.launcher=new at}async launch(t){return this.launcher.launch(t)}};
'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)},3e3)})};
function initPage(adapter) {
return {
'Page.getElement': function (params) {
return adapter.querySelector(
adapter.getDocument(params.pageId),
params.selector
)
},
'Page.getElements': function (params) {
return adapter.querySelectorAll(
adapter.getDocument(params.pageId),
params.selector
)
},
'Page.getWindowProperties': function (params) {
return adapter.queryProperties(
adapter.getWindow(params.pageId),
params.names
)
},
}
}
function initElement(adapter) {
var getEl = function (params) {
return adapter.getEl(params.elementId, params.pageId)
}
return {
'Element.getElement': function (params) {
return adapter.querySelector(getEl(params), params.selector)
},
'Element.getElements': function (params) {
return adapter.querySelectorAll(getEl(params), params.selector)
},
'Element.getDOMProperties': function (params) {
return adapter.queryProperties(getEl(params), params.names)
},
'Element.getProperties': function (params) {
var el = getEl(params)
var ctx = el.__vue__ || el.attr || {}
return adapter.queryProperties(ctx, params.names)
},
'Element.getOffset': function (params) {
return adapter.getOffset(getEl(params))
},
'Element.getAttributes': function (params) {
return adapter.queryAttributes(getEl(params), params.names)
},
'Element.getStyles': function (params) {
return adapter.queryStyles(getEl(params), params.names)
},
'Element.getHTML': function (params) {
return adapter.queryHTML(getEl(params), params.type)
},
'Element.tap': function (params) {
return adapter.dispatchTapEvent(getEl(params))
},
'Element.longpress': function (params) {
return adapter.dispatchLongpressEvent(getEl(params))
},
'Element.touchstart': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchstart', params)
},
'Element.touchmove': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchmove', params)
},
'Element.touchend': function (params) {
return adapter.dispatchTouchEvent(getEl(params), 'touchend', params)
},
'Element.callFunction': function (params) {
return adapter.callFunction(
getEl(params),
params.functionName,
params.args
)
},
'Element.triggerEvent': function (params) {
return adapter.triggerEvent(getEl(params), params.type, params.detail)
},
}
}
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
......@@ -94,419 +12,354 @@ MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++)
s += arguments[i].length
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j]
function e() {
for (var e = 0, t = 0, n = arguments.length; t < n; t++)
e += arguments[t].length
var r = Array(e),
o = 0
for (t = 0; t < n; t++)
for (var u = arguments[t], i = 0, a = u.length; i < a; i++, o++) r[o] = u[i]
return r
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
var getRandomValues =
(typeof crypto != 'undefined' &&
var t =
('undefined' != typeof crypto &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
(typeof msCrypto != 'undefined' &&
typeof msCrypto.getRandomValues == 'function' &&
msCrypto.getRandomValues.bind(msCrypto))
var rnds8 = new Uint8Array(16) // eslint-disable-line no-undef
function rng() {
if (!getRandomValues) {
('undefined' != typeof msCrypto &&
'function' == typeof msCrypto.getRandomValues &&
msCrypto.getRandomValues.bind(msCrypto)),
n = new Uint8Array(16)
function r() {
if (!t)
throw new Error(
'crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'
)
}
return getRandomValues(rnds8)
}
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = []
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1)
}
function bytesToUuid(buf, offset) {
var i = offset || 0
var bth = byteToHex // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
return t(n)
}
for (var o = [], u = 0; u < 256; ++u) o[u] = (u + 256).toString(16).substr(1)
function i(e, t, n) {
var u = (t && n) || 0
'string' == typeof e &&
((t = 'binary' === e ? new Array(16) : null), (e = null))
var i = (e = e || {}).random || (e.rng || r)()
if (((i[6] = (15 & i[6]) | 64), (i[8] = (63 & i[8]) | 128), t))
for (var a = 0; a < 16; ++a) t[u + a] = i[a]
return (
t ||
(function (e, t) {
var n = t || 0,
r = o
return [
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
'-',
bth[buf[i++]],
bth[buf[i++]],
r[e[n++]],
r[e[n++]],
'-',
bth[buf[i++]],
bth[buf[i++]],
r[e[n++]],
r[e[n++]],
'-',
bth[buf[i++]],
bth[buf[i++]],
r[e[n++]],
r[e[n++]],
'-',
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
bth[buf[i++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
r[e[n++]],
].join('')
}
function v4(options, buf, offset) {
var i = (buf && offset) || 0
if (typeof options == 'string') {
buf = options === 'binary' ? new Array(16) : null
options = null
}
options = options || {}
var rnds = options.random || (options.rng || rng)() // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40
rnds[8] = (rnds[8] & 0x3f) | 0x80 // Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii]
}
}
return buf || bytesToUuid(rnds)
}
var hasOwnProperty = Object.prototype.hasOwnProperty
var hasOwn = function (val, key) {
return hasOwnProperty.call(val, key)
}
var isUndef = function (v) {
return v === undefined || v === null
}
var isArray = Array.isArray
var isPromise = function (obj) {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
})(i)
)
}
var cacheStringFunction = function (fn) {
var cache = Object.create(null)
return function (str) {
var hit = cache[str]
return hit || (cache[str] = fn(str))
var a = Object.prototype.hasOwnProperty,
c = function (e) {
return null == e
},
s = Array.isArray,
f = function (e) {
var t = Object.create(null)
return function (n) {
return t[n] || (t[n] = e(n))
}
}
var camelizeRE = /-(\w)/g
var camelize = cacheStringFunction(function (str) {
return str.replace(camelizeRE, function (_, c) {
return c ? c.toUpperCase() : ''
},
l = /-(\w)/g,
g = f(function (e) {
return e.replace(l, function (e, t) {
return t ? t.toUpperCase() : ''
})
})
var capitalize = cacheStringFunction(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
})
var PATH_RE =
}),
p = f(function (e) {
return e.charAt(0).toUpperCase() + e.slice(1)
}),
d =
/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g
function getPaths(path, data) {
if (isArray(path)) {
return path
}
if (data && hasOwn(data, path)) {
return [path]
}
var res = []
path.replace(PATH_RE, function (match, p1, offset, string) {
res.push(offset ? string.replace(/\\(\\)?/g, '$1') : p1 || match)
return string
})
return res
}
function getDataByPath(data, path) {
var paths = getPaths(path, data)
var dataPath
for (dataPath = paths.shift(); !isUndef(dataPath); ) {
if (null == (data = data[dataPath])) {
return
}
dataPath = paths.shift()
}
return data
}
function getVmNodeId(vm) {
//@ts-ignore
{
return vm._uid
}
}
var elementMap = new Map()
function getElId(element) {
var elementId = element._id
if (!elementId) {
elementId = v4()
element._id = elementId
elementMap.set(elementId, { id: elementId, element: element })
}
return elementId
}
function isValidEl(el) {
if (el) {
var tagName = el.tagName
return tagName.indexOf('UNI-') === 0 || tagName === 'BODY'
}
return false
function m(e, t) {
if (s(e)) return e
if (t && ((n = t), (r = e), a.call(n, r))) return [e]
var n,
r,
o = []
return (
e.replace(d, function (e, t, n, r) {
return o.push(n ? r.replace(/\\(\\)?/g, '$1') : t || e), r
}),
o
)
}
function transEl(el) {
if (!isValidEl(el)) {
function v(e, t) {
var n,
r = m(t, e)
for (n = r.shift(); !c(n); ) {
if (null == (e = e[n])) return
n = r.shift()
}
return e
}
var h = new Map()
function _(e) {
if (
!(function (e) {
if (e) {
var t = e.tagName
return 0 === t.indexOf('UNI-') || 'BODY' === t
}
return !1
})(e)
)
throw Error('no such element')
}
var elem = {
elementId: getElId(el),
tagName: el.tagName.toLocaleLowerCase().replace('uni-', ''),
}
var vm = el.__vue__
if (vm) {
if (vm.$parent && vm.$parent.$el === el) {
vm = vm.$parent
}
if (vm && !vm.$options.isReserved) {
elem.nodeId = getVmNodeId(vm)
}
}
if (elem.tagName === 'video') {
elem.videoId = elem.nodeId
}
return elem
}
function formatHTML(html) {
return html
.replace(/\n/g, '')
.replace(
/(<uni-text[^>]*>)(<span[^>]*>[^<]*<\/span>)(.*?<\/uni-text>)/g,
'$1$3'
var t,
n,
r = {
elementId:
((t = e),
(n = t._id),
n || ((n = i()), (t._id = n), h.set(n, { id: n, element: t })),
n),
tagName: e.tagName.toLocaleLowerCase().replace('uni-', ''),
},
o = e.__vue__
return (
o &&
(o.$parent && o.$parent.$el === e && (o = o.$parent),
o &&
!o.$options.isReserved &&
(r.nodeId = (function (e) {
return e._uid
})(o))),
'video' === r.tagName && (r.videoId = r.nodeId),
r
)
.replace(/<\/?[^>]*>/g, function (replacement) {
if (-1 < replacement.indexOf('<body')) {
return '<page>'
} else if ('</body>' === replacement) {
return '</page>'
} else if (
0 !== replacement.indexOf('<uni-') &&
0 !== replacement.indexOf('</uni-')
) {
return ''
}
return replacement
.replace(/uni-/g, '')
.replace(/ role=""/g, '')
.replace(/ aria-label=""/g, '')
})
}
var FUNCTIONS = {
var y = {
input: {
input: function (el, value) {
var vm = el.__vue__
vm.valueSync = value
vm.$triggerInput({}, { value: value })
input: function (e, t) {
var n = e.__vue__
;(n.valueSync = t), n.$triggerInput({}, { value: t })
},
},
textarea: {
input: function (el, value) {
var vm = el.__vue__
vm.valueSync = value
vm.$triggerInput({}, { value: value })
input: function (e, t) {
var n = e.__vue__
;(n.valueSync = t), n.$triggerInput({}, { value: t })
},
},
'scroll-view': {
scrollTo: function (el, x, y) {
var main = el.__vue__.$refs.main
main.scrollLeft = x
main.scrollTop = y
scrollTo: function (e, t, n) {
var r = e.__vue__.$refs.main
;(r.scrollLeft = t), (r.scrollTop = n)
},
scrollTop: function (el) {
return el.__vue__.$refs.main.scrollTop
scrollTop: function (e) {
return e.__vue__.$refs.main.scrollTop
},
scrollLeft: function (el) {
return el.__vue__.$refs.main.scrollLeft
scrollLeft: function (e) {
return e.__vue__.$refs.main.scrollLeft
},
scrollWidth: function (el) {
return el.__vue__.$refs.main.scrollWidth
scrollWidth: function (e) {
return e.__vue__.$refs.main.scrollWidth
},
scrollHeight: function (el) {
return el.__vue__.$refs.main.scrollHeight
scrollHeight: function (e) {
return e.__vue__.$refs.main.scrollHeight
},
},
swiper: {
swipeTo: function (el, index) {
el.__vue__.current = index
swipeTo: function (e, t) {
e.__vue__.current = t
},
},
'movable-view': {
moveTo: function (el, x, y) {
el.__vue__._animationTo(x, y)
moveTo: function (e, t, n) {
e.__vue__._animationTo(t, n)
},
},
switch: {
tap: function (el) {
el.click()
tap: function (e) {
e.click()
},
},
slider: {
slideTo: function (el, value) {
var vm = el.__vue__
var slider = vm.$refs['uni-slider']
var offsetWidth = slider.offsetWidth
var boxLeft = slider.getBoundingClientRect().left
vm.value = value
vm._onClick({
x: ((value - vm.min) * offsetWidth) / (vm.max - vm.min) + boxLeft,
})
slideTo: function (e, t) {
var n = e.__vue__,
r = n.$refs['uni-slider'],
o = r.offsetWidth,
u = r.getBoundingClientRect().left
;(n.value = t),
n._onClick({ x: ((t - n.min) * o) / (n.max - n.min) + u })
},
},
}
var adapter = {
getWindow: function (pageId) {
},
E = {
getWindow: function (e) {
return window
},
getDocument: function (pageId) {
getDocument: function (e) {
return document
},
getEl: function (elementId) {
var element = elementMap.get(elementId)
if (!element) {
throw Error('element destroyed')
}
return element.element
getEl: function (e) {
var t = h.get(e)
if (!t) throw Error('element destroyed')
return t.element
},
getOffset: function (node) {
var rect = node.getBoundingClientRect()
getOffset: function (e) {
var t = e.getBoundingClientRect()
return Promise.resolve({
left: rect.left + window.pageXOffset,
top: rect.top + window.pageYOffset,
left: t.left + window.pageXOffset,
top: t.top + window.pageYOffset,
})
},
querySelector: function (context, selector) {
if (selector === 'page') {
//TODO h5平台?
selector = 'body'
}
return Promise.resolve(transEl(context.querySelector(selector)))
querySelector: function (e, t) {
return (
'page' === t && (t = 'body'), Promise.resolve(_(e.querySelector(t)))
)
},
querySelectorAll: function (context, selector) {
var elements = []
var nodeList = document.querySelectorAll(selector)
;[].forEach.call(nodeList, function (node) {
querySelectorAll: function (e, t) {
var n = [],
r = document.querySelectorAll(t)
return (
[].forEach.call(r, function (e) {
try {
elements.push(transEl(node))
n.push(_(e))
} catch (e) {}
})
return Promise.resolve({ elements: elements })
}),
Promise.resolve({ elements: n })
)
},
queryProperties: function (context, names) {
queryProperties: function (e, t) {
return Promise.resolve({
properties: names.map(function (name) {
var value = getDataByPath(context, name)
if (name === 'document.documentElement.scrollTop' && value === 0) {
value = getDataByPath(context, 'document.body.scrollTop')
}
return value
properties: t.map(function (t) {
var n = v(e, t)
return (
'document.documentElement.scrollTop' === t &&
0 === n &&
(n = v(e, 'document.body.scrollTop')),
n
)
}),
})
},
queryAttributes: function (context, names) {
queryAttributes: function (e, t) {
return Promise.resolve({
attributes: names.map(function (name) {
return String(context.getAttribute(name))
attributes: t.map(function (t) {
return String(e.getAttribute(t))
}),
})
},
queryStyles: function (context, names) {
var style = getComputedStyle(context)
queryStyles: function (e, t) {
var n = getComputedStyle(e)
return Promise.resolve({
styles: names.map(function (name) {
return style[name]
styles: t.map(function (e) {
return n[e]
}),
})
},
queryHTML: function (context, type) {
queryHTML: function (e, t) {
return Promise.resolve({
html: formatHTML(
type === 'outer' ? context.outerHTML : context.innerHTML
),
html:
((n = 'outer' === t ? e.outerHTML : e.innerHTML),
n
.replace(/\n/g, '')
.replace(
/(<uni-text[^>]*>)(<span[^>]*>[^<]*<\/span>)(.*?<\/uni-text>)/g,
'$1$3'
)
.replace(/<\/?[^>]*>/g, function (e) {
return -1 < e.indexOf('<body')
? '<page>'
: '</body>' === e
? '</page>'
: 0 !== e.indexOf('<uni-') && 0 !== e.indexOf('</uni-')
? ''
: e
.replace(/uni-/g, '')
.replace(/ role=""/g, '')
.replace(/ aria-label=""/g, '')
})),
})
var n
},
dispatchTapEvent: function (el) {
el.click()
return Promise.resolve()
dispatchTapEvent: function (e) {
return e.click(), Promise.resolve()
},
dispatchLongpressEvent: function (el) {
dispatchLongpressEvent: function (e) {
return Promise.resolve()
},
dispatchTouchEvent: function (el, type, eventInitDict) {
if (!eventInitDict) {
eventInitDict = {}
}
if (!eventInitDict.touches) {
eventInitDict.touches = []
}
if (!eventInitDict.changedTouches) {
eventInitDict.changedTouches = []
}
if (!eventInitDict.touches.length) {
eventInitDict.touches.push({
identifier: Date.now(),
target: el,
})
}
var touches = eventInitDict.touches.map(function (touch) {
return new Touch(touch)
})
var changedTouches = eventInitDict.changedTouches.map(function (touch) {
return new Touch(touch)
})
el.dispatchEvent(
new TouchEvent(type, {
cancelable: true,
bubbles: true,
touches: touches,
targetTouches: [],
changedTouches: changedTouches,
dispatchTouchEvent: function (e, t, n) {
n || (n = {}),
n.touches || (n.touches = []),
n.changedTouches || (n.changedTouches = []),
n.touches.length ||
n.touches.push({ identifier: Date.now(), target: e })
var r = T(n.touches),
o = T(n.changedTouches),
u = T([])
return (
e.dispatchEvent(
new TouchEvent(t, {
cancelable: !0,
bubbles: !0,
touches: r,
targetTouches: u,
changedTouches: o,
})
),
Promise.resolve()
)
return Promise.resolve()
},
callFunction: function (el, functionName, args) {
var fn = getDataByPath(FUNCTIONS, functionName)
if (!fn) {
return Promise.reject(Error(functionName + ' not exists'))
}
return Promise.resolve({
result: fn.apply(null, __spreadArrays([el], args)),
callFunction: function (t, n, r) {
var o = v(y, n)
return o
? Promise.resolve({ result: o.apply(null, e([t], r)) })
: Promise.reject(Error(n + ' not exists'))
},
triggerEvent: function (e, t, n) {
var r = e.__vue__
return r.$trigger && r.$trigger(t, {}, n), Promise.resolve()
},
}
function T(e) {
var t,
n = e.map(function (e) {
return (function (e) {
if (document.createTouch)
return document.createTouch(
window,
e.target,
e.identifier,
e.pageX,
e.pageY,
e.screenX,
e.screenY
)
return new Touch(e)
})(e)
})
},
triggerEvent: function (el, type, detail) {
var vm = el.__vue__
vm.$trigger && vm.$trigger(type, {}, detail)
return Promise.resolve()
},
return document.createTouchList
? (t = document).createTouchList.apply(t, n)
: n
}
var BUILITIN = [
;[
'movable-view',
'picker',
'ad',
......@@ -528,150 +381,187 @@ var BUILITIN = [
'swiper-item',
'swiper',
'switch',
]
var BUILITIN_ALIAS = BUILITIN.map(function (tag) {
return capitalize(camelize(tag))
})
function initWebApi() {
return Object.assign({}, initPage(adapter), initElement(adapter))
}
var Api = initWebApi()
function send(data) {
return UniViewJSBridge.publishHandler('onAutoMessageReceive', data)
}
UniViewJSBridge.subscribe('sendAutoMessage', function (_a) {
var id = _a.id,
method = _a.method,
params = _a.params
var data = { id: id }
var fn = Api[method]
if (!fn) {
data.error = {
message: method + ' unimplemented',
}
return send(data)
}
try {
fn(params)
.then(function (res) {
res && (data.result = res)
})
.catch(function (err) {
data.error = {
message: err.message,
}
})
.finally(function () {
send(data)
})
} catch (err) {
data.error = {
message: err.message,
}
send(data)
}
].map(function (e) {
return p(g(e))
})
function getPageId(page) {
if (page.__wxWebviewId__) {
//mp-weixin
return page.__wxWebviewId__
}
if (page.privateProperties) {
//mp-baidu
return page.privateProperties.slaveId
var S,
w = Object.assign(
{},
(function (e) {
return {
'Page.getElement': function (t) {
return e.querySelector(e.getDocument(t.pageId), t.selector)
},
'Page.getElements': function (t) {
return e.querySelectorAll(e.getDocument(t.pageId), t.selector)
},
'Page.getWindowProperties': function (t) {
return e.queryProperties(e.getWindow(t.pageId), t.names)
},
}
if (page.$page) {
//h5 and app-plus
return page.$page.id
})(E),
(function (e) {
var t = function (t) {
return e.getEl(t.elementId, t.pageId)
}
}
function getPagePath(page) {
return page.route || page.uri
}
function getPageQuery(page) {
return page.options || (page.$page && page.$page.options) || {}
}
function parsePage(page) {
return {
id: getPageId(page),
path: getPagePath(page),
query: getPageQuery(page),
'Element.getElement': function (n) {
return e.querySelector(t(n), n.selector)
},
'Element.getElements': function (n) {
return e.querySelectorAll(t(n), n.selector)
},
'Element.getDOMProperties': function (n) {
return e.queryProperties(t(n), n.names)
},
'Element.getProperties': function (n) {
var r = t(n),
o = r.__vue__ || r.attr || {}
return e.queryProperties(o, n.names)
},
'Element.getOffset': function (n) {
return e.getOffset(t(n))
},
'Element.getAttributes': function (n) {
return e.queryAttributes(t(n), n.names)
},
'Element.getStyles': function (n) {
return e.queryStyles(t(n), n.names)
},
'Element.getHTML': function (n) {
return e.queryHTML(t(n), n.type)
},
'Element.tap': function (n) {
return e.dispatchTapEvent(t(n))
},
'Element.longpress': function (n) {
return e.dispatchLongpressEvent(t(n))
},
'Element.touchstart': function (n) {
return e.dispatchTouchEvent(t(n), 'touchstart', n)
},
'Element.touchmove': function (n) {
return e.dispatchTouchEvent(t(n), 'touchmove', n)
},
'Element.touchend': function (n) {
return e.dispatchTouchEvent(t(n), 'touchend', n)
},
'Element.callFunction': function (n) {
return e.callFunction(t(n), n.functionName, n.args)
},
'Element.triggerEvent': function (n) {
return e.triggerEvent(t(n), n.type, n.detail)
},
}
})(E)
)
function P(e) {
return UniViewJSBridge.publishHandler('onAutoMessageReceive', e)
}
function getPageById(id) {
return getCurrentPages().find(function (page) {
return getPageId(page) === id
})
function b(e) {
return e.__wxWebviewId__
? e.__wxWebviewId__
: e.privateProperties
? e.privateProperties.slaveId
: e.$page
? e.$page.id
: void 0
}
function getPageVm(id) {
var page = getPageById(id)
return page && page.$vm
function O(e) {
return e.route || e.uri
}
function matchNodeId(vm, nodeId) {
//@ts-ignore
{
return vm._uid === nodeId
}
function I(e) {
return e.options || (e.$page && e.$page.options) || {}
}
function M(e) {
return { id: b(e), path: O(e), query: I(e) }
}
function findComponentVm(vm, nodeId) {
var res
if (vm) {
if (matchNodeId(vm, nodeId)) {
res = vm
} else {
vm.$children.find(function (child) {
res = findComponentVm(child, nodeId)
return res
function C(e) {
var t = (function (e) {
return getCurrentPages().find(function (t) {
return b(t) === e
})
}
}
return res
})(e)
return t && t.$vm
}
function getComponentVm(pageId, nodeId) {
var pageVm = getPageVm(pageId)
return pageVm && findComponentVm(pageVm, nodeId)
function $(e, t) {
var n = C(e)
return (
n &&
(function e(t, n) {
var r
return (
t &&
(!(function (e, t) {
return e._uid === t
})(t, n)
? t.$children.find(function (t) {
return (r = e(t, n))
})
: (r = t)),
r
)
})(n, t)
)
}
function getData(vm, path) {
var data
if (vm) {
data = path ? getDataByPath(vm.$data, path) : Object.assign({}, vm.$data)
}
return Promise.resolve({ data: data })
function x(e, t) {
var n
return (
e && (n = t ? v(e.$data, t) : Object.assign({}, e.$data)),
Promise.resolve({ data: n })
)
}
function setData(vm, data) {
if (vm) {
Object.keys(data).forEach(function (name) {
vm[name] = data[name]
})
}
return Promise.resolve()
function A(e, t) {
return (
e &&
Object.keys(t).forEach(function (n) {
e[n] = t[n]
}),
Promise.resolve()
)
}
var CALL_METHOD_ERROR
;(function (CALL_METHOD_ERROR) {
CALL_METHOD_ERROR['VM_NOT_EXISTS'] = 'VM_NOT_EXISTS'
CALL_METHOD_ERROR['METHOD_NOT_EXISTS'] = 'METHOD_NOT_EXISTS'
})(CALL_METHOD_ERROR || (CALL_METHOD_ERROR = {}))
function callMethod(vm, method, args) {
return new Promise(function (resolve, reject) {
if (!vm) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
if (!vm[method]) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
var ret = vm[method].apply(vm, args)
isPromise(ret)
? ret.then(function (res) {
resolve({ result: res })
function N(e, t, n) {
return new Promise(function (r, o) {
if (!e) return o(S.VM_NOT_EXISTS)
if (!e[t]) return o(S.VM_NOT_EXISTS)
var u,
i = e[t].apply(e, n)
!(u = i) ||
('object' != typeof u && 'function' != typeof u) ||
'function' != typeof u.then
? r({ result: i })
: i.then(function (e) {
r({ result: e })
})
})
}
UniViewJSBridge.subscribe('sendAutoMessage', function (e) {
var t = e.id,
n = e.method,
r = e.params,
o = { id: t },
u = w[n]
if (!u) return (o.error = { message: n + ' unimplemented' }), P(o)
try {
u(r)
.then(function (e) {
e && (o.result = e)
})
: resolve({ result: ret })
.catch(function (e) {
o.error = { message: e.message }
})
}
var SYNC_APIS = [
.finally(function () {
P(o)
})
} catch (e) {
;(o.error = { message: e.message }), P(o)
}
}),
(function (e) {
;(e.VM_NOT_EXISTS = 'VM_NOT_EXISTS'),
(e.METHOD_NOT_EXISTS = 'METHOD_NOT_EXISTS')
})(S || (S = {}))
var k = [
'stopRecord',
'getRecorderManager',
'pauseVoice',
......@@ -704,298 +594,214 @@ var SYNC_APIS = [
'stopPullDownRefresh',
'arrayBufferToBase64',
'base64ToArrayBuffer',
]
var originUni = {}
var SYNC_API_RE = /Sync$/
var MOCK_API_BLACKLIST_RE = /^on|^off/
function isSyncApi(method) {
return SYNC_API_RE.test(method) || SYNC_APIS.indexOf(method) !== -1
}
function canIMock(method) {
return !MOCK_API_BLACKLIST_RE.test(method)
}
var App = {
],
q = {},
L = /Sync$/,
V = /^on|^off/
function B(e) {
return L.test(e) || -1 !== k.indexOf(e)
}
var D = {
getPageStack: function () {
return Promise.resolve({
pageStack: getCurrentPages().map(function (page) {
return parsePage(page)
pageStack: getCurrentPages().map(function (e) {
return M(e)
}),
})
},
getCurrentPage: function () {
var pages = getCurrentPages()
var len = pages.length
return new Promise(function (resolve, reject) {
if (!len) {
reject(Error('getCurrentPages().length=0'))
} else {
resolve(parsePage(pages[len - 1]))
}
})
},
callUniMethod: function (params) {
var method = params.method
var args = params.args
return new Promise(function (resolve, reject) {
if (!uni[method]) {
return reject(Error('uni.' + method + ' not exists'))
}
if (isSyncApi(method)) {
return resolve({
result: uni[method].apply(uni, args),
})
}
var params = [
Object.assign({}, args[0] || {}, {
success: function (result) {
var timeout = method === 'pageScrollTo' ? 350 : 0
setTimeout(function () {
resolve({ result: result })
}, timeout)
var e = getCurrentPages(),
t = e.length
return new Promise(function (n, r) {
t ? n(M(e[t - 1])) : r(Error('getCurrentPages().length=0'))
})
},
callUniMethod: function (e) {
var t = e.method,
n = e.args
return new Promise(function (e, r) {
if (!uni[t]) return r(Error('uni.' + t + ' not exists'))
if (B(t)) return e({ result: uni[t].apply(uni, n) })
var o = [
Object.assign({}, n[0] || {}, {
success: function (n) {
setTimeout(
function () {
e({ result: n })
},
'pageScrollTo' === t ? 350 : 0
)
},
fail: function (res) {
reject(Error(res.errMsg.replace(method + ':fail ', '')))
fail: function (e) {
r(Error(e.errMsg.replace(t + ':fail ', '')))
},
}),
]
uni[method].apply(uni, params)
uni[t].apply(uni, o)
})
},
mockUniMethod: function (params) {
var method = params.method
if (!uni[method]) {
throw Error('uni.' + method + ' not exists')
}
if (!canIMock(method)) {
throw Error("You can't mock uni." + method)
}
// TODO getOwnPropertyDescriptor?
var result = params.result
if (isUndef(result)) {
// restoreUniMethod
if (originUni[method]) {
uni[method] = originUni[method]
delete originUni[method]
}
return Promise.resolve()
}
var mockFn = isSyncApi(method)
mockUniMethod: function (e) {
var t = e.method
if (!uni[t]) throw Error('uni.' + t + ' not exists')
if (
!(function (e) {
return !V.test(e)
})(t)
)
throw Error("You can't mock uni." + t)
var n = e.result
if (c(n)) return q[t] && ((uni[t] = q[t]), delete q[t]), Promise.resolve()
var r = B(t)
? function () {
return result
return n
}
: function (params) {
: function (e) {
setTimeout(function () {
var isFail = result.errMsg && result.errMsg.indexOf(':fail') !== -1
if (isFail) {
params.fail && params.fail(result)
} else {
params.success && params.success(result)
}
params.complete && params.complete(result)
n.errMsg && -1 !== n.errMsg.indexOf(':fail')
? e.fail && e.fail(n)
: e.success && e.success(n),
e.complete && e.complete(n)
}, 4)
}
// mockFn.origin = originUni[method] || uni[method];
if (!originUni[method]) {
originUni[method] = uni[method]
}
uni[method] = mockFn
return Promise.resolve()
return q[t] || (q[t] = uni[t]), (uni[t] = r), Promise.resolve()
},
}
var Page = {
getData: function (params) {
return getData(getPageVm(params.pageId), params.path)
},
setData: function (params) {
return setData(getPageVm(params.pageId), params.data)
},
callMethod: function (params) {
var _a
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Page[' + params.pageId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'page.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(getPageVm(params.pageId), params.method, params.args)
.then(function (res) {
return resolve(res)
},
R = {
getData: function (e) {
return x(C(e.pageId), e.path)
},
setData: function (e) {
return A(C(e.pageId), e.data)
},
callMethod: function (e) {
var t,
n =
(((t = {})[S.VM_NOT_EXISTS] = 'Page[' + e.pageId + '] not exists'),
(t[S.METHOD_NOT_EXISTS] = 'page.' + e.method + ' not exists'),
t)
return new Promise(function (t, r) {
N(C(e.pageId), e.method, e.args)
.then(function (e) {
return t(e)
})
.catch(function (type) {
reject(Error(err[type]))
.catch(function (e) {
r(Error(n[e]))
})
})
},
}
function j(e) {
return e.nodeId || e.elementId
}
function getNodeId(params) {
return params.nodeId || params.elementId
}
var Element = {
getData: function (params) {
return getData(
getComponentVm(params.pageId, getNodeId(params)),
params.path
)
var H = {
getData: function (e) {
return x($(e.pageId, j(e)), e.path)
},
setData: function (params) {
return setData(
getComponentVm(params.pageId, getNodeId(params)),
params.data
)
setData: function (e) {
return A($(e.pageId, j(e)), e.data)
},
callMethod: function (params) {
var _a
var nodeId = getNodeId(params)
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Component[' + params.pageId + ':' + nodeId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'component.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(
getComponentVm(params.pageId, nodeId),
params.method,
params.args
)
.then(function (res) {
return resolve(res)
callMethod: function (e) {
var t,
n = j(e),
r =
(((t = {})[S.VM_NOT_EXISTS] =
'Component[' + e.pageId + ':' + n + '] not exists'),
(t[S.METHOD_NOT_EXISTS] = 'component.' + e.method + ' not exists'),
t)
return new Promise(function (t, o) {
N($(e.pageId, n), e.method, e.args)
.then(function (e) {
return t(e)
})
.catch(function (type) {
reject(Error(err[type]))
.catch(function (e) {
o(Error(r[e]))
})
})
},
}
var Api$1 = {}
Object.keys(App).forEach(function (method) {
Api$1['App.' + method] = App[method]
})
Object.keys(Page).forEach(function (method) {
Api$1['Page.' + method] = Page[method]
})
Object.keys(Element).forEach(function (method) {
Api$1['Element.' + method] = Element[method]
})
var wsEndpoint = process.env.UNI_AUTOMATOR_WS_ENDPOINT
var fallback
var socketTask
//@ts-ignore
{
fallback = function (id, method, params, data) {
var pageId = params.pageId
var page = findPageByPageId(pageId)
if (!page) {
data.error = {
message: 'page[' + pageId + '] not exists',
}
send$1(data)
return true
}
var isNVue = !!page.$page.meta.isNVue
//@ts-ignore
{
UniServiceJSBridge.publishHandler(
'sendAutoMessage',
{
id: id,
method: method,
params: params,
},
pageId
)
return true
}
}
UniServiceJSBridge.subscribe('onAutoMessageReceive', function (res) {
send$1(res)
})
}
function send$1(data) {
socketTask.send({ data: JSON.stringify(data) })
}
function findPageByPageId(pageId) {
var pages = getCurrentPages()
if (!pageId) {
return pages[pages.length - 1]
}
return pages.find(function (page) {
return page.$page.id === pageId
})
}
function onMessage(res) {
var _a = JSON.parse(res.data),
id = _a.id,
method = _a.method,
params = _a.params
var data = { id: id }
var fn = Api$1[method]
if (!fn) {
if (fallback) {
var result = fallback(id, method, params, data)
if (result === true) {
return
}
fn = result
}
if (!fn) {
data.error = {
message: method + ' unimplemented',
}
return send$1(data)
}
U = {}
Object.keys(D).forEach(function (e) {
U['App.' + e] = D[e]
}),
Object.keys(R).forEach(function (e) {
U['Page.' + e] = R[e]
}),
Object.keys(H).forEach(function (e) {
U['Element.' + e] = H[e]
})
var X,
W,
J = process.env.UNI_AUTOMATOR_WS_ENDPOINT
function Y(e) {
W.send({ data: JSON.stringify(e) })
}
function F(e) {
var t = JSON.parse(e.data),
n = t.id,
r = t.method,
o = t.params,
u = { id: n },
i = U[r]
if (!i) {
if (X) {
var a = X(n, r, o, u)
if (!0 === a) return
i = a
}
if (!i) return (u.error = { message: r + ' unimplemented' }), Y(u)
}
try {
fn(params)
.then(function (res) {
res && (data.result = res)
i(o)
.then(function (e) {
e && (u.result = e)
})
.catch(function (err) {
data.error = {
message: err.message,
}
.catch(function (e) {
u.error = { message: e.message }
})
.finally(function () {
send$1(data)
Y(u)
})
} catch (err) {
data.error = {
message: err.message,
}
send$1(data)
} catch (e) {
;(u.error = { message: e.message }), Y(u)
}
}
function initRuntimeAutomator(options) {
if (options === void 0) {
options = {}
}
socketTask = uni.connectSocket({
url: wsEndpoint,
complete: function () {},
})
socketTask.onMessage(onMessage)
socketTask.onOpen(function (res) {
options.success && options.success()
console.log('已开启自动化测试...')
;(X = function (e, t, n, r) {
var o = n.pageId,
u = (function (e) {
var t = getCurrentPages()
if (!e) return t[t.length - 1]
return t.find(function (t) {
return t.$page.id === e
})
socketTask.onError(function (res) {
console.log('automator.onError', res)
})
socketTask.onClose(function () {
options.fail && options.fail({ errMsg: '$$initRuntimeAutomator:fail' })
})(o)
if (!u) return (r.error = { message: 'page[' + o + '] not exists' }), Y(r), !0
u.$page.meta.isNVue
return (
UniServiceJSBridge.publishHandler(
'sendAutoMessage',
{ id: e, method: t, params: n },
o
),
!0
)
}),
UniServiceJSBridge.subscribe('onAutoMessageReceive', function (e) {
Y(e)
}),
setTimeout(function () {
var e
void 0 === e && (e = {}),
(W = uni.connectSocket({ url: J, complete: function () {} })).onMessage(
F
),
W.onOpen(function (t) {
e.success && e.success(), console.log('已开启自动化测试...')
}),
W.onError(function (e) {
console.log('automator.onError', e)
}),
W.onClose(function () {
e.fail && e.fail({ errMsg: '$$initRuntimeAutomator:fail' }),
console.log('automator.onClose')
})
}
//@ts-ignore
{
setTimeout(function () {
// (global as any).testMessage = onMessage;
initRuntimeAutomator()
}, 500)
}
'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 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()],
})
}
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,
}),
o.on('pageerror', (e) => {
i.emit('App.exceptionThrown', e)
}),
await o.goto(s.url || r),
await o.waitFor(1e3)
},
options.options.defaultViewport || {}
)
if (!options.teardown) {
options.teardown =
options.options.headless === false ? 'disconnect' : 'close'
close: () => t.close(),
screenshot: (e = !1) =>
o.screenshot({ encoding: 'base64', fullPage: e }),
}
return options
})()
})(t)),
c.set(t, o)),
o
)
}
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(1e3)
},
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,
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)
},
shouldCompile(options, devtoolsOptions) {
if (devtoolsOptions.url) {
return false
}
return true
},
adapter,
shouldCompile: (e, t) => !t.url,
adapter: f,
}
module.exports = puppet
module.exports = h
var hasOwnProperty = Object.prototype.hasOwnProperty
var hasOwn = function (val, key) {
return hasOwnProperty.call(val, key)
}
var isUndef = function (v) {
return v === undefined || v === null
}
var isArray = Array.isArray
var isPromise = function (obj) {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
)
}
var cacheStringFunction = function (fn) {
var cache = Object.create(null)
return function (str) {
var hit = cache[str]
return hit || (cache[str] = fn(str))
}
}
var camelizeRE = /-(\w)/g
var camelize = cacheStringFunction(function (str) {
return str.replace(camelizeRE, function (_, c) {
return c ? c.toUpperCase() : ''
})
})
var capitalize = cacheStringFunction(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
})
var PATH_RE =
/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g
function getPaths(path, data) {
if (isArray(path)) {
return path
}
if (data && hasOwn(data, path)) {
return [path]
}
var res = []
path.replace(PATH_RE, function (match, p1, offset, string) {
res.push(offset ? string.replace(/\\(\\)?/g, '$1') : p1 || match)
return string
})
return res
}
function getDataByPath(data, path) {
var paths = getPaths(path, data)
var dataPath
for (dataPath = paths.shift(); !isUndef(dataPath); ) {
if (null == (data = data[dataPath])) {
return
}
dataPath = paths.shift()
}
return data
}
function getPageId(page) {
if (page.__wxWebviewId__) {
//mp-weixin
return page.__wxWebviewId__
}
if (page.privateProperties) {
//mp-baidu
return page.privateProperties.slaveId
}
if (page.$page) {
//h5 and app-plus
return page.$page.id
}
}
function getPagePath(page) {
return page.route || page.uri
}
function getPageQuery(page) {
return page.options || (page.$page && page.$page.options) || {}
}
function parsePage(page) {
return {
id: getPageId(page),
path: getPagePath(page),
query: getPageQuery(page),
}
}
function getPageById(id) {
return getCurrentPages().find(function (page) {
return getPageId(page) === id
})
}
function getPageVm(id) {
var page = getPageById(id)
return page && page.$vm
}
function getNodeId(scope) {
return scope.__wxExparserNodeId__ || scope.nodeId || scope.id
}
function matchNodeId(vm, nodeId) {
return vm.$scope && getNodeId(vm.$scope) === nodeId
}
function findComponentVm(vm, nodeId) {
var res
if (vm) {
if (matchNodeId(vm, nodeId)) {
res = vm
} else {
vm.$children.find(function (child) {
res = findComponentVm(child, nodeId)
return res
})
}
}
return res
}
function getComponentVm(pageId, nodeId) {
var pageVm = getPageVm(pageId)
return pageVm && findComponentVm(pageVm, nodeId)
}
function getData(vm, path) {
var data
if (vm) {
data = path ? getDataByPath(vm.$data, path) : Object.assign({}, vm.$data)
}
return Promise.resolve({ data: data })
}
function setData(vm, data) {
if (vm) {
Object.keys(data).forEach(function (name) {
vm[name] = data[name]
})
}
return Promise.resolve()
}
var CALL_METHOD_ERROR
;(function (CALL_METHOD_ERROR) {
CALL_METHOD_ERROR['VM_NOT_EXISTS'] = 'VM_NOT_EXISTS'
CALL_METHOD_ERROR['METHOD_NOT_EXISTS'] = 'METHOD_NOT_EXISTS'
})(CALL_METHOD_ERROR || (CALL_METHOD_ERROR = {}))
function callMethod(vm, method, args) {
return new Promise(function (resolve, reject) {
if (!vm) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
if (!vm[method]) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
var ret = vm[method].apply(vm, args)
isPromise(ret)
? ret.then(function (res) {
resolve({ result: res })
})
: resolve({ result: ret })
})
}
var SYNC_APIS = [
'stopRecord',
'getRecorderManager',
'pauseVoice',
'stopVoice',
'pauseBackgroundAudio',
'stopBackgroundAudio',
'getBackgroundAudioManager',
'createAudioContext',
'createInnerAudioContext',
'createVideoContext',
'createCameraContext',
'createMapContext',
'canIUse',
'startAccelerometer',
'stopAccelerometer',
'startCompass',
'stopCompass',
'hideToast',
'hideLoading',
'showNavigationBarLoading',
'hideNavigationBarLoading',
'navigateBack',
'createAnimation',
'pageScrollTo',
'createSelectorQuery',
'createCanvasContext',
'createContext',
'drawCanvas',
'hideKeyboard',
'stopPullDownRefresh',
'arrayBufferToBase64',
'base64ToArrayBuffer',
]
var originUni = {}
var SYNC_API_RE = /Sync$/
var MOCK_API_BLACKLIST_RE = /^on|^off/
function isSyncApi(method) {
return SYNC_API_RE.test(method) || SYNC_APIS.indexOf(method) !== -1
}
function canIMock(method) {
return !MOCK_API_BLACKLIST_RE.test(method)
}
var App = {
getPageStack: function () {
return Promise.resolve({
pageStack: getCurrentPages().map(function (page) {
return parsePage(page)
}),
})
},
getCurrentPage: function () {
var pages = getCurrentPages()
var len = pages.length
return new Promise(function (resolve, reject) {
if (!len) {
reject(Error('getCurrentPages().length=0'))
} else {
resolve(parsePage(pages[len - 1]))
}
})
},
callUniMethod: function (params) {
var method = params.method
var args = params.args
return new Promise(function (resolve, reject) {
if (!uni[method]) {
return reject(Error('uni.' + method + ' not exists'))
}
if (isSyncApi(method)) {
return resolve({
result: uni[method].apply(uni, args),
})
}
var params = [
Object.assign({}, args[0] || {}, {
success: function (result) {
var timeout = method === 'pageScrollTo' ? 350 : 0
setTimeout(function () {
resolve({ result: result })
}, timeout)
},
fail: function (res) {
reject(Error(res.errMsg.replace(method + ':fail ', '')))
},
}),
]
uni[method].apply(uni, params)
})
},
mockUniMethod: function (params) {
var method = params.method
if (!uni[method]) {
throw Error('uni.' + method + ' not exists')
}
if (!canIMock(method)) {
throw Error("You can't mock uni." + method)
}
// TODO getOwnPropertyDescriptor?
var result = params.result
if (isUndef(result)) {
// restoreUniMethod
if (originUni[method]) {
uni[method] = originUni[method]
delete originUni[method]
}
return Promise.resolve()
}
var mockFn = isSyncApi(method)
? function () {
return result
}
: function (params) {
setTimeout(function () {
var isFail = result.errMsg && result.errMsg.indexOf(':fail') !== -1
if (isFail) {
params.fail && params.fail(result)
} else {
params.success && params.success(result)
}
params.complete && params.complete(result)
}, 4)
}
// mockFn.origin = originUni[method] || uni[method];
if (!originUni[method]) {
originUni[method] = uni[method]
}
uni[method] = mockFn
return Promise.resolve()
},
}
var Page = {
getData: function (params) {
return getData(getPageVm(params.pageId), params.path)
},
setData: function (params) {
return setData(getPageVm(params.pageId), params.data)
},
callMethod: function (params) {
var _a
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Page[' + params.pageId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'page.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(getPageVm(params.pageId), params.method, params.args)
.then(function (res) {
return resolve(res)
})
.catch(function (type) {
reject(Error(err[type]))
})
})
},
}
function getNodeId$1(params) {
return params.nodeId || params.elementId
}
var Element = {
getData: function (params) {
return getData(
getComponentVm(params.pageId, getNodeId$1(params)),
params.path
)
},
setData: function (params) {
return setData(
getComponentVm(params.pageId, getNodeId$1(params)),
params.data
)
},
callMethod: function (params) {
var _a
var nodeId = getNodeId$1(params)
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Component[' + params.pageId + ':' + nodeId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'component.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(
getComponentVm(params.pageId, nodeId),
params.method,
params.args
)
.then(function (res) {
return resolve(res)
})
.catch(function (type) {
reject(Error(err[type]))
})
})
},
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
var getRandomValues =
(typeof crypto != 'undefined' &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
(typeof msCrypto != 'undefined' &&
typeof msCrypto.getRandomValues == 'function' &&
msCrypto.getRandomValues.bind(msCrypto))
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = []
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1)
}
var BUILITIN = [
'movable-view',
'picker',
'ad',
'button',
'checkbox-group',
'checkbox',
'form',
'icon',
'label',
'movable-area',
'navigator',
'picker-view-column',
'picker-view',
'progress',
'radio-group',
'radio',
'rich-text',
'u-slider',
'swiper-item',
'swiper',
'switch',
]
var BUILITIN_ALIAS = BUILITIN.map(function (tag) {
return capitalize(camelize(tag))
})
var Api = {}
Object.keys(App).forEach(function (method) {
Api['App.' + method] = App[method]
})
Object.keys(Page).forEach(function (method) {
Api['Page.' + method] = Page[method]
})
Object.keys(Element).forEach(function (method) {
Api['Element.' + method] = Element[method]
})
var wsEndpoint = process.env.UNI_AUTOMATOR_WS_ENDPOINT
var socketTask
function send(data) {
socketTask.send({ data: JSON.stringify(data) })
}
function onMessage(res) {
var _a = JSON.parse(res.data),
id = _a.id,
method = _a.method,
params = _a.params
var data = { id: id }
var fn = Api[method]
if (!fn) {
if (!fn) {
data.error = {
message: method + ' unimplemented',
}
return send(data)
}
}
try {
fn(params)
.then(function (res) {
res && (data.result = res)
})
.catch(function (err) {
data.error = {
message: err.message,
}
})
.finally(function () {
send(data)
})
} catch (err) {
data.error = {
message: err.message,
}
send(data)
}
}
function initRuntimeAutomator(options) {
if (options === void 0) {
options = {}
}
socketTask = uni.connectSocket({
url: wsEndpoint,
complete: function () {},
})
socketTask.onMessage(onMessage)
socketTask.onOpen(function (res) {
options.success && options.success()
console.log('已开启自动化测试...')
})
socketTask.onError(function (res) {
console.log('automator.onError', res)
})
socketTask.onClose(function () {
options.fail && options.fail({ errMsg: '$$initRuntimeAutomator:fail' })
console.log('automator.onClose')
})
}
//@ts-ignore
{
//@ts-ignore
swan.$$initRuntimeAutomator = initRuntimeAutomator
setTimeout(function () {
//@ts-ignore
swan.$$initRuntimeAutomator()
}, 500)
}
var e,t=Object.prototype.hasOwnProperty,n=function(e){return null==e},r=Array.isArray,o=function(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}},a=/-(\w)/g,i=o((function(e){return e.replace(a,(function(e,t){return t?t.toUpperCase():""}))})),u=o((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),c=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;function s(e,n){if(r(e))return e;if(n&&(o=n,a=e,t.call(o,a)))return[e];var o,a,i=[];return e.replace(c,(function(e,t,n,r){return i.push(n?r.replace(/\\(\\)?/g,"$1"):t||e),r})),i}function f(e){return e.__wxWebviewId__?e.__wxWebviewId__:e.privateProperties?e.privateProperties.slaveId:e.$page?e.$page.id:void 0}function p(e){return e.route||e.uri}function d(e){return e.options||e.$page&&e.$page.options||{}}function l(e){return{id:f(e),path:p(e),query:d(e)}}function g(e){var t=function(e){return getCurrentPages().find((function(t){return f(t)===e}))}(e);return t&&t.$vm}function m(e,t){var n=g(e);return n&&function e(t,n){var r;return t&&(!function(e,t){return e.$scope&&((n=e.$scope).__wxExparserNodeId__||n.nodeId||n.id)===t;var n}(t,n)?t.$children.find((function(t){return r=e(t,n)})):r=t),r}(n,t)}function v(e,t){var r;return e&&(r=t?function(e,t){var r,o=s(t,e);for(r=o.shift();!n(r);){if(null==(e=e[r]))return;r=o.shift()}return e}(e.$data,t):Object.assign({},e.$data)),Promise.resolve({data:r})}function h(e,t){return e&&Object.keys(t).forEach((function(n){e[n]=t[n]})),Promise.resolve()}function T(t,n,r){return new Promise((function(o,a){if(!t)return a(e.VM_NOT_EXISTS);if(!t[n])return a(e.VM_NOT_EXISTS);var i,u=t[n].apply(t,r);!(i=u)||"object"!=typeof i&&"function"!=typeof i||"function"!=typeof i.then?o({result:u}):u.then((function(e){o({result:e})}))}))}!function(e){e.VM_NOT_EXISTS="VM_NOT_EXISTS",e.METHOD_NOT_EXISTS="METHOD_NOT_EXISTS"}(e||(e={}));var _=["stopRecord","getRecorderManager","pauseVoice","stopVoice","pauseBackgroundAudio","stopBackgroundAudio","getBackgroundAudioManager","createAudioContext","createInnerAudioContext","createVideoContext","createCameraContext","createMapContext","canIUse","startAccelerometer","stopAccelerometer","startCompass","stopCompass","hideToast","hideLoading","showNavigationBarLoading","hideNavigationBarLoading","navigateBack","createAnimation","pageScrollTo","createSelectorQuery","createCanvasContext","createContext","drawCanvas","hideKeyboard","stopPullDownRefresh","arrayBufferToBase64","base64ToArrayBuffer"],y={},O=/Sync$/,S=/^on|^off/;function E(e){return O.test(e)||-1!==_.indexOf(e)}var I={getPageStack:function(){return Promise.resolve({pageStack:getCurrentPages().map((function(e){return l(e)}))})},getCurrentPage:function(){var e=getCurrentPages(),t=e.length;return new Promise((function(n,r){t?n(l(e[t-1])):r(Error("getCurrentPages().length=0"))}))},callUniMethod:function(e){var t=e.method,n=e.args;return new Promise((function(e,r){if(!uni[t])return r(Error("uni."+t+" not exists"));if(E(t))return e({result:uni[t].apply(uni,n)});var o=[Object.assign({},n[0]||{},{success:function(n){setTimeout((function(){e({result:n})}),"pageScrollTo"===t?350:0)},fail:function(e){r(Error(e.errMsg.replace(t+":fail ","")))}})];uni[t].apply(uni,o)}))},mockUniMethod:function(e){var t=e.method;if(!uni[t])throw Error("uni."+t+" not exists");if(!function(e){return!S.test(e)}(t))throw Error("You can't mock uni."+t);var r=e.result;if(n(r))return y[t]&&(uni[t]=y[t],delete y[t]),Promise.resolve();var o=E(t)?function(){return r}:function(e){setTimeout((function(){r.errMsg&&-1!==r.errMsg.indexOf(":fail")?e.fail&&e.fail(r):e.success&&e.success(r),e.complete&&e.complete(r)}),4)};return y[t]||(y[t]=uni[t]),uni[t]=o,Promise.resolve()}},C={getData:function(e){return v(g(e.pageId),e.path)},setData:function(e){return h(g(e.pageId),e.data)},callMethod:function(t){var n,r=((n={})[e.VM_NOT_EXISTS]="Page["+t.pageId+"] not exists",n[e.METHOD_NOT_EXISTS]="page."+t.method+" not exists",n);return new Promise((function(e,n){T(g(t.pageId),t.method,t.args).then((function(t){return e(t)})).catch((function(e){n(Error(r[e]))}))}))}};function w(e){return e.nodeId||e.elementId}for(var M={getData:function(e){return v(m(e.pageId,w(e)),e.path)},setData:function(e){return h(m(e.pageId,w(e)),e.data)},callMethod:function(t){var n,r=w(t),o=((n={})[e.VM_NOT_EXISTS]="Component["+t.pageId+":"+r+"] not exists",n[e.METHOD_NOT_EXISTS]="component."+t.method+" not exists",n);return new Promise((function(e,n){T(m(t.pageId,r),t.method,t.args).then((function(t){return e(t)})).catch((function(e){n(Error(o[e]))}))}))}},P=("undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),[]),b=0;b<256;++b)P[b]=(b+256).toString(16).substr(1);["movable-view","picker","ad","button","checkbox-group","checkbox","form","icon","label","movable-area","navigator","picker-view-column","picker-view","progress","radio-group","radio","rich-text","u-slider","swiper-item","swiper","switch"].map((function(e){return u(i(e))}));var x={};Object.keys(I).forEach((function(e){x["App."+e]=I[e]})),Object.keys(C).forEach((function(e){x["Page."+e]=C[e]})),Object.keys(M).forEach((function(e){x["Element."+e]=M[e]}));var $,k=process.env.UNI_AUTOMATOR_WS_ENDPOINT;function A(e){$.send({data:JSON.stringify(e)})}function N(e){var t=JSON.parse(e.data),n=t.id,r=t.method,o=t.params,a={id:n},i=x[r];if(!i&&!i)return a.error={message:r+" unimplemented"},A(a);try{i(o).then((function(e){e&&(a.result=e)})).catch((function(e){a.error={message:e.message}})).finally((function(){A(a)}))}catch(e){a.error={message:e.message},A(a)}}swan.$$initRuntimeAutomator=function(e){void 0===e&&(e={}),($=uni.connectSocket({url:k,complete:function(){}})).onMessage(N),$.onOpen((function(t){e.success&&e.success(),console.log("已开启自动化测试...")})),$.onError((function(e){console.log("automator.onError",e)})),$.onClose((function(){e.fail&&e.fail({errMsg:"$$initRuntimeAutomator:fail"}),console.log("automator.onClose")}))},setTimeout((function(){swan.$$initRuntimeAutomator()}),500);
'use strict'
function _interopDefault(ex) {
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex
}
var os = _interopDefault(require('os'))
var path = _interopDefault(require('path'))
var debug = _interopDefault(require('debug'))
var isWindows = _interopDefault(require('licia/isWindows'))
var fs = _interopDefault(require('fs'))
var child_process = _interopDefault(require('child_process'))
var sleep = _interopDefault(require('licia/sleep'))
var toStr = _interopDefault(require('licia/toStr'))
var waitUntil = _interopDefault(require('licia/waitUntil'))
var concat = _interopDefault(require('licia/concat'))
var getPort = _interopDefault(require('licia/getPort'))
var dateFormat = _interopDefault(require('licia/dateFormat'))
require('address')
require('default-gateway')
require('licia/isStr')
var WebSocket = _interopDefault(require('ws'))
var events = require('events')
var uuid = _interopDefault(require('licia/uuid'))
var stringify = _interopDefault(require('licia/stringify'))
const TAGNAME_REGEX = /(^[a-z][a-z0-9-]*)/i
const NAVIGATOR_SELECTOR_REGEX = /^navigator/i
const NAVIGATOR_TAGNAME_REGEX = /^swan-nav$/i
var TYPES
;(function (TYPES) {
TYPES['SELECTOR'] = 'selector'
TYPES['TAGNAME'] = 'tagName'
})(TYPES || (TYPES = {}))
const argsProcessors = {
[TYPES.SELECTOR]: [
{
test: NAVIGATOR_SELECTOR_REGEX,
processor: (str) => str.replace(NAVIGATOR_SELECTOR_REGEX, 'nav'),
},
{
test: TAGNAME_REGEX,
processor: (str) => `swan-${str}`,
},
],
[TYPES.TAGNAME]: [
{
test: NAVIGATOR_TAGNAME_REGEX,
processor: (str) =>
str.replace(NAVIGATOR_TAGNAME_REGEX, 'swan-navigator'),
},
{
test: TAGNAME_REGEX,
processor: (str) => str.toLocaleLowerCase().replace('swan-', ''),
},
],
}
const getProcess = (arg) => {
return (str) => {
const processors = (argsProcessors[arg] || []).filter((processor) =>
processor.test.test(str)
)
for (const processor of processors) {
str = processor.processor(str)
}
return str
}
}
const processSingleSelector = getProcess(TYPES.SELECTOR)
const processTagName = getProcess(TYPES.TAGNAME)
const processSelector = (selector) =>
selector
.split(' ')
.map((selector) => processSingleSelector(selector))
.join(' ')
const addElementId = (params) =>
Object.assign({}, params, {
type: 'id',
info: {
id: params.elementId,
},
})
const qrCodeTerminal = require('qrcode-terminal')
const QrCodeReader = require('qrcode-reader')
const isWin = /^win/.test(process.platform)
async function resolvePort(port, defaultPort) {
const newPort = await getPort(port || defaultPort)
if (port && newPort !== port) {
throw Error(`Port ${port} is in use, please specify another port`)
}
return newPort
}
class Transport extends events.EventEmitter {
constructor(ws) {
super()
this.ws = ws
this.ws.addEventListener('message', (event) => {
this.emit('message', event.data)
})
this.ws.addEventListener('close', () => {
this.emit('close')
})
}
send(message) {
this.ws.send(message)
}
close() {
this.ws.close()
}
}
const CLOSE_ERR_TIP = 'Connection closed'
class Connection extends events.EventEmitter {
constructor(transport, puppet, namespace) {
super()
this.puppet = puppet
this.namespace = namespace
this.callbacks = new Map()
this.transport = transport
this.debug = debug('automator:protocol:' + this.namespace)
this.onMessage = (msg) => {
this.debug(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} ◀ RECV ${msg}`)
const { id, method, error, result, params } = JSON.parse(msg)
if (!id) {
return this.puppet.emit(method, params)
}
const { callbacks } = this
if (id && callbacks.has(id)) {
const promise = callbacks.get(id)
callbacks.delete(id)
error ? promise.reject(Error(error.message)) : promise.resolve(result)
}
}
this.onClose = () => {
this.callbacks.forEach((promise) => {
promise.reject(Error(CLOSE_ERR_TIP))
})
}
this.transport.on('message', this.onMessage)
this.transport.on('close', this.onClose)
}
send(method, params = {}, reflect = true) {
if (reflect && this.puppet.adapter.has(method)) {
return this.puppet.adapter.send(this, method, params)
}
const id = uuid()
const data = stringify({
id,
method,
params,
})
this.debug(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} SEND ► ${data}`)
return new Promise((resolve, reject) => {
try {
this.transport.send(data)
} catch (e) {
reject(Error(CLOSE_ERR_TIP))
}
this.callbacks.set(id, {
resolve,
reject,
})
})
}
dispose() {
this.transport.close()
}
static createDevtoolConnection(url, puppet) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(url)
ws.addEventListener('open', () => {
resolve(new Connection(new Transport(ws), puppet, 'devtool'))
})
ws.addEventListener('error', reject)
})
}
static createRuntimeConnection(port, puppet, timeout) {
return new Promise((resolve, reject) => {
debug('automator:runtime')(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} port=${port}`
)
const wss = new WebSocket.Server({
port,
})
waitUntil(
async () => {
if (puppet.runtimeConnection) {
return true
}
},
timeout,
1e3
).catch(() => {
wss.close()
reject(
'Failed to connect to runtime, please make sure the project is running'
)
})
wss.on('connection', function connection(ws) {
debug('automator:runtime')(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} connected`
)
const connection = new Connection(new Transport(ws), puppet, 'runtime')
// 可能会被重新连接,刷新成最新的
puppet.setRuntimeConnection(connection)
resolve(connection)
})
puppet.setRuntimeServer(wss)
})
}
}
const debugDevtools = debug('automator:devtool')
function resolveDevtoolsPath(cliPath, puppet) {
const paths = puppet.devtools.paths.slice(0)
if (cliPath) {
paths.unshift(cliPath)
}
for (const cliPath of paths) {
if (fs.existsSync(cliPath)) {
return cliPath
}
}
throw Error(
`${puppet.devtools.name} not found, please specify executablePath option`
)
}
async function validateDevtools(options, puppet) {
const cliPath = resolveDevtoolsPath(options.executablePath, puppet)
let port = options.port || puppet.devtools.defaultPort
if (options.launch !== false) {
try {
port = await resolvePort(port)
} catch (e) {
// console.log(`Port ${port} is in use, try to connect directly`);
options.launch = false
}
} else {
const newPort = await getPort(port)
if (port === newPort) {
options.launch = true
// console.log(`try to launch ${this.puppet.devtools.name}`);
}
}
return Object.assign(Object.assign({}, options), { port, cliPath })
}
async function connectTool(options, puppet) {
let connection
try {
connection = await Connection.createDevtoolConnection(
options.wsEndpoint,
puppet
)
} catch (e) {
throw Error(
`Failed connecting to ${options.wsEndpoint}, check if target project window is opened with automation enabled`
)
}
return connection
}
async function createDevtools(projectPath, options, puppet) {
const {
port,
cliPath,
timeout,
cwd = '',
account = '',
args = [],
launch = true,
} = options
let launchFailed = false
let connectFailed = false
if (launch !== false) {
const spawnOptions = {
stdio: 'ignore',
}
cwd && (spawnOptions.cwd = cwd)
let spawnArgs = concat(args, [])
//@ts-ignore
{
spawnArgs = concat(spawnArgs, ['--auto'])
}
spawnArgs = concat(spawnArgs, [projectPath, '--auto-port', toStr(port)])
account && (spawnArgs = concat(spawnArgs, ['--auto-account', account]))
try {
debugDevtools('%s %o %o', cliPath, spawnArgs, spawnOptions)
const cliProcess = child_process.spawn(cliPath, spawnArgs, spawnOptions)
cliProcess.on('error', (err) => {
launchFailed = true
})
cliProcess.on('exit', () => {
setTimeout(() => {
connectFailed = true
}, 15e3)
})
// TODO unref?
cliProcess.unref()
} catch (err) {
launchFailed = false
}
} else {
setTimeout(() => {
connectFailed = true
}, 15e3)
}
const connection = await waitUntil(
async () => {
try {
if (launchFailed || connectFailed) {
return true
}
const connection = await connectTool(
{ wsEndpoint: `ws://127.0.0.1:${port}` },
puppet
)
return connection
} catch (err) {}
},
timeout,
1e3
)
if (launchFailed) {
throw Error(
`Failed to launch ${puppet.devtools.name}, please make sure cliPath is correctly specified`
)
}
if (connectFailed) {
throw Error(
`Failed to launch ${puppet.devtools.name} , please make sure http port is open`
)
}
await sleep(5e3)
debugDevtools(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} connected`)
return connection
}
const paths = []
;['', '-rc'].forEach((v) => {
if (isWindows) {
paths.push(
path.join(os.homedir(), `AppData/Local/Programs/swan-ide-gui${v}/cli.bat`)
)
paths.push(`C:/Program Files/swan-ide-gui${v}/cli.bat`)
} else {
paths.push(`/Applications/百度开发者工具${v}.app/Contents/MacOS/cli`)
}
})
const puppet = {
devtools: {
name: 'Baidu DevTools',
remote: true,
automator: true,
paths,
required: ['project.swan.json', 'app.json', 'app.js'],
defaultPort: 9430,
validate: validateDevtools,
async create(projectPath, options, puppet) {
const connection = await createDevtools(projectPath, options, puppet)
if (!puppet.compiled) {
debug('automator:devtool')('initRuntimeAutomator')
connection.send('smartapp.swan', {
api: '$$initRuntimeAutomator',
params: [],
})
} else {
debug('automator:devtool')('Waiting for runtime automator')
}
return connection
},
},
adapter: {
'Tool.enableRemoteDebug': {
reflect: async (send) => {
return { qrCode: (await send('Tool.enablePreview')).url }
},
},
'App.exit': {
reflect: async () => Promise.resolve(),
},
// "App.callUniMethod": {
// reflect: "smartapp.swan",
// params: (params) =>
// Object.assign(
// {
// api: params.method,
// params: params.args,
// },
// params
// ),
// },
'Page.getElement': {
reflect: async (send, params) => {
return (await send('Page.getElements', params)).elements[0]
},
},
'Page.getElements': {
reflect: async (send, params) => {
return {
elements: (
await send(
'smartapp.element.getBySelector',
Object.assign(Object.assign({}, params), {
properties: ['id', 'tagName'],
selector: processSelector(params.selector),
})
)
).map((element) => {
const properties = element.properties
return {
elementId: properties.id,
nodeId: properties.id,
tagName: processTagName(properties.tagName),
}
}),
}
},
},
'Page.getWindowProperties': {
reflect: async (send, params) => {
const properties = params.names.map((name) =>
name.replace('document.documentElement.', '')
)
const elem = (
await send('smartapp.element.getBySelector', {
properties,
selector: 'html',
})
)[0]
return {
properties: properties.map((name) => elem.properties[name]),
}
},
},
'Element.getHTML': {
reflect: async (send, params) => {
const names = [params.type + 'HTML']
return {
html: (
await send(
'Element.getDOMProperties',
Object.assign(Object.assign({}, params), { names })
)
).properties[0],
}
},
},
'Element.getElement': {
reflect: async (send, params) => {
return (await send('Element.getElements', params)).elements[0]
},
},
'Element.getElements': {
reflect: async (send, params) => {
const { elements } = await send(
'Page.getElements',
Object.assign(Object.assign({}, params), {
selector: `#${params.elementId} ${params.selector}`,
})
)
elements.forEach((element) => {
element.nodeId = element.id
})
return { elements }
},
},
'Element.getAttributes': {
reflect: async (send, params) => {
const attributes = []
for (const attribute of params.names) {
attributes.push(
await send(
'smartapp.element.getAttribute',
Object.assign({ attribute }, params)
)
)
}
return {
attributes,
}
},
params: addElementId,
},
'Element.getStyles': {
reflect: async (send, params) => {
const styles = []
for (const style of params.names) {
styles.push(
await send(
'smartapp.element.getComputedStyle',
Object.assign({ style }, params)
)
)
}
return {
styles,
}
},
params: addElementId,
},
'Element.getDOMProperties': {
reflect: async (send, params) => {
const properties = []
for (const property of params.names) {
properties.push(
await send(
'smartapp.element.getProperty',
Object.assign({ property }, params)
)
)
}
return {
properties,
}
},
params: addElementId,
},
'Element.getProperties': {
reflect: async (send, params) => {
const properties = []
for (const attribute of params.names) {
properties.push(
await send(
'smartapp.element.getAttribute',
Object.assign({ attribute }, params)
)
)
}
return {
properties,
}
},
params: addElementId,
},
'Element.getOffset': {
reflect: async (send, params) => ({
left: await send(
'smartapp.element.getProperty',
Object.assign({ property: 'offsetLeft' }, params)
),
top: await send(
'smartapp.element.getProperty',
Object.assign({ property: 'offsetTop' }, params)
),
}),
params: addElementId,
},
'Element.tap': {
reflect: 'smartapp.element.touch',
params: addElementId,
},
},
}
module.exports = puppet
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=e(require("os")),r=e(require("path")),s=e(require("debug")),a=e(require("licia/isWindows")),n=e(require("fs")),o=e(require("child_process")),i=e(require("licia/sleep")),c=e(require("licia/toStr")),l=e(require("licia/waitUntil")),p=e(require("licia/concat")),u=e(require("licia/getPort")),m=e(require("licia/dateFormat"));require("address"),require("default-gateway"),require("licia/isStr");var d=e(require("ws")),h=require("events"),f=e(require("licia/uuid")),g=e(require("licia/stringify"));const w=/(^[a-z][a-z0-9-]*)/i,y=/^navigator/i,E=/^swan-nav$/i;var b;!function(e){e.SELECTOR="selector",e.TAGNAME="tagName"}(b||(b={}));const v={[b.SELECTOR]:[{test:y,processor:e=>e.replace(y,"nav")},{test:w,processor:e=>"swan-"+e}],[b.TAGNAME]:[{test:E,processor:e=>e.replace(E,"swan-navigator")},{test:w,processor:e=>e.toLocaleLowerCase().replace("swan-","")}]},P=e=>t=>{const r=(v[e]||[]).filter(e=>e.test.test(t));for(const e of r)t=e.processor(t);return t},j=P(b.SELECTOR),q=P(b.TAGNAME),O=e=>Object.assign({},e,{type:"id",info:{id:e.elementId}});require("qrcode-terminal"),require("qrcode-reader"),/^win/.test(process.platform);class M extends h.EventEmitter{constructor(e){super(),this.ws=e,this.ws.addEventListener("message",e=>{this.emit("message",e.data)}),this.ws.addEventListener("close",()=>{this.emit("close")})}send(e){this.ws.send(e)}close(){this.ws.close()}}class C extends h.EventEmitter{constructor(e,t,r){super(),this.puppet=t,this.namespace=r,this.callbacks=new Map,this.transport=e,this.debug=s("automator:protocol:"+this.namespace),this.onMessage=e=>{this.debug(`${m("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${e}`);const{id:t,method:r,error:s,result:a,params:n}=JSON.parse(e);if(!t)return this.puppet.emit(r,n);const{callbacks:o}=this;if(t&&o.has(t)){const e=o.get(t);o.delete(t),s?e.reject(Error(s.message)):e.resolve(a)}},this.onClose=()=>{this.callbacks.forEach(e=>{e.reject(Error("Connection closed"))})},this.transport.on("message",this.onMessage),this.transport.on("close",this.onClose)}send(e,t={},r=!0){if(r&&this.puppet.adapter.has(e))return this.puppet.adapter.send(this,e,t);const s=f(),a=g({id:s,method:e,params:t});return this.debug(`${m("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${a}`),new Promise((e,t)=>{try{this.transport.send(a)}catch(e){t(Error("Connection closed"))}this.callbacks.set(s,{resolve:e,reject:t})})}dispose(){this.transport.close()}static createDevtoolConnection(e,t){return new Promise((r,s)=>{const a=new d(e);a.addEventListener("open",()=>{r(new C(new M(a),t,"devtool"))}),a.addEventListener("error",s)})}static createRuntimeConnection(e,t,r){return new Promise((a,n)=>{s("automator:runtime")(`${m("yyyy-mm-dd HH:MM:ss:l")} port=${e}`);const o=new d.Server({port:e});l(async()=>{if(t.runtimeConnection)return!0},r,1e3).catch(()=>{o.close(),n("Failed to connect to runtime, please make sure the project is running")}),o.on("connection",(function(e){s("automator:runtime")(m("yyyy-mm-dd HH:MM:ss:l")+" connected");const r=new C(new M(e),t,"runtime");t.setRuntimeConnection(r),a(r)})),t.setRuntimeServer(o)})}}const $=s("automator:devtool");async function S(e,t,r){const{port:s,cliPath:a,timeout:n,cwd:u="",account:d="",args:h=[],launch:f=!0}=t;let g=!1,w=!1;if(!1!==f){const t={stdio:"ignore"};u&&(t.cwd=u);let r=p(h,[]);r=p(r,["--auto"]),r=p(r,[e,"--auto-port",c(s)]),d&&(r=p(r,["--auto-account",d]));try{$("%s %o %o",a,r,t);const e=o.spawn(a,r,t);e.on("error",e=>{g=!0}),e.on("exit",()=>{setTimeout(()=>{w=!0},15e3)}),e.unref()}catch(e){g=!1}}else setTimeout(()=>{w=!0},15e3);const y=await l(async()=>{try{if(g||w)return!0;return await async function(e,t){let r;try{r=await C.createDevtoolConnection(e.wsEndpoint,t)}catch(t){throw Error(`Failed connecting to ${e.wsEndpoint}, check if target project window is opened with automation enabled`)}return r}({wsEndpoint:"ws://127.0.0.1:"+s},r)}catch(e){}},n,1e3);if(g)throw Error(`Failed to launch ${r.devtools.name}, please make sure cliPath is correctly specified`);if(w)throw Error(`Failed to launch ${r.devtools.name} , please make sure http port is open`);return await i(5e3),$(m("yyyy-mm-dd HH:MM:ss:l")+" connected"),y}const A=[];["","-rc"].forEach(e=>{a?(A.push(r.join(t.homedir(),`AppData/Local/Programs/swan-ide-gui${e}/cli.bat`)),A.push(`C:/Program Files/swan-ide-gui${e}/cli.bat`)):A.push(`/Applications/百度开发者工具${e}.app/Contents/MacOS/cli`)});const T={devtools:{name:"Baidu DevTools",remote:!0,automator:!0,paths:A,required:["project.swan.json","app.json","app.js"],defaultPort:9430,validate:async function(e,t){const r=function(e,t){const r=t.devtools.paths.slice(0);e&&r.unshift(e);for(const e of r)if(n.existsSync(e))return e;throw Error(t.devtools.name+" not found, please specify executablePath option")}(e.executablePath,t);let s=e.port||t.devtools.defaultPort;if(!1!==e.launch)try{s=await async function(e,t){const r=await u(e||t);if(e&&r!==e)throw Error(`Port ${e} is in use, please specify another port`);return r}(s)}catch(t){e.launch=!1}else{s===await u(s)&&(e.launch=!0)}return Object.assign(Object.assign({},e),{port:s,cliPath:r})},async create(e,t,r){const a=await S(e,t,r);return r.compiled?s("automator:devtool")("Waiting for runtime automator"):(s("automator:devtool")("initRuntimeAutomator"),a.send("smartapp.swan",{api:"$$initRuntimeAutomator",params:[]})),a}},adapter:{"Tool.enableRemoteDebug":{reflect:async e=>({qrCode:(await e("Tool.enablePreview")).url})},"App.exit":{reflect:async()=>Promise.resolve()},"Page.getElement":{reflect:async(e,t)=>(await e("Page.getElements",t)).elements[0]},"Page.getElements":{reflect:async(e,t)=>{return{elements:(await e("smartapp.element.getBySelector",Object.assign(Object.assign({},t),{properties:["id","tagName"],selector:(r=t.selector,r.split(" ").map(e=>j(e)).join(" "))}))).map(e=>{const t=e.properties;return{elementId:t.id,nodeId:t.id,tagName:q(t.tagName)}})};var r}},"Page.getWindowProperties":{reflect:async(e,t)=>{const r=t.names.map(e=>e.replace("document.documentElement.","")),s=(await e("smartapp.element.getBySelector",{properties:r,selector:"html"}))[0];return{properties:r.map(e=>s.properties[e])}}},"Element.getHTML":{reflect:async(e,t)=>{const r=[t.type+"HTML"];return{html:(await e("Element.getDOMProperties",Object.assign(Object.assign({},t),{names:r}))).properties[0]}}},"Element.getElement":{reflect:async(e,t)=>(await e("Element.getElements",t)).elements[0]},"Element.getElements":{reflect:async(e,t)=>{const{elements:r}=await e("Page.getElements",Object.assign(Object.assign({},t),{selector:`#${t.elementId} ${t.selector}`}));return r.forEach(e=>{e.nodeId=e.id}),{elements:r}}},"Element.getAttributes":{reflect:async(e,t)=>{const r=[];for(const s of t.names)r.push(await e("smartapp.element.getAttribute",Object.assign({attribute:s},t)));return{attributes:r}},params:O},"Element.getStyles":{reflect:async(e,t)=>{const r=[];for(const s of t.names)r.push(await e("smartapp.element.getComputedStyle",Object.assign({style:s},t)));return{styles:r}},params:O},"Element.getDOMProperties":{reflect:async(e,t)=>{const r=[];for(const s of t.names)r.push(await e("smartapp.element.getProperty",Object.assign({property:s},t)));return{properties:r}},params:O},"Element.getProperties":{reflect:async(e,t)=>{const r=[];for(const s of t.names)r.push(await e("smartapp.element.getAttribute",Object.assign({attribute:s},t)));return{properties:r}},params:O},"Element.getOffset":{reflect:async(e,t)=>({left:await e("smartapp.element.getProperty",Object.assign({property:"offsetLeft"},t)),top:await e("smartapp.element.getProperty",Object.assign({property:"offsetTop"},t))}),params:O},"Element.tap":{reflect:"smartapp.element.touch",params:O}}};module.exports=T;
var hasOwnProperty = Object.prototype.hasOwnProperty
var hasOwn = function (val, key) {
return hasOwnProperty.call(val, key)
}
var isUndef = function (v) {
return v === undefined || v === null
}
var isArray = Array.isArray
var isPromise = function (obj) {
return (
!!obj &&
(typeof obj === 'object' || typeof obj === 'function') &&
typeof obj.then === 'function'
)
}
var cacheStringFunction = function (fn) {
var cache = Object.create(null)
return function (str) {
var hit = cache[str]
return hit || (cache[str] = fn(str))
}
}
var camelizeRE = /-(\w)/g
var camelize = cacheStringFunction(function (str) {
return str.replace(camelizeRE, function (_, c) {
return c ? c.toUpperCase() : ''
})
})
var capitalize = cacheStringFunction(function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
})
var PATH_RE =
/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g
function getPaths(path, data) {
if (isArray(path)) {
return path
}
if (data && hasOwn(data, path)) {
return [path]
}
var res = []
path.replace(PATH_RE, function (match, p1, offset, string) {
res.push(offset ? string.replace(/\\(\\)?/g, '$1') : p1 || match)
return string
})
return res
}
function getDataByPath(data, path) {
var paths = getPaths(path, data)
var dataPath
for (dataPath = paths.shift(); !isUndef(dataPath); ) {
if (null == (data = data[dataPath])) {
return
}
dataPath = paths.shift()
}
return data
}
function getPageId(page) {
if (page.__wxWebviewId__) {
//mp-weixin
return page.__wxWebviewId__
}
if (page.privateProperties) {
//mp-baidu
return page.privateProperties.slaveId
}
if (page.$page) {
//h5 and app-plus
return page.$page.id
}
}
function getPagePath(page) {
return page.route || page.uri
}
function getPageQuery(page) {
return page.options || (page.$page && page.$page.options) || {}
}
function parsePage(page) {
return {
id: getPageId(page),
path: getPagePath(page),
query: getPageQuery(page),
}
}
function getPageById(id) {
return getCurrentPages().find(function (page) {
return getPageId(page) === id
})
}
function getPageVm(id) {
var page = getPageById(id)
return page && page.$vm
}
function getNodeId(scope) {
return scope.__wxExparserNodeId__ || scope.nodeId || scope.id
}
function matchNodeId(vm, nodeId) {
return vm.$scope && getNodeId(vm.$scope) === nodeId
}
function findComponentVm(vm, nodeId) {
var res
if (vm) {
if (matchNodeId(vm, nodeId)) {
res = vm
} else {
vm.$children.find(function (child) {
res = findComponentVm(child, nodeId)
return res
})
}
}
return res
}
function getComponentVm(pageId, nodeId) {
var pageVm = getPageVm(pageId)
return pageVm && findComponentVm(pageVm, nodeId)
}
function getData(vm, path) {
var data
if (vm) {
data = path ? getDataByPath(vm.$data, path) : Object.assign({}, vm.$data)
}
return Promise.resolve({ data: data })
}
function setData(vm, data) {
if (vm) {
Object.keys(data).forEach(function (name) {
vm[name] = data[name]
})
}
return Promise.resolve()
}
var CALL_METHOD_ERROR
;(function (CALL_METHOD_ERROR) {
CALL_METHOD_ERROR['VM_NOT_EXISTS'] = 'VM_NOT_EXISTS'
CALL_METHOD_ERROR['METHOD_NOT_EXISTS'] = 'METHOD_NOT_EXISTS'
})(CALL_METHOD_ERROR || (CALL_METHOD_ERROR = {}))
function callMethod(vm, method, args) {
return new Promise(function (resolve, reject) {
if (!vm) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
if (!vm[method]) {
return reject(CALL_METHOD_ERROR.VM_NOT_EXISTS)
}
var ret = vm[method].apply(vm, args)
isPromise(ret)
? ret.then(function (res) {
resolve({ result: res })
})
: resolve({ result: ret })
})
}
var SYNC_APIS = [
'stopRecord',
'getRecorderManager',
'pauseVoice',
'stopVoice',
'pauseBackgroundAudio',
'stopBackgroundAudio',
'getBackgroundAudioManager',
'createAudioContext',
'createInnerAudioContext',
'createVideoContext',
'createCameraContext',
'createMapContext',
'canIUse',
'startAccelerometer',
'stopAccelerometer',
'startCompass',
'stopCompass',
'hideToast',
'hideLoading',
'showNavigationBarLoading',
'hideNavigationBarLoading',
'navigateBack',
'createAnimation',
'pageScrollTo',
'createSelectorQuery',
'createCanvasContext',
'createContext',
'drawCanvas',
'hideKeyboard',
'stopPullDownRefresh',
'arrayBufferToBase64',
'base64ToArrayBuffer',
]
var originUni = {}
var SYNC_API_RE = /Sync$/
var MOCK_API_BLACKLIST_RE = /^on|^off/
function isSyncApi(method) {
return SYNC_API_RE.test(method) || SYNC_APIS.indexOf(method) !== -1
}
function canIMock(method) {
return !MOCK_API_BLACKLIST_RE.test(method)
}
var App = {
getPageStack: function () {
return Promise.resolve({
pageStack: getCurrentPages().map(function (page) {
return parsePage(page)
}),
})
},
getCurrentPage: function () {
var pages = getCurrentPages()
var len = pages.length
return new Promise(function (resolve, reject) {
if (!len) {
reject(Error('getCurrentPages().length=0'))
} else {
resolve(parsePage(pages[len - 1]))
}
})
},
callUniMethod: function (params) {
var method = params.method
var args = params.args
return new Promise(function (resolve, reject) {
if (!uni[method]) {
return reject(Error('uni.' + method + ' not exists'))
}
if (isSyncApi(method)) {
return resolve({
result: uni[method].apply(uni, args),
})
}
var params = [
Object.assign({}, args[0] || {}, {
success: function (result) {
var timeout = method === 'pageScrollTo' ? 350 : 0
setTimeout(function () {
resolve({ result: result })
}, timeout)
},
fail: function (res) {
reject(Error(res.errMsg.replace(method + ':fail ', '')))
},
}),
]
uni[method].apply(uni, params)
})
},
mockUniMethod: function (params) {
var method = params.method
if (!uni[method]) {
throw Error('uni.' + method + ' not exists')
}
if (!canIMock(method)) {
throw Error("You can't mock uni." + method)
}
// TODO getOwnPropertyDescriptor?
var result = params.result
if (isUndef(result)) {
// restoreUniMethod
if (originUni[method]) {
uni[method] = originUni[method]
delete originUni[method]
}
return Promise.resolve()
}
var mockFn = isSyncApi(method)
? function () {
return result
}
: function (params) {
setTimeout(function () {
var isFail = result.errMsg && result.errMsg.indexOf(':fail') !== -1
if (isFail) {
params.fail && params.fail(result)
} else {
params.success && params.success(result)
}
params.complete && params.complete(result)
}, 4)
}
// mockFn.origin = originUni[method] || uni[method];
if (!originUni[method]) {
originUni[method] = uni[method]
}
uni[method] = mockFn
return Promise.resolve()
},
}
var Page = {
getData: function (params) {
return getData(getPageVm(params.pageId), params.path)
},
setData: function (params) {
return setData(getPageVm(params.pageId), params.data)
},
callMethod: function (params) {
var _a
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Page[' + params.pageId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'page.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(getPageVm(params.pageId), params.method, params.args)
.then(function (res) {
return resolve(res)
})
.catch(function (type) {
reject(Error(err[type]))
})
})
},
}
function getNodeId$1(params) {
return params.nodeId || params.elementId
}
var Element = {
getData: function (params) {
return getData(
getComponentVm(params.pageId, getNodeId$1(params)),
params.path
)
},
setData: function (params) {
return setData(
getComponentVm(params.pageId, getNodeId$1(params)),
params.data
)
},
callMethod: function (params) {
var _a
var nodeId = getNodeId$1(params)
var err =
((_a = {}),
(_a[CALL_METHOD_ERROR.VM_NOT_EXISTS] =
'Component[' + params.pageId + ':' + nodeId + '] not exists'),
(_a[CALL_METHOD_ERROR.METHOD_NOT_EXISTS] =
'component.' + params.method + ' not exists'),
_a)
return new Promise(function (resolve, reject) {
callMethod(
getComponentVm(params.pageId, nodeId),
params.method,
params.args
)
.then(function (res) {
return resolve(res)
})
.catch(function (type) {
reject(Error(err[type]))
})
})
},
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
var getRandomValues =
(typeof crypto != 'undefined' &&
crypto.getRandomValues &&
crypto.getRandomValues.bind(crypto)) ||
(typeof msCrypto != 'undefined' &&
typeof msCrypto.getRandomValues == 'function' &&
msCrypto.getRandomValues.bind(msCrypto))
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = []
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1)
}
var BUILITIN = [
'movable-view',
'picker',
'ad',
'button',
'checkbox-group',
'checkbox',
'form',
'icon',
'label',
'movable-area',
'navigator',
'picker-view-column',
'picker-view',
'progress',
'radio-group',
'radio',
'rich-text',
'u-slider',
'swiper-item',
'swiper',
'switch',
]
var BUILITIN_ALIAS = BUILITIN.map(function (tag) {
return capitalize(camelize(tag))
})
var Api = {}
Object.keys(App).forEach(function (method) {
Api['App.' + method] = App[method]
})
Object.keys(Page).forEach(function (method) {
Api['Page.' + method] = Page[method]
})
Object.keys(Element).forEach(function (method) {
Api['Element.' + method] = Element[method]
})
var wsEndpoint = process.env.UNI_AUTOMATOR_WS_ENDPOINT
var socketTask
function send(data) {
socketTask.send({ data: JSON.stringify(data) })
}
function onMessage(res) {
var _a = JSON.parse(res.data),
id = _a.id,
method = _a.method,
params = _a.params
var data = { id: id }
var fn = Api[method]
if (!fn) {
if (!fn) {
data.error = {
message: method + ' unimplemented',
}
return send(data)
}
}
try {
fn(params)
.then(function (res) {
res && (data.result = res)
})
.catch(function (err) {
data.error = {
message: err.message,
}
})
.finally(function () {
send(data)
})
} catch (err) {
data.error = {
message: err.message,
}
send(data)
}
}
function initRuntimeAutomator(options) {
if (options === void 0) {
options = {}
}
socketTask = uni.connectSocket({
url: wsEndpoint,
complete: function () {},
})
socketTask.onMessage(onMessage)
socketTask.onOpen(function (res) {
options.success && options.success()
console.log('已开启自动化测试...')
})
socketTask.onError(function (res) {
console.log('automator.onError', res)
})
socketTask.onClose(function () {
options.fail && options.fail({ errMsg: '$$initRuntimeAutomator:fail' })
console.log('automator.onClose')
})
}
//@ts-ignore
{
//@ts-ignore
wx.$$initRuntimeAutomator = initRuntimeAutomator
setTimeout(function () {
//@ts-ignore
wx.$$initRuntimeAutomator()
}, 500)
//@ts-ignore
}
var e,t=Object.prototype.hasOwnProperty,n=function(e){return null==e},r=Array.isArray,o=function(e){var t=Object.create(null);return function(n){return t[n]||(t[n]=e(n))}},i=/-(\w)/g,a=o((function(e){return e.replace(i,(function(e,t){return t?t.toUpperCase():""}))})),u=o((function(e){return e.charAt(0).toUpperCase()+e.slice(1)})),c=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;function s(e,n){if(r(e))return e;if(n&&(o=n,i=e,t.call(o,i)))return[e];var o,i,a=[];return e.replace(c,(function(e,t,n,r){return a.push(n?r.replace(/\\(\\)?/g,"$1"):t||e),r})),a}function f(e){return e.__wxWebviewId__?e.__wxWebviewId__:e.privateProperties?e.privateProperties.slaveId:e.$page?e.$page.id:void 0}function p(e){return e.route||e.uri}function d(e){return e.options||e.$page&&e.$page.options||{}}function l(e){return{id:f(e),path:p(e),query:d(e)}}function g(e){var t=function(e){return getCurrentPages().find((function(t){return f(t)===e}))}(e);return t&&t.$vm}function m(e,t){var n=g(e);return n&&function e(t,n){var r;return t&&(!function(e,t){return e.$scope&&((n=e.$scope).__wxExparserNodeId__||n.nodeId||n.id)===t;var n}(t,n)?t.$children.find((function(t){return r=e(t,n)})):r=t),r}(n,t)}function v(e,t){var r;return e&&(r=t?function(e,t){var r,o=s(t,e);for(r=o.shift();!n(r);){if(null==(e=e[r]))return;r=o.shift()}return e}(e.$data,t):Object.assign({},e.$data)),Promise.resolve({data:r})}function h(e,t){return e&&Object.keys(t).forEach((function(n){e[n]=t[n]})),Promise.resolve()}function T(t,n,r){return new Promise((function(o,i){if(!t)return i(e.VM_NOT_EXISTS);if(!t[n])return i(e.VM_NOT_EXISTS);var a,u=t[n].apply(t,r);!(a=u)||"object"!=typeof a&&"function"!=typeof a||"function"!=typeof a.then?o({result:u}):u.then((function(e){o({result:e})}))}))}!function(e){e.VM_NOT_EXISTS="VM_NOT_EXISTS",e.METHOD_NOT_EXISTS="METHOD_NOT_EXISTS"}(e||(e={}));var _=["stopRecord","getRecorderManager","pauseVoice","stopVoice","pauseBackgroundAudio","stopBackgroundAudio","getBackgroundAudioManager","createAudioContext","createInnerAudioContext","createVideoContext","createCameraContext","createMapContext","canIUse","startAccelerometer","stopAccelerometer","startCompass","stopCompass","hideToast","hideLoading","showNavigationBarLoading","hideNavigationBarLoading","navigateBack","createAnimation","pageScrollTo","createSelectorQuery","createCanvasContext","createContext","drawCanvas","hideKeyboard","stopPullDownRefresh","arrayBufferToBase64","base64ToArrayBuffer"],y={},O=/Sync$/,S=/^on|^off/;function E(e){return O.test(e)||-1!==_.indexOf(e)}var I={getPageStack:function(){return Promise.resolve({pageStack:getCurrentPages().map((function(e){return l(e)}))})},getCurrentPage:function(){var e=getCurrentPages(),t=e.length;return new Promise((function(n,r){t?n(l(e[t-1])):r(Error("getCurrentPages().length=0"))}))},callUniMethod:function(e){var t=e.method,n=e.args;return new Promise((function(e,r){if(!uni[t])return r(Error("uni."+t+" not exists"));if(E(t))return e({result:uni[t].apply(uni,n)});var o=[Object.assign({},n[0]||{},{success:function(n){setTimeout((function(){e({result:n})}),"pageScrollTo"===t?350:0)},fail:function(e){r(Error(e.errMsg.replace(t+":fail ","")))}})];uni[t].apply(uni,o)}))},mockUniMethod:function(e){var t=e.method;if(!uni[t])throw Error("uni."+t+" not exists");if(!function(e){return!S.test(e)}(t))throw Error("You can't mock uni."+t);var r=e.result;if(n(r))return y[t]&&(uni[t]=y[t],delete y[t]),Promise.resolve();var o=E(t)?function(){return r}:function(e){setTimeout((function(){r.errMsg&&-1!==r.errMsg.indexOf(":fail")?e.fail&&e.fail(r):e.success&&e.success(r),e.complete&&e.complete(r)}),4)};return y[t]||(y[t]=uni[t]),uni[t]=o,Promise.resolve()}},C={getData:function(e){return v(g(e.pageId),e.path)},setData:function(e){return h(g(e.pageId),e.data)},callMethod:function(t){var n,r=((n={})[e.VM_NOT_EXISTS]="Page["+t.pageId+"] not exists",n[e.METHOD_NOT_EXISTS]="page."+t.method+" not exists",n);return new Promise((function(e,n){T(g(t.pageId),t.method,t.args).then((function(t){return e(t)})).catch((function(e){n(Error(r[e]))}))}))}};function w(e){return e.nodeId||e.elementId}for(var x={getData:function(e){return v(m(e.pageId,w(e)),e.path)},setData:function(e){return h(m(e.pageId,w(e)),e.data)},callMethod:function(t){var n,r=w(t),o=((n={})[e.VM_NOT_EXISTS]="Component["+t.pageId+":"+r+"] not exists",n[e.METHOD_NOT_EXISTS]="component."+t.method+" not exists",n);return new Promise((function(e,n){T(m(t.pageId,r),t.method,t.args).then((function(t){return e(t)})).catch((function(e){n(Error(o[e]))}))}))}},M=("undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto),[]),P=0;P<256;++P)M[P]=(P+256).toString(16).substr(1);["movable-view","picker","ad","button","checkbox-group","checkbox","form","icon","label","movable-area","navigator","picker-view-column","picker-view","progress","radio-group","radio","rich-text","u-slider","swiper-item","swiper","switch"].map((function(e){return u(a(e))}));var b={};Object.keys(I).forEach((function(e){b["App."+e]=I[e]})),Object.keys(C).forEach((function(e){b["Page."+e]=C[e]})),Object.keys(x).forEach((function(e){b["Element."+e]=x[e]}));var $,k=process.env.UNI_AUTOMATOR_WS_ENDPOINT;function A(e){$.send({data:JSON.stringify(e)})}function N(e){var t=JSON.parse(e.data),n=t.id,r=t.method,o=t.params,i={id:n},a=b[r];if(!a&&!a)return i.error={message:r+" unimplemented"},A(i);try{a(o).then((function(e){e&&(i.result=e)})).catch((function(e){i.error={message:e.message}})).finally((function(){A(i)}))}catch(e){i.error={message:e.message},A(i)}}wx.$$initRuntimeAutomator=function(e){void 0===e&&(e={}),($=uni.connectSocket({url:k,complete:function(){}})).onMessage(N),$.onOpen((function(t){e.success&&e.success(),console.log("已开启自动化测试...")})),$.onError((function(e){console.log("automator.onError",e)})),$.onClose((function(){e.fail&&e.fail({errMsg:"$$initRuntimeAutomator:fail"}),console.log("automator.onClose")}))},setTimeout((function(){wx.$$initRuntimeAutomator()}),500);
'use strict'
function _interopDefault(ex) {
return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex
}
var debug = _interopDefault(require('debug'))
var isWindows = _interopDefault(require('licia/isWindows'))
require('address')
require('default-gateway')
require('licia/isStr')
var getPort = _interopDefault(require('licia/getPort'))
var fs = _interopDefault(require('fs'))
var child_process = _interopDefault(require('child_process'))
var sleep = _interopDefault(require('licia/sleep'))
var toStr = _interopDefault(require('licia/toStr'))
var waitUntil = _interopDefault(require('licia/waitUntil'))
var concat = _interopDefault(require('licia/concat'))
var dateFormat = _interopDefault(require('licia/dateFormat'))
var WebSocket = _interopDefault(require('ws'))
var events = require('events')
var uuid = _interopDefault(require('licia/uuid'))
var stringify = _interopDefault(require('licia/stringify'))
const qrCodeTerminal = require('qrcode-terminal')
const QrCodeReader = require('qrcode-reader')
const isWin = /^win/.test(process.platform)
function decodeQrCode(qrCode) {
const buffer = new Buffer(qrCode, 'base64')
return new Promise(async (resolve, reject) => {
const img = await require('jimp').read(buffer)
const qrCodeReader = new QrCodeReader()
qrCodeReader.callback = function (error, value) {
if (error) {
return reject(error)
}
resolve(value.result)
}
qrCodeReader.decode(img.bitmap)
})
}
async function resolvePort(port, defaultPort) {
const newPort = await getPort(port || defaultPort)
if (port && newPort !== port) {
throw Error(`Port ${port} is in use, please specify another port`)
}
return newPort
}
class Transport extends events.EventEmitter {
constructor(ws) {
super()
this.ws = ws
this.ws.addEventListener('message', (event) => {
this.emit('message', event.data)
})
this.ws.addEventListener('close', () => {
this.emit('close')
})
}
send(message) {
this.ws.send(message)
}
close() {
this.ws.close()
}
}
const CLOSE_ERR_TIP = 'Connection closed'
class Connection extends events.EventEmitter {
constructor(transport, puppet, namespace) {
super()
this.puppet = puppet
this.namespace = namespace
this.callbacks = new Map()
this.transport = transport
this.debug = debug('automator:protocol:' + this.namespace)
this.onMessage = (msg) => {
this.debug(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} ◀ RECV ${msg}`)
const { id, method, error, result, params } = JSON.parse(msg)
if (!id) {
return this.puppet.emit(method, params)
}
const { callbacks } = this
if (id && callbacks.has(id)) {
const promise = callbacks.get(id)
callbacks.delete(id)
error ? promise.reject(Error(error.message)) : promise.resolve(result)
}
}
this.onClose = () => {
this.callbacks.forEach((promise) => {
promise.reject(Error(CLOSE_ERR_TIP))
})
}
this.transport.on('message', this.onMessage)
this.transport.on('close', this.onClose)
}
send(method, params = {}, reflect = true) {
if (reflect && this.puppet.adapter.has(method)) {
return this.puppet.adapter.send(this, method, params)
}
const id = uuid()
const data = stringify({
id,
method,
params,
})
this.debug(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} SEND ► ${data}`)
return new Promise((resolve, reject) => {
try {
this.transport.send(data)
} catch (e) {
reject(Error(CLOSE_ERR_TIP))
}
this.callbacks.set(id, {
resolve,
reject,
})
})
}
dispose() {
this.transport.close()
}
static createDevtoolConnection(url, puppet) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(url)
ws.addEventListener('open', () => {
resolve(new Connection(new Transport(ws), puppet, 'devtool'))
})
ws.addEventListener('error', reject)
})
}
static createRuntimeConnection(port, puppet, timeout) {
return new Promise((resolve, reject) => {
debug('automator:runtime')(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} port=${port}`
)
const wss = new WebSocket.Server({
port,
})
waitUntil(
async () => {
if (puppet.runtimeConnection) {
return true
}
},
timeout,
1e3
).catch(() => {
wss.close()
reject(
'Failed to connect to runtime, please make sure the project is running'
)
})
wss.on('connection', function connection(ws) {
debug('automator:runtime')(
`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} connected`
)
const connection = new Connection(new Transport(ws), puppet, 'runtime')
// 可能会被重新连接,刷新成最新的
puppet.setRuntimeConnection(connection)
resolve(connection)
})
puppet.setRuntimeServer(wss)
})
}
}
const debugDevtools = debug('automator:devtool')
function resolveDevtoolsPath(cliPath, puppet) {
const paths = puppet.devtools.paths.slice(0)
if (cliPath) {
paths.unshift(cliPath)
}
for (const cliPath of paths) {
if (fs.existsSync(cliPath)) {
return cliPath
}
}
throw Error(
`${puppet.devtools.name} not found, please specify executablePath option`
)
}
async function validateDevtools(options, puppet) {
const cliPath = resolveDevtoolsPath(options.executablePath, puppet)
let port = options.port || puppet.devtools.defaultPort
if (options.launch !== false) {
try {
port = await resolvePort(port)
} catch (e) {
// console.log(`Port ${port} is in use, try to connect directly`);
options.launch = false
}
} else {
const newPort = await getPort(port)
if (port === newPort) {
options.launch = true
// console.log(`try to launch ${this.puppet.devtools.name}`);
}
}
return Object.assign(Object.assign({}, options), { port, cliPath })
}
async function connectTool(options, puppet) {
let connection
try {
connection = await Connection.createDevtoolConnection(
options.wsEndpoint,
puppet
)
} catch (e) {
throw Error(
`Failed connecting to ${options.wsEndpoint}, check if target project window is opened with automation enabled`
)
}
return connection
}
async function createDevtools(projectPath, options, puppet) {
const {
port,
cliPath,
timeout,
cwd = '',
account = '',
args = [],
launch = true,
} = options
let launchFailed = false
let connectFailed = false
if (launch !== false) {
const spawnOptions = {
stdio: 'ignore',
}
//@ts-ignore
{
spawnOptions.detached = true
}
cwd && (spawnOptions.cwd = cwd)
let spawnArgs = concat(args, [])
//@ts-ignore
{
spawnArgs = concat(spawnArgs, ['auto', '--project'])
}
spawnArgs = concat(spawnArgs, [projectPath, '--auto-port', toStr(port)])
account && (spawnArgs = concat(spawnArgs, ['--auto-account', account]))
try {
debugDevtools('%s %o %o', cliPath, spawnArgs, spawnOptions)
const cliProcess = child_process.spawn(cliPath, spawnArgs, spawnOptions)
cliProcess.on('error', (err) => {
launchFailed = true
})
cliProcess.on('exit', () => {
setTimeout(() => {
connectFailed = true
}, 15e3)
})
// TODO unref?
cliProcess.unref()
} catch (err) {
launchFailed = false
}
} else {
setTimeout(() => {
connectFailed = true
}, 15e3)
}
const connection = await waitUntil(
async () => {
try {
if (launchFailed || connectFailed) {
return true
}
const connection = await connectTool(
{ wsEndpoint: `ws://127.0.0.1:${port}` },
puppet
)
return connection
} catch (err) {}
},
timeout,
1e3
)
if (launchFailed) {
throw Error(
`Failed to launch ${puppet.devtools.name}, please make sure cliPath is correctly specified`
)
}
if (connectFailed) {
throw Error(
`Failed to launch ${puppet.devtools.name} , please make sure http port is open`
)
}
await sleep(5e3)
debugDevtools(`${dateFormat('yyyy-mm-dd HH:MM:ss:l')} connected`)
return connection
}
function wrapper(fnStr) {
if (fnStr[fnStr.length - 1] === '}') {
return fnStr.replace('{', '{\nvar uni = wx;\n')
}
return fnStr.replace('=>', '=>{\nvar uni = wx;\nreturn ') + '}'
}
const puppet = {
devtools: {
name: 'Wechat web devTools',
remote: true,
automator: true,
paths: [
isWindows
? 'C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat'
: '/Applications/wechatwebdevtools.app/Contents/MacOS/cli',
],
required: ['project.config.json', 'app.json', 'app.js'],
defaultPort: 9420,
validate: validateDevtools,
async create(projectPath, options, puppet) {
const connection = await createDevtools(projectPath, options, puppet)
if (!puppet.compiled) {
debug('automator:devtool')('initRuntimeAutomator')
connection.send('App.callWxMethod', {
method: '$$initRuntimeAutomator',
args: [],
})
} else {
debug('automator:devtool')('Waiting for runtime automator')
}
return connection
},
},
adapter: {
'Tool.enableRemoteDebug': {
reflect: async (send, params) => {
let { qrCode } = await send('Tool.enableRemoteDebug', params, false)
qrCode && (qrCode = await decodeQrCode(qrCode))
return { qrCode }
},
},
// "App.callUniMethod": {
// reflect: "App.callWxMethod",
// },
'App.callFunction': {
reflect: async (send, params) => {
return send(
'App.callFunction',
Object.assign(Object.assign({}, params), {
functionDeclaration: wrapper(params.functionDeclaration),
}),
false
)
},
},
'Element.getHTML': {
reflect: async (send, params) => {
return { html: (await send('Element.getWXML', params, false)).wxml }
},
},
},
}
module.exports = puppet
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var t=e(require("debug")),r=e(require("licia/isWindows"));require("address"),require("default-gateway"),require("licia/isStr");var o=e(require("licia/getPort")),n=e(require("fs")),s=e(require("child_process")),a=e(require("licia/sleep")),i=e(require("licia/toStr")),c=e(require("licia/waitUntil")),u=e(require("licia/concat")),l=e(require("licia/dateFormat")),d=e(require("ws")),p=require("events"),m=e(require("licia/uuid")),h=e(require("licia/stringify"));require("qrcode-terminal");const w=require("qrcode-reader");/^win/.test(process.platform);class f extends p.EventEmitter{constructor(e){super(),this.ws=e,this.ws.addEventListener("message",e=>{this.emit("message",e.data)}),this.ws.addEventListener("close",()=>{this.emit("close")})}send(e){this.ws.send(e)}close(){this.ws.close()}}class y extends p.EventEmitter{constructor(e,r,o){super(),this.puppet=r,this.namespace=o,this.callbacks=new Map,this.transport=e,this.debug=t("automator:protocol:"+this.namespace),this.onMessage=e=>{this.debug(`${l("yyyy-mm-dd HH:MM:ss:l")} ◀ RECV ${e}`);const{id:t,method:r,error:o,result:n,params:s}=JSON.parse(e);if(!t)return this.puppet.emit(r,s);const{callbacks:a}=this;if(t&&a.has(t)){const e=a.get(t);a.delete(t),o?e.reject(Error(o.message)):e.resolve(n)}},this.onClose=()=>{this.callbacks.forEach(e=>{e.reject(Error("Connection closed"))})},this.transport.on("message",this.onMessage),this.transport.on("close",this.onClose)}send(e,t={},r=!0){if(r&&this.puppet.adapter.has(e))return this.puppet.adapter.send(this,e,t);const o=m(),n=h({id:o,method:e,params:t});return this.debug(`${l("yyyy-mm-dd HH:MM:ss:l")} SEND ► ${n}`),new Promise((e,t)=>{try{this.transport.send(n)}catch(e){t(Error("Connection closed"))}this.callbacks.set(o,{resolve:e,reject:t})})}dispose(){this.transport.close()}static createDevtoolConnection(e,t){return new Promise((r,o)=>{const n=new d(e);n.addEventListener("open",()=>{r(new y(new f(n),t,"devtool"))}),n.addEventListener("error",o)})}static createRuntimeConnection(e,r,o){return new Promise((n,s)=>{t("automator:runtime")(`${l("yyyy-mm-dd HH:MM:ss:l")} port=${e}`);const a=new d.Server({port:e});c(async()=>{if(r.runtimeConnection)return!0},o,1e3).catch(()=>{a.close(),s("Failed to connect to runtime, please make sure the project is running")}),a.on("connection",(function(e){t("automator:runtime")(l("yyyy-mm-dd HH:MM:ss:l")+" connected");const o=new y(new f(e),r,"runtime");r.setRuntimeConnection(o),n(o)})),r.setRuntimeServer(a)})}}const g=t("automator:devtool");async function v(e,t,r){const{port:o,cliPath:n,timeout:d,cwd:p="",account:m="",args:h=[],launch:w=!0}=t;let f=!1,v=!1;if(!1!==w){const t={stdio:"ignore",detached:!0};p&&(t.cwd=p);let r=u(h,[]);r=u(r,["auto","--project"]),r=u(r,[e,"--auto-port",i(o)]),m&&(r=u(r,["--auto-account",m]));try{g("%s %o %o",n,r,t);const e=s.spawn(n,r,t);e.on("error",e=>{f=!0}),e.on("exit",()=>{setTimeout(()=>{v=!0},15e3)}),e.unref()}catch(e){f=!1}}else setTimeout(()=>{v=!0},15e3);const b=await c(async()=>{try{if(f||v)return!0;return await async function(e,t){let r;try{r=await y.createDevtoolConnection(e.wsEndpoint,t)}catch(t){throw Error(`Failed connecting to ${e.wsEndpoint}, check if target project window is opened with automation enabled`)}return r}({wsEndpoint:"ws://127.0.0.1:"+o},r)}catch(e){}},d,1e3);if(f)throw Error(`Failed to launch ${r.devtools.name}, please make sure cliPath is correctly specified`);if(v)throw Error(`Failed to launch ${r.devtools.name} , please make sure http port is open`);return await a(5e3),g(l("yyyy-mm-dd HH:MM:ss:l")+" connected"),b}const b={devtools:{name:"Wechat web devTools",remote:!0,automator:!0,paths:[r?"C:/Program Files (x86)/Tencent/微信web开发者工具/cli.bat":"/Applications/wechatwebdevtools.app/Contents/MacOS/cli"],required:["project.config.json","app.json","app.js"],defaultPort:9420,validate:async function(e,t){const r=function(e,t){const r=t.devtools.paths.slice(0);e&&r.unshift(e);for(const e of r)if(n.existsSync(e))return e;throw Error(t.devtools.name+" not found, please specify executablePath option")}(e.executablePath,t);let s=e.port||t.devtools.defaultPort;if(!1!==e.launch)try{s=await async function(e,t){const r=await o(e||t);if(e&&r!==e)throw Error(`Port ${e} is in use, please specify another port`);return r}(s)}catch(t){e.launch=!1}else{s===await o(s)&&(e.launch=!0)}return Object.assign(Object.assign({},e),{port:s,cliPath:r})},async create(e,r,o){const n=await v(e,r,o);return o.compiled?t("automator:devtool")("Waiting for runtime automator"):(t("automator:devtool")("initRuntimeAutomator"),n.send("App.callWxMethod",{method:"$$initRuntimeAutomator",args:[]})),n}},adapter:{"Tool.enableRemoteDebug":{reflect:async(e,t)=>{let{qrCode:r}=await e("Tool.enableRemoteDebug",t,!1);return r&&(r=await function(e){const t=new Buffer(e,"base64");return new Promise(async(e,r)=>{const o=await require("jimp").read(t),n=new w;n.callback=function(t,o){if(t)return r(t);e(o.result)},n.decode(o.bitmap)})}(r)),{qrCode:r}}},"App.callFunction":{reflect:async(e,t)=>{return e("App.callFunction",Object.assign(Object.assign({},t),{functionDeclaration:(r=t.functionDeclaration,"}"===r[r.length-1]?r.replace("{","{\nvar uni = wx;\n"):r.replace("=>","=>{\nvar uni = wx;\nreturn ")+"}")}),!1);var r}},"Element.getHTML":{reflect:async(e,t)=>({html:(await e("Element.getWXML",t,!1)).wxml})}}};module.exports=b;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册