!4148 【迁移验证sample】验证onContinue新接口

Merge pull request !4148 from dengxiaoyu/master
This commit is contained in:
openharmony_ci 2024-03-19 04:20:06 +00:00 committed by Gitee
commit e25ec9d38d
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
21 changed files with 551 additions and 84 deletions

View File

@ -20,6 +20,7 @@
4. 在笔记页,可以编辑笔记标题、笔记内容、选择图片,在打开迁移能力和迁移页面栈的情况下,所编辑的内容和选择的图片可以同步迁移到对端设备;
5. 在待办事项页,勾选多选框,在打开迁移能力和迁移页面栈的情况下,可以迁移当前的勾选状态;
6. 在图片墙页,滑动页面到某个位置,在打开迁移能力和迁移页面栈的情况下,可以迁移当前的瀑布流控件索引位置。
7. 点击“迁移时使用异步接口保存数据”进入页面输入文本可以迁移文本数据RK3568设备不支持
### 工程目录
@ -70,8 +71,8 @@ entry/src/main/ets/
### 约束与限制
1. 本示例仅支持标准系统上运行支持设备RK3568;
2. 本示例完整功能必须双端授予允许使用分布式协同能力
3. 本示例为stage模型已适配API version 11版本SDKSDK版本号(API Version 11 Release),镜像版本号(4.1.5.5)。
2. 本示例完整功能必须双端授予允许使用分布式协同能力,迁移等功能暂不支持RK3568。
3. 本示例为stage模型已适配API version 12版本SDKSDK版本号(API Version 12 Release),镜像版本号(5.0.0.16)。
4. 本示例需要使用DevEco Studio 版本号(4.0Release)才可编译运行。
5. 本示例需要使用 ohos.permission.READ_IMAGEVIDEO权限级别为system_basic的系统接口。
6. 本示例涉及系统接口,需要配置系统应用签名,可以参考[特殊权限配置方法](https://gitee.com/link?target=https%3A%2F%2Fdocs.openharmony.cn%2Fpages%2Fv3.2%2Fzh-cn%2Fapplication-dev%2Fsecurity%2Fhapsigntool-overview.md%2F) 把配置文件中的“app-feature”字段信息改为“hos_system_app”。

View File

@ -20,9 +20,9 @@
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 11,
"compatibleSdkVersion": 11,
"targetSdkVersion": 11,
"compileSdkVersion": 12,
"compatibleSdkVersion": 12,
"targetSdkVersion": 12,
"runtimeOS": "OpenHarmony"
}
],

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
import Logger from '../utils/Logger';
const TAG = '[testTag_AsyncAbility]: ';
export default class AsyncAbility extends UIAbility {
contentStorage?: LocalStorage;
handleContinueParam(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 迁移应用启动时onCreate&应用热启动时onNewWant:恢复保存的迁移数据
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
// 从want中恢复迁移数据
let testDate = want?.parameters?.testDate;
AppStorage.setOrCreate<string>('testDate', testDate as string);
//显式调用页面恢复
this.contentStorage = new LocalStorage();
Logger.info(TAG, 'handleContinueParam() ready to restore');
this.context.restoreWindowStage(this.contentStorage);
}
}
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
Logger.info(TAG, 'onCreate : Ability onCreate');
// 调用原因为迁移时,设置状态为可迁移,应对冷启动情况(保证迁移连续性)
if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
Logger.info(TAG, `setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`);
});
}
// 迁移应用启动时恢复保存的迁移数据
this.handleContinueParam(want, launchParam);
}
async setAsyncWant(wantParam: Record<string, Object>) {
Logger.info(TAG, 'setAsyncWant : onContinue setWant start');
let testDate: string = AppStorage.get<string>('testDate') as string;
wantParam['testDate'] = testDate;
Logger.info(TAG, `onContinue testDate ${testDate}`);
Logger.info(TAG, 'setAsyncWant : onContinue setWant end');
}
onContinue(wantParam: Record<string, Object>): Promise<AbilityConstant.OnContinueResult> {
Logger.info(TAG, 'onContinue : wantParam.version,wantParam.targetDevice : ' + wantParam.version + wantParam.targetDevice);
return this.setAsyncWant(wantParam).then(() => {
return AbilityConstant.OnContinueResult.AGREE;
});
}
onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam) {
Logger.info(TAG, 'Ability onNewWant');
Logger.info(TAG, 'onNewWant, want:' + want.abilityName);
Logger.info(TAG, 'onNewWant, launchParams:' + JSON.stringify(launchParams));
Logger.info(TAG, `onNewWant, want: ${want.abilityName}`);
Logger.info(TAG, `onNewWant, launchParam: ${JSON.stringify(launchParams)}`);
// 调用原因为迁移时,设置状态为可迁移,应对热启动情况(保证迁移连续性)
if (launchParams.launchReason == AbilityConstant.LaunchReason.CONTINUATION) {
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
Logger.info(`setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`);
});
}
//应用热启动时:恢复保存的迁移数据
this.handleContinueParam(want, launchParams);
Logger.info(TAG, 'onNewWant end')
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Page_AsyncAbility', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageRestore(windowStage: window.WindowStage) {
Logger.info(TAG, 'onWindowStageRestore, pageStack_isON: ' + AppStorage.get<boolean>('pageStack_isON'));
if (AppStorage.get<boolean>('pageStack_isON') == false) {
Logger.info(TAG, 'onWindowStageRestore : ' + 'no pageStack');
windowStage.loadContent('pages/Page_AsyncAbility', (err, data) => {
if (err.code) {
Logger.error(TAG, `Failed to load the content. Cause: ${JSON.stringify(err)}`);
return;
}
Logger.info(TAG, `Succeeded in loading the content. Data: ${JSON.stringify(data)}`);
});
} else {
Logger.info(TAG, 'onWindowStageRestore : have pageStack');
}
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}

View File

@ -29,6 +29,7 @@ export default class CommonConstants {
static readonly MIGRATION_SOURCE_END: Resource = $r('app.string.MIGRATION_SOURCE_END');
static readonly TO_DO_LIST: Resource = $r('app.string.TO_DO_LIST');
static readonly LIST_ARRAY: Array<Resource> = [$r('app.string.LIST_ITEM_ONE'), $r('app.string.LIST_ITEM_TWO'), $r('app.string.LIST_ITEM_THREE'), $r('app.string.LIST_ITEM_FOUR'), $r('app.string.LIST_ITEM_FIVE'), $r('app.string.LIST_ITEM_SIX'), $r('app.string.LIST_ITEM_SEVEN'), $r('app.string.LIST_ITEM_EIGHT'), $r('app.string.LIST_ITEM_ONE'), $r('app.string.LIST_ITEM_TWO'), $r('app.string.LIST_ITEM_THREE')];
static readonly PLEASE_INPUT_ASYNC_TEXT: Resource = $r('app.string.PLEASE_INPUT_ASYNC_TEXT');
// Distributed asset use
static readonly BUNDLE_NAME = 'com.samples.distributedjotnote';

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -26,6 +26,7 @@ import commonType from '@ohos.data.commonType';
import Logger from '../utils/Logger';
import { LooperUtil } from '../utils/LooperUtil';
import CommonConstants from '../common/constants/CommonConstants';
const TAG = 'testTag_ability: ';
class SourceObject {
@ -118,6 +119,8 @@ export default class EntryAbility extends UIAbility {
let pageStack_isON = want?.parameters?.pageStack_isON; // 对端变化后的toggle迁移页面栈的 isON 状态信息
let sourceEnd_isON = want?.parameters?.sourceEnd_isON; // 对端变化后的toggle迁移后源端退出的isON状态信息
let image2Path = want?.parameters?.image2Path;
let testDate = want?.parameters?.testDate;
AppStorage.setOrCreate<boolean>('isContinuation', isContinuation as boolean);
AppStorage.setOrCreate<boolean>('isSelectImg', isSelectImg as boolean);
AppStorage.setOrCreate<number>('swiperIndex', swiperIndex as number);
@ -126,6 +129,7 @@ export default class EntryAbility extends UIAbility {
AppStorage.setOrCreate<boolean>('pageStack_isON', pageStack_isON as boolean);
AppStorage.setOrCreate<boolean>('sourceEnd_isON', sourceEnd_isON as boolean);
AppStorage.setOrCreate<string>('image2Path', image2Path as string);
AppStorage.setOrCreate<string>('testDate', testDate as string);
//显式调用页面恢复
this.contentStorage = new LocalStorage();
@ -164,9 +168,10 @@ export default class EntryAbility extends UIAbility {
this.d_object['notesTitle'] = undefined;
this.d_object['asset'] = undefined;
this.d_object.on('status', (sessionId: string, networkId: string, status: "online"|"offline"|"restored") => {
this.d_object.on('status', (sessionId: string, networkId: string, status: "online" | "offline" | "restored") => {
if (status !== 'restored') {
Logger.info(TAG, `status: ${status}`);
return;
}
Logger.info(TAG, ` status == restored`);
let image2Path = AppStorage.get<string>('image2Path');
@ -187,8 +192,6 @@ export default class EntryAbility extends UIAbility {
await this.d_object.setSessionId(this.sessionId, (): void => {
Logger.info(TAG, 'join session');
});
}
}
@ -304,7 +307,6 @@ export default class EntryAbility extends UIAbility {
wantParam[wantConstant.Params.SUPPORT_CONTINUE_SOURCE_EXIT_KEY])
}
return AbilityConstant.OnContinueResult.AGREE;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@ -19,6 +19,8 @@ import mainViewModel from '../viewmodel/MainViewModel';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import Logger from '../utils/Logger';
import CommonConstants from '../common/constants/CommonConstants';
import Want from '@ohos.app.ability.Want';
import { BusinessError } from '@ohos.base';
const TAG = 'testTag_Home: ';
@ -28,6 +30,7 @@ struct Home {
@StorageLink('ability_isON') stoLink_ability_isON: boolean = true;
@StorageLink('ContinueWork') inputTxt: string = '';
@StorageLink('swiperIndex') swiperIndex: number = -1;
@StorageLink('testDate') testDate: string = '';
private swiperController: SwiperController = new SwiperController();
private context = getContext(this) as common.UIAbilityContext;
@ -42,7 +45,6 @@ struct Home {
build() {
Row() {
Column() {
Column() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Image($r('app.media.ic_set'))
@ -103,6 +105,7 @@ struct Home {
.margin({ left: 12 })
.width(18)
.height(22)
.id('notePage')
Text($r('app.string.NOTES_TITLE'))
.width(244)
@ -114,6 +117,7 @@ struct Home {
.margin({ left: 19 })
.fontFamily('HarmonyHeiTi')
Row() {
Image($r('app.media.ic_arrow'))
.width(12)
@ -153,6 +157,7 @@ struct Home {
.fontWeight(500)
.textAlign(TextAlign.Start)
.margin({ left: 19 })
.id('todolist_btn')
Row() {
Image($r('app.media.ic_arrow'))
@ -193,6 +198,7 @@ struct Home {
.fontWeight(500)
.textAlign(TextAlign.Start)
.margin({ left: 19 })
.id('imgWall_btn')
Row() {
Image($r('app.media.ic_arrow'))
@ -216,6 +222,40 @@ struct Home {
.onClick(() => {
router.pushUrl({ url: 'pages/ImgWall' })
})
Column() {
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
Text($r('app.string.USE_ASYNC_SAVE_DATA'))
.width(244)
.height(22)
.fontSize(16)
.lineHeight(22)
.fontWeight(500)
.textAlign(TextAlign.Start)
.margin({ left: 19 })
.id('async_save_data')
}
.width(336)
.height(64)
}
.width(336)
.height(64)
.backgroundColor('#ffffff')
.borderRadius(24)
.alignItems(HorizontalAlign.Center)
.margin({ top: 16 })
.onClick(() => {
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
let want: Want = {
bundleName: 'com.samples.distributedjotnote',
abilityName: 'AsyncAbility'
};
context.startAbility(want).then(() => {
}).catch((err: BusinessError) => {
Logger.error(TAG, `Failed to start MigrationAbility. Code is ${err.code}, message is ${err.message}`);
});
})
}
.width('100%')

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import common from '@ohos.app.ability.common';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import CommonConstants from '../common/constants/CommonConstants';
import Logger from '../utils/Logger';
const TAG = '[testTag_Page_AsyncAbility]: ';
@Entry
@Component
struct Page_AsyncAbility {
@StorageLink('testDate') testDate: string = '';
@StorageLink('ability_isON') stoLink_ability_isON: boolean = true;
private context = getContext(this) as common.UIAbilityContext;
onPageShow() {
// 进入该页面时,将应用设置为可迁移状态
this.context.setMissionContinueState(AbilityConstant.ContinueState.ACTIVE, (result) => {
this.stoLink_ability_isON = true;
Logger.info(TAG, `setMissionContinueState ACTIVE result: ${JSON.stringify(result)}`);
});
}
build() {
Row() {
Column() {
Column() {
TextInput({ text: this.testDate,
placeholder: CommonConstants.PLEASE_INPUT_ASYNC_TEXT
})
.fontWeight(500)
.fontSize(16)
.textAlign(TextAlign.JUSTIFY)
.align(Alignment.Center)
.onChange((value: string) => {
this.testDate = value;
AppStorage.set('testDate', value);
Logger.info(TAG, 'this.testDate: ' + this.testDate);
})
.type(InputType.Normal)
.backgroundColor(Color.Transparent)
.width(336)
.height(64)
.id('asyncTextInput')
}
.width(336)
.height(64)
.backgroundColor('#ffffff')
.borderRadius(24)
.alignItems(HorizontalAlign.Center)
.margin({ top: 16 })
}
.width('100%')
}
.height('100%')
.alignItems(VerticalAlign.Top)
.backgroundColor('#f1f3f5')
}
}

View File

@ -1,18 +1,17 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"module": {
"name": "entry",
@ -48,6 +47,16 @@
]
}
]
},
{
"name": "AsyncAbility",
"srcEntry": "./ets/asyncability/AsyncAbility.ets",
"description": "$string:AsyncAbility_desc",
"icon": "$media:icon",
"label": "$string:AsyncAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"continuable": true
}
],
"requestPermissions": [

View File

@ -115,6 +115,22 @@
{
"name": "pick_photo_two",
"value": "pick photo 2"
},
{
"name": "PLEASE_INPUT_ASYNC_TEXT",
"value": "please enter the text to be saved asynchronously"
},
{
"name": "AsyncAbility_desc",
"value": "description"
},
{
"name": "AsyncAbility_label",
"value": "label"
},
{
"name": "USE_ASYNC_SAVE_DATA",
"value": " use an asynchronous func to save data during migration"
}
]
}

View File

@ -5,6 +5,7 @@
"pages/Settings",
"pages/Notes",
"pages/Todolist",
"pages/ImgWall"
"pages/ImgWall",
"pages/Page_AsyncAbility"
]
}

View File

@ -115,6 +115,22 @@
{
"name": "pick_photo_two",
"value": "pick photo 2"
},
{
"name": "PLEASE_INPUT_ASYNC_TEXT",
"value": "please enter the text to be saved asynchronously"
},
{
"name": "AsyncAbility_desc",
"value": "description"
},
{
"name": "AsyncAbility_label",
"value": "label"
},
{
"name": "USE_ASYNC_SAVE_DATA",
"value": " use an asynchronous func to save data during migration"
}
]
}

View File

@ -115,6 +115,22 @@
{
"name": "pick_photo_two",
"value": "选择图片2"
},
{
"name": "PLEASE_INPUT_ASYNC_TEXT",
"value": "请输入异步保存的文本"
},
{
"name": "AsyncAbility_desc",
"value": "description"
},
{
"name": "AsyncAbility_label",
"value": "label"
},
{
"name": "USE_ASYNC_SAVE_DATA",
"value": "迁移时使用异步接口保存数据"
}
]
}

View File

@ -17,19 +17,27 @@ import { describe, expect, it } from '@ohos/hypium';
import abilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import { Driver, ON } from '@ohos.UiTest';
import hilog from '@ohos.hilog';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
const TAG = '[Sample_DistributedJotNote]';
const DOMAIN = 0xF811;
const BUNDLE = 'DistributedJotNote_';
const driver = Driver.create();
async function getResourceString(resource: Resource): Promise<string> {
let manage = abilityDelegator.getAppContext().resourceManager;
let text = await manage.getStringValue(resource);
return text;
}
export default function appTest() {
describe('ActsAbilityTest', () => {
/**
* 拉起应用
*/
it(BUNDLE + 'StartAbility_001', 0, async (done: Function) => {
it('StartAbility_001', 0, async (done: Function) => {
hilog.info(DOMAIN, TAG, BUNDLE + 'StartAbility_001 begin');
let abilityDelegator = abilityDelegatorRegistry.getAbilityDelegator();
try {
@ -47,16 +55,16 @@ export default function appTest() {
/**
* 点击允许进行授权
*/
it(BUNDLE + 'ClickAccept_001', 0, async (done: Function) => {
it('ClickAccept_001', 0, async (done: Function) => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickAccept_001 begin');
let driver = Driver.create();
await driver.delayMs(2000);
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickAccept_001 clickAccept');
// 点击允许
let arr = await driver.findComponents(ON.type('允许'));
let arr = await driver.findComponents(ON.type(await getResourceString($r('app.string.accept'))));
hilog.info(DOMAIN, TAG, 'arr : ' + arr);
await driver.assertComponentExist(ON.text('允许'));
let btnAccept = await driver.findComponent(ON.text('允许'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.accept'))));
let btnAccept = await driver.findComponent(ON.text(await getResourceString($r('app.string.accept'))));
await btnAccept.click();
await driver.delayMs(1000);
done();
@ -66,7 +74,7 @@ export default function appTest() {
/**
* 欢迎页展示,点击按钮,进入主页面
*/
it(BUNDLE + 'ClickEnter_001', 0, async () => {
it('ClickEnter_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnter_001 begin');
// 点击进入按钮
await driver.assertComponentExist(ON.id('enter_in_jot'));
@ -79,7 +87,7 @@ export default function appTest() {
/**
* 进入主页,滑动轮播图
*/
it(BUNDLE + 'ClickEnterSwiper_002', 0, async () => {
it('ClickEnterSwiper_002', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterSwiper_002 begin');
// 滑动轮播图
await driver.assertComponentExist(ON.id('swiper'));
@ -98,7 +106,7 @@ export default function appTest() {
/**
* 点击主页右上角:设置图标
*/
it(BUNDLE + 'ClickSettings_001', 0, async () => {
it('ClickSettings_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickSettings_001 begin');
// 点击设置图标
await driver.assertComponentExist(ON.id('settingsImg'));
@ -111,7 +119,7 @@ export default function appTest() {
/**
* 进入迁移设置页:点击开关(迁移能力)
*/
it(BUNDLE + 'ClickToggle_001', 0, async () => {
it('ClickToggle_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickToggle_001 begin');
// 点击开关
await driver.assertComponentExist(ON.id('toggle_ability_isOn'));
@ -124,7 +132,7 @@ export default function appTest() {
/**
* 进入迁移设置页:点击开关(迁移页面栈)
*/
it(BUNDLE + 'ClickToggle_002', 0, async () => {
it('ClickToggle_002', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickToggle_002 begin');
// 点击开关
await driver.assertComponentExist(ON.id('toggle_pageStack_isOn'));
@ -138,7 +146,7 @@ export default function appTest() {
/**
* 进入迁移设置页:点击开关(迁移是否退出源端)
*/
it(BUNDLE + 'ClickToggle_003', 0, async () => {
it('ClickToggle_003', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickToggle_003 begin');
// 点击开关
await driver.assertComponentExist(ON.id('toggle_sourceEnd_isOn'));
@ -152,7 +160,7 @@ export default function appTest() {
/**
* 返回主页
*/
it(BUNDLE + 'ClickBackArrow_001', 0, async () => {
it('ClickBackArrow_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickBackArrow_001 begin');
// 点击返回箭头
await driver.assertComponentExist(ON.id('back_arrow_setting'));
@ -165,26 +173,27 @@ export default function appTest() {
/**
* 点击笔记页:进入笔记页界面
*/
it(BUNDLE + 'ClickEnterNotes_001', 0, async () => {
it('ClickEnterNotes_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterNotes_001 begin');
// 点击笔记页
await driver.assertComponentExist(ON.text('笔记页'));
let notesBar = await driver.findComponent(ON.text('笔记页'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.NOTE_PAGE'))));
let notesBar = await driver.findComponent(ON.text(await getResourceString($r('app.string.NOTE_PAGE'))));
await notesBar.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('笔记页'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.NOTE_PAGE'))));
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterNotes_001 end');
})
/**
* 笔记页界面:输入笔记标题
*/
it(BUNDLE + 'InputText_001', 0, async () => {
it('InputText_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'InputText_001 begin');
// 输入笔记标题
await driver.assertComponentExist(ON.id('textInput'));
let textInput = await driver.findComponent(ON.id('textInput'));
await textInput.inputText('记第一次夜跑');
await textInput.inputText(await getResourceString($r('app.string.TEST_DATA')));
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('textInput'));
hilog.info(DOMAIN, TAG, BUNDLE + 'InputText_001 end');
@ -193,12 +202,12 @@ export default function appTest() {
/**
* 笔记页界面:输入笔记内容
*/
it(BUNDLE + 'TextArea_001', 0, async () => {
it('TextArea_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'InputText_001 begin');
// 输入笔记内容
await driver.assertComponentExist(ON.id('textArea'));
let textInput = await driver.findComponent(ON.id('textArea'));
await textInput.inputText('绕湖跑3公里拉伸15min');
await textInput.inputText(await getResourceString($r('app.string.TEST_DATA')));
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('textArea'));
hilog.info(DOMAIN, TAG, BUNDLE + 'TextArea_001 end');
@ -207,7 +216,7 @@ export default function appTest() {
/**
* 返回主页
*/
it(BUNDLE + 'ClickBackArrow_002', 0, async () => {
it('ClickBackArrow_002', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickBackArrow_002 begin');
// 点击返回箭头
await driver.assertComponentExist(ON.id('back_arrow_notes'));
@ -221,21 +230,21 @@ export default function appTest() {
/**
* 点击待办事项:进入待办事项页界面
*/
it(BUNDLE + 'ClickEnterToDoList_001', 0, async () => {
it('ClickEnterToDoList_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterToDoList_001 begin');
// 点击待办事项
await driver.assertComponentExist(ON.text('待办事项'));
let itemChosen = await driver.findComponent(ON.text('待办事项'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.TODO_LIST'))));
let itemChosen = await driver.findComponent(ON.text(await getResourceString($r('app.string.TODO_LIST'))));
await itemChosen.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('待办事项'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.TODO_LIST'))));
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterToDoList_001 end');
})
/**
* 待办事项页滑动待办事项页list
*/
it(BUNDLE + 'ScrollToDoList_001', 0, async () => {
it('ScrollToDoList_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ScrollToDoList_001 begin');
// 滑动待办事项页list
await driver.assertComponentExist(ON.id('Scroll_List'));
@ -249,7 +258,7 @@ export default function appTest() {
/**
* 待办事项页:点击待办事项页勾选框
*/
it(BUNDLE + 'ClickCheckBox_001', 0, async () => {
it('ClickCheckBox_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickCheckBox_001 begin');
// 点击待办事项页勾选框
await driver.assertComponentExist(ON.id('Checkbox'));
@ -263,7 +272,7 @@ export default function appTest() {
/**
* 返回主页
*/
it(BUNDLE + 'ClickBackArrow_003', 0, async () => {
it('ClickBackArrow_003', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickBackArrow_003 begin');
// 点击返回箭头
await driver.assertComponentExist(ON.id('back_arrow_todolist'));
@ -276,21 +285,21 @@ export default function appTest() {
/**
* 点击图片墙页:进入图片墙页界面
*/
it(BUNDLE + 'ClickEnterImgWall_001', 0, async () => {
it('ClickEnterImgWall_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterImgWall_001 begin');
// 点击图片墙
await driver.assertComponentExist(ON.text('图片墙'));
let itemChosen = await driver.findComponent(ON.text('图片墙'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.IMG_WALL'))));
let itemChosen = await driver.findComponent(ON.text(await getResourceString($r('app.string.IMG_WALL'))));
await itemChosen.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('图片墙'));
await driver.assertComponentExist(ON.text(await getResourceString($r('app.string.IMG_WALL'))));
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterImgWall_001 end');
})
/**
* 图片墙页:滑动瀑布流组件
*/
it(BUNDLE + 'ScrollWaterFlow_001', 0, async () => {
it('ScrollWaterFlow_001', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ScrollWaterFlow_001 begin');
// 滑动瀑布流组件
await driver.assertComponentExist(ON.id('WaterFlow_row'));
@ -303,7 +312,7 @@ export default function appTest() {
/**
* 返回主页
*/
it(BUNDLE + 'ClickBackArrow_004', 0, async () => {
it('ClickBackArrow_004', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickBackArrow_004 begin');
// 点击返回箭头
await driver.assertComponentExist(ON.id('back_arrow_imgWall'));
@ -313,5 +322,31 @@ export default function appTest() {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickBackArrow_004 end');
})
/**
* 点击迁移时使用异步接口保存数据:进入异步接口保存数据页界面
*/
it('ClickEnterAsyncMigration', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterAsyncMigration begin');
// 点击异步接口
await driver.assertComponentExist(ON.id('async_save_data'));
let itemChosen = await driver.findComponent(ON.id('async_save_data'));
await itemChosen.click();
await driver.delayMs(1000);
hilog.info(DOMAIN, TAG, BUNDLE + 'ClickEnterAsyncMigration end');
})
/**
* 异步接口保存数据页界面:输入内容
*/
it('AsyncTextInput', 0, async () => {
hilog.info(DOMAIN, TAG, BUNDLE + 'AsyncTextInput begin');
// 输入内容
await driver.assertComponentExist(ON.id('asyncTextInput'));
let textInput = await driver.findComponent(ON.id('asyncTextInput'));
await textInput.inputText(await getResourceString($r('app.string.TEST_DATA')));
await driver.delayMs(1000);
await driver.assertComponentExist(ON.id('asyncTextInput'));
hilog.info(DOMAIN, TAG, BUNDLE + 'AsyncTextInput end');
})
})
}

View File

@ -15,6 +15,22 @@
{
"name": "accept",
"value": "accept"
},
{
"name": "TEST_DATA",
"value": "test data"
},
{
"name": "NOTE_PAGE",
"value": "note page"
},
{
"name": "TODO_LIST",
"value": "to do list"
},
{
"name": "IMG_WALL",
"value": "img wall"
}
]
}

View File

@ -0,0 +1,36 @@
{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
},
{
"name": "accept",
"value": "accept"
},
{
"name": "TEST_DATA",
"value": "test data"
},
{
"name": "NOTE_PAGE",
"value": "note page"
},
{
"name": "TODO_LIST",
"value": "to do list"
},
{
"name": "IMG_WALL",
"value": "img wall"
}
]
}

View File

@ -0,0 +1,36 @@
{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
},
{
"name": "accept",
"value": "允许"
},
{
"name": "TEST_DATA",
"value": "测试数据"
},
{
"name": "NOTE_PAGE",
"value": "笔记页"
},
{
"name": "TODO_LIST",
"value": "待办事项"
},
{
"name": "IMG_WALL",
"value": "图片墙"
}
]
}

View File

@ -1,7 +1,21 @@
/*
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"hvigorVersion": "3.0.2",
"hvigorVersion": "3.0.9",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "3.0.2"
"@ohos/hvigor-ohos-plugin": "3.0.9"
},
"execution": {
// "daemon": true, /* Enable daemon compilation. Default: true */
@ -15,4 +29,4 @@
"debugging": {
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2023-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at

View File

@ -2,31 +2,33 @@
## 用例表
| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
|---------|--------------|----------------|-----------------------|------|------|
| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass |
|允许权限| 设备正常运行 | 点击权限弹窗允许按钮 |授权后成功进入欢迎页 | 是 |Pass|
| 欢迎页展示 | 设备正常运行 | | 展示随手记入口欢迎页 | 是 | Pass |
| 欢迎页按钮点击 | 设备正常运行且组网 | 点击”进入随手记“ | 跳转随手记主页,对端出现迁移入口 | 是 | Pass |
| 跨端迁移 | 设备正常运行且组网,对端出现迁移入口 | 点击对端迁移入口 | 应用迁移到对端设备,且携带页面栈信息,迁移后源端应用退出 | 是 | Pass |
| 主页展示 | 设备正常运行 | | 展示主页 | 是 | Pass |
| 主页轮播图滑动 | 位于主页 | 滑动主页图片轮播图 | 展示不同轮播图 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击设置图标 | 跳转“迁移设置”页面 | 是 | Pass |
| 设置迁移能力 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭再打开迁移能力开关 | 对端迁移入口消失后出现 | 是 | Pass |
| 设置迁移页面栈 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭迁移页面栈开关,发起迁移 | 应用迁移到对端设备,且不携带页面栈信息 | 是 | Pass |
| 设置迁移后远端退出 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭迁移后源端退出开关,发起迁移 | 应用迁移到对端设备,且源端应用不退出 | 是 | Pass |
| 返回主页 | 位于设置页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”笔记页“ | 展示笔记页 | 是 | Pass |
| 输入笔记标题 | 位于笔记页 | 输入笔记标题 | 输入内容正常展示 | 是 | Pass |
| 迁移笔记标题 | 位于笔记页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 发起迁移 | 笔记标题迁移到对端 | 是 | Pass |
| 返回主页 | 位于笔记页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”待办事项“ | 展示待办事项页 | 是 | Pass |
| 待办事项页滑动 | 位于待办事项页 | 上下滑动事项列表 | 待办事项列表滑动 | 是 | Pass |
| 待办事项scroll组件迁移 | 位于待办事项页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 上下滑动事项列表,发起迁移 | 迁移后,待办事项所在位置相同 | 是 | Pass |
| 待办事项页组件点击 | 位于待办事项页 | 点击事项选择框 | 选择框展示为对勾 | 是 | Pass |
| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
|------------------|--------------|----------------|-----------------------|------|------|
| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass |
| 允许权限 | 设备正常运行 | 点击权限弹窗允许按钮 |授权后成功进入欢迎页 | 是 |Pass|
| 欢迎页展示 | 设备正常运行 | | 展示随手记入口欢迎页 | 是 | Pass |
| 欢迎页按钮点击 | 设备正常运行且组网 | 点击”进入随手记“ | 跳转随手记主页,对端出现迁移入口 | 是 | Pass |
| 跨端迁移 | 设备正常运行且组网,对端出现迁移入口 | 点击对端迁移入口 | 应用迁移到对端设备,且携带页面栈信息,迁移后源端应用退出 | 是 | Pass |
| 主页展示 | 设备正常运行 | | 展示主页 | 是 | Pass |
| 主页轮播图滑动 | 位于主页 | 滑动主页图片轮播图 | 展示不同轮播图 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击设置图标 | 跳转“迁移设置”页面 | 是 | Pass |
| 设置迁移能力 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭再打开迁移能力开关 | 对端迁移入口消失后出现 | 是 | Pass |
| 设置迁移页面栈 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭迁移页面栈开关,发起迁移 | 应用迁移到对端设备,且不携带页面栈信息 | 是 | Pass |
| 设置迁移后远端退出 | 位于设置页,设备正常运行且组网,对端出现迁移入口 | 关闭迁移后源端退出开关,发起迁移 | 应用迁移到对端设备,且源端应用不退出 | 是 | Pass |
| 返回主页 | 位于设置页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”笔记页“ | 展示笔记页 | 是 | Pass |
| 输入笔记标题 | 位于笔记页 | 输入笔记标题 | 输入内容正常展示 | 是 | Pass |
| 迁移笔记标题 | 位于笔记页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 发起迁移 | 笔记标题迁移到对端 | 是 | Pass |
| 返回主页 | 位于笔记页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”待办事项“ | 展示待办事项页 | 是 | Pass |
| 待办事项页滑动 | 位于待办事项页 | 上下滑动事项列表 | 待办事项列表滑动 | 是 | Pass |
| 待办事项scroll组件迁移 | 位于待办事项页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 上下滑动事项列表,发起迁移 | 迁移后,待办事项所在位置相同 | 是 | Pass |
| 待办事项页组件点击 | 位于待办事项页 | 点击事项选择框 | 选择框展示为对勾 | 是 | Pass |
| 待办事项checkbox组件迁移 | 位于待办事项页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 随机点击一些待办事项选择框,发起迁移 | 迁移后,待办事项完成情况相同 | 是 | Pass |
| 返回主页 | 位于待办事项页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”图片墙“ | 展示图片墙页 | 是 | Pass |
| 图片墙瀑布流组件滑动 | 位于图片墙页 | 上下滑动 | 展示瀑布流图片 | 是 | Pass |
| 图片墙瀑布流组件迁移 | 位于图片墙页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 上下滑动瀑布流图片,发起迁移 | 迁移后,展示的图片偏移量相同 | 是 | Pass |
| 返回主页 | 位于图片墙页 | 点击返回 | 回到主页 | 是 | Pass |
| 返回主页 | 位于待办事项页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”图片墙“ | 展示图片墙页 | 是 | Pass |
| 图片墙瀑布流组件滑动 | 位于图片墙页 | 上下滑动 | 展示瀑布流图片 | 是 | Pass |
| 图片墙瀑布流组件迁移 | 位于图片墙页,设备正常运行且组网,对端出现迁移入口,且设置携带页面栈信息 | 上下滑动瀑布流图片,发起迁移 | 迁移后,展示的图片偏移量相同 | 是 | Pass |
| 返回主页 | 位于图片墙页 | 点击返回 | 回到主页 | 是 | Pass |
| 主页按钮点击 | 位于主页 | 点击”迁移时使用异步接口保存数据“ | 显示异步保存输入文本页面 | 是 | Pass |
| 输入异步测试文本 | 位于输入文本页面 | 输入异步测试文本 | 输入异步测试文本正常显示 | 是 | Pass |