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

Merge branch 'dev' into alpha

...@@ -67,10 +67,10 @@ ...@@ -67,10 +67,10 @@
uni.exit() uni.exit()
} }
}, },
// #endif
onExit() { onExit() {
console.log('App Exit') console.log('App Exit')
}, },
// #endif
methods: { methods: {
increasetLifeCycleNum() { increasetLifeCycleNum() {
setLifeCycleNum(state.lifeCycleNum + 100) setLifeCycleNum(state.lifeCycleNum + 100)
......
...@@ -458,6 +458,13 @@ ...@@ -458,6 +458,13 @@
"navigationBarTitleText": "文件管理" "navigationBarTitleText": "文件管理"
} }
}, },
{
"path" : "pages/API/env/env",
"style" :
{
"navigationBarTitleText" : "env"
}
},
// #endif // #endif
{ {
"path": "pages/API/action-sheet/action-sheet", "path": "pages/API/action-sheet/action-sheet",
...@@ -1273,6 +1280,41 @@ ...@@ -1273,6 +1280,41 @@
"navigationBarTitleText" : "editor" "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 // #endif
// #ifdef APP // #ifdef APP
{ {
...@@ -1281,13 +1323,20 @@ ...@@ -1281,13 +1323,20 @@
"navigationBarTitleText": "日历" "navigationBarTitleText": "日历"
} }
}, },
{
"path": "pages/API/theme-change/theme-change",
"style": {
"navigationBarTitleText": "主题切换",
"enablePullDownRefresh": false
}
},
// #endif
{ {
"path": "pages/template/schema/schema", "path": "pages/template/schema/schema",
"style": { "style": {
"navigationBarTitleText": "打开schema示例" "navigationBarTitleText": "打开schema示例"
} }
}, },
// #endif
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
{ {
"path": "pages/template/share/share", "path": "pages/template/share/share",
...@@ -1352,13 +1401,6 @@ ...@@ -1352,13 +1401,6 @@
"enablePullDownRefresh": false "enablePullDownRefresh": false
} }
}, },
{
"path": "pages/API/theme-change/theme-change",
"style": {
"navigationBarTitleText": "主题切换",
"enablePullDownRefresh": false
}
},
{ {
"path": "uni_modules/uni-pay-x/pages/success/success", "path": "uni_modules/uni-pay-x/pages/success/success",
"style": { "style": {
...@@ -1406,7 +1448,6 @@ ...@@ -1406,7 +1448,6 @@
"backgroundColorContent": "#fffae8" "backgroundColorContent": "#fffae8"
} }
}, },
// #ifdef APP-ANDROID || WEB
{ {
"path" : "pages/API/resize-observer/resize-observer", "path" : "pages/API/resize-observer/resize-observer",
"style" : "style" :
...@@ -1414,7 +1455,6 @@ ...@@ -1414,7 +1455,6 @@
"navigationBarTitleText" : "resize observer" "navigationBarTitleText" : "resize observer"
} }
}, },
// #endif
{ {
"path" : "pages/CSS/overflow/overflow-visible-event", "path" : "pages/CSS/overflow/overflow-visible-event",
"style" : "style" :
...@@ -1429,9 +1469,7 @@ ...@@ -1429,9 +1469,7 @@
"navigationBarTextStyle": "white", "navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#007AFF", "navigationBarBackgroundColor": "#007AFF",
"backgroundColorContent": "#efeff4", "backgroundColorContent": "#efeff4",
"backgroundColor": "#efeff4", "backgroundColor": "#efeff4"
"backgroundColorTop": "#F4F5F6",
"backgroundColorBottom": "#F4F5F6"
}, },
"tabBar": { "tabBar": {
"color": "#7A7E83", "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>
<template> <template>
<view> <view>
<text>当前电量:{{level}}%</text> <text>当前电量:{{level}}%</text>
<text>是否充电中:{{isCharging}}</text> <text>是否充电中:{{isCharging}}</text>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
level: 0, level: 0,
isCharging: false isCharging: false
} }
}, },
onLoad() { onLoad() {
uni.getBatteryInfo({ try {
success: res => { uni.getBatteryInfo({
this.level = res.level; success: res => {
this.isCharging = res.isCharging; this.level = res.level;
} this.isCharging = res.isCharging;
}); }
} });
} } catch (e) {
console.error(e.message);
uni.showModal({
content: e.message,
showCancel: false
});
}
}
}
</script> </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', () => { 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 let page
beforeAll(async () => { beforeAll(async () => {
......
...@@ -4,13 +4,15 @@ ...@@ -4,13 +4,15 @@
<view v-show="boxDisplay" style="align-items: center; justify-content: center; margin: 10px;"> <view v-show="boxDisplay" style="align-items: center; justify-content: center; margin: 10px;">
<view <view
style="width: 140px; height: 140px; background-color: blue; align-items: center; justify-content: center; padding: 5px;" style="width: 140px; height: 140px; background-color: blue; align-items: center; justify-content: center; padding: 5px;"
id="outBox" @click="outBoxClick"> id="outBox" @click="outBoxClick">
<view style="width: 80px; height: 80px; background-color: red; padding: 5px;" id="innerBox" <view style="width: 80px; height: 80px; background-color: red; padding: 5px;" id="innerBox"
@click="innerBoxClick"></view> @click="innerBoxClick"></view>
</view> </view>
</view> </view>
<button @click="revertBoxSize">还原修改前元素宽高</button> <button @click="revertBoxSize">还原修改前元素宽高</button>
<button @click="toggleDisplay">{{boxDisplay? '隐藏元素': '显示元素'}}</button> <button @click="toggleDisplay">{{boxDisplay? '隐藏元素': '显示元素'}}</button>
<button @click='cancelListen'>停止监听</button>
<button @click='goOnListen'>恢复监听</button>
<view> <view>
<text class="info-text">蓝色方块元素:</text> <text class="info-text">蓝色方块元素:</text>
<view class="info-item"> <view class="info-item">
...@@ -34,7 +36,7 @@ ...@@ -34,7 +36,7 @@
boxDisplay: false, boxDisplay: false,
outBoxElement: null as UniElement | null, outBoxElement: null as UniElement | null,
innerBoxElement: null as UniElement | null, innerBoxElement: null as UniElement | null,
resizeObserver: null as UniResizeObserver | null, resizeObserver: null as UniResizeObserver | null,
outBoxElementOnResize: false outBoxElementOnResize: false
} }
}, },
...@@ -47,9 +49,10 @@ ...@@ -47,9 +49,10 @@
onReady() { onReady() {
if (this.resizeObserver == null) { if (this.resizeObserver == null) {
this.resizeObserver = new UniResizeObserver((entries : Array<UniResizeObserverEntry>) => { this.resizeObserver = new UniResizeObserver((entries : Array<UniResizeObserverEntry>) => {
entries.forEach(entry => { entries.forEach(entry => {
if (entry.target == this.outBoxElement) { if (entry.target == this.outBoxElement) {
this.outBoxSizeInfo = this.analysisResizeObserverEntry(entry) this.outBoxSizeInfo = this.analysisResizeObserverEntry(entry)
this.outBoxElementOnResize = true this.outBoxElementOnResize = true
} else if (entry.target == this.innerBoxElement) { } else if (entry.target == this.innerBoxElement) {
this.innerBoxSizeInfo = this.analysisResizeObserverEntry(entry) this.innerBoxSizeInfo = this.analysisResizeObserverEntry(entry)
...@@ -63,7 +66,7 @@ ...@@ -63,7 +66,7 @@
this.innerBoxElement = uni.getElementById("innerBox") this.innerBoxElement = uni.getElementById("innerBox")
if (this.innerBoxElement != null) { if (this.innerBoxElement != null) {
this.resizeObserver!.observe(this.innerBoxElement!) this.resizeObserver!.observe(this.innerBoxElement!)
} }
this.boxDisplay = true this.boxDisplay = true
} }
}, },
...@@ -89,13 +92,13 @@ ...@@ -89,13 +92,13 @@
this.innerBoxElement!.style.setProperty("width", "80px") this.innerBoxElement!.style.setProperty("width", "80px")
this.innerBoxElement!.style.setProperty("height", "80px") this.innerBoxElement!.style.setProperty("height", "80px")
} }
}, },
//自动化测试专用 //自动化测试专用
setOutBoxMarginLeft(value: string) { setOutBoxMarginLeft(value : string) {
if (this.outBoxElement != null) { if (this.outBoxElement != null) {
this.outBoxElementOnResize = false this.outBoxElementOnResize = false
this.outBoxElement!.style.setProperty("margin-left", value) this.outBoxElement!.style.setProperty("margin-left", value)
} }
}, },
toggleDisplay() { toggleDisplay() {
this.boxDisplay = !this.boxDisplay this.boxDisplay = !this.boxDisplay
...@@ -108,6 +111,15 @@ ...@@ -108,6 +111,15 @@
"contentBoxSize: \n{blockSize:" + contentBoxSize.blockSize + ", inlineSize:" + contentBoxSize.inlineSize + "}\n" + "contentBoxSize: \n{blockSize:" + contentBoxSize.blockSize + ", inlineSize:" + contentBoxSize.inlineSize + "}\n" +
"devicePixelContentBoxSize: \n{blockSize:" + devicePixelContentBoxSize.blockSize + ", inlineSize:" + devicePixelContentBoxSize.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 + "}" "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> <template>
<view class="uni-padding-wrap"> <view class="uni-padding-wrap">
<view class="uni-common-mt flex justify-between flex-row"> <view class="uni-common-mt item-box">
<text>theme:</text> <text>osTheme:</text>
<text id="theme">{{ dataInfo.theme }}</text> <text id="theme">{{ osTheme }}</text>
</view> </view>
<view class="uni-common-mt flex justify-between flex-row"> <view class="uni-common-mt item-box">
<text>fn1 trigger num:</text> <text>appTheme:</text>
<text id="fn1-trigger-num">{{ dataInfo.fn1TriggerNum }}</text> <text id="theme">{{ appTheme }}</text>
</view> </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>
<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) => { <view>
dataInfo.fn2TriggerNum++ <view class="uni-title uni-common-mt">
console.log('fn2 triggered options: ', options) <text class="uni-title-text"> 修改appTheme主题 </text>
dataInfo.theme = options.theme </view>
} </view>
<view class="uni-list uni-common-pl">
const bindFn1 = () => { <radio-group @change="radioChange" class="radio-group">
uni.onOSThemeChange(fn1) <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"
const removeFn1 = () => { :checked="index === current">
uni.offOSThemeChange(fn1) {{ item }}
} </radio>
const bindFn2 = () => { </radio-group>
uni.onOSThemeChange(fn2) </view>
}
const removeFn2 = () => { </view>
uni.offOSThemeChange(fn2) </template>
}
<script>
onReady(() => { export default {
bindFn1() data() {
bindFn2() return {
}) osThemeChangeId: 0,
</script> appThemeChangeId: 0,
osTheme: "light" as string,
<style> appTheme: "light" as string,
.flex { current: 0,
display: flex; items: [
} "light",
.flex-row { "dark",
flex-direction: row; "auto"
} ] as string[]
.justify-between { }
justify-content: space-between; },
} 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>
.item-box {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-list-cell {
justify-content: flex-start;
}
</style> </style>
...@@ -6,9 +6,16 @@ function getData(key = '') { ...@@ -6,9 +6,16 @@ function getData(key = '') {
} }
let page let page
let originEventCallbackNum
beforeAll(async () => { beforeAll(async () => {
page = await program.reLaunch('/pages/component/checkbox/checkbox') 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', () => { describe('Checkbox.uvue', () => {
...@@ -68,4 +75,10 @@ describe('Checkbox.uvue', () => { ...@@ -68,4 +75,10 @@ describe('Checkbox.uvue', () => {
}) })
expect(await cb.attribute('disabled')).toBe(false + '') 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> <script>
import { state, setEventCallbackNum } from '@/store/index.uts'
type ItemType = { type ItemType = {
value : string value : string
name : string name : string
...@@ -58,7 +59,24 @@ ...@@ -58,7 +59,24 @@
} }
}, },
methods: { methods: {
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
checkboxChange: function (e : UniCheckboxGroupChangeEvent) { 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[] = [] const selectedNames : string[] = []
this.items.forEach((item) => { this.items.forEach((item) => {
if (e.detail.value.includes(item.value)) { if (e.detail.value.includes(item.value)) {
...@@ -156,9 +174,10 @@ ...@@ -156,9 +174,10 @@
</view> </view>
</view> </view>
<view class="uni-list uni-common-pl"> <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" <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 }} {{ item.name }}
</checkbox> </checkbox>
</checkbox-group> </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 @@ ...@@ -30,7 +30,7 @@
data-name="marginTop" data-value="20px"></view> data-name="marginTop" data-value="20px"></view>
<view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju" <view :class="formats.marginBottom ? 'ql-active' : ''" class="iconfont icon-723bianjiqi_duanhouju"
data-name="marginBottom" data-value="20px"></view> 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" <view :class="formats.fontFamily ? 'ql-active' : ''" class="iconfont icon-font"
data-name="fontFamily" data-value="Pacifico"></view> data-name="fontFamily" data-value="Pacifico"></view>
<view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize" <view :class="formats.fontSize === '24px' ? 'ql-active' : ''" class="iconfont icon-fontsize"
...@@ -39,27 +39,35 @@ ...@@ -39,27 +39,35 @@
data-name="color" data-value="#0000ff"></view> data-name="color" data-value="#0000ff"></view>
<view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''" <view :class="formats.backgroundColor === '#00ff00' ? 'ql-active' : ''"
class="iconfont icon-fontbgcolor" data-name="backgroundColor" data-value="#00ff00"></view> 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="iconfont icon--checklist" data-name="list" data-value="check"></view>
<view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie" <view :class="formats.list === 'ordered' ? 'ql-active' : ''" class="iconfont icon-youxupailie"
data-name="list" data-value="ordered"></view> data-name="list" data-value="ordered"></view>
<view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie" <view :class="formats.list === 'bullet' ? 'ql-active' : ''" class="iconfont icon-wuxupailie"
data-name="list" data-value="bullet"></view> 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-outdent" data-name="indent" data-value="-1"></view>
<view class="iconfont icon-indent" 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" <view :class="formats.header === 1 ? 'ql-active' : ''" class="iconfont icon-format-header-1"
data-name="header" :data-value="1"></view> data-name="header" :data-value="1"></view>
<view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao" <view :class="formats.script === 'sub' ? 'ql-active' : ''" class="iconfont icon-zitixiabiao"
data-name="script" data-value="sub"></view> data-name="script" data-value="sub"></view>
<view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao" <view :class="formats.script === 'super' ? 'ql-active' : ''" class="iconfont icon-zitishangbiao"
data-name="script" data-value="super"></view> 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" <view :class="formats.direction === 'rtl' ? 'ql-active' : ''" class="iconfont icon-direction-rtl"
data-name="direction" data-value="rtl"></view> 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>
<view class="editor-wrapper"> <view class="editor-wrapper">
...@@ -86,7 +94,12 @@ ...@@ -86,7 +94,12 @@
return { return {
readOnly: false, readOnly: false,
formats: {}, formats: {},
editorCtx:{} as Context editorCtx:{} as Context,
// 自动化测试
autoTest:false,
undoTest:false,
redoTest:false,
removeFormatTest:false
} }
}, },
onLoad() { onLoad() {
...@@ -110,6 +123,20 @@ ...@@ -110,6 +123,20 @@
this.editorCtx = res.context this.editorCtx = res.context
}).exec() }).exec()
}, },
// 自动化测试专用
setContents(options) {
this.editorCtx.setContents({
delta: {
ops:options
},
success: (res) => {
console.log('setContents-success', res)
},
fail: (err) => {
console.log(err)
}
})
},
getCon() { getCon() {
this.editorCtx.getContents({ this.editorCtx.getContents({
success: (res) => { success: (res) => {
...@@ -121,16 +148,27 @@ ...@@ -121,16 +148,27 @@
}) })
}, },
undo() { undo() {
this.editorCtx.undo() this.editorCtx.undo({
success: (res) => {
this.undoTest = true
},
fail: (err) => {
this.undoTest = false
}
})
}, },
redo() { redo() {
this.editorCtx.redo() this.editorCtx.redo({
success: (res) => {
this.redoTest = true
},
fail: (err) => {
this.redoTest = false
}
})
}, },
format(e) { format(e) {
let { let {name,value} = e.target.dataset
name,
value
} = e.target.dataset
if (!name) return if (!name) return
// console.log('format', name, value) // console.log('format', name, value)
this.editorCtx.format(name, value) this.editorCtx.format(name, value)
...@@ -146,23 +184,34 @@ ...@@ -146,23 +184,34 @@
} }
}) })
}, },
clear() { clear() {
uni.showModal({ this.editorCtx.clear({
title: '清空编辑器', success: function(res) {
content: '确定清空编辑器全部内容?', console.log("clear success")
success: res => { }
if (res.confirm) { })
this.editorCtx.clear({ },
success: function(res) { clearShowModal() {
console.log("clear success") uni.showModal({
} title: '清空编辑器',
}) content: '确定清空编辑器全部内容?',
} success: res => {
} if (res.confirm) {
}) this.clear()
}
}
})
}, },
removeFormat() { removeFormat() {
this.editorCtx.removeFormat() this.editorCtx.removeFormat({
success: (res) => {
console.log('removeFormat-success', res)
this.removeFormatTest = true
},
fail: (err) => {
this.removeFormatTest = false
}
})
}, },
insertDate() { insertDate() {
const date = new Date() const date = new Date()
...@@ -171,19 +220,22 @@ ...@@ -171,19 +220,22 @@
text: formatDate text: formatDate
}) })
}, },
insertImage() { insertImage(image){
uni.chooseImage({ this.editorCtx.insertImage({
count: 1, src:image,
success: (res) => { alt: '图像',
this.editorCtx.insertImage({ success: function() {
src: res.tempFilePaths[0], console.log('insert image success')
alt: '图像', }
success: function() { })
console.log('insert image success') },
} chooseInsertImage() {
}) uni.chooseImage({
} count: 1,
}) success: (res) => {
this.insertImage(res.tempFilePaths[0])
}
})
} }
} }
} }
...@@ -201,17 +253,18 @@ ...@@ -201,17 +253,18 @@
} }
.editor-wrapper { .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; background: #fff;
} }
.iconfont { .iconfont {
display: inline-block; display: inline-block;
padding: 8px 8px;
width: 30px; width: 30px;
height: 30px; height: 30px;
cursor: pointer; cursor: pointer;
font-size: 20px; font-size: 20px;
margin: 0px 6px;
align-content: center;
} }
.toolbar { .toolbar {
...@@ -220,7 +273,8 @@ ...@@ -220,7 +273,8 @@
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
height: 110px; height: 140px;
padding-left: 10px;
} }
.ql-container { .ql-container {
......
...@@ -198,4 +198,9 @@ describe('component-native-input', () => { ...@@ -198,4 +198,9 @@ describe('component-native-input', () => {
}) })
expect(image).toSaveImageSnapshot() expect(image).toSaveImageSnapshot()
}) })
it('both set modelValue and value', async()=>{
const input2 = await page.$('#both-model-value');
expect(await input2.value()).toEqual("123")
})
}); });
此差异已折叠。
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 @@ ...@@ -5,7 +5,7 @@
<view class="uni-form-item uni-column"> <view class="uni-form-item uni-column">
<view class="title">表单组件在label内</view> <view class="title">表单组件在label内</view>
<checkbox-group class="uni-list" @change="checkboxChange"> <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> <view>
<checkbox :value="item.name" :checked="item.checked"></checkbox> <checkbox :value="item.name" :checked="item.checked"></checkbox>
</view> </view>
...@@ -70,17 +70,19 @@ ...@@ -70,17 +70,19 @@
checked: 'true' checked: 'true'
} }
], ],
hidden: false hidden: false,
checkboxValue: [] as string[],
radioValue:''
} }
}, },
methods: { methods: {
checkboxChange: function (e) { checkboxChange: function (e : UniCheckboxGroupChangeEvent) {
var checked = e.detail.value console.log(e.detail.value)
console.log(checked) this.checkboxValue = e.detail.value
}, },
radioChange: function (e) { radioChange: function (e : UniRadioGroupChangeEvent) {
var checked = e.detail.value console.log(e.detail.value)
console.log(checked) this.radioValue = e.detail.value
} }
} }
} }
......
...@@ -4,21 +4,26 @@ function getData(key = '') { ...@@ -4,21 +4,26 @@ function getData(key = '') {
resolve(key ? data[key] : data) resolve(key ? data[key] : data)
}) })
} }
const PAGE_PATH = '/pages/component/picker-view/picker-view' const PAGE_PATH = '/pages/component/picker-view/picker-view'
let page let page
beforeAll(async () => { beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH) page = await program.reLaunch(PAGE_PATH)
await page.waitFor('view') await page.waitFor('view')
await page.callMethod('setEventCallbackNum', 0)
})
afterEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
}) })
describe('PickerView.uvue', () => { describe('PickerView.uvue', () => {
it('value', async () => { it('value', async () => {
const el = await page.$('.picker-view') const el = await page.$('.picker-view')
await page.callMethod('setValue') await page.callMethod('setValue')
await page.waitFor(1000) await page.waitFor(1000)
const newValue1 = await el.property('value') const newValue1 = await el.property('value')
// TODO // TODO
expect(newValue1.toString()).toEqual('0,0,0') expect(newValue1.toString()).toEqual('0,0,0')
if (process.env.UNI_PLATFORM === 'app-android') { if (process.env.UNI_PLATFORM === 'app-android') {
...@@ -26,8 +31,8 @@ describe('PickerView.uvue', () => { ...@@ -26,8 +31,8 @@ describe('PickerView.uvue', () => {
} }
await page.callMethod('setValue1') await page.callMethod('setValue1')
await page.waitFor(1000) await page.waitFor(1000)
const newValue2 = await el.property('value') const newValue2 = await el.property('value')
// TODO // TODO
expect(newValue2.toString()).toEqual('10,10,10') expect(newValue2.toString()).toEqual('10,10,10')
if (process.env.UNI_PLATFORM === 'app-android') { if (process.env.UNI_PLATFORM === 'app-android') {
...@@ -62,21 +67,39 @@ describe('PickerView.uvue', () => { ...@@ -62,21 +67,39 @@ describe('PickerView.uvue', () => {
maskBottomStyle: 'background: #ffffff;', maskBottomStyle: 'background: #ffffff;',
}) })
expect(await el.attribute('mask-bottom-style')).toBe('background: #ffffff;') expect(await el.attribute('mask-bottom-style')).toBe('background: #ffffff;')
})
it('reopen-picker-view-page', async () => {
page = await program.switchTab('/pages/tabBar/component')
await page.waitFor(500)
page = await program.navigateTo(PAGE_PATH)
await page.waitFor(500)
const date = new Date()
const {
year,
month,
day
} = await page.data()
expect(year).toEqual(date.getFullYear())
expect(month).toEqual(date.getMonth() + 1)
expect(day).toEqual(date.getDate())
}) })
})
it('reopen-picker-view-page', async () => {
page = await program.switchTab('/pages/tabBar/component')
await page.waitFor(500)
page = await program.navigateTo(PAGE_PATH)
await page.waitFor(500)
const date = new Date()
const {
year,
month,
day
} = await page.data()
expect(year).toEqual(date.getFullYear())
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)
})
})
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
</view> </view>
</template> </template>
<script lang="uts"> <script lang="uts">
import { state, setEventCallbackNum } from '@/store/index.uts'
export default { export default {
data() { data() {
const date = new Date() const date = new Date()
...@@ -56,8 +57,25 @@ ...@@ -56,8 +57,25 @@
maskBottomStyle: '' maskBottomStyle: ''
} }
}, },
methods: { methods: {
bindChange(e : UniPickerViewChangeEvent) { // 自动化测试
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 const val = e.detail.value
this.result = val this.result = val
this.year = this.years[val[0]] 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 @@ ...@@ -8,8 +8,8 @@
当前选择 当前选择
</view> </view>
<view class="uni-list-cell-db"> <view class="uni-list-cell-db">
<picker @change="bindPickerChange" :value="index" :range="array" range-key="name"> <picker class="picker" @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input">{{array[index].name}}</view> <view class="uni-input pickerValue">{{array[index].name}}</view>
</picker> </picker>
</view> </view>
</view> </view>
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
当前选择 当前选择
</view> </view>
<view class="uni-list-cell-db"> <view class="uni-list-cell-db">
<picker mode="multiSelector" @columnchange="bindMultiPickerColumnChange" :value="multiIndex" :range="multiArray"> <picker class="pickerMulti" 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> <view class="uni-input pickerMultiValue">{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}}</view>
</picker> </picker>
</view> </view>
</view> </view>
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
当前选择 当前选择
</view> </view>
<view class="uni-list-cell-db"> <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> <view class="uni-input">{{time}}</view>
</picker> </picker>
</view> </view>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
当前选择 当前选择
</view> </view>
<view class="uni-list-cell-db"> <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> <view class="uni-input">{{date}}</view>
</picker> </picker>
</view> </view>
......
...@@ -11,6 +11,10 @@ beforeAll(async () => { ...@@ -11,6 +11,10 @@ beforeAll(async () => {
await page.waitFor(2000); await page.waitFor(2000);
}) })
beforeEach(async () => {
await page.callMethod('setEventCallbackNum', 0)
})
describe('Progress.uvue', () => { describe('Progress.uvue', () => {
it('percent', async () => { it('percent', async () => {
await page.callMethod('setProgress') await page.callMethod('setProgress')
...@@ -80,4 +84,21 @@ describe('Progress.uvue', () => { ...@@ -80,4 +84,21 @@ describe('Progress.uvue', () => {
}) })
expect(await el.attribute('background-color')).toEqual('#007aff') 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> <script>
import { state, setEventCallbackNum } from '@/store/index.uts'
import { ItemType } from '@/components/enum-data/enum-data' import { ItemType } from '@/components/enum-data/enum-data'
export default { export default {
data() { data() {
...@@ -25,6 +26,15 @@ ...@@ -25,6 +26,15 @@
} }
}, },
methods: { methods: {
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
setProgress() { setProgress() {
this.pgList = [20, 40, 60, 80] as number[] this.pgList = [20, 40, 60, 80] as number[]
}, },
...@@ -32,6 +42,13 @@ ...@@ -32,6 +42,13 @@
this.pgList = [0, 0, 0, 0] as number[] this.pgList = [0, 0, 0, 0] as number[]
}, },
activeend(e : UniProgressActiveendEvent) { 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 this.curPercent = e.detail.curPercent
}, },
progress_touchstart() { console.log("手指触摸动作开始") }, progress_touchstart() { console.log("手指触摸动作开始") },
......
...@@ -6,9 +6,14 @@ function getData(key = '') { ...@@ -6,9 +6,14 @@ function getData(key = '') {
} }
let page let page
let originEventCallbackNum
beforeAll(async () => { beforeAll(async () => {
page = await program.reLaunch('/pages/component/radio/radio') 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', () => { describe('Radio.uvue', () => {
...@@ -65,4 +70,10 @@ describe('Radio.uvue', () => { ...@@ -65,4 +70,10 @@ describe('Radio.uvue', () => {
}) })
expect(await radio.attribute('disabled')).toBe(false + '') 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> <script>
import { state, setEventCallbackNum } from '@/store/index.uts'
type ItemType = { type ItemType = {
value : string value : string
name : string name : string
...@@ -62,7 +63,23 @@ ...@@ -62,7 +63,23 @@
title: '当前选中:' + selected?.name, title: '当前选中:' + selected?.name,
}) })
}, },
// 自动化测试
getEventCallbackNum() : number {
return state.eventCallbackNum
},
// 自动化测试
setEventCallbackNum(num : number) {
setEventCallbackNum(num)
},
testChange(e : UniRadioGroupChangeEvent) { 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 this.value = e.detail.value
}, },
radio_click() { console.log("组件被点击时触发") }, radio_click() { console.log("组件被点击时触发") },
...@@ -119,7 +136,8 @@ ...@@ -119,7 +136,8 @@
<text class="uni-title-text"> 默认样式 </text> <text class="uni-title-text"> 默认样式 </text>
</view> </view>
<radio-group class="uni-flex uni-row radio-group" @change="testChange" style="flex-wrap: wrap"> <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>
<radio value="r1" style="margin-right: 15px" class="radio r1">{{ <radio value="r1" style="margin-right: 15px" class="radio r1">{{
text text
......
...@@ -73,4 +73,9 @@ describe('component-native-textarea', () => { ...@@ -73,4 +73,9 @@ describe('component-native-textarea', () => {
await page.waitFor(500) await page.waitFor(500)
} }
}) })
it('both set modelValue and value', async () => {
let textarea2 = await page.$('.both-set-textarea');
expect(await textarea2.value()).toBe("123")
})
}); });
<script> <script>
import { ItemType } from '@/components/enum-data/enum-data' import { ItemType } from '@/components/enum-data/enum-data'
export default { export default {
data() { data() {
return { return {
adjust_position_boolean: false, adjust_position_boolean: false,
show_confirm_bar_boolean: false, show_confirm_bar_boolean: false,
fixed_boolean: false, fixed_boolean: false,
auto_height_boolean: false, auto_height_boolean: false,
confirm_hold_boolean: false, confirm_hold_boolean: false,
focus_boolean: true, focus_boolean: true,
auto_focus_boolean: false, auto_focus_boolean: false,
default_value:"1\n2\n3\n4\n5\n6", default_value:"1\n2\n3\n4\n5\n6",
maxlength:-1, maxlength:-1,
inputmode_enum: [{"value":1,"name":"text"},{"value":2,"name":"decimal"},{"value":3,"name":"numeric"},{"value":4,"name":"tel"},{"value":5,"name":"search"},{"value":6,"name":"email"},{"value":7,"name":"url"},{"value":0,"name":"none"}] as ItemType[], inputmode_enum: [{"value":1,"name":"text"},{"value":2,"name":"decimal"},{"value":3,"name":"numeric"},{"value":4,"name":"tel"},{"value":5,"name":"search"},{"value":6,"name":"email"},{"value":7,"name":"url"},{"value":0,"name":"none"}] as ItemType[],
confirm_type_list: [{"value":0,"name":"return"},{"value":1,"name":"done"},{"value":2,"name":"send"},{"value":3,"name":"search"},{"value":4,"name":"next"},{"value":5,"name":"go"}] as ItemType[], confirm_type_list: [{"value":0,"name":"return"},{"value":1,"name":"done"},{"value":2,"name":"send"},{"value":3,"name":"search"},{"value":4,"name":"next"},{"value":5,"name":"go"}] as ItemType[],
cursor_color: "#3393E2", cursor_color: "#3393E2",
cursor: 0, cursor: 0,
inputmode_enum_current: 0, inputmode_enum_current: 0,
confirm_type_current: 0, confirm_type_current: 0,
placeholder_value: "请输入" placeholder_value: "请输入",
} defaultModel:'123'
}
}, },
methods: { methods: {
textarea_click() { console.log("组件被点击时触发") }, textarea_click() { console.log("组件被点击时触发") },
textarea_touchstart() { console.log("手指触摸动作开始") }, textarea_touchstart() { console.log("手指触摸动作开始") },
textarea_touchmove() { console.log("手指触摸后移动") }, textarea_touchmove() { console.log("手指触摸后移动") },
textarea_touchcancel() { console.log("手指触摸动作被打断,如来电提醒,弹窗") }, textarea_touchcancel() { console.log("手指触摸动作被打断,如来电提醒,弹窗") },
textarea_touchend() { console.log("手指触摸动作结束") }, textarea_touchend() { console.log("手指触摸动作结束") },
textarea_tap() { console.log("手指触摸后马上离开") }, textarea_tap() { console.log("手指触摸后马上离开") },
textarea_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") }, textarea_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
textarea_confirm() { console.log("点击完成时, 触发 confirm 事件,event.detail = {value: value}") }, textarea_confirm() { console.log("点击完成时, 触发 confirm 事件,event.detail = {value: value}") },
textarea_input() { console.log("当键盘输入时,触发 input 事件,event.detail = {value, cursor}, @input 处理函数的返回值并不会反映到 textarea 上") }, textarea_input() { console.log("当键盘输入时,触发 input 事件,event.detail = {value, cursor}, @input 处理函数的返回值并不会反映到 textarea 上") },
textarea_linechange() { console.log("输入框行数变化时调用,event.detail = {height: 0, height: 0, lineCount: 0}") }, textarea_linechange() { console.log("输入框行数变化时调用,event.detail = {height: 0, height: 0, lineCount: 0}") },
textarea_blur() { console.log("输入框失去焦点时触发,event.detail = {value, cursor}") }, textarea_blur() { console.log("输入框失去焦点时触发,event.detail = {value, cursor}") },
textarea_keyboardheightchange() { console.log("键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration}") }, textarea_keyboardheightchange() { console.log("键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration}") },
textarea_focus() { console.log("输入框聚焦时触发,event.detail = { value, height },height 为键盘高度") }, textarea_focus() { console.log("输入框聚焦时触发,event.detail = { value, height },height 为键盘高度") },
change_adjust_position_boolean(checked : boolean) { this.adjust_position_boolean = checked }, change_adjust_position_boolean(checked : boolean) { this.adjust_position_boolean = checked },
change_show_confirm_bar_boolean(checked : boolean) { this.show_confirm_bar_boolean = checked }, change_show_confirm_bar_boolean(checked : boolean) { this.show_confirm_bar_boolean = checked },
change_fixed_boolean(checked : boolean) { this.fixed_boolean = checked }, change_fixed_boolean(checked : boolean) { this.fixed_boolean = checked },
change_auto_height_boolean(checked : boolean) { this.auto_height_boolean = checked }, change_auto_height_boolean(checked : boolean) { this.auto_height_boolean = checked },
change_confirm_hold_boolean(checked : boolean) { this.confirm_hold_boolean = checked }, change_confirm_hold_boolean(checked : boolean) { this.confirm_hold_boolean = checked },
change_focus_boolean(checked : boolean) { this.focus_boolean = checked }, change_focus_boolean(checked : boolean) { this.focus_boolean = checked },
change_auto_focus_boolean(checked : boolean) { this.auto_focus_boolean = checked }, change_auto_focus_boolean(checked : boolean) { this.auto_focus_boolean = checked },
change_cursor_color_boolean(checked : boolean) { if(checked){ this.cursor_color = "transparent"} else {this.cursor_color = "#3393E2"}}, change_cursor_color_boolean(checked : boolean) { if(checked){ this.cursor_color = "transparent"} else {this.cursor_color = "#3393E2"}},
radio_change_inputmode_enum(checked : number) { this.inputmode_enum_current = checked }, radio_change_inputmode_enum(checked : number) { this.inputmode_enum_current = checked },
radio_change_confirm_type(checked : number) { this.confirm_type_current = checked } radio_change_confirm_type(checked : number) { this.confirm_type_current = checked }
} }
} }
</script> </script>
<template> <template>
<!-- #ifdef APP --> <!-- #ifdef APP -->
<scroll-view style="flex: 1"> <scroll-view style="flex: 1">
<!-- #endif --> <!-- #endif -->
...@@ -86,17 +87,17 @@ export default { ...@@ -86,17 +87,17 @@ export default {
@focus="textarea_focus" @focus="textarea_focus"
style="padding: 10px; border: 1px solid #666;height: 200px" style="padding: 10px; border: 1px solid #666;height: 200px"
/> />
</view> </view>
<view class="content"> <view class="content">
<boolean-data <boolean-data
:defaultValue="false" :defaultValue="false"
title="键盘弹起时,是否自动上推页面(限非 Web 平台)" title="键盘弹起时,是否自动上推页面(限非 Web 平台)"
@change="change_adjust_position_boolean" @change="change_adjust_position_boolean"
></boolean-data> ></boolean-data>
<boolean-data <boolean-data
:defaultValue="false" :defaultValue="false"
title="是否自动增高,设置auto-height时,style.height不生效" title="是否自动增高,设置auto-height时,style.height不生效"
@change="change_auto_height_boolean" @change="change_auto_height_boolean"
></boolean-data> ></boolean-data>
<boolean-data <boolean-data
:defaultValue="focus_boolean" :defaultValue="focus_boolean"
...@@ -117,12 +118,12 @@ export default { ...@@ -117,12 +118,12 @@ export default {
:items="confirm_type_list" :items="confirm_type_list"
title="confirm-type,设置键盘右下角按钮。(Android仅支持return)" title="confirm-type,设置键盘右下角按钮。(Android仅支持return)"
@change="radio_change_confirm_type" @change="radio_change_confirm_type"
></enum-data> ></enum-data>
<boolean-data <boolean-data
:defaultValue="false" :defaultValue="false"
title="点击软键盘右下角按钮时是否保持键盘不收起(confirm-type为return时必然不收起)" title="点击软键盘右下角按钮时是否保持键盘不收起(confirm-type为return时必然不收起)"
@change="change_confirm_hold_boolean" @change="change_confirm_hold_boolean"
></boolean-data> ></boolean-data>
<enum-data <enum-data
:items="inputmode_enum" :items="inputmode_enum"
title="input-mode,控制软键盘类型。(仅限 Web 平台符合条件的高版本浏览器或webview)。" title="input-mode,控制软键盘类型。(仅限 Web 平台符合条件的高版本浏览器或webview)。"
...@@ -140,25 +141,30 @@ export default { ...@@ -140,25 +141,30 @@ export default {
></boolean-data> ></boolean-data>
<view style="flex-direction:row;justify-content:center;"> <view style="flex-direction:row;justify-content:center;">
<textarea id="textarea-height-exception" style="flex:1;border: 1 solid #666;margin: 10px" placeholder="底部textarea测试键盘遮挡"/> <textarea id="textarea-height-exception" style="flex:1;border: 1 solid #666;margin: 10px" placeholder="底部textarea测试键盘遮挡"/>
</view> </view>
</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 --> <!-- #ifdef APP -->
</scroll-view> </scroll-view>
<!-- #endif --> <!-- #endif -->
</template> </template>
<style> <style>
.main { .main {
min-height: 100px; min-height: 100px;
padding: 5px 0; padding: 5px 0;
border-bottom: 1px solid rgba(0, 0, 0, 0.06); border-bottom: 1px solid rgba(0, 0, 0, 0.06);
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
} }
.main .list-item { .main .list-item {
width: 100%; width: 100%;
height: 100px; height: 100px;
border: 1px solid #666; border: 1px solid #666;
} }
</style> </style>
...@@ -85,11 +85,17 @@ ...@@ -85,11 +85,17 @@
name: '获取启动参数', name: '获取启动参数',
url: 'get-launch-options-sync', url: 'get-launch-options-sync',
}, },
// #ifndef WEB
{
name: 'env环境变量',
url: 'env'
},
// #endif
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
{ {
name: '退出应用', name: '退出应用',
url: 'exit', url: 'exit',
}, }
// #endif // #endif
] as Page[], ] as Page[],
}, },
...@@ -166,12 +172,10 @@ ...@@ -166,12 +172,10 @@
api: ["Element.takeSnapshot"] api: ["Element.takeSnapshot"]
}, },
// #endif // #endif
// #ifdef APP-ANDROID || WEB
{ {
name: 'element大小变化监听', name: 'element大小变化监听',
url: 'resize-observer' url: 'resize-observer'
}, },
// #endif
{ {
name: 'node节点', name: 'node节点',
url: 'nodes-info', url: 'nodes-info',
...@@ -277,10 +281,13 @@ ...@@ -277,10 +281,13 @@
url: 'install-apk' url: 'install-apk'
}, },
// #endif // #endif
/* { // #ifdef WEB
{
name: "打电话", name: "打电话",
url: "make-phone-call", url: "make-phone-call",
}, },
// #endif
/*
{ {
name: "震动", name: "震动",
url: "vibrate", url: "vibrate",
...@@ -384,10 +391,13 @@ ...@@ -384,10 +391,13 @@
url: 'compress-video' url: 'compress-video'
}, },
// #endif // #endif
/* { // #ifdef WEB
{
name: "音频", name: "音频",
url: "inner-audio", url: "inner-audio",
}, },
// #endif
/*
{ {
name: "背景音频", name: "背景音频",
url: "background-audio", url: "background-audio",
...@@ -411,6 +421,12 @@ ...@@ -411,6 +421,12 @@
name: '获取当前位置', name: '获取当前位置',
url: 'get-location', url: 'get-location',
}, },
// #ifdef WEB
{
name: "地图控制",
url: "map",
},
// #endif
/* { /* {
name: "使用地图查看位置", name: "使用地图查看位置",
url: "open-location", url: "open-location",
...@@ -419,10 +435,6 @@ ...@@ -419,10 +435,6 @@
name: "使用地图选择位置", name: "使用地图选择位置",
url: "choose-location", url: "choose-location",
}, },
{
name: "地图控制",
url: "map",
},
{ {
name: "地图搜索", name: "地图搜索",
url: "map-search", url: "map-search",
...@@ -448,7 +460,7 @@ ...@@ -448,7 +460,7 @@
{ {
name: 'fileSystemManager文件管理', name: 'fileSystemManager文件管理',
url: 'get-file-system-manager' url: 'get-file-system-manager'
}, }
] as Page[], ] as Page[],
}, },
// #endif // #endif
...@@ -488,6 +500,16 @@ ...@@ -488,6 +500,16 @@
url: 'facial-recognition-verify', url: 'facial-recognition-verify',
} }
] as Page[], ] as Page[],
},
{
id: 'theme-change',
name: '主题切换',
pages: [
{
name: '主题切换',
url: 'theme-change',
}
] as Page[]
}, },
// #endif // #endif
{ {
...@@ -534,16 +556,6 @@ ...@@ -534,16 +556,6 @@
} }
] as Page[] ] as Page[]
}, },
{
id: 'theme-change',
name: '主题切换',
pages: [
{
name: '主题切换',
url: 'theme-change',
}
] as Page[]
},
// #endif // #endif
/* /*
{ {
......
...@@ -184,16 +184,16 @@ ...@@ -184,16 +184,16 @@
open: false, open: false,
pages: [] as Page[], pages: [] as Page[],
}, },
// #endif
{ {
id: 'schema', id: 'schema',
url: 'schema', url: 'schema',
name: '打开外部链接', name: '打开外部链接',
open: false, open: false,
pages: [] as Page[], pages: [] as Page[],
} },
// #endif
// #ifdef APP-ANDROID // #ifdef APP-ANDROID
,{ {
id: 'share', id: 'share',
url: 'share', url: 'share',
name: '分享示例', name: '分享示例',
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
</list-view> </list-view>
<web-view v-if="indexView==2" src="/hybrid/html/local.html" id="webv" style="height:380px"></web-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}"> <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>
</view> </view>
......
<template> <template>
<view> <view>
<!-- #ifdef APP -->
<button class="button" @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用外部浏览器打开指定URL</button> <button class="button" @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用外部浏览器打开指定URL</button>
<!-- #endif -->
<!-- #ifdef APP-ANDROID --> <!-- #ifdef APP-ANDROID -->
<button class="button" @click="openSchema('market://details?id=com.tencent.mm')">使用应用商店打开指定App</button> <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')"> <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 @@ ...@@ -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> <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 --> <!-- apple协议:https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html -->
<!-- #endif --> <!-- #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> </view>
</template> </template>
...@@ -23,4 +32,12 @@ import { openSchema } from '@/uni_modules/uts-openSchema' ...@@ -23,4 +32,12 @@ import { openSchema } from '@/uni_modules/uts-openSchema'
.button { .button {
margin: 15px; margin: 15px;
} }
.tip {
padding: 8px;
}
.link {
color: #7A7E83;
font-size: 14px;
line-height: 20px;
}
</style> </style>
...@@ -14,12 +14,15 @@ type State = { ...@@ -14,12 +14,15 @@ type State = {
safeArea : SafeArea safeArea : SafeArea
// 设备像素比 // 设备像素比
devicePixelRatio : number devicePixelRatio : number
// 事件判断回调
eventCallbackNum: number
} }
export const state = reactive({ export const state = reactive({
lifeCycleNum: 0, lifeCycleNum: 0,
statusBarHeight: 0, statusBarHeight: 0,
devicePixelRatio: 1, devicePixelRatio: 1,
eventCallbackNum: 0,
safeArea: { safeArea: {
top: 0, top: 0,
right: 0, right: 0,
...@@ -32,6 +35,10 @@ export const state = reactive({ ...@@ -32,6 +35,10 @@ export const state = reactive({
export const setLifeCycleNum = (num : number) => { export const setLifeCycleNum = (num : number) => {
state.lifeCycleNum = num state.lifeCycleNum = num
}
export const setEventCallbackNum = (num : number) => {
state.eventCallbackNum = num
} }
export const setStatusBarHeight = (height : number) => { export const setStatusBarHeight = (height : number) => {
...@@ -45,3 +52,4 @@ export const setSafeArea = (value : SafeArea) => { ...@@ -45,3 +52,4 @@ export const setSafeArea = (value : SafeArea) => {
export const setDevicePixelRatio = (devicePixelRatio : number) => { export const setDevicePixelRatio = (devicePixelRatio : number) => {
state.devicePixelRatio = devicePixelRatio state.devicePixelRatio = devicePixelRatio
} }
...@@ -31,12 +31,13 @@ declare interface Uni { ...@@ -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; getBatteryInfo(option?: UniNamespace.GetBatteryInfoOption): void;
/** /**
* 同步获取电池电量信息 * 同步获取电池电量信息
* @tutorial https://uniapp.dcloud.net.cn/api/system/batteryInfo.html
*/ */
getBatteryInfoSync(): UniNamespace.GetBatteryInfoSuccessCallbackResult; 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.
先完成此消息的编辑!
想要评论请 注册