提交 704d64d0 编写于 作者: DCloud-yyl's avatar DCloud-yyl

Merge branch 'alpha'

# Conflicts:
#	changelog.md
#	manifest.json
#	package.json
#	pages.json
#	pages/API/choose-location/choose-location.uvue
#	pages/API/compress-image/compress-image.uvue
#	pages/API/compress-video/compress-video.test.js
#	pages/API/compress-video/compress-video.uvue
#	pages/API/create-inner-audio-context/inner-audio.test.js
#	pages/API/download-file/download-file.uvue
#	pages/API/get-video-info/get-video-info.uvue
#	pages/API/inner-audio/inner-audio.uvue
#	pages/API/navigator/navigator.uvue
#	pages/API/open-location/open-location.uvue
#	pages/API/pull-down-refresh/pull-down-refresh.test.js
#	pages/API/request/request.test.js
#	pages/API/request/request.uvue
#	pages/API/show-modal/show-modal.test.js
#	pages/API/unicloud/unicloud/database.test.js
#	pages/API/upload-file/upload-file.uvue
#	pages/CSS/overflow/overflow-visible-event.uvue
#	pages/CSS/transform/scale.uvue
#	pages/component/canvas/canvas.test.js
#	pages/component/canvas/canvas.uvue
#	pages/component/checkbox/checkbox.uvue
#	pages/component/editor/editor.test.js
#	pages/component/general-event/general-event.test.js
#	pages/component/general-event/general-event.uvue
#	pages/component/image/image.test.js
#	pages/component/input/input.test.js
#	pages/component/input/input.uvue
#	pages/component/list-view/list-view-children-in-slot.test.js
#	pages/component/list-view/list-view-refresh.test.js
#	pages/component/list-view/list-view.test.js
#	pages/component/list-view/list-view.uvue
#	pages/component/map/map.test.js
#	pages/component/map/map.uvue
#	pages/component/radio/radio.uvue
#	pages/component/scroll-view/scroll-view-refresher.test.js
#	pages/component/scroll-view/scroll-view.test.js
#	pages/component/scroll-view/scroll-view.uvue
#	pages/component/swiper/swiper.test.js
#	pages/component/swiper/swiper.uvue
#	pages/component/textarea/textarea.uvue
#	pages/component/video/video.test.js
#	pages/component/video/video.uvue
#	pages/component/web-view-local/web-view-local.test.js
#	pages/component/web-view-local/web-view-local.uvue
#	pages/component/web-view/web-view.test.js
#	pages/component/web-view/web-view.uvue
#	pages/pages.test.js
#	pages/tabBar/API.uvue
#	pages/tabBar/CSS.uvue
#	pages/tabBar/component.uvue
#	pages/tabBar/template.uvue
#	pages/template/browser-canvas/browser-canvas.uvue
#	pages/template/slider-100/slider-100.uvue
#	readme.md
#	testSequencer.js
...@@ -20,9 +20,17 @@ ...@@ -20,9 +20,17 @@
myMap: new Map<string, any>(), myMap: new Map<string, any>(),
func: () : string => { func: () : string => {
return 'globalData func' return 'globalData func'
}
}, },
onLaunch: function () { launchOptions: {
path: '',
} as OnLaunchOptions,
onShowOption: {
path: ''
} as OnShowOptions
},
onLaunch: function (res : OnLaunchOptions) {
this.globalData.launchOptions = res
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 1000) setLifeCycleNum(state.lifeCycleNum + 1000)
console.log('App Launch') console.log('App Launch')
...@@ -37,16 +45,57 @@ ...@@ -37,16 +45,57 @@
// observer1.observe({ // observer1.observe({
// entryTypes: ['render', 'navigation'], // entryTypes: ['render', 'navigation'],
// } as PerformanceObserverOptions) // } as PerformanceObserverOptions)
// 统计上报 - 应用启动
// uni.report({
// name: 'uni-app-launch',
// options: res,
// success(res_data) {
// console.log(res_data);
// }, fail(err_data) {
// console.log(err_data);
// }
// })
}, },
onShow: function () { onShow: function (res : OnShowOptions) {
this.globalData.onShowOption = res
// 处理scheme或通用链接直达
let url = this.getRedirectUrl(res.appScheme, res.appLink);
if (null != url) {
uni.navigateTo({
url: url
})
}
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum + 100) setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App Show') console.log('App Show')
// 统计上报 - 应用显示
// uni.report({
// name: 'uni-app-show',
// success(res_data) {
// console.log(res_data);
// }, fail(err_data) {
// console.log(err_data);
// }
// })
}, },
onHide: function () { onHide: function () {
// 自动化测试 // 自动化测试
setLifeCycleNum(state.lifeCycleNum - 100) setLifeCycleNum(state.lifeCycleNum - 100)
console.log('App Hide') console.log('App Hide')
// 统计上报 - 应用进入后台
// uni.report({
// name: 'uni-app-hide',
// success(res) {
// console.log(res);
// }, fail(err) {
// console.log(err);
// }
// })
}, },
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
onLastPageBackPress: function () { onLastPageBackPress: function () {
...@@ -70,11 +119,56 @@ ...@@ -70,11 +119,56 @@
onExit() { onExit() {
console.log('App Exit') console.log('App Exit')
}, },
// onError(err : any) {
// // 统计上报 - 应用发生错误
// uni.report({
// name: 'uni-app-error',
// options: err,
// success(res) {
// console.log(res);
// }, fail(err) {
// console.log(err);
// }
// })
// },
// #endif // #endif
methods: { methods: {
increasetLifeCycleNum() { increasetLifeCycleNum() {
setLifeCycleNum(state.lifeCycleNum + 100) setLifeCycleNum(state.lifeCycleNum + 100)
console.log('App increasetLifeCycleNum') console.log('App increasetLifeCycleNum')
},
getRedirectUrl(scheme : string | null, ulink : string | null) : string | null {
//解析scheme或universal link启动直达页面:
//scheme格式:uniappx://redirect/pages/component/view/view?key=value //其中redirect后为页面路径
//universal link格式:https://uniappx.dcloud.net.cn/ulink/redirect.html?url=%2Fpages%2Fcomponent%2Fview%2Fview%3Fkey%3Dvalue //通用链接路径需固定,?后面的url参数为直达页面路径,注意url字段值需做url编码(可使用encodeURIComponent方法)
let url : string | null = null;
if (null != scheme && scheme.length > 0) {
const PATHPRE = 'redirect';
let parts : string | null = null;
let pos = scheme.search('//');
if (pos > 0) {
parts = scheme.substring(pos + 2);
}
if (null != parts && parts.startsWith(PATHPRE)) {
url = parts.substring(PATHPRE.length);
}
} else if (null != ulink && ulink.length > 0) {
const PATH = 'ulink/redirect.html';
let parts = ulink.split('?');
if (parts.length > 1 && parts[0].endsWith(PATH) && parts[1].length > 0) {
parts[1].split('&').forEach((e) => {
let params = e.split('=');
if (params.length > 1 && params[0].length > 0 && params[1].length > 0) {
if ('url' == params[0]) {
if (null == url) {
url = decodeURIComponent(params[1]);
}
}
}
});
}
}
return url;
} }
} }
} }
...@@ -83,4 +177,15 @@ ...@@ -83,4 +177,15 @@
<style> <style>
/*每个页面公共css */ /*每个页面公共css */
@import "./common/uni.css"; @import "./common/uni.css";
/* #ifdef WEB */
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .uni-page-head-btn {
display: none !important;
}
/* #endif */
</style> </style>
## 1.0.16 ## 1.0.31
* update 4.24.2024072208 * update 4.28.2024092105-alpha
## 1.0.15 ## 1.0.30
* update 4.23.2024070804 * update 4.27.2024091308-alpha
## 1.0.27 ## 1.0.29
* update 4.23.2024070309-alpha * update 4.26.2024082213-alpha
## 1.0.25 ## 1.0.28
* update 4.22.2024062415-alpha * update 4.25.2024081703-alpha
## 1.0.24
* update 4.21.2024061818-alpha
## 1.0.23
* update 4.19.2024060704-alpha
## 1.0.22
* update 4.18.2024060311-alpha
## 1.0.21
* update 4.17.2024051110-alpha
## 1.0.20
* update 4.16.2024051009-alpha
## 1.0.19
* update 4.14.2024042905-alpha
## 1.0.18
* update 4.13.2024042321-alpha
## 1.0.17
* update 4.12.2024041009-alpha
## 1.0.11 ## 1.0.11
* update 4.01.2024020211-alpha * update 4.01.2024020211-alpha
......
...@@ -189,7 +189,7 @@ ...@@ -189,7 +189,7 @@
} }
.text-disabled { .text-disabled {
color: #a0a0a0; color: #a0a0a0!important;
} }
...@@ -246,6 +246,11 @@ ...@@ -246,6 +246,11 @@
font-weight: normal; font-weight: normal;
} }
/* left-windows */
.left-win-active {
color: #007AFF!important;
}
/* --tab-bar-end-- */ /* --tab-bar-end-- */
/* #ifdef APP */ /* #ifdef APP */
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
<button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button> <button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button>
<button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button> <button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button>
<button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button> <button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button>
<button class="button" @click="hideTabBarItem">{{ !hasHiddenTabBarItem ? '隐藏接口Item' : '显示接口Item' }}</button>
<button class="button" @click="setTabBarTitle">{{ !hasSetLongTitle ? '自定义超长标题' : '移除自定义信息' }}</button>
<view class="btn-area"> <view class="btn-area">
<!-- <button class="button" type="primary" @click="navigateBack">关闭</button> --> <!-- <button class="button" type="primary" @click="navigateBack">关闭</button> -->
</view> </view>
...@@ -21,7 +23,9 @@ ...@@ -21,7 +23,9 @@
hasShownTabBarRedDot: false, hasShownTabBarRedDot: false,
hasCustomedStyle: false, hasCustomedStyle: false,
hasCustomedItem: false, hasCustomedItem: false,
hasHiddenTabBar: false hasHiddenTabBar: false,
hasHiddenTabBarItem: false,
hasSetLongTitle: false,
} }
}, },
destroyed() { destroyed() {
...@@ -56,8 +60,58 @@ ...@@ -56,8 +60,58 @@
} as SetTabBarItemOptions } as SetTabBarItemOptions
uni.setTabBarItem(tabBarOptions) uni.setTabBarItem(tabBarOptions)
} }
if (this.hasHiddenTabBarItem || this.hasSetLongTitle) {
let tabBarOptions = {
visible: true,
index: 1,
text: '接口',
iconPath: '/static/api.png',
selectedIconPath: '/static/apiHL.png'
} as SetTabBarItemOptions
uni.setTabBarItem(tabBarOptions)
}
}, },
methods: { methods: {
setTabBarTitle(){
let tabBarOptions = {
visible: true,
index: 1,
text: '接口',
iconPath: '/static/api.png',
selectedIconPath: '/static/apiHL.png'
} as SetTabBarItemOptions
if (!this.hasSetLongTitle) {
tabBarOptions.text = "超长标题内容超长标题内容超长标题内容超长标题测试";
tabBarOptions.iconPath = "";
tabBarOptions.selectedIconPath = "";
} else {
tabBarOptions.text = "接口";
tabBarOptions.iconPath = "/static/api.png";
tabBarOptions.selectedIconPath = "/static/apiHL.png";
}
uni.setTabBarItem(tabBarOptions)
this.hasSetLongTitle = !this.hasSetLongTitle
},
hideTabBarItem(){
let tabBarOptions = {
visible: true,
index: 1,
text: '接口',
iconPath: '/static/api.png',
selectedIconPath: '/static/apiHL.png'
} as SetTabBarItemOptions
if (!this.hasHiddenTabBarItem) {
tabBarOptions.visible = false;
} else {
tabBarOptions.visible = true;
}
uni.setTabBarItem(tabBarOptions)
this.hasHiddenTabBarItem = !this.hasHiddenTabBarItem
},
navigateBack() { navigateBack() {
this.$emit('unmount') this.$emit('unmount')
}, },
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
<button class="btn" type="button" data-action="reLaunch">reLaunch</button> <button class="btn" type="button" data-action="reLaunch">reLaunch</button>
<button class="btn" type="button" data-action="switchTab">switchTab</button> <button class="btn" type="button" data-action="switchTab">switchTab</button>
<button class="btn" type="button" data-action="getEnv">getEnv</button> <button class="btn" type="button" data-action="getEnv">getEnv</button>
<!-- <button class="btn" type="button" data-action="getTheme">获取主题</button> -->
</div> </div>
<p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p> <p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
<div class="btn-list"> <div class="btn-list">
...@@ -88,6 +89,9 @@ ...@@ -88,6 +89,9 @@
}) })
}); });
break; break;
/* case 'getTheme':
alert(getThemePreference())
break; */
default: default:
uni.webView[action]({ uni.webView[action]({
url: '/pages/component/button/button' url: '/pages/component/button/button'
...@@ -108,6 +112,15 @@ ...@@ -108,6 +112,15 @@
} }
}) })
}) })
/* function getThemePreference() {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
} else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) {
return 'light';
}
return 'unknown';
} */
</script> </script>
</body> </body>
</html> </html>
// 仅测试 console.log 时机问题 // 仅测试 console.log 时机问题
import './test-main-console.uts' import './test-main-console.uts'
import App from './App.uvue' import App from './App.uvue'
import { createSSRApp } from 'vue' import { createSSRApp } from 'vue'
export function createApp() { export function createApp() {
const app = createSSRApp(App) const app = createSSRApp(App)
// app.mixin({ // app.mixin({
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
"name": "Hello uni-app x", "name": "Hello uni-app x",
"appid": "__UNI__HelloUniAppX", "appid": "__UNI__HelloUniAppX",
"description": "", "description": "",
"versionName": "1.4", "versionName": "1.5",
"versionCode": 10400, "versionCode": 10500,
"uni-app-x": {}, "uni-app-x": {},
/* 快应用特有相关 */ /* 快应用特有相关 */
"quickapp": {}, "quickapp": {},
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
} }
} }
}, },
"uni-getLocation":{
"system":{},
"tencent":{}
},
"uni-ad": { "uni-ad": {
"gdt": {} "gdt": {}
} }
...@@ -64,7 +68,7 @@ ...@@ -64,7 +68,7 @@
"sdkConfigs" : { "sdkConfigs" : {
"maps" : { "maps" : {
"qqmap" : { "qqmap" : {
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU" "key" : ""
} }
} }
} }
......
此差异已折叠。
const PAGE_PATH = '/pages/API/animation-frame/animation-frame'
describe('API-cancelAnimationFrame', () => {
let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(600);
});
it('cancelAnimationFrame', async () => {
await page.callMethod('startRequestAnimationFrame')
await page.waitFor(100)
const data1 = await page.data()
expect(data1.testFrameCount > 0).toBe(true)
await page.callMethod('stopRequestAnimationFrame')
await page.waitFor(100)
const data2 = await page.data()
const testFrameCount = data2.testFrameCount
await page.waitFor(100)
const data3 = await page.data()
expect(data3.testFrameCount).toBe(testFrameCount)
});
});
<template>
<view class="page">
<page-head :title="title"></page-head>
<button @click="startRequestAnimationFrame">requestAnimationFrame</button>
<button @click="stopRequestAnimationFrame">cancelAnimationFrame</button>
<text class="frame-count">FPS: {{FPSString}}</text>
<text class="frame-count">FrameCount: {{testFrameCount}}</text>
<text class="tips">提示: 在当前测试例子中,每增加一次调用 requestAnimationFrame 帧率翻倍,cancelAnimationFrame 后恢复</text>
</view>
</template>
<script>
export default {
data() {
return {
title: 'AnimationFrame',
taskId: 0,
FPSString: '- / -ms',
lastTime: 0,
frameCount: 0,
testFrameCount: 0
}
},
onUnload() {
if (this.taskId > 0) {
this.stopRequestAnimationFrame()
}
},
methods: {
startRequestAnimationFrame() {
this.taskId = requestAnimationFrame((timestamp : number) => {
this.updateFPS(timestamp)
this.testFrameCount++
this.startRequestAnimationFrame()
})
},
stopRequestAnimationFrame() {
cancelAnimationFrame(this.taskId)
this.lastTime = 0
this.frameCount = 0
this.FPSString = '- / -ms'
},
updateFPS(timestamp : number) {
this.frameCount++
if (timestamp - this.lastTime >= 1000) {
const timeOfFrame = (1000 / this.frameCount)
this.FPSString = `${this.frameCount} / ${timeOfFrame.toFixed(3)}ms`
this.frameCount = 0
this.lastTime = timestamp
}
}
}
}
</script>
<style>
.page {
padding: 15px;
}
.frame-count {
margin-top: 15px;
}
.tips {
font-size: 12px;
margin-top: 30px;
opacity: 0.7;
}
</style>
<template>
<view class="page">
<page-head :title="title"></page-head>
<canvas class="canvas-element" canvas-id="canvas" id="canvas"></canvas>
<scroll-view class="scroll-view">
<view class="grid-view">
<view class="grid-item" v-for="(name, index) in names" :key="index">
<button class="canvas-drawing-button" @click="handleCanvasButton(name)">{{name}}</button>
</view>
</view>
<button class="btn-to-image" @click="toTempFilePath" type="primary">toTempFilePath</button>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'createContext',
names: ["rotate", "scale", "reset", "translate", "save", "restore", "drawImage", "fillText", "fill",
"stroke", "clearRect", "beginPath", "closePath", "moveTo", "lineTo", "rect", "arc",
"quadraticCurveTo", "bezierCurveTo", "setFillStyle", "setStrokeStyle", "setGlobalAlpha",
"setShadow", "setFontSize", "setLineCap", "setLineJoin", "setLineWidth", "setMiterLimit"
],
// TODO 缺失 CanvasContext
canvasContext: null as any | null
}
},
onReady() {
// @ts-ignore
this.canvasContext = uni.createCanvasContext('canvas', this)
},
methods: {
toTempFilePath() {
// TODO 缺失
// uni.canvasToTempFilePath({
// canvasId: 'canvas',
// success: (res) => {
// console.log(res.tempFilePath)
// },
// fail: (err) => {
// console.error(JSON.stringify(err))
// }
// })
},
handleCanvasButton(name : string) {
switch (name) {
case "rotate":
this.rotate();
break;
case "scale":
this.scale();
break;
case "reset":
this.reset();
break;
case "translate":
this.translate();
break;
case "save":
this.save();
break;
case "restore":
this.restore();
break;
case "drawImage":
this.drawImage();
break;
case "fillText":
this.fillText();
break;
case "fill":
this.fill();
break;
case "stroke":
this.stroke();
break;
case "clearRect":
this.clearRect();
break;
case "beginPath":
this.beginPath();
break;
case "closePath":
this.closePath();
break;
case "moveTo":
this.moveTo();
break;
case "lineTo":
this.lineTo();
break;
case "rect":
this.rect();
break;
case "arc":
this.arc();
break;
case "quadraticCurveTo":
this.quadraticCurveTo();
break;
case "bezierCurveTo":
this.bezierCurveTo();
break;
case "setFillStyle":
this.setFillStyle();
break;
case "setStrokeStyle":
this.setStrokeStyle();
break;
case "setGlobalAlpha":
this.setGlobalAlpha();
break;
case "setShadow":
this.setShadow();
break;
case "setFontSize":
this.setFontSize();
break;
case "setLineCap":
this.setLineCap();
break;
case "setLineJoin":
this.setLineJoin();
break;
case "setLineWidth":
this.setLineWidth();
break;
case "setMiterLimit":
this.setMiterLimit();
break;
default:
break;
}
},
rotate() {
this.canvasContext!.beginPath()
this.canvasContext!.rotate(10 * Math.PI / 180)
this.canvasContext!.rect(225, 75, 20, 10)
this.canvasContext!.fill()
this.canvasContext!.draw()
},
scale() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(25, 25, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.scale(2, 2)
this.canvasContext!.beginPath()
this.canvasContext!.rect(25, 25, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
reset() {
this.canvasContext!.beginPath()
this.canvasContext!.setFillStyle('#000000')
this.canvasContext!.setStrokeStyle('#000000')
this.canvasContext!.setFontSize(10)
this.canvasContext!.setGlobalAlpha(1)
this.canvasContext!.setShadow(0, 0, 0, 'rgba(0, 0, 0, 0)')
this.canvasContext!.setLineCap('butt')
this.canvasContext!.setLineJoin('miter')
this.canvasContext!.setLineWidth(1)
this.canvasContext!.setMiterLimit(10)
this.canvasContext!.draw()
},
translate() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(10, 10, 100, 50)
this.canvasContext!.fill()
this.canvasContext!.translate(70, 70)
this.canvasContext!.beginPath()
this.canvasContext!.fill()
this.canvasContext!.draw()
},
save() {
this.canvasContext!.beginPath()
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.save()
this.canvasContext!.scale(2, 2)
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.rect(0, 0, 100, 100)
this.canvasContext!.stroke()
this.canvasContext!.restore()
this.canvasContext!.rect(0, 0, 50, 50)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
restore() {
[3, 2, 1].forEach((item) => {
this.canvasContext!.beginPath()
this.canvasContext!.save()
this.canvasContext!.scale(item, item)
this.canvasContext!.rect(10, 10, 100, 100)
this.canvasContext!.stroke()
this.canvasContext!.restore()
});
this.canvasContext!.draw()
},
drawImage() {
// #ifdef APP-PLUS
this.canvasContext!.drawImage('../../../static/app-plus/uni@2x.png', 0, 0)
// #endif
// #ifndef APP-PLUS
this.canvasContext!.drawImage('../../../static/uni.png', 0, 0)
// #endif
this.canvasContext!.draw()
},
fillText() {
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 10)
this.canvasContext!.lineTo(300, 10)
this.canvasContext!.stroke()
// this.canvasContext!.save()
// this.canvasContext!.scale(1.5, 1.5)
// this.canvasContext!.translate(20, 20)
this.canvasContext!.setFontSize(10)
this.canvasContext!.fillText('Hello World', 0, 30)
this.canvasContext!.setFontSize(20)
this.canvasContext!.fillText('Hello World', 100, 30)
// this.canvasContext!.restore()
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 30)
this.canvasContext!.lineTo(300, 30)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
fill() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(20, 20, 150, 100)
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.fill()
this.canvasContext!.draw()
},
stroke() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.setStrokeStyle('#00ff00')
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
clearRect() {
this.canvasContext!.setFillStyle('#ff0000')
this.canvasContext!.beginPath()
this.canvasContext!.rect(0, 0, 300, 150)
this.canvasContext!.fill()
this.canvasContext!.clearRect(20, 20, 100, 50)
this.canvasContext!.draw()
},
beginPath() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(5)
this.canvasContext!.setStrokeStyle('#ff0000')
this.canvasContext!.moveTo(0, 75)
this.canvasContext!.lineTo(250, 75)
this.canvasContext!.stroke()
this.canvasContext!.beginPath()
this.canvasContext!.setStrokeStyle('#0000ff')
this.canvasContext!.moveTo(50, 0)
this.canvasContext!.lineTo(150, 130)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
closePath() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(1)
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.closePath()
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
moveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(0, 0)
this.canvasContext!.lineTo(300, 150)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
lineTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.lineTo(20, 100)
this.canvasContext!.lineTo(70, 100)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
rect() {
this.canvasContext!.beginPath()
this.canvasContext!.rect(20, 20, 150, 100)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
arc() {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(2)
this.canvasContext!.arc(75, 75, 50, 0, Math.PI * 2, true)
this.canvasContext!.moveTo(110, 75)
this.canvasContext!.arc(75, 75, 35, 0, Math.PI, false)
this.canvasContext!.moveTo(65, 65)
this.canvasContext!.arc(60, 65, 5, 0, Math.PI * 2, true)
this.canvasContext!.moveTo(95, 65)
this.canvasContext!.arc(90, 65, 5, 0, Math.PI * 2, true)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
quadraticCurveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.quadraticCurveTo(20, 100, 200, 20)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
bezierCurveTo() {
this.canvasContext!.beginPath()
this.canvasContext!.moveTo(20, 20)
this.canvasContext!.bezierCurveTo(20, 100, 200, 100, 200, 20)
this.canvasContext!.stroke()
this.canvasContext!.draw()
},
setFillStyle() {
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
this.canvasContext!.setFillStyle(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.fill()
})
this.canvasContext!.draw()
},
setStrokeStyle() {
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach((item : string, index : number) => {
this.canvasContext!.setStrokeStyle(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setGlobalAlpha() {
this.canvasContext!.setFillStyle('#000000');
[1, 0.5, 0.1].forEach((item : number, index : number) => {
this.canvasContext!.setGlobalAlpha(item)
this.canvasContext!.beginPath()
this.canvasContext!.rect(0 + 75 * index, 0, 50, 50)
this.canvasContext!.fill()
})
this.canvasContext!.draw()
this.canvasContext!.setGlobalAlpha(1)
},
setShadow() {
this.canvasContext!.beginPath()
this.canvasContext!.setShadow(10, 10, 10, 'rgba(0, 0, 0, 199)')
this.canvasContext!.rect(10, 10, 100, 100)
this.canvasContext!.fill()
this.canvasContext!.draw()
},
setFontSize() {
[10, 20, 30, 40].forEach((item : number, index : number) => {
this.canvasContext!.setFontSize(item)
this.canvasContext!.fillText('Hello, world', 20, 20 + 40 * index)
})
this.canvasContext!.draw()
},
setLineCap() {
this.canvasContext!.setLineWidth(10);
['butt', 'round', 'square'].forEach((item : string, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineCap(item)
this.canvasContext!.moveTo(20, 20 + 20 * index)
this.canvasContext!.lineTo(100, 20 + 20 * index)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setLineJoin() {
this.canvasContext!.setLineWidth(10);
['bevel', 'round', 'miter'].forEach((item : string, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineJoin(item)
this.canvasContext!.moveTo(20 + 80 * index, 20)
this.canvasContext!.lineTo(100 + 80 * index, 50)
this.canvasContext!.lineTo(20 + 80 * index, 100)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setLineWidth() {
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setLineWidth(item)
this.canvasContext!.moveTo(20, 20 + 20 * index)
this.canvasContext!.lineTo(100, 20 + 20 * index)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
},
setMiterLimit() {
this.canvasContext!.setLineWidth(4);
[2, 4, 6, 8, 10].forEach((item : number, index : number) => {
this.canvasContext!.beginPath()
this.canvasContext!.setMiterLimit(item)
this.canvasContext!.moveTo(20 + 80 * index, 20)
this.canvasContext!.lineTo(100 + 80 * index, 50)
this.canvasContext!.lineTo(20 + 80 * index, 100)
this.canvasContext!.stroke()
})
this.canvasContext!.draw()
}
}
}
</script>
<style>
.page {
flex: 1;
height: 100%;
overflow: hidden;
}
.scroll-view {
flex: 1;
padding-bottom: 50px;
}
.canvas-element {
width: 100%;
height: 250px;
background-color: #ffffff;
}
.grid-view {
padding: 10px;
flex-direction: row;
flex-wrap: wrap;
}
.grid-item {
width: 50%;
padding: 5px;
}
.btn-to-image {
margin: 10px;
}
</style>
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
</block> </block>
</view> </view>
<view class="uni-btn-v"> <view class="uni-btn-v">
<view class="tips">注意:需要正确配置地图服务商的Key才能正常选择位置</view>
<button type="primary" @tap="chooseLocation">选择位置</button> <button type="primary" @tap="chooseLocation">选择位置</button>
<button @tap="clear">清空</button> <button @tap="clear">清空</button>
</view> </view>
...@@ -25,7 +26,7 @@ ...@@ -25,7 +26,7 @@
</view> </view>
</template> </template>
<script lang="uts"> <script lang="uts">
function formatLocation(longitude, latitude) { function formatLocation (longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') { if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude) longitude = parseFloat(longitude)
latitude = parseFloat(latitude) latitude = parseFloat(latitude)
...@@ -38,7 +39,7 @@ ...@@ -38,7 +39,7 @@
} }
} }
export default { export default {
data() { data () {
return { return {
title: 'chooseLocation', title: 'chooseLocation',
hasLocation: false, hasLocation: false,
...@@ -50,9 +51,9 @@ ...@@ -50,9 +51,9 @@
chooseLocation: function () { chooseLocation: function () {
uni.chooseLocation({ uni.chooseLocation({
success: (res) => { success: (res) => {
console.log(res,123) console.log(res, 123)
this.hasLocation = true, this.hasLocation = true
this.location = formatLocation(res.longitude, res.latitude), this.location = formatLocation(res.longitude, res.latitude)
this.locationAddress = res.address this.locationAddress = res.address
} }
}) })
...@@ -69,4 +70,10 @@ ...@@ -69,4 +70,10 @@
padding-bottom: 0; padding-bottom: 0;
height: 440rpx; height: 440rpx;
} }
.tips {
font-size: 12px;
margin-top: 15px;
opacity: .8;
}
</style> </style>
...@@ -28,19 +28,21 @@ ...@@ -28,19 +28,21 @@
<script> <script>
import { ItemType } from '@/components/enum-data/enum-data'; import { ItemType } from '@/components/enum-data/enum-data';
type Camera = "back" | "front"
type Source = "album" | "camera"
export default { export default {
data() { data() {
return { return {
title: "chooseVideo", title: "chooseVideo",
src: "", src: "",
sourceTypeItemTypes: [{ "value": 0, "name": "从相册中选择视频" }, { "value": 1, "name": "拍摄视频" }, { "value": 2, "name": "从相册中选择视频或拍摄视频" }] as ItemType[], sourceTypeItemTypes: [{ "value": 0, "name": "从相册中选择视频" }, { "value": 1, "name": "拍摄视频" }, { "value": 2, "name": "从相册中选择视频或拍摄视频" }] as ItemType[],
sourceTypeItems: [["album"], ["camera"], ["album", "camera"]], sourceTypeItems: [["album"], ["camera"], ["album", "camera"]] as Source[][],
cameraItemTypes: [{ "value": 0, "name": "后置摄像头" }, { "value": 1, "name": "前置摄像头" }] as ItemType[], cameraItemTypes: [{ "value": 0, "name": "后置摄像头" }, { "value": 1, "name": "前置摄像头" }] as ItemType[],
cameraItems: ["back", "front"], cameraItems: ["back", "front"] as Camera[],
sourceType: ["album", "camera"], sourceType: ["album", "camera"] as Source[],
compressed: true, compressed: true,
maxDuration: 60, maxDuration: 60,
camera: "back", camera: "back" as Camera,
videoInfo: "" videoInfo: ""
} }
}, },
......
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap">
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
旋转手机即可获取方位信息
</view>
<view class="direction">
<view class="bg-compass-line"></view>
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'"></image>
<view class="direction-value">
<text>{{direction}}</text>
<text class="direction-degree">o</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'onCompassChange',
direction: 0
}
},
onReady: function () {
uni.onCompassChange((res) => {
console.log('onCompassChange', res)
this.direction = res.direction
})
},
onUnload() {
uni.stopCompass();
this.direction = 0;
}
}
</script>
<style>
.direction {
position: relative;
margin-top: 70rpx;
display: flex;
width: 540rpx;
height: 540rpx;
align-items: center;
justify-content: center;
margin:0 auto;
}
.direction-value {
position: relative;
font-size: 200rpx;
color: #353535;
line-height: 1;
z-index: 1;
}
.direction-degree {
position: absolute;
top: 0;
right: -40rpx;
font-size: 60rpx;
}
.bg-compass {
position: absolute;
top: 0;
left: 0;
width: 540rpx;
height: 540rpx;
transition: .1s;
}
.bg-compass-line {
position: absolute;
left: 267rpx;
top: -10rpx;
width: 6rpx;
height: 56rpx;
background-color: #1AAD19;
border-radius: 999rpx;
z-index: 1;
}
</style>
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<view>
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view class="image-container"> <view class="image-container">
...@@ -27,9 +28,8 @@ ...@@ -27,9 +28,8 @@
@confirm="onQualityConfirm"></input-data> @confirm="onQualityConfirm"></input-data>
<input-data title="压缩后图片的宽度,单位px" type="string" @confirm="onCompressedWidthConfirm"></input-data> <input-data title="压缩后图片的宽度,单位px" type="string" @confirm="onCompressedWidthConfirm"></input-data>
<input-data title="压缩后图片的高度,单位px" type="string" @confirm="onCompressedHeightConfirm"></input-data> <input-data title="压缩后图片的高度,单位px" type="string" @confirm="onCompressedHeightConfirm"></input-data>
<input-data defaultValue="auto" title="压缩后图片的宽度,支持px、%、auto" type="string" @confirm="onWidthConfirm"></input-data>
<input-data defaultValue="auto" title="压缩后图片的高度,支持px、%、auto" type="string" @confirm="onHeightConfirm"></input-data>
<input-data defaultValue="0" title="旋转度数,范围0~360" type="number" @confirm="onRotateConfirm"></input-data> <input-data defaultValue="0" title="旋转度数,范围0~360" type="number" @confirm="onRotateConfirm"></input-data>
</view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
...@@ -156,7 +156,7 @@ ...@@ -156,7 +156,7 @@
uni.getImageInfo({ uni.getImageInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (_res) => { success: (_res) => {
let beforeCompressSize: number, afterComoressSize: number; let beforeCompressSize : number, afterComoressSize : number;
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
beforeCompressSize = new FileInputStream(UTSAndroid.convert2AbsFullPath(this.imageSrcForTest)).available(); beforeCompressSize = new FileInputStream(UTSAndroid.convert2AbsFullPath(this.imageSrcForTest)).available();
afterComoressSize = new FileInputStream(res.tempFilePath.substring("file://".length)).available(); afterComoressSize = new FileInputStream(res.tempFilePath.substring("file://".length)).available();
......
...@@ -19,7 +19,7 @@ describe('API-compressVideo', () => { ...@@ -19,7 +19,7 @@ describe('API-compressVideo', () => {
if (process.env.uniTestPlatformInfo.startsWith('android')) { if (process.env.uniTestPlatformInfo.startsWith('android')) {
const infos = process.env.uniTestPlatformInfo.split(' '); const infos = process.env.uniTestPlatformInfo.split(' ');
const version = parseInt(infos[infos.length - 1]); const version = parseInt(infos[infos.length - 1]);
if (version == 5 || version == 7 || version == 10) return; // android5.1、android7、android10存在兼容问题,待修复 if (version == 5 || version == 7 || version == 9 || version == 10) return; // android5.1、android7、android9、android10存在兼容问题,待修复
expect(await page.data('videoInfoForTest')).toEqual({ expect(await page.data('videoInfoForTest')).toEqual({
width: 640, width: 640,
height: 360, height: 360,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<scroll-view style="flex:1"> <scroll-view style="flex:1">
<!-- #endif --> <!-- #endif -->
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<video class="video" :src="beforeCompressPath" :controls="true"></video> <video class="video" :src="beforeCompressPath" :controls="true"></video>
<view class="uni-title"> <view class="uni-title">
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
<slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider> <slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider>
</view> </view>
</view> </view>
</view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
...@@ -116,7 +118,7 @@ ...@@ -116,7 +118,7 @@
this.resolution = event.detail.value; this.resolution = event.detail.value;
}, },
testCompressVideo() { testCompressVideo() {
let beforeCompressSize: number, afterComoressSize: number; let beforeCompressSize : number, afterComoressSize : number;
uni.compressVideo({ uni.compressVideo({
src: this.videoSrcForTest, src: this.videoSrcForTest,
quality: 'medium', quality: 'medium',
...@@ -124,11 +126,11 @@ ...@@ -124,11 +126,11 @@
uni.getVideoInfo({ uni.getVideoInfo({
src: this.videoSrcForTest, src: this.videoSrcForTest,
success: (_res) => { success: (_res) => {
beforeCompressSize = _res.size.toInt(); beforeCompressSize = Math.trunc(_res.size);
uni.getVideoInfo({ uni.getVideoInfo({
src: res.tempFilePath, src: res.tempFilePath,
success: (__res) => { success: (__res) => {
afterComoressSize = __res.size.toInt(); afterComoressSize = Math.trunc(__res.size);
this.videoInfoForTest = { this.videoInfoForTest = {
"width": __res.width, "width": __res.width,
"height": __res.height, "height": __res.height,
......
...@@ -6,49 +6,46 @@ describe('inner-audio', () => { ...@@ -6,49 +6,46 @@ describe('inner-audio', () => {
return return
} }
beforeAll(async () => { beforeAll(async () => {
page = await program.reLaunch('/pages/API/inner-audio/inner-audio') page = await program.reLaunch('/pages/API/create-inner-audio-context/create-inner-audio-context')
await page.waitFor('view'); await page.waitFor('view');
}); });
function getData(key = '') {
return new Promise(async (resolve, reject) => {
const data = await page.data()
resolve(key ? data[key] : data)
})
}
it('onCanplay',async()=>{ it('onCanplay',async()=>{
await page.waitFor(1000) await page.waitFor(1000)
await page.waitFor(async()=>{ await page.waitFor(async()=>{
return await getData('isCanplay') return await page.data('isCanplay')
}) })
expect(await getData('buffered')).toBeGreaterThan(0) expect(await page.data('buffered')).toBeGreaterThan(0)
}) })
it('play-onPlay-onTimeUpdate', async () => { it('play-onPlay-onTimeUpdate', async () => {
await page.callMethod('play') await page.callMethod('play')
await page.waitFor(3000); const waitTime = process.env.uniTestPlatformInfo.includes('chrome') ? 5000:3000
expect(await getData('isPlaying')).toBeTruthy() await page.waitFor(waitTime)
console.log("duration:",await getData('duration'),"currentTime:",await getData('currentTime')) expect(await page.data('isPlaying')).toBeTruthy()
expect(await getData('duration')).toBeCloseTo(175.109, 0); console.log("duration:",await page.data('duration'),"currentTime:",await page.data('currentTime'))
// console.log("isPaused",await getData('isPaused')) expect(await page.data('duration')).toBeCloseTo(175.109, 0);
// expect(await getData('currentTime')).toBeGreaterThan(0); // console.log("isPaused",await page.data('isPaused'))
// expect(await getData('isPaused')).toBeFalsy(); // expect(await page.data('currentTime')).toBeGreaterThan(0);
// expect(await page.data('isPaused')).toBeFalsy();
}); });
it('seek-onSeeking-onSeeked', async () => { it('seek-onSeeking-onSeeked', async () => {
await page.callMethod('onchange',20) await page.callMethod('onchange',20)
await page.waitFor(500); const waitTime = process.env.uniTestPlatformInfo.includes('chrome') ? 1500:500
expect(await getData('onSeekingTest')).toBeTruthy(); await page.waitFor(waitTime)
// expect(await getData('onWaitingTest')).toBeTruthy(); console.log("seek-onSeeking-onSeeked:",await page.data())
expect(await getData('onSeekedTest')).toBeTruthy(); expect(await page.data('onSeekingTest')).toBeTruthy();
// expect(await page.data('onWaitingTest')).toBeTruthy();
// expect(await page.data('onSeekedTest')).toBeTruthy();
expect(await program.screenshot()).toSaveImageSnapshot();
}); });
it('pause-onPause', async () => { it('pause-onPause', async () => {
await page.callMethod('pause') await page.callMethod('pause')
await page.waitFor(500); await page.waitFor(500);
expect(await getData('isPlaying')).toBeFalsy() expect(await page.data('isPlaying')).toBeFalsy()
// expect(await getData('isPaused')).toBeTruthy(); // expect(await page.data('isPaused')).toBeTruthy();
}); });
it('stop-onStop', async () => { it('stop-onStop', async () => {
...@@ -58,8 +55,8 @@ describe('inner-audio', () => { ...@@ -58,8 +55,8 @@ describe('inner-audio', () => {
await page.callMethod('stop') await page.callMethod('stop')
await page.callMethod('stop') await page.callMethod('stop')
await page.waitFor(1000); await page.waitFor(1000);
expect(await getData('isPlaying')).toBeFalsy() expect(await page.data('isPlaying')).toBeFalsy()
// expect(await getData('isPaused')).toBeTruthy(); // expect(await page.data('isPaused')).toBeTruthy();
}); });
it('onEnded', async () => { it('onEnded', async () => {
...@@ -67,7 +64,7 @@ describe('inner-audio', () => { ...@@ -67,7 +64,7 @@ describe('inner-audio', () => {
await page.waitFor(500); await page.waitFor(500);
await page.callMethod('play') await page.callMethod('play')
await page.waitFor(3000); await page.waitFor(3000);
// expect(await getData('isPlayEnd')).toBeTruthy(); // expect(await page.data('isPlayEnd')).toBeTruthy();
}); });
}); });
...@@ -32,10 +32,10 @@ ...@@ -32,10 +32,10 @@
<view class="uni-title"> <view class="uni-title">
<text class="uni-title-text">格式/路径示例</text> <text class="uni-title-text">格式/路径示例</text>
</View> </View>
<navigator url="/pages/API/inner-audio/inner-audio-format" class="uni-btn"> <navigator url="/pages/API/create-inner-audio-context/inner-audio-format" class="uni-btn">
<button type="primary" @click="pause">音频格式示例</button> <button type="primary" @click="pause">音频格式示例</button>
</navigator> </navigator>
<navigator url="/pages/API/inner-audio/inner-audio-path" class="uni-btn uni-common-mb"> <navigator url="/pages/API/create-inner-audio-context/inner-audio-path" class="uni-btn uni-common-mb">
<button type="primary" @click="pause">音频路径示例</button> <button type="primary" @click="pause">音频路径示例</button>
</navigator> </navigator>
</view> </view>
...@@ -58,9 +58,9 @@ ...@@ -58,9 +58,9 @@
_isChanging: false, _isChanging: false,
_audioContext: null as InnerAudioContext | null, _audioContext: null as InnerAudioContext | null,
// 自动化测试 // 自动化测试
onSeekingTest:false, onSeekingTest: false,
onSeekedTest:false, onSeekedTest: false,
onWaitingTest:false onWaitingTest: false
} }
}, },
computed: { computed: {
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
} }
this._audioContext!.onPlay(() => { this._audioContext!.onPlay(() => {
this.isPaused = false; this.isPaused = false;
console.log('开始播放',this.isPaused); console.log('开始播放', this.isPaused);
}); });
this.onTimeUpdate() this.onTimeUpdate()
this.onWaiting() this.onWaiting()
...@@ -159,6 +159,7 @@ ...@@ -159,6 +159,7 @@
// console.log('onTimeUpdate:音频播放进度更新事件,currentTime',this._audioContext!.currentTime); // console.log('onTimeUpdate:音频播放进度更新事件,currentTime',this._audioContext!.currentTime);
if (this._isChanging === true) { return; } if (this._isChanging === true) { return; }
this.currentTime = this._audioContext!.currentTime || 0; this.currentTime = this._audioContext!.currentTime || 0;
console.log('currentTime', this.currentTime);
if (this.currentTime > this.buffered) { if (this.currentTime > this.buffered) {
console.log('缓冲不足'); console.log('缓冲不足');
} }
...@@ -208,7 +209,7 @@ ...@@ -208,7 +209,7 @@
console.log('音频停止事件'); console.log('音频停止事件');
}); });
this.isPlaying = false; this.isPlaying = false;
console.log('stop',this.isPaused); console.log('stop', this.isPaused);
} }
} }
} }
......
const PAGE_PATH = '/pages/API/nodes-info/nodes-info' const PAGE_PATH = '/pages/API/create-selector-query/create-selector-query'
const RECT_LEFT = 15; const RECT_LEFT = 15;
const RECT_WIDTH = 150; const RECT_WIDTH = 150;
...@@ -57,9 +57,22 @@ describe('nodes-info', () => { ...@@ -57,9 +57,22 @@ describe('nodes-info', () => {
it('get-node-info-child', async () => { it('get-node-info-child', async () => {
const child = await page.$('.node-child') const child = await page.$('.node-child')
const childData = await child.data() const childData = await child.data()
console.log('get-node-info-child.childData.top', childData.top);
expect(childData.top > 100).toBe(true) expect(childData.top > 100).toBe(true)
}) })
it('multi-child', async () => {
const pageData = await page.data()
expect(pageData.selectCount).toBe(1)
expect(pageData.selectAllCount).toBe(2)
})
it('multi-child', async () => {
const pageData = await page.data()
expect(pageData.selectCount).toBe(1)
expect(pageData.selectAllCount).toBe(2)
})
// #ifdef APP // #ifdef APP
//检测onResize获取BoundingClientRect信息是否有效 //检测onResize获取BoundingClientRect信息是否有效
/* it('check_resizeRectValid', async () => { /* it('check_resizeRectValid', async () => {
...@@ -68,6 +81,23 @@ describe('nodes-info', () => { ...@@ -68,6 +81,23 @@ describe('nodes-info', () => {
}) */ }) */
// #endif // #endif
it('test filelds', async () => {
if (process.env.uniTestPlatformInfo.startsWith('web')) {
expect(true).toBe(true)
} else {
const pageData = await page.data()
expect(pageData.fieldsResultContainNode).toBe(true)
}
})
it('test node', async () => {
if (process.env.uniTestPlatformInfo.startsWith('web')) {
expect(true).toBe(true)
} else {
const pageData = await page.data()
expect(pageData.nodeResultContainNode).toBe(true)
}
})
}) })
async function getRootNode(selector) { async function getRootNode(selector) {
......
<template> <template>
<!-- #ifdef APP -->
<scroll-view class="page-scroll-view">
<!-- #endif -->
<view class="page" id="page"> <view class="page" id="page">
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button> <button class="btn btn-get-node-info" @click="getNodeInfo">getNodeInfo</button>
...@@ -36,11 +39,28 @@ ...@@ -36,11 +39,28 @@
</view> </view>
</view> </view>
<node-child class="node-child"></node-child> <node-child class="node-child"></node-child>
<text>子组件多根节点</text>
<multi-child ref="multi-child" id="multi-child"></multi-child>
<text>子组件多根节点(仅测试,用于验证查询是否超出范围)</text>
<multi-child id="multi-child-2"></multi-child>
<view>
<text>测试.fields</text>
<text>{{fieldsResultContainNode}}</text>
</view> </view>
<view>
<text>测试.node</text>
<text>{{nodeResultContainNode}}</text>
</view>
<canvas id="canvas1"></canvas>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template> </template>
<script> <script>
import nodeChild from './nodes-info-child.uvue' import nodeChild from './nodes-info-child.uvue'
import multiChild from './selector-query-child-multi.uvue'
type NodeInfoType = { type NodeInfoType = {
left : number | null, left : number | null,
...@@ -53,7 +73,8 @@ ...@@ -53,7 +73,8 @@
export default { export default {
components: { components: {
nodeChild nodeChild,
multiChild
}, },
data() { data() {
return { return {
...@@ -63,8 +84,21 @@ ...@@ -63,8 +84,21 @@
rootNodeInfo: null as NodeInfoType | null, rootNodeInfo: null as NodeInfoType | null,
//供自动化测试使用 //供自动化测试使用
// resizeRectValid: false // resizeRectValid: false
// TODO
selectCount: 0,
selectAllCount: 0,
fieldsResultContainNode: false,
nodeResultContainNode: false
} }
}, },
onReady() {
const instance2 = (this.$refs['multi-child'] as ComponentPublicInstance)
this.selectCount = instance2.$data['selectCount'] as number
this.selectAllCount = instance2.$data['selectAllCount'] as number
this.testFields()
this.testNode()
},
onResize() { onResize() {
//供自动化测试使用 //供自动化测试使用
/* var rect12Element = uni.getElementById("rect-1-2") /* var rect12Element = uni.getElementById("rect-1-2")
...@@ -122,7 +156,32 @@ ...@@ -122,7 +156,32 @@
} as NodeInfoType) } as NodeInfoType)
}) })
}) })
} },
// test .fields
testFields() {
uni.createSelectorQuery().select('.rect1').fields({
node: true
} as NodeField, (ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement
if(isElement){
this.fieldsResultContainNode = true
} else {
this.fieldsResultContainNode = false
}
}).exec()
},
// test .node
testNode() {
uni.createSelectorQuery().select('#canvas1').node((ret) => {
const isElement = (ret as NodeInfo).node instanceof UniElement
const isCanvasElement = ((ret as NodeInfo).node as UniCanvasElement).tagName == 'CANVAS'
if(isElement && isCanvasElement){
this.nodeResultContainNode = true
} else {
this.nodeResultContainNode = false
}
}).exec()
},
} }
} }
</script> </script>
...@@ -130,7 +189,6 @@ ...@@ -130,7 +189,6 @@
<style> <style>
.page { .page {
padding: 15px; padding: 15px;
flex: 1;
} }
.btn { .btn {
......
<template>
<view class="selector-query-view">
<text>selector-query</text>
<text class="text red">{{text1}}</text>
</view>
<view class="selector-query-view">
<text>selector-query</text>
<text class="text green">{{text2}}</text>
</view>
<view v-if="text1.length>0">1</view>
<text>{{text3}}</text>
</template>
<script>
export default {
data() {
return {
text1: "",
text2: "",
text3: "test-text-node",
viewCount: 0,
selectCount: 0,
selectAllCount: 0,
show: false
}
},
mounted() {
uni.createSelectorQuery().in(this).select('.selector-query-view').boundingClientRect().exec((ret) => {
this.text1 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectCount = ret.length
}
})
uni.createSelectorQuery().in(this).selectAll('.selector-query-view').boundingClientRect().exec((ret) => {
this.text2 = JSON.stringify(ret, null, 2)
if (ret.length == 1) {
this.selectAllCount = (ret[0] as NodeInfo[]).length
}
})
}
}
</script>
<style>
.green {
border: 3px solid green;
}
.red {
border: 3px solid red;
}
.view {
border: 3px dashed lime;
padding: 10px;
}
.text {
margin-top: 20px;
padding: 5px;
}
</style>
...@@ -55,11 +55,13 @@ ...@@ -55,11 +55,13 @@
success: (res) => { success: (res) => {
console.log('downloadFile success, res is', res.tempFilePath) console.log('downloadFile success, res is', res.tempFilePath)
self.imageSrc = res.tempFilePath; self.imageSrc = res.tempFilePath;
uni.hideLoading();
}, },
fail: (err) => { fail: (err) => {
console.log('downloadFile fail, err is:', err) console.log('downloadFile fail, err is:', err)
},
complete: (res) => {
uni.hideLoading(); uni.hideLoading();
this.task = null;
} }
}); });
this.task?.onProgressUpdate((update) => { this.task?.onProgressUpdate((update) => {
...@@ -140,11 +142,9 @@ ...@@ -140,11 +142,9 @@
// #ifdef APP // #ifdef APP
testInovkeDownloadFile({ testInovkeDownloadFile({
success:(res: any)=>{ success:(res: any)=>{
console.log("success :", res);
this.jest_result = true this.jest_result = true
}, },
fail:(err: any)=>{ fail:(err: any)=>{
console.log("fail :", err);
this.jest_result = false this.jest_result = false
} }
} as CommonOptions) } as CommonOptions)
...@@ -155,7 +155,6 @@ ...@@ -155,7 +155,6 @@
url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png", url: "https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/1789834995055525889-你好%23你好.png",
success: (res: DownloadFileSuccess) => { success: (res: DownloadFileSuccess) => {
this.jest_result = true; this.jest_result = true;
console.log("res :", res);
}, },
fail: () => { fail: () => {
this.jest_result = false; this.jest_result = false;
......
...@@ -32,9 +32,9 @@ ...@@ -32,9 +32,9 @@
}, },
methods: { methods: {
geAbsPath(path ?: Any) { geAbsPath(path ?: any) {
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
this.log += UTSAndroid.convert2AbsFullPath(path as String) + '\n' this.log += UTSAndroid.convert2AbsFullPath(path as string) + '\n'
// #endif // #endif
} }
......
...@@ -52,6 +52,14 @@ describe('event-bus', () => { ...@@ -52,6 +52,14 @@ describe('event-bus', () => {
expect(l3).toBe(0) expect(l3).toBe(0)
}) })
it('emit object params', async () => {
await page.callMethod('onObj')
await page.callMethod('emitWithObj')
const objArg = await page.data('objArg')
expect(objArg.a).toBe(1)
expect(objArg.b).toBe(2)
})
it('off-all', async () => { it('off-all', async () => {
await page.callMethod('clear') await page.callMethod('clear')
await page.callMethod('on') await page.callMethod('on')
......
...@@ -14,6 +14,12 @@ ...@@ -14,6 +14,12 @@
<view> <view>
<view v-for="(item, index) in log" :key="index">{{ item }}</view> <view v-for="(item, index) in log" :key="index">{{ item }}</view>
</view> </view>
<button @click="onObj">开始监听 obj 参数</button>
<button @click="emitWithObj">触发监听 obj 参数</button>
<view class="box">
<text>接收到的 obj 参数:</text>
<text>{{JSON.stringify(objArg)}}</text>
</view>
</view> </view>
</view> </view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
...@@ -26,6 +32,7 @@ ...@@ -26,6 +32,7 @@
data() { data() {
return { return {
log: [] as string[], log: [] as string[],
objArg: {},
} }
}, },
methods: { methods: {
...@@ -41,6 +48,11 @@ ...@@ -41,6 +48,11 @@
on2() { on2() {
uni.$on('test', this.fn2) uni.$on('test', this.fn2)
}, },
onObj() {
uni.$on('test-obj', (res: UTSJSONObject) => {
this.objArg = res
})
},
once() { once() {
uni.$once('test', this.fn) uni.$once('test', this.fn)
}, },
...@@ -53,6 +65,9 @@ ...@@ -53,6 +65,9 @@
emit() { emit() {
uni.$emit('test', 'msg:' + Date.now()) uni.$emit('test', 'msg:' + Date.now())
}, },
emitWithObj() {
uni.$emit('test-obj', { a: 1, b: 2 })
},
clear() { clear() {
this.log.length = 0 this.log.length = 0
}, },
......
...@@ -21,6 +21,15 @@ describe('ExtApi-GetAppAuthorizeSetting', () => { ...@@ -21,6 +21,15 @@ describe('ExtApi-GetAppAuthorizeSetting', () => {
await page.waitFor(600); await page.waitFor(600);
res = await uni.getAppAuthorizeSetting(); res = await uni.getAppAuthorizeSetting();
}); });
it('Check albumAuthorized', async () => {
expect(commonSupportList).toContain(res.albumAuthorized)
});
it('Check bluetoothAuthorized', async () => {
expect(commonSupportList).toContain(res.bluetoothAuthorized)
});
it('Check cameraAuthorized', async () => { it('Check cameraAuthorized', async () => {
expect(commonSupportList).toContain(res.cameraAuthorized) expect(commonSupportList).toContain(res.cameraAuthorized)
}); });
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="uni-common-mt"> <view class="uni-common-mt">
<view class="uni-list"> <view class="uni-list">
<!-- #ifdef APP-IOS -->
<view class="uni-list-cell"> <view class="uni-list-cell">
<view class="uni-pd"> <view class="uni-pd">
<view class="uni-label" style="width:180px;">是否授权使用相册</view> <view class="uni-label" style="width:180px;">是否授权使用相册</view>
...@@ -19,7 +18,6 @@ ...@@ -19,7 +18,6 @@
<input type="text" :disabled="true" placeholder="未获取" :value="bluetoothAuthorized" /> <input type="text" :disabled="true" placeholder="未获取" :value="bluetoothAuthorized" />
</view> </view>
</view> </view>
<!-- #endif -->
<view class="uni-list-cell"> <view class="uni-list-cell">
<view class="uni-pd"> <view class="uni-pd">
<view class="uni-label" style="width:180px;">是否授权使用摄像头</view> <view class="uni-label" style="width:180px;">是否授权使用摄像头</view>
...@@ -118,6 +116,8 @@ ...@@ -118,6 +116,8 @@
methods: { methods: {
getAppAuthorizeSetting: function () { getAppAuthorizeSetting: function () {
const res = uni.getAppAuthorizeSetting(); const res = uni.getAppAuthorizeSetting();
this.albumAuthorized = res.albumAuthorized;
this.bluetoothAuthorized = res.bluetoothAuthorized;
this.cameraAuthorized = res.cameraAuthorized; this.cameraAuthorized = res.cameraAuthorized;
this.locationAuthorized = res.locationAuthorized; this.locationAuthorized = res.locationAuthorized;
this.locationAccuracy = res.locationAccuracy ?? "unsupported"; this.locationAccuracy = res.locationAccuracy ?? "unsupported";
...@@ -127,8 +127,6 @@ ...@@ -127,8 +127,6 @@
this.notificationAlertAuthorized = res.notificationAlertAuthorized; this.notificationAlertAuthorized = res.notificationAlertAuthorized;
this.notificationBadgeAuthorized = res.notificationBadgeAuthorized; this.notificationBadgeAuthorized = res.notificationBadgeAuthorized;
this.notificationSoundAuthorized = res.notificationSoundAuthorized; this.notificationSoundAuthorized = res.notificationSoundAuthorized;
this.bluetoothAuthorized = res.bluetoothAuthorized;
this.albumAuthorized = res.albumAuthorized;
// #endif // #endif
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view class="page-scroll-view"> <scroll-view class="page-scroll-view">
<!-- #endif --> <!-- #endif -->
<view>
<page-head title="getCurrentPages"></page-head> <page-head title="getCurrentPages"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<button @click="_getCurrentPages">getCurrentPages</button> <button @click="_getCurrentPages">getCurrentPages</button>
...@@ -31,11 +32,14 @@ ...@@ -31,11 +32,14 @@
</view> </view>
<view class="set-value" v-else-if="item.type == 'string'"> <view class="set-value" v-else-if="item.type == 'string'">
<radio-group class="radio-set-value" @change="radioChange(item.key, $event as RadioGroupChangeEvent)"> <radio-group class="radio-set-value" @change="radioChange(item.key, $event as RadioGroupChangeEvent)">
<radio class="radio-value" v-for="(item2, index2) in item.value" :key="index2" :value="item2" >{{item2}}</radio> <radio class="radio-value" v-for="(item2, index2) in item.value" :key="index2" :value="item2">{{item2}}
</radio>
</radio-group> </radio-group>
</view> </view>
</view> </view>
</template> </template>
<button style='margin: 10px;' @click="goSetDisablePullDownRefresh">go set disable pullDownRefresh</button>
</view>
<!-- #ifdef APP --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
...@@ -117,6 +121,11 @@ ...@@ -117,6 +121,11 @@
const currentPage = pages[pages.length - 1]; const currentPage = pages[pages.length - 1];
currentPage.$setPageStyle(style); currentPage.$setPageStyle(style);
}, },
goSetDisablePullDownRefresh() {
uni.navigateTo({
url: '/pages/API/get-current-pages/set-page-style-disable-pull-down-refresh'
});
}
// getCurrentPage(): Page { // getCurrentPage(): Page {
// const pages = getCurrentPages(); // const pages = getCurrentPages();
// const currentPage = pages[pages.length - 1]; // const currentPage = pages[pages.length - 1];
......
const PAGE_PATH = '/pages/API/get-enter-options-sync/get-enter-options-sync'
describe('getEnterOptionsSync', () => {
it('app onShow 和 getEnterOptionsSync 结果一致', async () => {
const page = await program.navigateTo(PAGE_PATH)
await page.waitFor('view')
const pageData = await page.data()
expect(pageData.testResult).toBe(true)
})
})
<template>
<page-head title="getEnterOptionsSync"></page-head>
<view class="uni-padding-wrap">
<view class="uni-common-mt">
<text>应用本次启动路径:</text>
<text style="margin-top: 5px">{{ enterOptionsString }}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
enterOptionsString: '',
testResult: false }
},
onReady() {
const app = getApp()
const appOnShow = app.globalData.onShowOption
const onShowOption = uni.getEnterOptionsSync()
this.enterOptionsString = JSON.stringify(onShowOption, null, 2)
this.testResult = (onShowOption.path == appOnShow.path && onShowOption.appScheme == appOnShow.appScheme && onShowOption.appLink == appOnShow.appLink)
}
}
</script>
...@@ -1306,6 +1306,12 @@ describe('ExtApi-FileManagerTest', () => { ...@@ -1306,6 +1306,12 @@ describe('ExtApi-FileManagerTest', () => {
await btnWrite.tap() await btnWrite.tap()
await isDone() await isDone()
let bytesWritten = await getData("bytesWritten") let bytesWritten = await getData("bytesWritten")
let lastFailError = await getData("lastFailError")
if(bytesWritten != 7){
let writeData = await getData("writeData")
console.log('writeTest',lastFailError.errCode,lastFailError.errMsg,bytesWritten,writeData)
}
expect(bytesWritten).toEqual(7) expect(bytesWritten).toEqual(7)
console.log('writeTest', '2') console.log('writeTest', '2')
//writeSyncTest //writeSyncTest
......
...@@ -1092,13 +1092,14 @@ ...@@ -1092,13 +1092,14 @@
} }
console.log("success", res) console.log("success", res)
this.bytesWritten = res.bytesWritten this.bytesWritten = res.bytesWritten
this.lastFailError=new UniError('uni-fileSystemManager', 0,'writeTest success:'+ JSON.stringify(res))
}, },
fail: (res : IUniError) => { fail: (res : IUniError) => {
if (this.logAble) { if (this.logAble) {
this.log += 'writeTest fail:' + JSON.stringify(res) + '\n\n' this.log += 'writeTest fail:' + JSON.stringify(res) + '\n\n'
} }
console.log('fail', res) console.log('fail', res)
this.lastFailError=new UniError(res.errSubject, res.errCode, res.errMsg) this.lastFailError=new UniError(res.errSubject, res.errCode,'writeTest:'+ res.errMsg)
}, },
complete: (_) => { complete: (_) => {
......
...@@ -8,4 +8,10 @@ describe('getLaunchOptionsSync', () => { ...@@ -8,4 +8,10 @@ describe('getLaunchOptionsSync', () => {
const data = await page.data() const data = await page.data()
expect(data.checked).toBe(true) expect(data.checked).toBe(true)
}) })
it('app onLaunch 和 getLaunchOptionsSync 结果一致', async () => {
const page = await program.navigateTo(PAGE_PATH)
await page.waitFor('view')
const pageData = await page.data()
expect(pageData.testResult).toBe(true)
})
}) })
...@@ -2,31 +2,53 @@ ...@@ -2,31 +2,53 @@
<page-head title="getLaunchOptionsSync"></page-head> <page-head title="getLaunchOptionsSync"></page-head>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<button @click="getLaunchOptionsSync">getLaunchOptionsSync</button> <button @click="getLaunchOptionsSync">getLaunchOptionsSync</button>
<view v-if="launchOptionsPath.length > 0" class="uni-common-mt"> <view class="uni-common-mt">
<text>应用启动路径:</text> <text>应用本次启动路径:</text>
<text style="margin-top: 5px">{{ launchOptionsPath }}</text> <text style="margin-top: 5px">{{ launchOptionsPath }}</text>
</view> </view>
<view class="uni-common-mt">
<text>应用本次启动:</text>
<text style="margin-top: 5px">{{ launchOptionsString }}</text>
</view>
</view> </view>
</template> </template>
<script lang="uts"> <script>
export default {
export default {
data() { data() {
return { return {
checked: false, checked: false,
homePagePath: 'pages/tabBar/component', homePagePath: 'pages/tabBar/component',
launchOptionsPath: '', launchOptionsPath: '',
launchOptionsString: '',
testResult: false
} }
}, },
onReady(){
this.compareOnLaunchRes()
},
methods: { methods: {
compareOnLaunchRes() {
const launchOptions = uni.getLaunchOptionsSync();
this.launchOptionsString = JSON.stringify(launchOptions, null, 2)
const app = getApp()
const appOnLaunch = app.globalData.launchOptions
const isPathSame = launchOptions.path == appOnLaunch.path
const isAppSchemeSame = launchOptions.appScheme == appOnLaunch.appScheme
const isAppLinkSame = launchOptions.appLink == appOnLaunch.appLink
this.testResult = isPathSame && isAppSchemeSame && isAppLinkSame
},
getLaunchOptionsSync() { getLaunchOptionsSync() {
const launchOptions = uni.getLaunchOptionsSync() const launchOptions = uni.getLaunchOptionsSync()
this.launchOptionsPath = launchOptions.path this.launchOptionsPath = launchOptions.path
if (launchOptions.path == this.homePagePath) { if (launchOptions.path == this.homePagePath) {
this.checked = true this.checked = true
} }
}, },
}, },
} }
</script> </script>
const PAGE_PATH = "/pages/API/get-location/get-location";
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
const isAndroid = platformInfo.startsWith('android')
const isIos = platformInfo.startsWith('ios')
const isApp = isAndroid || isIos
const isWeb = platformInfo.startsWith('web')
describe("get-location", () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor(600)
});
//system 定位
it("system+type=wgs84+success", async () => {
await page.setData({
jest_provider: 'system',
jest_type: 'wgs84',
jest_isAltitude: true,
jest_isGeocode: false,
jest_isHighAccuracy: false
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
const data = await page.data()
const jest_errCode = data['jest_errCode']
if (jest_errCode > 0) {
expect((await page.data())['jest_errCode']).toEqual(expect.any(Number));
} else {
//判断经纬度是否在正常范围
expect((await page.data())['jest_longitude']).toBeGreaterThanOrEqual(-180);
expect((await page.data())['jest_longitude']).toBeLessThanOrEqual(180);
expect((await page.data())['jest_latitude']).toBeGreaterThanOrEqual(-90);
expect((await page.data())['jest_latitude']).toBeLessThanOrEqual(90);
//判断海拔是否正确
expect((await page.data())['jest_altitude']).toEqual(expect.any(Number));
}
});
//system 定位
it("system+type=wgs84+success+geocode=true", async () => {
await page.setData({
jest_provider: 'system',
jest_type: 'wgs84',
jest_isAltitude: true,
jest_isGeocode: true,
jest_isHighAccuracy: false
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
const data = await page.data()
const jest_errCode = data['jest_errCode']
if (jest_errCode > 0) {
if (isIos) {
expect((await page.data())['jest_errCode']).toEqual(1505603);
} else if (isAndroid) {
expect((await page.data())['jest_errCode']).toEqual(1505700);
} else {
expect((await page.data())['jest_errCode']).toEqual(expect.any(Number));
}
}
});
//system 定位
it("system+type=wgs84+success+altitude=false", async () => {
await page.setData({
jest_provider: 'system',
jest_type: 'wgs84',
jest_isAltitude: false,
jest_isGeocode: true,
jest_isHighAccuracy: false
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
const data = await page.data()
const jest_errCode = data['jest_errCode']
if (jest_errCode > 0) {
//如果定位出错
expect((await page.data())['jest_errCode']).toEqual(expect.any(Number));
} else {
expect((await page.data())['jest_altitude']).toEqual(0);
}
});
//system 定位
it("system+type=gcj02+fail", async () => {
await page.setData({
jest_provider: 'system',
jest_type: 'gcj02',
jest_isAltitude: true,
jest_isGeocode: true,
jest_isHighAccuracy: false
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
if (isApp) {
expect((await page.data())['jest_errCode']).toEqual(1505601);
}
});
//tencent 定位
it("tencent+type=gcj02+success", async () => {
await page.setData({
jest_provider: 'tencent',
jest_type: 'gcj02',
jest_isAltitude: true,
jest_isGeocode: true,
jest_isHighAccuracy: true
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
const data = await page.data()
const jest_errCode = data['jest_errCode']
if (jest_errCode > 0) {
//如果定位出错
expect((await page.data())['jest_errCode']).toEqual(expect.any(Number));
} else {
//判断逆地理编码是否正确
expect((await page.data())['jest_address']).toEqual(expect.any(String));
//判断经纬度是否在正常范围
expect((await page.data())['jest_longitude']).toBeGreaterThanOrEqual(-180);
expect((await page.data())['jest_longitude']).toBeLessThanOrEqual(180);
expect((await page.data())['jest_latitude']).toBeGreaterThanOrEqual(-90);
expect((await page.data())['jest_latitude']).toBeLessThanOrEqual(90);
//判断海拔是否正确
expect((await page.data())['jest_altitude']).toEqual(expect.any(Number));
}
});
//tencent 定位
it("tencent+type=wgs84+fail", async () => {
await page.setData({
jest_provider: 'tencent',
jest_type: 'wgs84',
jest_isAltitude: true,
jest_isGeocode: true,
jest_isHighAccuracy: true
})
await page.callMethod('jestGetLocation')
await page.waitFor(async () => {
return await page.data('jest_complete') === true;
});
if (isApp) {
expect((await page.data())['jest_errCode']).toEqual(1505607);
}
});
});
<template> <template>
<!-- #ifdef APP -->
<scroll-view style="flex: 1;">
<!-- #endif -->
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view style="padding: 4px;"> <view style="padding: 4px">
<text class="hello-text"> <text class="hello-text">
定位功能默认调用操作系统定位API实现。\n 定位功能默认调用操作系统定位API实现, 也支持腾讯定位。\n
部分手机因gms兼容不好可能导致无法定位。\n 部分手机因gms兼容不好可能导致无法使用系统定位, gcj国标、逆地理信息等功能需调用内置腾讯定位。</text>
gcj国标、逆地理信息等功能需三方sdk定位。如果需要类似能力可以下载腾讯定位插件,打包自定义基座。参考示例:</text>
<u-link :href="'https://ext.dcloud.net.cn/plugin?id=14569'" :text="'https://ext.dcloud.net.cn/plugin?id=14569'" :inWhiteList="true"></u-link>
</view> </view>
<view class="uni-padding-wrap uni-common-mt"> <view class="uni-padding-wrap uni-common-mt">
<!-- #ifdef APP -->
<view class="uni-list-cell-db">定位服务商provider(如系统定位,腾讯定位等)</view>
<view class="uni-list" style="margin-bottom: 20px">
<radio-group @change="radioChangePV">
<radio class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in providerList" :key="item.id"
:class="index < providerList.length - 1 ? 'uni-list-cell-line' : ''" :value="item.id"
:checked="index === currentProvider">
{{ item.name }}
</radio>
</radio-group>
</view>
<!-- #endif -->
<view class="uni-list-cell-db">定位类型</view>
<view class="uni-list"> <view class="uni-list">
<radio-group @change="radioChange"> <radio-group @change="radioChange">
<radio class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" :key="item.value" <radio class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" :key="item.value"
:class="index < items.length - 1 ? 'uni-list-cell-line': ''" :value="item.value" :class="index < items.length - 1 ? 'uni-list-cell-line' : ''" :value="item.value"
:checked="index === current"> :checked="index === current">
{{item.name}} {{ item.name }}
</radio> </radio>
</radio-group> </radio-group>
</view> </view>
<view class="uni-list-cell uni-list-cell-pd"> <view class="uni-list-cell uni-list-cell-pd" style="margin-top: 20px">
<view class="uni-list-cell-db">高度信息</view> <view class="uni-list-cell-db">高度信息</view>
<switch :checked="altitudeSelect" @change="altitudeChange" /> <switch :checked="altitudeSelect" @change="altitudeChange" />
</view> </view>
...@@ -30,17 +44,22 @@ ...@@ -30,17 +44,22 @@
<view class="uni-list-cell-db">是否解析地址信息</view> <view class="uni-list-cell-db">是否解析地址信息</view>
<switch :checked="geocodeSelect" @change="geocodeChange" /> <switch :checked="geocodeSelect" @change="geocodeChange" />
</view> </view>
<text>{{exeRet}}</text> <text>{{ exeRet }}</text>
<view class="uni-btn-v"> <view class="uni-btn-v">
<button class="uni-btn" type="default" @tap="getLocationTap">获取定位</button> <button class="uni-btn" type="default" @tap="getLocationTap">
获取定位
</button>
</view> </view>
</view> </view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template> </template>
<script lang="uts"> <script lang="uts">
type ItemType = { type GetLocationType = 'wgs84' | 'gcj02'
value : 'wgs84' | 'gcj02', export type LocationItem = { id : string, name : string, provider ?: UniProvider }
name : string, export type ItemType = { value : GetLocationType, name : GetLocationType }
}
export default { export default {
data() { data() {
return { return {
...@@ -59,10 +78,56 @@ ...@@ -59,10 +78,56 @@
name: 'gcj02' name: 'gcj02'
} }
] as ItemType[], ] as ItemType[],
providerList: [] as LocationItem[],
current: 0, current: 0,
currentProvider: 0,
jest_provider: '',
jest_type: 'wgs84' as GetLocationType,
jest_isAltitude: false,
jest_isGeocode: false,
jest_isHighAccuracy: false,
jest_altitude: -1000,
jest_longitude: 200,
jest_latitude: 100,
jest_address: '',
jest_errCode: 0,
jest_complete: false
} }
}, },
onLoad: function () {
// #ifdef APP
this.getProvider()
// #endif
},
methods: { methods: {
getProvider() {
// #ifdef APP
let provider = uni.getProviderSync({
service: "location",
} as GetProviderSyncOptions)
console.log(provider)
provider.providerObjects.forEach((value : UniProvider) => {
var currentProvider = value
if (value.id == 'system') {
currentProvider = value as UniLocationSystemProvider
} else if (value.id == 'tencent') {
currentProvider = value as UniLocationTencentProvider
}
this.providerList.push({
name: currentProvider.description,
id: currentProvider.id,
provider: currentProvider
} as LocationItem);
})
this.providerList.forEach((value, index) => {
if (value.id == "system") {
this.currentProvider = index
}
})
// #endif
},
altitudeChange: function (e : UniSwitchChangeEvent) { altitudeChange: function (e : UniSwitchChangeEvent) {
this.altitudeSelect = e.detail.value this.altitudeSelect = e.detail.value
}, },
...@@ -80,35 +145,83 @@ ...@@ -80,35 +145,83 @@
} }
} }
}, },
radioChangePV(e : UniRadioGroupChangeEvent) {
for (let i = 0; i < this.providerList.length; i++) {
if (this.providerList[i].id === e.detail.value) {
this.currentProvider = i;
break;
}
}
if (e.detail.value == "system") {
this.current = 0
} else if (e.detail.value == "tencent") {
this.current = 1
}
},
getLocationTap: function () { getLocationTap: function () {
// #ifdef APP
if (this.providerList.length == 0) {
uni.showToast({
title: '未获取到provider,请确定基座中包含location功能',
icon: "error"
})
console.log("未获取到provider,请确定基座中包含location功能")
return
}
// #endif
uni.showLoading({ uni.showLoading({
title: '定位中' title: '定位中'
}) })
uni.getLocation(({ uni.getLocation(({
// #ifdef APP
provider: this.providerList[this.currentProvider].id,
// #endif
type: this.items[this.current].value, type: this.items[this.current].value,
altitude: this.altitudeSelect, altitude: this.altitudeSelect,
isHighAccuracy: this.isHighAccuracySelect, isHighAccuracy: this.isHighAccuracySelect,
geocode: this.geocodeSelect, geocode: this.geocodeSelect,
success: (res : any) => { success: (res : any) => {
uni.hideLoading() uni.hideLoading()
console.log(res);
this.exeRet = JSON.stringify(res) this.exeRet = JSON.stringify(res)
}, },
fail: (res : any) => { fail: (res : any) => {
uni.hideLoading() uni.hideLoading()
console.log(res);
this.exeRet = JSON.stringify(res) this.exeRet = JSON.stringify(res)
}, },
complete: (res : any) => { complete: (res : any) => {
uni.hideLoading() uni.hideLoading()
console.log(res);
this.exeRet = JSON.stringify(res) this.exeRet = JSON.stringify(res)
} }
})); }));
},
// 仅用于自动化测试
jestGetLocation() {
this.jest_complete = false
this.jest_errCode = 0
uni.getLocation(({
// #ifdef APP
provider: this.jest_provider,
// #endif
type: this.jest_type,
altitude: this.jest_isAltitude,
isHighAccuracy: this.jest_isHighAccuracy,
geocode: this.jest_isGeocode,
success: (res) => {
if (res.address != null) {
this.jest_address = res.address!
}
this.jest_longitude = res.longitude
this.jest_latitude = res.latitude
this.jest_altitude = res.altitude
this.jest_complete = true
},
fail: (err) => {
this.jest_errCode = err.errCode
this.jest_complete = true
}
}));
} }
} }
} }
</script> </script>
describe('get-native-view', () => {
if (process.env.uniTestPlatformInfo.indexOf('web') > -1 || process.env.UNI_AUTOMATOR_APP_WEBVIEW == 'true') {
it('object', () => {
expect(1).toBe(1)
})
return
}
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
if (
platformInfo.indexOf('14.5') != -1 ||
platformInfo.indexOf('13.7') != -1 ||
platformInfo.indexOf('12.4') != -1
) {
// TODO: 排查 ios 不兼容版本 测试异常原因
it('14.5 13.7 12.4 测试异常', () => {
expect(1).toBe(1)
})
return
}
let page
beforeAll(async () => {
page = await program.reLaunch('/pages/API/get-native-view/element-getnativeview')
await page.waitFor('web-view')
})
//检测view标签原生View是否匹配
it('check_view_native_view', async () => {
page.waitFor(100)
const value = await page.callMethod('checkViewNativeView')
expect(value).toBe(true)
})
//检测input标签原生View是否匹配
it('check_input_native_view', async () => {
page.waitFor(100)
const value = await page.callMethod('checkInputNativeView')
expect(value).toBe(true)
})
//检测textarea标签原生View是否匹配
it('check_textarea_native_view', async () => {
page.waitFor(100)
const value = await page.callMethod('checkTextareaNativeView')
expect(value).toBe(true)
})
//检测webview标签原生View是否匹配
it('check_web_view_native_view', async () => {
page.waitFor(100)
const value = await page.callMethod('checkWebViewNativeView')
expect(value).toBe(true)
})
})
此差异已折叠。
...@@ -63,4 +63,15 @@ describe('ExtApi-GetSystemInfo', () => { ...@@ -63,4 +63,15 @@ describe('ExtApi-GetSystemInfo', () => {
expect(`${key} not null: ${res[key] != null}`).toBe(`${key} not null: true`) expect(`${key} not null: ${res[key] != null}`).toBe(`${key} not null: true`)
} }
}) })
it('Check screenHeight at different stages', async ()=> {
console.log("deviceOrientation ", res["deviceOrientation"]);
if(res["deviceOrientation"] == "landscape"){
expect(1).toBe(1)
}else{
await page.callMethod('jest_getScreenHeight_at_different_stages')
const res = await page.data('jest_result');
expect(res).toBe(true)
}
})
}); });
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
this.videoInfoForTest = { this.videoInfoForTest = {
"orientation": res.orientation, "orientation": res.orientation,
"type": res.type, "type": res.type,
"duration": res.duration.toInt(), "duration": Math.trunc(res.duration),
"size": res.size, "size": res.size,
"width": res.width, "width": res.width,
"height": res.height, "height": res.height,
......
...@@ -56,4 +56,23 @@ describe('interceptor', () => { ...@@ -56,4 +56,23 @@ describe('interceptor', () => {
expect(currentPage.path).toBe('pages/API/interceptor/page1') expect(currentPage.path).toBe('pages/API/interceptor/page1')
await program.navigateBack() await program.navigateBack()
}) })
it('addSwitchTabInterceptor', async () => {
await page.callMethod('addSwitchTabInterceptor')
await page.callMethod('switchTab')
await page.waitFor(300)
const currentPage = await program.currentPage()
expect(currentPage.path).toBe('pages/tabBar/API')
})
it('removeSwitchTabInterceptor', async () => {
const currentPage1 = await program.navigateTo(PAGE_PATH)
await currentPage1.callMethod('addSwitchTabInterceptor')
await currentPage1.callMethod('removeSwitchTabInterceptor')
await currentPage1.callMethod('switchTab')
await page.waitFor(300)
const currentPage2 = await program.currentPage()
expect(currentPage2.path).toBe('pages/tabBar/component')
})
}) })
此差异已折叠。
此差异已折叠。
...@@ -11,6 +11,13 @@ describe("payment", () => { ...@@ -11,6 +11,13 @@ describe("payment", () => {
return return
} }
if (process.env.UNI_TEST_DEVICES_DIRECTION == 'landscape') {
it('跳过横屏模式', () => {
expect(1).toBe(1)
})
return
}
it("trigger pulldown refresh by swipe", async () => { it("trigger pulldown refresh by swipe", async () => {
const page = await program.navigateTo(PAGE_PATH) const page = await program.navigateTo(PAGE_PATH)
await page.waitFor('view') await page.waitFor('view')
......
此差异已折叠。
此差异已折叠。
...@@ -6,7 +6,7 @@ describe('API-loading', () => { ...@@ -6,7 +6,7 @@ describe('API-loading', () => {
const isApp = process.env.UNI_OS_NAME === "android" || process.env.UNI_OS_NAME === "ios"; const isApp = process.env.UNI_OS_NAME === "android" || process.env.UNI_OS_NAME === "ios";
beforeAll(async () => { beforeAll(async () => {
page = await program.reLaunch('/pages/API/action-sheet/action-sheet') page = await program.reLaunch('/pages/API/show-action-sheet/show-action-sheet')
await page.waitFor(500); await page.waitFor(500);
}); });
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
const PAGE_PATH = '/pages/API/unicloud-call-function/unicloud-call-function' const PAGE_PATH = '/pages/API/unicloud/unicloud/cloud-function'
describe('unicloud-call-function', () => { describe('unicloud-call-function', () => {
let page let page
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册