refactor: 确立独立子工程架构 (backend, admin, mpuniapp) 并同步更新 AGENTS.md 规范
这个提交包含在:
@@ -0,0 +1,156 @@
|
||||
const platformInfo = process.env.uniTestPlatformInfo.toLocaleLowerCase()
|
||||
const isMP = platformInfo.startsWith('mp')
|
||||
|
||||
describe('API-loading', () => {
|
||||
if ( isMP) {
|
||||
it('skip', async () => {
|
||||
expect(1).toBe(1);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const isAndroid = platformInfo.startsWith('android')
|
||||
const isIos = platformInfo.startsWith('ios')
|
||||
const isHarmony = platformInfo.startsWith('harmony')
|
||||
const isAppWebView = process.env.UNI_AUTOMATOR_APP_WEBVIEW == 'true'
|
||||
const PAGE_PATH = '/pages/API/loading/loading'
|
||||
let deviceShotOptions = {}
|
||||
let page;
|
||||
// 测试辅助函数
|
||||
async function setPageData(newData) {
|
||||
return await page.setData({ data: newData });
|
||||
}
|
||||
|
||||
function getData (key = '') {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const data = await page.data('data')
|
||||
resolve(key ? data[key] : data)
|
||||
})
|
||||
}
|
||||
|
||||
async function toScreenshot(imgName) {
|
||||
const image = await program.screenshot(deviceShotOptions);
|
||||
expect(image).toSaveImageSnapshot({customSnapshotIdentifier() {
|
||||
return imgName
|
||||
}})
|
||||
await page.waitFor(500);
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
page = await program.reLaunch(PAGE_PATH)
|
||||
await page.waitFor('view');
|
||||
const windowInfo = await program.callUniMethod('getWindowInfo');
|
||||
let topSafeArea = windowInfo.safeAreaInsets.top;
|
||||
if (isAppWebView) {
|
||||
if (isIos) {
|
||||
topSafeArea = 59
|
||||
if (platformInfo.includes('26')) {
|
||||
topSafeArea = 62
|
||||
}
|
||||
} else if (isAndroid) {
|
||||
topSafeArea = 24
|
||||
windowInfo.safeArea.bottom = 867
|
||||
if (platformInfo.startsWith('android 5')) {
|
||||
topSafeArea = 25
|
||||
}if (platformInfo.startsWith('android 6')) {
|
||||
windowInfo.safeArea.bottom = 592
|
||||
}if (platformInfo.startsWith('android 8')) {
|
||||
windowInfo.safeArea.bottom = 534
|
||||
} else if (platformInfo.startsWith('android 11')) {
|
||||
topSafeArea = 52
|
||||
} else if (platformInfo.startsWith('android 12')) {
|
||||
topSafeArea = 24
|
||||
windowInfo.safeArea.bottom = 716
|
||||
} else if (platformInfo.startsWith('android 13') || platformInfo.startsWith('android 15')) {
|
||||
topSafeArea = 49
|
||||
windowInfo.safeArea.bottom = 891
|
||||
} else if (platformInfo.startsWith('android 14')) {
|
||||
windowInfo.safeArea.bottom = 891
|
||||
}
|
||||
} else if (isHarmony) {
|
||||
topSafeArea = 39
|
||||
if (platformInfo.includes('nova_12')) {
|
||||
topSafeArea = 35
|
||||
}
|
||||
}
|
||||
}
|
||||
const top = topSafeArea + 44
|
||||
const bottom = Math.min(top + windowInfo.windowHeight, windowInfo.safeArea.bottom)
|
||||
const left = windowInfo.safeArea.left
|
||||
const right = windowInfo.safeArea.right
|
||||
deviceShotOptions = {
|
||||
deviceShot: true,
|
||||
area: {
|
||||
x: left,
|
||||
y: top,
|
||||
width: right - left,
|
||||
height: bottom - top
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
it('onLoad showLoading', async () => {
|
||||
await toScreenshot('loading-onload')
|
||||
// 等待 loading 关闭
|
||||
await page.waitFor(2000)
|
||||
})
|
||||
|
||||
async function showLoadingWithTitle(index) {
|
||||
const items = await getData('items')
|
||||
await page.callMethod('selectTitle', index)
|
||||
await page.waitFor(100)
|
||||
await page.callMethod('showLoading')
|
||||
await page.waitFor(300)
|
||||
await toScreenshot(`loading-title-${items[index].name}`)
|
||||
// 等待 loading 关闭
|
||||
await page.waitFor(3000)
|
||||
}
|
||||
|
||||
it('showLoading with empty title', async () => {
|
||||
await showLoadingWithTitle(0)
|
||||
})
|
||||
|
||||
it('showLoading with normal title', async () => {
|
||||
await showLoadingWithTitle(1)
|
||||
})
|
||||
|
||||
it('showLoading with long title', async () => {
|
||||
await showLoadingWithTitle(2)
|
||||
})
|
||||
|
||||
it('hideLoading', async () => {
|
||||
await page.callMethod('showLoading')
|
||||
await page.waitFor(300)
|
||||
await toScreenshot('loading-show')
|
||||
await page.callMethod('hideLoading')
|
||||
await page.waitFor(300)
|
||||
await toScreenshot('loading-hide')
|
||||
})
|
||||
|
||||
it('hideLoading with loadingPage', async () => {
|
||||
await page.callMethod('closeSomeLoading')
|
||||
await page.waitFor(300)
|
||||
await toScreenshot('show-loading')
|
||||
await page.waitFor(1200)
|
||||
await toScreenshot('closed-loading-2')
|
||||
await page.waitFor(2100)
|
||||
await toScreenshot('closed-loading-1')
|
||||
const dataRet = await getData('callbackText')
|
||||
const callbackTextRet = JSON.stringify(dataRet)
|
||||
expect(callbackTextRet)
|
||||
.toEqual('["showLoading 1 success","showLoading 1 complete","showLoading 2 success","showLoading 2 complete","hideLoading 2 success","hideLoading 2 complete","hideLoading 1 success","hideLoading 1 complete"]')
|
||||
await setPageData({callbackText: []})
|
||||
})
|
||||
|
||||
it('showLoading noParam', async () => {
|
||||
await page.callMethod('noParamLoading')
|
||||
await page.waitFor(300)
|
||||
await toScreenshot('indicated-loading')
|
||||
await page.waitFor(2100)
|
||||
await toScreenshot('hided-loading')
|
||||
const dataRet = await getData('callbackText')
|
||||
const callbackTextRet = JSON.stringify(dataRet)
|
||||
expect(callbackTextRet)
|
||||
.toEqual('["noParamLoading 1 success","noParamLoading 1 complete","noParamLoading 2 success","noParamLoading 2 complete","hide loading success"]')
|
||||
})
|
||||
});
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<view>
|
||||
<page-head :title="data.title"></page-head>
|
||||
<view class="uni-list">
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title uni-common-mt">
|
||||
<text class="uni-title-text"> 设置标题 </text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list uni-common-pl">
|
||||
<radio-group @change="radioChange">
|
||||
<radio class="uni-list-cell uni-list-cell-pd radio" v-for="(item, index) in data.items"
|
||||
:key="item.value" :class="index < data.items.length - 1 ? 'uni-list-cell-line' : ''"
|
||||
:value="item.value" :checked="index === data.current">
|
||||
{{ item.name }}
|
||||
</radio>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- <view class="uni-padding-wrap uni-common-mt" style="flex-direction: row; justify-content: space-between; align-items: center;">
|
||||
<text class="uni-title-text"> iOS 雪花样式 </text>
|
||||
<switch :checked="data.iosSpinner" @change="iosSpinnerChange" />
|
||||
</view> -->
|
||||
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="showLoading">显示 loading 提示框</button>
|
||||
<button @click="hideLoading">隐藏 loading 提示框</button>
|
||||
<text>为方便演示,loading弹出3秒后自动关闭</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<text>{{data.callbackText}}</text>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="closeSomeLoading">关闭指定loading</button>
|
||||
<button type="primary" @click="noParamLoading">无参数测试</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="uts">
|
||||
type ItemType = {
|
||||
value : string
|
||||
name : string
|
||||
}
|
||||
|
||||
type DataType = {
|
||||
title : string;
|
||||
items : ItemType[];
|
||||
current : number;
|
||||
callbackText : string[];
|
||||
titleSelect : string;
|
||||
iosSpinner : boolean;
|
||||
}
|
||||
|
||||
|
||||
const data = reactive({
|
||||
title: 'loading',
|
||||
items: [
|
||||
{
|
||||
value: 'null',
|
||||
name: '无标题',
|
||||
},
|
||||
{
|
||||
value: '三秒后自动关闭',
|
||||
name: '普通标题',
|
||||
},
|
||||
{
|
||||
value: '超长文本内容,测试超出范围-超长文本内容,测试超出范围-三秒后自动关闭',
|
||||
name: '长标题',
|
||||
},
|
||||
],
|
||||
callbackText: [] as Array<string>,
|
||||
current: 0,
|
||||
titleSelect: "null",
|
||||
iosSpinner: true
|
||||
} as DataType)
|
||||
|
||||
const jest_getWindowInfo = () : GetWindowInfoResult => {
|
||||
return uni.getWindowInfo();
|
||||
}
|
||||
|
||||
const selectTitle = (index : number) => {
|
||||
if (index < 0 || index >= data.items.length) {
|
||||
return
|
||||
}
|
||||
data.current = index
|
||||
data.titleSelect = data.items[index].value
|
||||
}
|
||||
|
||||
const radioChange = (e : UniRadioGroupChangeEvent) => {
|
||||
const selectedIndex = data.items.findIndex((item) : boolean => {
|
||||
return item.value == e.detail.value
|
||||
})
|
||||
selectTitle(selectedIndex)
|
||||
}
|
||||
|
||||
const iosSpinnerChange = (e : UniSwitchChangeEvent) => {
|
||||
data.iosSpinner = e.detail.value
|
||||
}
|
||||
|
||||
const hideLoading = () => {
|
||||
uni.hideLoading();
|
||||
}
|
||||
const noParamLoading = () => {
|
||||
uni.showLoading()
|
||||
uni.showLoading({
|
||||
success: function (showRet : ShowLoadingSuccess) {
|
||||
data.callbackText.push("noParamLoading 1 success")
|
||||
},
|
||||
complete: function (showRet : any) {
|
||||
data.callbackText.push("noParamLoading 1 complete")
|
||||
}
|
||||
})
|
||||
uni.showLoading({
|
||||
success: function (showRet : ShowLoadingSuccess) {
|
||||
data.callbackText.push("noParamLoading 2 success")
|
||||
},
|
||||
complete: function (showRet : any) {
|
||||
data.callbackText.push("noParamLoading 2 complete")
|
||||
}
|
||||
})
|
||||
setTimeout(function () {
|
||||
uni.hideLoading({
|
||||
success: function (ret : HideLoadingSuccess) {
|
||||
data.callbackText.push("hide loading success")
|
||||
}
|
||||
})
|
||||
}, 2000)
|
||||
}
|
||||
/**
|
||||
* 关闭指定loading
|
||||
*/
|
||||
const closeSomeLoading = () => {
|
||||
const loading1 = uni.showLoading({
|
||||
title: "第一个loading",
|
||||
iosSpinner: data.iosSpinner,
|
||||
success: function (res : ShowLoadingSuccess) {
|
||||
data.callbackText.push("showLoading 1 success")
|
||||
console.log("showLoading 1 success", res)
|
||||
},
|
||||
fail: function (res : ShowLoadingFail) {
|
||||
data.callbackText.push("showLoading 1 fail")
|
||||
console.log("showLoading 1 fail", res)
|
||||
},
|
||||
complete: function (res : any) {
|
||||
data.callbackText.push("showLoading 1 complete")
|
||||
console.log("showLoading 1 complete", res)
|
||||
},
|
||||
})
|
||||
const loading2 = uni.showLoading({
|
||||
title: "第二个loading",
|
||||
iosSpinner: data.iosSpinner,
|
||||
success: function (res : ShowLoadingSuccess) {
|
||||
data.callbackText.push("showLoading 2 success")
|
||||
console.log("showLoading 2 success", res)
|
||||
},
|
||||
fail: function (res : ShowLoadingFail) {
|
||||
data.callbackText.push("showLoading 2 fail")
|
||||
console.log("showLoading 2 fail", res)
|
||||
},
|
||||
complete: function (res : any) {
|
||||
data.callbackText.push("showLoading 2 complete")
|
||||
console.log("showLoading 2 complete", res)
|
||||
},
|
||||
})
|
||||
setTimeout(function () {
|
||||
uni.hideLoading({
|
||||
loadingPage: loading2,
|
||||
success: function (res : HideLoadingSuccess) {
|
||||
data.callbackText.push("hideLoading 2 success")
|
||||
console.log("hideLoading 2 success", res)
|
||||
},
|
||||
fail: function (res : HideLoadingFail) {
|
||||
data.callbackText.push("hideLoading 2 fail")
|
||||
console.log("hideLoading 2 fail", res)
|
||||
},
|
||||
complete: function (res : any) {
|
||||
data.callbackText.push("hideLoading 2 complete")
|
||||
console.log("hideLoading 2 complete", res)
|
||||
},
|
||||
})
|
||||
}, 1000)
|
||||
setTimeout(function () {
|
||||
uni.hideLoading({
|
||||
loadingPage: loading1,
|
||||
success: function (res : HideLoadingSuccess) {
|
||||
data.callbackText.push("hideLoading 1 success")
|
||||
console.log("hideLoading 1 success", res)
|
||||
},
|
||||
fail: function (res : HideLoadingFail) {
|
||||
data.callbackText.push("hideLoading 1 fail")
|
||||
console.log("hideLoading 1 fail", res)
|
||||
},
|
||||
complete: function (res : any) {
|
||||
data.callbackText.push("hideLoading 1 complete")
|
||||
console.log("hideLoading 1 complete", res)
|
||||
},
|
||||
})
|
||||
}, 3000)
|
||||
}
|
||||
const showLoading = () => {
|
||||
console.log(data.titleSelect)
|
||||
if (data.titleSelect == "null") {
|
||||
uni.showLoading({
|
||||
title: "",
|
||||
iosSpinner: data.iosSpinner,
|
||||
});
|
||||
} else {
|
||||
uni.showLoading({
|
||||
title: data.titleSelect,
|
||||
iosSpinner: data.iosSpinner,
|
||||
});
|
||||
}
|
||||
setTimeout(() => {
|
||||
hideLoading();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
onLoad(() => {
|
||||
uni.showLoading()
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
}, 2000);
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
data,
|
||||
showLoading,
|
||||
hideLoading,
|
||||
closeSomeLoading,
|
||||
noParamLoading,
|
||||
selectTitle,
|
||||
})
|
||||
</script>
|
||||
在新工单中引用
屏蔽一个用户