提交 2361ea84 编写于 作者: DCloud_iOS_XHY's avatar DCloud_iOS_XHY

Merge branch 'dev' into alpha

......@@ -67,10 +67,10 @@
uni.exit()
}
},
// #endif
onExit() {
console.log('App Exit')
},
// #endif
methods: {
increasetLifeCycleNum() {
setLifeCycleNum(state.lifeCycleNum + 100)
......
......@@ -458,6 +458,13 @@
"navigationBarTitleText": "文件管理"
}
},
{
"path" : "pages/API/env/env",
"style" :
{
"navigationBarTitleText" : "env"
}
},
// #endif
{
"path": "pages/API/action-sheet/action-sheet",
......@@ -1273,6 +1280,41 @@
"navigationBarTitleText" : "editor"
}
},
{
"path" : "pages/API/map/map",
"style" :
{
"navigationBarTitleText" : "map"
}
},
{
"path" : "pages/API/make-phone-call/make-phone-call",
"style" :
{
"navigationBarTitleText" : "make-phone-call"
}
},
{
"path" : "pages/API/inner-audio/inner-audio",
"style" :
{
"navigationBarTitleText" : "inner-audio"
}
},
{
"path" : "pages/API/inner-audio/inner-audio-format",
"style" :
{
"navigationBarTitleText" : "inner-audio-format"
}
},
{
"path" : "pages/API/inner-audio/inner-audio-path",
"style" :
{
"navigationBarTitleText" : "inner-audio-path"
}
},
// #endif
// #ifdef APP
{
......@@ -1281,13 +1323,20 @@
"navigationBarTitleText": "日历"
}
},
{
"path": "pages/API/theme-change/theme-change",
"style": {
"navigationBarTitleText": "主题切换",
"enablePullDownRefresh": false
}
},
// #endif
{
"path": "pages/template/schema/schema",
"style": {
"navigationBarTitleText": "打开schema示例"
}
},
// #endif
// #ifdef APP-ANDROID
{
"path": "pages/template/share/share",
......@@ -1352,13 +1401,6 @@
"enablePullDownRefresh": false
}
},
{
"path": "pages/API/theme-change/theme-change",
"style": {
"navigationBarTitleText": "主题切换",
"enablePullDownRefresh": false
}
},
{
"path": "uni_modules/uni-pay-x/pages/success/success",
"style": {
......@@ -1406,7 +1448,6 @@
"backgroundColorContent": "#fffae8"
}
},
// #ifdef APP-ANDROID || WEB
{
"path" : "pages/API/resize-observer/resize-observer",
"style" :
......@@ -1414,7 +1455,6 @@
"navigationBarTitleText" : "resize observer"
}
},
// #endif
{
"path" : "pages/CSS/overflow/overflow-visible-event",
"style" :
......@@ -1429,9 +1469,7 @@
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColorContent": "#efeff4",
"backgroundColor": "#efeff4",
"backgroundColorTop": "#F4F5F6",
"backgroundColorBottom": "#F4F5F6"
"backgroundColor": "#efeff4"
},
"tabBar": {
"color": "#7A7E83",
......
<template>
<!-- #ifdef APP -->
<text>操作日志</text><button size="mini" @click="log=''">清空日志</button>
<text style="margin: 2px; padding: 2px; border: 1px solid #000000;">{{ log }}</text>
<scroll-view style="flex: 1;">
<!-- #endif -->
<!-- #ifdef APP -->
<button class="btnstyle" type="primary" @tap="geAbsPath(sandboxPath)" id="btn-path">应用外置沙盒目录uni.env.SANDBOX_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(cachePath)" id="btn-path">缓存文件目录uni.env.CACHE_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(userPath)" id="btn-path">用户文件目录uni.env.USER_DATA_PATH</button>
<button class="btnstyle" type="primary" @tap="geAbsPath(internalSandboxPath)"
id="btn-path">应用内置沙盒目录uni.env.ANDROID_INTERNAL_SANDBOX_PATH</button>
<!-- #endif -->
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
log: "",
userPath: uni.env.USER_DATA_PATH,
sandboxPath: uni.env.SANDBOX_PATH,
cachePath: uni.env.CACHE_PATH,
internalSandboxPath: uni.env.ANDROID_INTERNAL_SANDBOX_PATH,
}
},
onLoad() {
},
methods: {
geAbsPath(path ?: Any) {
// #ifdef APP-ANDROID
this.log += UTSAndroid.convert2AbsFullPath(path as String) + '\n'
// #endif
}
}
}
</script>
<style>
.btnstyle {
margin: 4px;
}
</style>
......@@ -14,15 +14,20 @@
}
},
onLoad() {
try {
uni.getBatteryInfo({
success: res => {
this.level = res.level;
this.isCharging = res.isCharging;
}
});
} catch (e) {
console.error(e.message);
uni.showModal({
content: e.message,
showCancel: false
});
}
}
}
</script>
<style>
</style>
\ No newline at end of file
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">支持的音频格式示例</text>
</view>
<view class="formats" v-for="(item,index) in supportFormats" :key="index">
<text class="uni-subtitle-text">{{item.format}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioFormat = {
format : string
src : string
}
export default {
data() {
return {
title: 'audio-format',
playIndex:0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportFormats: [
{
format: 'mp3',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
{
format: 'mp4',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp4'
},
{
format: 'm4a',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.m4a'
},
{
format: 'aac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aac'
},
{
format: 'flac',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.flac'
},
{
format: 'ogg',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.ogg'
},
{
format: 'wav',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wav'
},
// {
// format: 'wma',
// src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.wma'
// },
// {
// format: 'aiff',
// src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.aiff'
// },
// {
// format: 'caf',
// src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.caf'
// },
] as Array<AudioFormat>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl,index){
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err',err);
});
},
},
}
</script>
<style>
.formats{
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
</style>
<template>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-title">
<text class="uni-title-text">支持的音频路径示例</text>
</view>
<view class="formats" v-for="(item,index) in supportPaths" :key="index">
<text class="uni-subtitle-text">{{item.description}}</text>
<image class="icon-play" :src="(isPlaying && playIndex==index)?'/static/pause.png':'/static/play.png'" @click="play(item.src,index)"></image>
</view>
</view>
</template>
<script>
type AudioPath = {
description : string
src : string
}
export default {
data() {
return {
title: 'audio-path',
playIndex:0,
isPlaying: false,
_audioContext: null as InnerAudioContext | null,
supportPaths: [
{
description: '本地路径:/static方式',
src: '/static/test-audio/ForElise.mp3'
},
{
description: '本地路径:../static/',
src: '../../../static/test-audio/ForElise.mp3'
},
{
description: '网络路径',
src: 'https://web-ext-storage.dcloud.net.cn/uni-app-x/audio/ForElise.mp3'
},
] as Array<AudioPath>
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
},
onUnload() {
if (this._audioContext != null) {
this.pause();
this._audioContext!.destroy()
}
},
methods: {
pause() {
this._audioContext!.pause();
this.isPlaying = false;
},
play(audioUrl,index){
// console.log(index,audioUrl);
if (this.isPlaying && this.playIndex == index) {
this.pause();
return;
}
this.playIndex = index
this._audioContext!.src = audioUrl;
this._audioContext!.play();
this.isPlaying = true;
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.isPlaying = false;
});
this._audioContext!.onError((err) => {
this.isPlaying = false;
console.log('err',err);
});
}
}
}
</script>
<style>
.formats{
align-items: center;
}
.icon-play {
width: 60px;
height: 60px;
margin: 10px;
}
</style>
<template>
<view class="uni-padding-wrap">
<page-head title="audio"></page-head>
<view class="uni-common-mt">
<slider :value="position" :min="0" :max="duration" @changing="onchanging" @change="onchange"></slider>
</view>
<!-- <view class="uni-common-mt play-time-area">
<text class="current-time">{{currentTime}}</text>
<text class="duration">{{duration}}</text>
</view>
<view class="play-button-area">
<image class="icon-play" :src="playImage" @click="play"></image>
</view> -->
<button type="primary" @click="play" class="uni-btn">播放</button>
<button type="primary" @click="pause" class="uni-btn">暂停</button>
<button type="primary" @click="stop" class="uni-btn">停止</button>
<button type="primary" @click="onchange('seek')" class="uni-btn">跳转到指定位置</button>
<button type="primary" @click="setAutoplay" class="uni-btn">是否自动开始播放</button>
<button type="primary" @click="setLoop" class="uni-btn">是否循环播放</button>
<view class="uni-title">
<text class="uni-title-text">格式/路径示例</text>
</View>
<navigator url="/pages/API/inner-audio/inner-audio-format" class="uni-btn">
<button type="primary" @click="pause">音频格式示例</button>
</navigator>
<navigator url="/pages/API/inner-audio/inner-audio-path" class="uni-btn">
<button type="primary" @click="pause">音频路径示例</button>
</navigator>
</view>
</template>
<script lang="uts">
const audioUrl = 'https://web-ext-storage.dcloud.net.cn/uni-app/ForElise.mp3'
export default {
data() {
return {
title: "innerAudioContext",
isPlaying: false,
isPlayEnd: false,
currentTime: 0,
duration: 100,
pos:10,
paused:false,
_isChanging:false,
_audioContext: null as InnerAudioContext | null
}
},
computed: {
position() {
return this.isPlayEnd ? 0 : this.currentTime;
},
playImage() {
return this.isPlaying ? "/static/pause.png" : "/static/play.png"
}
},
onReady() {
this._audioContext = uni.createInnerAudioContext();
this._audioContext!.src = audioUrl;
this.onCanplay()
},
onUnload() {
if (this._audioContext != null && this.isPlaying) {
this.stop();
this._audioContext!.destroy()
}
},
methods: {
setAutoplay(){
this._audioContext!.autoplay = !this._audioContext!.autoplay;
console.log(this._audioContext!.autoplay,'autoplay');
},
setLoop(){
this._audioContext!.loop = !this._audioContext!.loop;
console.log(this._audioContext!.loop,'loop');
},
onchanging() {
this._isChanging = true;
},
onSeeking(){
this._audioContext!.onSeeking(() => {
console.log('音频进行 seek 操作事件');
});
},
onSeeked(){
this._audioContext!.onSeeked(() => {
console.log('音频完成 seek 操作事件');
});
},
onchange(e) {
let pos = e == 'seek' ? 20 : e.detail.value
this._audioContext!.seek(pos);
this.onSeeking()
this.onSeeked()
this._isChanging = false;
},
onCanplay(){
this._audioContext!.onCanplay(() => {
console.log('音频进入可以播放状态事件');
});
},
onTimeUpdate(){
this._audioContext!.onTimeUpdate((e) => {
// console.log('onTimeUpdate:音频播放进度更新事件',e);
if (this._isChanging === true) {
return;
}
this.currentTime = this._audioContext!.currentTime || 0;
this.duration = this._audioContext!.duration || 0;
});
},
onPlay(){
this._audioContext!.onPlay(() => {
console.log('开始播放');
});
},
onEnded(){
this._audioContext!.onEnded(() => {
console.log('播放结束');
this.currentTime = 0;
this.isPlaying = false;
this.isPlayEnd = true;
});
},
onError(){
this._audioContext!.onError((err) => {
console.log('err',err);
this.isPlaying = false;
});
},
onWaiting(){
this._audioContext!.onWaiting(() => {
console.log('音频加载中事件');
});
},
play() {
// if (this.isPlaying) {
// this.pause();
// return;
// }
this.isPlaying = true;
this._audioContext!.play();
this.isPlayEnd = false;
this.onPlay()
this.onWaiting()
this.onTimeUpdate()
this.onError()
this.onEnded()
},
onPause(){
this._audioContext!.onPause(() => {
console.log('音频暂停事件');
});
},
pause() {
this._audioContext!.pause();
this.onPause()
this.isPlaying = false;
},
onStop(){
this._audioContext!.onStop(() => {
console.log('音频停止事件');
});
},
stop() {
this._audioContext!.stop();
this.onStop()
this.isPlaying = false;
}
}
}
</script>
<style>
.play-time-area {
display: flex;
flex-direction: row;
margin-top: 20px;
}
.duration {
margin-left: auto;
}
.play-button-area {
display: flex;
flex-direction: row;
justify-content: center;
margin: 50px 0;
}
.icon-play {
width: 60px;
height: 60px;
}
</style>
<template>
<view>
<page-head :title="title"></page-head>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-hello-text uni-center">请在下方输入电话号码</view>
<input class="input uni-common-mt" type="number" name="input" @input="bindInput" />
<view class="uni-btn-v uni-common-mt">
<button @tap="makePhoneCall" type="primary" :disabled="disabled">拨打</button>
</view>
</view>
</view>
</template>
<script lang="uts">
export default {
data() {
return {
title: 'makePhoneCall',
disabled: true,
inputValue:''
}
},
methods: {
bindInput: function (e : UniInputEvent) {
this.inputValue = e.detail.value
if (this.inputValue.length > 0) {
this.disabled = false
} else {
this.disabled = true
}
},
makePhoneCall: function () {
uni.makePhoneCall({
phoneNumber: this.inputValue,
success: () => {
console.log("成功拨打电话")
}
})
}
}
}
</script>
<style>
.input {
height: 119rpx;
line-height: 119rpx;
font-size: 78rpx;
border-bottom: 1rpx solid #E2E2E2;
text-align:center;
}
</style>
let page;
describe('web-map', () => {
console.log("uniTestPlatformInfo",process.env.uniTestPlatformInfo)
if (!process.env.uniTestPlatformInfo.startsWith('web')) {
it('app', () => {
expect(1).toBe(1)
})
return
}
beforeAll(async () => {
page = await program.reLaunch('/pages/API/map/map')
await page.waitFor('view');
// 等待地图加载完成
await page.waitFor(4000);
await page.setData({autoTest:true})
});
it('Check MapMethods', async () => {
const mapMethods = ['changeScale', 'addMarkers', 'addPolyline', 'addPolygons', 'addCircles',
'includePoint', 'handleTranslateMarker'
]
for (var i = 0; i < mapMethods.length; i++) {
await page.callMethod(mapMethods[i])
if (mapMethods[i] == 'handleTranslateMarker') {
await page.waitFor(2000);
} else {
await page.waitFor(500);
}
expect(await program.screenshot()).toSaveImageSnapshot();
await page.waitFor(500);
}
});
it('handleGetCenterLocation', async () => {
await page.callMethod('handleGetCenterLocation')
await page.waitFor(500);
const centerLocationRes = await page.data('getCenterLocationTest')
expect(centerLocationRes.latitude).not.toBeNull();
expect(centerLocationRes.longitude).not.toBeNull();
});
it('handleGetRegion', async () => {
await page.callMethod('handleGetRegion')
await page.waitFor(500);
const regionRes = await page.data('getRegionTest')
const getRegionExpected = {
southwest: { latitude: 39.88334279187766, longitude: 116.31050146728515 },
northeast: { latitude: 40.0149408585477, longitude: 116.56799353271484 },
errMsg: 'getRegion:ok'
}
expect(regionRes).toEqual(expect.objectContaining(getRegionExpected));
});
});
<template>
<view class="content">
<map class="map" id="map1" ref="map1" :controls="controls" :scale="scale" :longitude="location.longitude"
:latitude="location.latitude" :show-location="showLocation" :enable-3D="enable3D" :rotate="rotate" :skew="skew"
:show-compass="showCompass" :enable-overlooking="enableOverlooking" :enable-zoom="enableZoom"
:enable-scroll="enableScroll" :enable-rotate="enableRotate" :enable-satellite="enableSatellite"
:enable-traffic="enableTraffic" :markers="markers" :polyline="polyline" :circles="circles" :polygons="polygons"
:include-points="includePoints" @tap="maptap" @controltap="oncontroltap" @markertap="onmarkertap"
@callouttap="oncallouttap" @poitap="onpoitap" @updated="onupdated" @regionchange="onregionchange"></map>
<scroll-view class="scrollview" scroll-y="true">
<button class="button" @click="changeScale">changeScale</button>
<button class="button" @click="addMarkers">addMarkers</button>
<button class="button" @click="addPolyline">addPolyline</button>
<button class="button" @click="addPolygons">addPolygons</button>
<button class="button" @click="addCircles">addCircles</button>
<button class="button" @click="includePoint">includePoints</button>
<button class="button" @click="handleGetCenterLocation">getCenterLocation</button>
<button class="button" @click="handleGetRegion">getRegion</button>
<button class="button" @click="handleTranslateMarker">translateMarker</button>
</scroll-view>
</view>
</template>
<script lang="uts">
type Anchor = {
x : number,
y : number
}
type Callout = {
content : string,
color : string,
fontSize : number,
borderRadius : number,
borderWidth : number,
borderColor : string,
bgColor : string,
padding : string,
display : string
}
type Markers = {
id : string | number,
latitude : number,
longitude : number,
title : string
zIndex : string,
iconPath : string,
rotate ?: number,
width : number,
height : number,
anchor : Anchor,
callout : Callout
}
type Points = {
latitude : number,
longitude : number
}
type Polyline = {
points : Points[],
color : string,
width : number,
dottedLine : boolean,
arrowLine : boolean,
borderColor : string,
borderWidth : number
}
type Polygons = {
points : Points[];
fillColor : string;
strokeWidth : number;
strokeColor : string;
zIndex : number;
}
type Circles = {
latitude : number;
longitude : number;
radius : number;
strokeWidth : number;
color : string;
fillColor : string;
}
const testMarkers = [{
id: 0,
latitude: 39.989631,
longitude: 116.481018,
title: '方恒国际 阜通东大街6号',
zIndex: '1',
iconPath: '../../../static/location.png',
rotate: 0,
width: 20,
height: 20,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '方恒国际 阜通东大街6号',
color: '#00BFFF',
fontSize: 10,
borderRadius: 4,
borderWidth: 1,
borderColor: '#333300',
bgColor: '#CCFF99',
padding: '5',
display: 'ALWAYS'
}
},
{
id: 1,
latitude: 39.9086920000,
longitude: 116.3974770000,
title: '天安门',
zIndex: '1',
iconPath: '../../../static/location.png',
width: 40,
height: 40,
anchor: {
x: 0.5,
y: 1
},
callout: {
content: '首都北京\n天安门',
color: '#00BFFF',
fontSize: 12,
borderRadius: 2,
borderWidth: 0,
borderColor: '#333300',
bgColor: '#CCFF11',
padding: '1',
display: 'ALWAYS'
}
}
];
const testPolyline = [{
points: [{
latitude: 39.925539,
longitude: 116.279037
},
{
latitude: 39.925539,
longitude: 116.520285
}],
color: '#FFCCFF',
width: 7,
dottedLine: true,
arrowLine: true,
borderColor: '#000000',
borderWidth: 2
},
{
points: [{
latitude: 39.938698,
longitude: 116.275177
},
{
latitude: 39.966069,
longitude: 116.289253
},
{
latitude: 39.944226,
longitude: 116.306076
},
{
latitude: 39.966069,
longitude: 116.322899
},
{
latitude: 39.938698,
longitude: 116.336975
}],
color: '#CCFFFF',
width: 5,
dottedLine: true,
arrowLine: true,
borderColor: '#CC0000',
borderWidth: 3
}
];
const testPolygons = [{
points: [{
latitude: 39.781892,
longitude: 116.293413
},
{
latitude: 39.787600,
longitude: 116.391842
},
{
latitude: 39.733187,
longitude: 116.417932
},
{
latitude: 39.704653,
longitude: 116.338255
}],
fillColor: '#FFCCFF',
strokeWidth: 3,
strokeColor: '#CC99CC',
zIndex: 11
},
{
points: [{
latitude: 39.887600,
longitude: 116.518932
},
{
latitude: 39.781892,
longitude: 116.518932
},
{
latitude: 39.781892,
longitude: 116.428932
},
{
latitude: 39.887600,
longitude: 116.428932
}
],
fillColor: '#CCFFFF',
strokeWidth: 5,
strokeColor: '#CC0000',
zIndex: 3
}
];
const testCircles = [{
latitude: 39.996441,
longitude: 116.411146,
radius: 15000,
strokeWidth: 5,
color: '#CCFFFF',
fillColor: '#CC0000'
},
{
latitude: 40.096441,
longitude: 116.511146,
radius: 12000,
strokeWidth: 3,
color: '#CCFFFF',
fillColor: '#FFCCFF'
},
{
latitude: 39.896441,
longitude: 116.311146,
radius: 9000,
strokeWidth: 1,
color: '#CCFFFF',
fillColor: '#CC0000'
}
];
const testIncludePoints = [{
latitude: 39.989631,
longitude: 116.481018,
},
{
latitude: 39.9086920000,
longitude: 116.3974770000,
}
];
export default {
data() {
return {
location: {
longitude: 116.3974770000,
latitude: 39.9086920000
},
controls: [{
id: 1,
position: {
left: 5,
top: 180,
width: 30,
height: 30
},
iconPath: '../../../static/uni.png',
clickable: true
}],
showLocation: false,
scale: 13,
showCompass: true,
enable3D: true,
enableOverlooking: true,
enableZoom: true,
enableScroll: true,
enableRotate: true,
enableSatellite: false,
enableTraffic: false,
polyline: [] as Polyline[],
markers: [] as Markers[],
polygons: [] as Polygons[],
circles: [] as Circles[],
includePoints: [] as Points[],
rotate: 0,
skew: 0,
map: null as MapContext | null,
// 自动化测试
autoTest: false,
getCenterLocationTest:{},
getRegionTest:{},
}
},
onReady() {
this.map = uni.createMapContext("map1", this);
},
methods: {
changeScale() {
this.scale = this.scale == 9 ? 15 : 9;
},
enableThreeD(e) {
this.enable3D = e.detail.value;
},
changeShowCompass(e) {
this.showCompass = e.detail.value;
},
changeEnableOverlooking(e) {
this.enableOverlooking = e.detail.value;
},
changeEnableZoom(e) {
this.enableZoom = e.detail.value;
},
changeEnableScroll(e) {
this.enableScroll = e.detail.value;
},
changeEnableRotate(e) {
this.enableRotate = e.detail.value;
},
changeEnableSatellite(e) {
this.enableSatellite = e.detail.value;
},
changeEnableTraffic(e) {
this.enableTraffic = e.detail.value;
},
addMarkers() {
this.markers = testMarkers;
},
addPolyline() {
this.polyline = testPolyline;
},
addPolygons() {
this.polygons = testPolygons;
},
addCircles() {
this.circles = testCircles;
},
includePoint() {
this.includePoints = testIncludePoints;
},
handleGetCenterLocation() {
this.map!.getCenterLocation({
success: ret => {
console.log(JSON.stringify(ret));
this.getCenterLocationTest = ret
if(!this.autoTest){
uni.showModal({
content: JSON.stringify(ret)
})
}
}
})
},
handleGetRegion() {
this.map!.getRegion({
success: ret => {
console.log(JSON.stringify(ret));
this.getRegionTest = ret
if(!this.autoTest){
uni.showModal({
content: JSON.stringify(ret)
})
}
}
})
},
handleTranslateMarker() {
this.map!.translateMarker({
markerId: 1,
destination: {
latitude: 39.989631,
longitude: 116.481018
},
duration: 2000,
success: ret => {
console.log(JSON.stringify(ret));
}
});
},
maptap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
onmarkertap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
oncontroltap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
oncallouttap(e) {
uni.showModal({
content: JSON.stringify(e)
})
},
onupdated(e) {
console.log(JSON.stringify(e))
},
onregionchange(e) {
console.log(JSON.stringify(e));
},
onpoitap(e) {
uni.showModal({
content: JSON.stringify(e)
})
}
}
}
</script>
<style>
.content {
flex: 1;
}
.map {
width: 100%;
height: 250px;
background-color: #f0f0f0;
}
.scrollview {
flex: 1;
padding: 10px;
}
.list-item {
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding: 5px 0px;
}
.list-text {
flex: 1;
}
.button {
margin-top: 5px;
margin-bottom: 5px;
}
</style>
describe('api-resize-observer', () => {
if (
!process.env.uniTestPlatformInfo.startsWith('android') &&
!process.env.uniTestPlatformInfo.startsWith('web')
) {
it('dummyTest', async () => {
expect(1).toBe(1)
})
return
}
let page
beforeAll(async () => {
......
......@@ -11,6 +11,8 @@
</view>
<button @click="revertBoxSize">还原修改前元素宽高</button>
<button @click="toggleDisplay">{{boxDisplay? '隐藏元素': '显示元素'}}</button>
<button @click='cancelListen'>停止监听</button>
<button @click='goOnListen'>恢复监听</button>
<view>
<text class="info-text">蓝色方块元素:</text>
<view class="info-item">
......@@ -47,6 +49,7 @@
onReady() {
if (this.resizeObserver == null) {
this.resizeObserver = new UniResizeObserver((entries : Array<UniResizeObserverEntry>) => {
entries.forEach(entry => {
if (entry.target == this.outBoxElement) {
this.outBoxSizeInfo = this.analysisResizeObserverEntry(entry)
......@@ -91,7 +94,7 @@
}
},
//自动化测试专用
setOutBoxMarginLeft(value: string) {
setOutBoxMarginLeft(value : string) {
if (this.outBoxElement != null) {
this.outBoxElementOnResize = false
this.outBoxElement!.style.setProperty("margin-left", value)
......@@ -108,6 +111,15 @@
"contentBoxSize: \n{blockSize:" + contentBoxSize.blockSize + ", inlineSize:" + contentBoxSize.inlineSize + "}\n" +
"devicePixelContentBoxSize: \n{blockSize:" + devicePixelContentBoxSize.blockSize + ", inlineSize:" + devicePixelContentBoxSize.inlineSize + "}\n" +
"contentRect: \n{x:" + entry.contentRect.x + ", y:" + entry.contentRect.y + ", width:" + entry.contentRect.width + ", height:" + entry.contentRect.height + "}"
},
cancelListen(){
// this.resizeObserver?.unobserve()
this.resizeObserver!.unobserve(this.outBoxElement!)
this.resizeObserver!.unobserve(this.innerBoxElement!)
},
goOnListen(){
this.resizeObserver!.observe(this.outBoxElement!)
this.resizeObserver!.observe(this.innerBoxElement!)
}
}
}
......
// uni-app自动化测试教程: uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
describe('API-theme-change', () => {
let page;
const isApp = process.env.UNI_OS_NAME === "android" || process.env.UNI_OS_NAME === "ios";
if (!isApp) {
it('dummyTest', () => {
expect(1).toBe(1)
})
return
}
beforeAll(async () => {
page = await program.reLaunch('/pages/API/theme-change/theme-change')
await page.waitFor(600);
});
it("check-set-app-theme", async () => {
await page.callMethod('setAppTheme', "dark")
await page.waitFor(300)
expect(await page.data('appTheme')).toBe("dark")
})
});
<template>
<view class="uni-padding-wrap">
<view class="uni-common-mt flex justify-between flex-row">
<text>theme:</text>
<text id="theme">{{ dataInfo.theme }}</text>
<view class="uni-common-mt item-box">
<text>osTheme:</text>
<text id="theme">{{ osTheme }}</text>
</view>
<view class="uni-common-mt flex justify-between flex-row">
<text>fn1 trigger num:</text>
<text id="fn1-trigger-num">{{ dataInfo.fn1TriggerNum }}</text>
<view class="uni-common-mt item-box">
<text>appTheme:</text>
<text id="theme">{{ appTheme }}</text>
</view>
<view class="uni-common-mt flex justify-between flex-row">
<text>fn2 trigger num:</text>
<text id="fn2-trigger-num">{{ dataInfo.fn2TriggerNum }}</text>
<view>
<view class="uni-title uni-common-mt">
<text class="uni-title-text"> 修改appTheme主题 </text>
</view>
<button class="uni-common-mt" id="bind-fn1" @click="bindFn1">
bind fn1
</button>
<button class="uni-common-mt" id="remove-fn1" @click="removeFn1">
remove fn1
</button>
<button class="uni-common-mt" id="bind-fn2" @click="bindFn2">
bind fn2
</button>
<button class="uni-common-mt" id="remove-fn2" @click="removeFn2">
remove fn2
</button>
</view>
</template>
<script setup lang="uts">
type DataInfo = {
fn1TriggerNum: number
fn2TriggerNum: number
theme: string
}
const dataInfo = reactive<DataInfo>({
fn1TriggerNum: 0,
fn2TriggerNum: 0,
theme: ''
})
const fn1 = (options : OnThemeChangeOptions) => {
dataInfo.fn1TriggerNum++
console.log('fn1 triggered options: ', options)
dataInfo.theme = options.theme
}
const fn2 = (options : OnThemeChangeOptions) => {
dataInfo.fn2TriggerNum++
console.log('fn2 triggered options: ', options)
dataInfo.theme = options.theme
}
<view class="uni-list uni-common-pl">
<radio-group @change="radioChange" class="radio-group">
<radio class="uni-list-cell uni-list-cell-pd radio" v-for="(item, index) in items" :key="item"
:class="index < items.length - 1 ? 'uni-list-cell-line' : ''" :value="item"
:checked="index === current">
{{ item }}
</radio>
</radio-group>
</view>
const bindFn1 = () => {
uni.onOSThemeChange(fn1)
}
const removeFn1 = () => {
uni.offOSThemeChange(fn1)
}
const bindFn2 = () => {
uni.onOSThemeChange(fn2)
}
const removeFn2 = () => {
uni.offOSThemeChange(fn2)
}
</view>
</template>
onReady(() => {
bindFn1()
bindFn2()
})
<script>
export default {
data() {
return {
osThemeChangeId: 0,
appThemeChangeId: 0,
osTheme: "light" as string,
appTheme: "light" as string,
current: 0,
items: [
"light",
"dark",
"auto"
] as string[]
}
},
methods: {
bindOsThemeChange(): number {
//注册osTheme变化监听
return uni.onOsThemeChange((res: OsThemeChangeResult)=> {
this.osTheme = res.osTheme
})
},
bindAppThemeChange(): number {
//注册appTheme变化监听
return uni.onAppThemeChange((res: AppThemeChangeResult) => {
this.appTheme = res.appTheme
})
},
radioChange(e : UniRadioGroupChangeEvent) {
const theme = e.detail.value
this.setAppTheme(theme)
uni.showToast({
icon: 'none',
title: '当前选中:'+theme,
})
},
setAppTheme(value: string) {
uni.setAppTheme({
theme: value,
success: function() {
console.log("设置appTheme为", value, "成功")
},
fail: function(e: IAppThemeFail) {
console.log("设置appTheme为", value, "失败,原因:", e.errMsg)
}
})
}
},
onReady() {
uni.getSystemInfo({
success: (res:GetSystemInfoResult) => {
this.osTheme = res.osTheme!
this.appTheme = res.appTheme!
this.current = this.items.indexOf(this.appTheme)
}
})
this.osThemeChangeId = this.bindOsThemeChange()
this.appThemeChangeId = this.bindAppThemeChange()
},
onUnload() {
//注销监听
uni.offAppThemeChange(this.appThemeChangeId)
uni.offOsThemeChange(this.osThemeChangeId)
}
}
</script>
<style>
.flex {
.item-box {
display: flex;
}
.flex-row {
flex-direction: row;
}
.justify-between {
justify-content: space-between;
}
}
.uni-list-cell {
justify-content: flex-start;
}
</style>
......@@ -6,9 +6,16 @@ function getData(key = '') {
}
let page
let originEventCallbackNum
beforeAll(async () => {
page = await program.reLaunch('/pages/component/checkbox/checkbox')
await page.waitFor(2000);
await page.waitFor(2000)
originEventCallbackNum = await page.callMethod('getEventCallbackNum')
})
beforeEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
})
describe('Checkbox.uvue', () => {
......@@ -68,4 +75,10 @@ describe('Checkbox.uvue', () => {
})
expect(await cb.attribute('disabled')).toBe(false + '')
})
it('trigger UniCheckboxGroupChangeEvent', async () => {
const element = await page.$('.checkbox-item-0')
await element.tap()
const eventCallbackNum = await page.callMethod('getEventCallbackNum')
expect(eventCallbackNum - originEventCallbackNum).toBe(3)
})
})
<script>
import { state, setEventCallbackNum } from '@/store/index.uts'
type ItemType = {
value : string
name : string
......@@ -58,7 +59,24 @@
}
},
methods: {
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
checkboxChange: function (e : UniCheckboxGroupChangeEvent) {
// 自动化测试
if ((e.target?.tagName ?? '').includes('CHECKBOX-GROUP')) {
this.setEventCallbackNum(state.eventCallbackNum + 1)
}
if (e.type === 'change') {
this.setEventCallbackNum(state.eventCallbackNum + 2)
}
const selectedNames : string[] = []
this.items.forEach((item) => {
if (e.detail.value.includes(item.value)) {
......@@ -156,9 +174,10 @@
</view>
</view>
<view class="uni-list uni-common-pl">
<checkbox-group @change="checkboxChange" class="checkbox-group">
<checkbox-group @change="checkboxChange" class="checkbox-group" id="trigger-change">
<checkbox class="uni-list-cell uni-list-cell-pd checkbox" v-for="(item, index) in items" :key="item.value"
:value="item.value" :checked="item.checked" :class="index < items.length - 1 ? 'uni-list-cell-line' : ''">
:value="item.value" :checked="item.checked"
:class="[index < items.length - 1 ? 'uni-list-cell-line' : '','checkbox-item-'+index]">
{{ item.name }}
</checkbox>
</checkbox-group>
......
// uni-app自动化测试教程: uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
jest.setTimeout(30000);
describe('editor.uvue', () => {
if (!process.env.uniTestPlatformInfo.startsWith('web')) {
it('app', () => {
expect(1).toBe(1)
})
return
}
let page, editor, options = [];
beforeAll(async () => {
page = await program.reLaunch("/pages/component/editor/editor");
await page.waitFor('view');
editor = await page.$('#editor');
await page.waitFor(3000);
await page.setData({autoTest:true})
});
it('editor-wrapper', async () => {
expect(await editor.attribute("placeholder")).toBe("开始输入...")
expect(await editor.attribute("read-only")).toBe("false")
});
it('editor-toolbar', async () => {
const iconfontsEl = await page.$$('.iconfont');
for (var i = 0; i < iconfontsEl.length - 7; i++) {
await iconfontsEl[i].tap()
// await page.waitFor(500)
const getFormats = await page.data('formats')
const name = await iconfontsEl[i].attribute('data-name')
options.push({
insert:'文本内容' + name,
attributes: getFormats
})
await page.callMethod('setContents', options)
await page.setData({
formats: {}
})
await iconfontsEl[i].tap()
}
});
it('editor-screenshot', async () => {
expect(await program.screenshot()).toSaveImageSnapshot();
await page.waitFor(500);
})
it('clear', async () => {
await page.callMethod('clear')
await page.waitFor(500)
expect(await editor.attribute("placeholder")).toBe("开始输入...")
})
it('undo-redo', async () => {
await page.callMethod('insertDate')
await page.callMethod('insertDivider')
await page.waitFor(500)
await page.callMethod('undo')
await page.waitFor(500)
expect(await page.data('undoTest')).toBe(true)
await page.callMethod('redo')
await page.waitFor(500)
expect(await page.data('redoTest')).toBe(true)
})
it('insertImage', async () => {
await page.callMethod('insertImage','https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-app.png')
await page.waitFor(500)
expect(await program.screenshot()).toSaveImageSnapshot();
})
it('removeFormat', async () => {
const bgcolorEl = await page.$('.icon-fontbgcolor');
await bgcolorEl.tap()
await page.waitFor(500)
const getFormats = await page.data('formats')
await page.callMethod('setContents', [
{
insert: '设置字体样式bgcolor',
attributes: getFormats
}
])
await page.waitFor(500)
await page.callMethod('removeFormat')
await page.waitFor(500)
expect(await page.data('removeFormatTest')).toBe(true)
expect(await page.data('formats')).toEqual({})
})
});
......@@ -30,7 +30,7 @@
data-name="marginTop" data-value="20px"></view>
<view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
data-name="marginBottom" data-value="20px"></view>
<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
<view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
data-name="fontFamily" data-value="Pacifico"></view>
<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
......@@ -39,27 +39,35 @@
data-name="color" data-value="#0000ff"></view>
<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view>
<view class="iconfont icon-date" @tap="insertDate"></view>
<view class="iconfont icon--checklist" data-name="list" data-value="check"></view>
<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
data-name="list" data-value="ordered"></view>
<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
data-name="list" data-value="bullet"></view>
<view class="iconfont icon-undo" @tap="undo"></view>
<view class="iconfont icon-redo" @tap="redo"></view>
<view class="iconfont icon-outdent" data-name="indent" data-value="-1"></view>
<view class="iconfont icon-indent" data-name="indent" data-value="+1"></view>
<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
<view class="iconfont icon-charutupian" @tap="insertImage"></view>
<view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
data-name="header" :data-value="1"></view>
<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
data-name="script" data-value="sub"></view>
<view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
data-name="script" data-value="super"></view>
<view class="iconfont icon-shanchu" @tap="clear"></view>
<view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
data-name="direction" data-value="rtl"></view>
<view class="iconfont icon-date" @tap="insertDate"></view>
<view class="iconfont icon-fengexian" @tap="insertDivider"></view>
<view class="iconfont icon-charutupian" @tap="chooseInsertImage"></view>
<view class="iconfont icon-clearedformat" @tap="removeFormat"></view>
<view class="iconfont icon-undo" @tap="undo"></view>
<view class="iconfont icon-redo" @tap="redo"></view>
<view class="iconfont icon-shanchu" @tap="clearShowModal"></view>
</view>
<view class="editor-wrapper">
......@@ -86,7 +94,12 @@
return {
readOnly: false,
formats: {},
editorCtx:{} as Context
editorCtx:{} as Context,
// 自动化测试
autoTest:false,
undoTest:false,
redoTest:false,
removeFormatTest:false
}
},
onLoad() {
......@@ -110,6 +123,20 @@
this.editorCtx = res.context
}).exec()
},
// 自动化测试专用
setContents(options) {
this.editorCtx.setContents({
delta: {
ops:options
},
success: (res) => {
console.log('setContents-success', res)
},
fail: (err) => {
console.log(err)
}
})
},
getCon() {
this.editorCtx.getContents({
success: (res) => {
......@@ -121,16 +148,27 @@
})
},
undo() {
this.editorCtx.undo()
this.editorCtx.undo({
success: (res) => {
this.undoTest = true
},
fail: (err) => {
this.undoTest = false
}
})
},
redo() {
this.editorCtx.redo()
this.editorCtx.redo({
success: (res) => {
this.redoTest = true
},
fail: (err) => {
this.redoTest = false
}
})
},
format(e) {
let {
name,
value
} = e.target.dataset
let {name,value} = e.target.dataset
if (!name) return
// console.log('format', name, value)
this.editorCtx.format(name, value)
......@@ -147,22 +185,33 @@
})
},
clear() {
uni.showModal({
title: '清空编辑器',
content: '确定清空编辑器全部内容?',
success: res => {
if (res.confirm) {
this.editorCtx.clear({
success: function(res) {
console.log("clear success")
}
})
},
clearShowModal() {
uni.showModal({
title: '清空编辑器',
content: '确定清空编辑器全部内容?',
success: res => {
if (res.confirm) {
this.clear()
}
}
})
},
removeFormat() {
this.editorCtx.removeFormat()
this.editorCtx.removeFormat({
success: (res) => {
console.log('removeFormat-success', res)
this.removeFormatTest = true
},
fail: (err) => {
this.removeFormatTest = false
}
})
},
insertDate() {
const date = new Date()
......@@ -171,17 +220,20 @@
text: formatDate
})
},
insertImage() {
uni.chooseImage({
count: 1,
success: (res) => {
insertImage(image){
this.editorCtx.insertImage({
src: res.tempFilePaths[0],
src:image,
alt: '图像',
success: function() {
console.log('insert image success')
}
})
},
chooseInsertImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.insertImage(res.tempFilePaths[0])
}
})
}
......@@ -201,17 +253,18 @@
}
.editor-wrapper {
height: calc(100vh - var(--window-top) - var(--status-bar-height) - 80px - 46px);
height: calc(100vh - var(--window-top) - var(--status-bar-height) - 140px - 46px);
background: #fff;
}
.iconfont {
display: inline-block;
padding: 8px 8px;
width: 30px;
height: 30px;
cursor: pointer;
font-size: 20px;
margin: 0px 6px;
align-content: center;
}
.toolbar {
......@@ -220,7 +273,8 @@
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
flex-direction: row;
flex-wrap: wrap;
height: 110px;
height: 140px;
padding-left: 10px;
}
.ql-container {
......
......@@ -198,4 +198,9 @@ describe('component-native-input', () => {
})
expect(image).toSaveImageSnapshot()
})
it('both set modelValue and value', async()=>{
const input2 = await page.$('#both-model-value');
expect(await input2.value()).toEqual("123")
})
});
......@@ -238,6 +238,16 @@
@click="changePassword"></image>
</view>
</view>
<view>
<view class="uni-title">
<text class="uni-title-text">同时存在 v-model 和 value</text>
</view>
<view class="input-wrapper">
<input id="both-model-value" class="uni-input" v-model='demoValue' value='456' />
</view>
</view>
</view>
<!-- #ifdef APP -->
</scroll-view>
......@@ -272,6 +282,7 @@
holdKeyboard: false,
keyboardHeight: 0,
focusedForKeyboardHeightChangeTest: false,
demoValue: '123'
}
},
methods: {
......
let page;
describe('label.uvue', () => {
console.log(process.env.uniTestPlatformInfo,process.env.uniTestPlatformInfo.startsWith('web'))
if (!process.env.uniTestPlatformInfo.startsWith('web')) {
it('app', () => {
expect(1).toBe(1)
})
return
}
beforeAll(async () => {
page = await program.reLaunch('/pages/component/label/label')
await page.waitFor('view');
});
afterEach(async() => {
await page.setData({
checkboxValue: [],
radioValue:''
})
});
function getData(key = '') {
return new Promise(async (resolve, reject) => {
const data = await page.data()
resolve(key ? data[key] : data)
})
}
it('表单组件在label内', async () => {
expect(await getData('checkboxValue')).toEqual([])
const checkboxItems = await page.$$('.checkboxItemsTest')
await checkboxItems[0].tap()
expect(await getData('checkboxValue')).toEqual(['USA', 'CHN'])
})
it('label用for标识表单组件', async () => {
const radioItems = await page.$$('.label-2-text')
await radioItems[0].tap()
expect(await getData('radioValue')).toEqual('USA')
await radioItems[1].tap()
expect(await getData('radioValue')).toEqual('CHN')
})
it('label内有多个时选中第一个', async () => {
const labelText = await page.$('.uni-center')
await labelText.tap()
expect(await getData('checkboxValue')).toEqual([''])
})
})
......@@ -5,7 +5,7 @@
<view class="uni-form-item uni-column">
<view class="title">表单组件在label内</view>
<checkbox-group class="uni-list" @change="checkboxChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="item in checkboxItems" :key="item.name">
<label class="uni-list-cell uni-list-cell-pd checkboxItemsTest" v-for="item in checkboxItems" :key="item.name">
<view>
<checkbox :value="item.name" :checked="item.checked"></checkbox>
</view>
......@@ -70,17 +70,19 @@
checked: 'true'
}
],
hidden: false
hidden: false,
checkboxValue: [] as string[],
radioValue:''
}
},
methods: {
checkboxChange: function (e) {
var checked = e.detail.value
console.log(checked)
checkboxChange: function (e : UniCheckboxGroupChangeEvent) {
console.log(e.detail.value)
this.checkboxValue = e.detail.value
},
radioChange: function (e) {
var checked = e.detail.value
console.log(checked)
radioChange: function (e : UniRadioGroupChangeEvent) {
console.log(e.detail.value)
this.radioValue = e.detail.value
}
}
}
......
......@@ -11,6 +11,11 @@ let page
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
await page.waitFor('view')
await page.callMethod('setEventCallbackNum', 0)
})
afterEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
})
describe('PickerView.uvue', () => {
......@@ -79,4 +84,22 @@ describe('PickerView.uvue', () => {
expect(month).toEqual(date.getMonth() + 1)
expect(day).toEqual(date.getDate())
})
it('trigger UniPickerViewChangeEvent', async () => {
// if web skip todo
if (
process.env.uniTestPlatformInfo.startsWith('web')
) {
expect(1).toBe(1)
return
}
const el = await page.$('.picker-view')
await page.callMethod('setValue')
await page.waitFor(1000)
const eventCallbackNum = await page.callMethod('getEventCallbackNum')
// 3 times 3*3
expect(eventCallbackNum).toBe(9)
})
})
......@@ -23,6 +23,7 @@
</template>
<script lang="uts">
import { state, setEventCallbackNum } from '@/store/index.uts'
export default {
data() {
const date = new Date()
......@@ -57,7 +58,24 @@
}
},
methods: {
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
bindChange(e : UniPickerViewChangeEvent) {
// 自动化测试
console.log(e.target?.tagName,e.type);
if ((e.target?.tagName ?? '').includes('PICKER-VIEW')) {
this.setEventCallbackNum(state.eventCallbackNum + 1)
}
if (e.type === 'change') {
this.setEventCallbackNum(state.eventCallbackNum + 2)
}
const val = e.detail.value
this.result = val
this.year = this.years[val[0]]
......
describe('Picker.uvue', () => {
console.log(process.env.uniTestPlatformInfo)
if (!process.env.uniTestPlatformInfo.startsWith('web')) {
it('app', () => {
expect(1).toBe(1)
})
return
}
beforeAll(async () => {
page = await program.reLaunch('/pages/component/picker/picker')
await page.waitFor('view');
});
function getData(key = '') {
return new Promise(async (resolve, reject) => {
const data = await page.data()
resolve(key ? data[key] : data)
})
}
function getValue(className,propertyValue='value') {
return new Promise(async (resolve, reject) => {
const el = await page.$(className)
const value = await el.property(propertyValue)
resolve(value)
})
}
it('普通选择器', async () => {
expect(await getValue('.picker')).toBe(await getData('index'))
await page.setData({index:1})
const pickerValueEl = await page.$('.pickerValue')
expect(await pickerValueEl.text()).toBe('美国')
})
it('多列选择器', async () => {
expect(await getValue('.pickerMulti')).toEqual(await getData('multiIndex'))
const pickerMultiValueEl = await page.$('.pickerMultiValue')
expect(await pickerMultiValueEl.text()).toStrictEqual('亚洲,中国,北京')
await page.setData({multiIndex:[0, 0, 2]})
const pickerMultiValueEl2 = await page.$('.pickerMultiValue')
expect(await pickerMultiValueEl2.text()).toStrictEqual('亚洲,中国,广州')
})
it('时间选择器', async () => {
expect(await getValue('.pickerTime')).toBe(await getData('time'))
await page.setData({time:'15:30'})
expect(await getValue('.pickerTime')).toEqual('15:30')
})
it('日期选择器', async () => {
expect(await getValue('.pickerDate')).toBe(await getData('date'))
await page.setData({date:'2028-05-20'})
expect(await getValue('.pickerDate')).toEqual('2028-05-20')
expect(await getValue('.pickerDate','start')).toStrictEqual(await getData('startDate'))
expect(await getValue('.pickerDate','end')).toStrictEqual(await getData('endDate'))
})
})
......@@ -8,8 +8,8 @@
当前选择
</view>
<view class="uni-list-cell-db">
<picker @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input">{{array[index].name}}</view>
<picker class="picker" @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input pickerValue">{{array[index].name}}</view>
</picker>
</view>
</view>
......@@ -22,8 +22,8 @@
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="multiSelector" @columnchange="bindMultiPickerColumnChange" :value="multiIndex" :range="multiArray">
<view class="uni-input">{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}</view>
<picker class="pickerMulti" mode="multiSelector" @columnchange="bindMultiPickerColumnChange" :value="multiIndex" :range="multiArray">
<view class="uni-input pickerMultiValue">{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}</view>
</picker>
</view>
</view>
......@@ -36,7 +36,7 @@
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange">
<picker class="pickerTime" mode="time" :value="time" start="09:01" end="21:01" @change="bindTimeChange">
<view class="uni-input">{{time}}</view>
</picker>
</view>
......@@ -53,7 +53,7 @@
当前选择
</view>
<view class="uni-list-cell-db">
<picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
<picker class="pickerDate" mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
<view class="uni-input">{{date}}</view>
</picker>
</view>
......
......@@ -11,6 +11,10 @@ beforeAll(async () => {
await page.waitFor(2000);
})
beforeEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
})
describe('Progress.uvue', () => {
it('percent', async () => {
await page.callMethod('setProgress')
......@@ -80,4 +84,21 @@ describe('Progress.uvue', () => {
})
expect(await el.attribute('background-color')).toEqual('#007aff')
})
it('trigger UniProgressActiveendEvent', async () => {
if (
process.env.uniTestPlatformInfo.startsWith('web')
) {
expect(1).toBe(1)
return
}
await page.setData({
pgList: [21, 40, 60, 80]
})
// 动画执行
await page.waitFor(1000);
const eventCallbackNum = await page.callMethod('getEventCallbackNum')
expect(eventCallbackNum).toBe(3)
})
})
<script>
import { state, setEventCallbackNum } from '@/store/index.uts'
import { ItemType } from '@/components/enum-data/enum-data'
export default {
data() {
......@@ -25,6 +26,15 @@
}
},
methods: {
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
setProgress() {
this.pgList = [20, 40, 60, 80] as number[]
},
......@@ -32,6 +42,13 @@
this.pgList = [0, 0, 0, 0] as number[]
},
activeend(e : UniProgressActiveendEvent) {
// 自动化测试
if ((e.target?.tagName ?? '').includes('PROGRESS')) {
this.setEventCallbackNum(state.eventCallbackNum + 1)
}
if (e.type === 'activeend') {
this.setEventCallbackNum(state.eventCallbackNum + 2)
}
this.curPercent = e.detail.curPercent
},
progress_touchstart() { console.log("手指触摸动作开始") },
......
......@@ -6,9 +6,14 @@ function getData(key = '') {
}
let page
let originEventCallbackNum
beforeAll(async () => {
page = await program.reLaunch('/pages/component/radio/radio')
await page.waitFor(2000);
await page.waitFor(2000)
originEventCallbackNum = await page.callMethod('getEventCallbackNum')
})
beforeEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
})
describe('Radio.uvue', () => {
......@@ -65,4 +70,10 @@ describe('Radio.uvue', () => {
})
expect(await radio.attribute('disabled')).toBe(false + '')
})
it('trigger UniRadioGroupChangeEvent', async () => {
const element = await page.$('#trigger-change')
await element.tap()
const eventCallbackNum = await page.callMethod('getEventCallbackNum')
expect(eventCallbackNum - originEventCallbackNum).toBe(3)
})
})
<script>
import { state, setEventCallbackNum } from '@/store/index.uts'
type ItemType = {
value : string
name : string
......@@ -62,7 +63,23 @@
title: '当前选中:' + selected?.name,
})
},
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
testChange(e : UniRadioGroupChangeEvent) {
// 自动化测试
if ((e.target?.tagName ?? '').includes('RADIO-GROUP')) {
this.setEventCallbackNum(state.eventCallbackNum + 1)
}
if (e.type === 'change') {
this.setEventCallbackNum(state.eventCallbackNum + 2)
}
this.value = e.detail.value
},
radio_click() { console.log("组件被点击时触发") },
......@@ -119,7 +136,8 @@
<text class="uni-title-text"> 默认样式 </text>
</view>
<radio-group class="uni-flex uni-row radio-group" @change="testChange" style="flex-wrap: wrap">
<radio value="r" :checked="checked" :color="color" style="margin-right: 15px" class="radio r">选中
<radio id="trigger-change" value="r" :checked="checked" :color="color" style="margin-right: 15px"
class="radio r">选中
</radio>
<radio value="r1" style="margin-right: 15px" class="radio r1">{{
text
......
......@@ -73,4 +73,9 @@ describe('component-native-textarea', () => {
await page.waitFor(500)
}
})
it('both set modelValue and value', async () => {
let textarea2 = await page.$('.both-set-textarea');
expect(await textarea2.value()).toBe("123")
})
});
......@@ -18,7 +18,8 @@ export default {
cursor: 0,
inputmode_enum_current: 0,
confirm_type_current: 0,
placeholder_value: "请输入"
placeholder_value: "请输入",
defaultModel:'123'
}
},
......@@ -142,6 +143,11 @@ export default {
<textarea id="textarea-height-exception" style="flex:1;border: 1 solid #666;margin: 10px" placeholder="底部textarea测试键盘遮挡"/>
</view>
</view>
<view>同时存在 v-model 和 value</view>
<view class="main">
<textarea class="list-item both-set-textarea" v-model='defaultModel' value='456'></textarea>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
......
......@@ -85,11 +85,17 @@
name: '获取启动参数',
url: 'get-launch-options-sync',
},
// #ifndef WEB
{
name: 'env环境变量',
url: 'env'
},
// #endif
// #ifdef APP-ANDROID
{
name: '退出应用',
url: 'exit',
},
}
// #endif
] as Page[],
},
......@@ -166,12 +172,10 @@
api: ["Element.takeSnapshot"]
},
// #endif
// #ifdef APP-ANDROID || WEB
{
name: 'element大小变化监听',
url: 'resize-observer'
},
// #endif
{
name: 'node节点',
url: 'nodes-info',
......@@ -277,10 +281,13 @@
url: 'install-apk'
},
// #endif
/* {
// #ifdef WEB
{
name: "打电话",
url: "make-phone-call",
},
// #endif
/*
{
name: "震动",
url: "vibrate",
......@@ -384,10 +391,13 @@
url: 'compress-video'
},
// #endif
/* {
// #ifdef WEB
{
name: "音频",
url: "inner-audio",
},
// #endif
/*
{
name: "背景音频",
url: "background-audio",
......@@ -411,6 +421,12 @@
name: '获取当前位置',
url: 'get-location',
},
// #ifdef WEB
{
name: "地图控制",
url: "map",
},
// #endif
/* {
name: "使用地图查看位置",
url: "open-location",
......@@ -419,10 +435,6 @@
name: "使用地图选择位置",
url: "choose-location",
},
{
name: "地图控制",
url: "map",
},
{
name: "地图搜索",
url: "map-search",
......@@ -448,7 +460,7 @@
{
name: 'fileSystemManager文件管理',
url: 'get-file-system-manager'
},
}
] as Page[],
},
// #endif
......@@ -489,6 +501,16 @@
}
] as Page[],
},
{
id: 'theme-change',
name: '主题切换',
pages: [
{
name: '主题切换',
url: 'theme-change',
}
] as Page[]
},
// #endif
{
id: "payment",
......@@ -534,16 +556,6 @@
}
] as Page[]
},
{
id: 'theme-change',
name: '主题切换',
pages: [
{
name: '主题切换',
url: 'theme-change',
}
] as Page[]
},
// #endif
/*
{
......
......@@ -184,16 +184,16 @@
open: false,
pages: [] as Page[],
},
// #endif
{
id: 'schema',
url: 'schema',
name: '打开外部链接',
open: false,
pages: [] as Page[],
}
// #endif
},
// #ifdef APP-ANDROID
,{
{
id: 'share',
url: 'share',
name: '分享示例',
......
......@@ -37,7 +37,7 @@
</list-view>
<web-view v-if="indexView==2" src="/hybrid/html/local.html" id="webv" style="height:380px"></web-view>
<view style="position:relative;background-color:white;" :style="{bottom: inputBottom}">
<input placeholder="滚动视图外的居底输入框" adjust-position="false" @blur="onInputBlur" @keyboardheightchange="onInputKeyboardChange" />
<input placeholder="滚动视图外的居底输入框,不上推,手动控制输入框top" adjust-position="false" @blur="onInputBlur" @keyboardheightchange="onInputKeyboardChange" />
</view>
</view>
......
<template>
<view>
<!-- #ifdef APP -->
<button class="button" @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用外部浏览器打开指定URL</button>
<!-- #endif -->
<!-- #ifdef APP-ANDROID -->
<button class="button" @click="openSchema('market://details?id=com.tencent.mm')">使用应用商店打开指定App</button>
<button class="button" @click="openSchema('androidamap://viewMap?sourceApplication=Hello%20uni-app&poiname=DCloud&lat=39.9631018208&lon=116.3406135236&dev=0')">
......@@ -12,6 +14,13 @@
<button class="button" @click="openSchema('http://maps.apple.com/?q=数字天堂公司&sll=39.9631018208,116.3406135236&z=10&t=s')">打开 iOS 地图坐标</button>
<!-- apple协议:https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html -->
<!-- #endif -->
<!-- #ifdef WEB -->
<view class="tip">
<text>仅Android/iOS设备的浏览器中支持使用此功能,需先安装“Hello uni-app x”应用,如未安装请前往以下网页安装:</text>
<text class="link" @click="openSchema('https://hellouniappx.dcloud.net.cn/')">https://hellouniappx.dcloud.net.cn/</text>
</view>
<button class="button" @click="openSchema('hellouniappx://')">启动 Hello uni-app x 应用</button>
<!-- #endif -->
</view>
</template>
......@@ -23,4 +32,12 @@ import { openSchema } from '@/uni_modules/uts-openSchema'
.button {
margin: 15px;
}
.tip {
padding: 8px;
}
.link {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
</style>
......@@ -14,12 +14,15 @@ type State = {
safeArea : SafeArea
// 设备像素比
devicePixelRatio : number
// 事件判断回调
eventCallbackNum: number
}
export const state = reactive({
lifeCycleNum: 0,
statusBarHeight: 0,
devicePixelRatio: 1,
eventCallbackNum: 0,
safeArea: {
top: 0,
right: 0,
......@@ -34,6 +37,10 @@ export const setLifeCycleNum = (num : number) => {
state.lifeCycleNum = num
}
export const setEventCallbackNum = (num : number) => {
state.eventCallbackNum = num
}
export const setStatusBarHeight = (height : number) => {
state.statusBarHeight = height
}
......@@ -45,3 +52,4 @@ export const setSafeArea = (value : SafeArea) => {
export const setDevicePixelRatio = (devicePixelRatio : number) => {
state.devicePixelRatio = devicePixelRatio
}
......@@ -31,12 +31,13 @@ declare interface Uni {
/**
* 获取设备电量
*
* 文档: [https://uniapp.dcloud.net.cn/api/system/batteryInfo.html](https://uniapp.dcloud.net.cn/api/system/batteryInfo.html)
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
*/
getBatteryInfo(option?: UniNamespace.GetBatteryInfoOption): void;
/**
* 同步获取电池电量信息
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
*/
getBatteryInfoSync(): UniNamespace.GetBatteryInfoSuccessCallbackResult;
}
import { OpenSchema } from '../interface.uts'
export const openSchema: OpenSchema = function(url: string): void {
location.href = url;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册