!4491 【Sample】增加输入法框架Sample

Merge pull request !4491 from zhaojunxia/inputMethod
This commit is contained in:
openharmony_ci 2024-06-12 08:48:02 +00:00 committed by Gitee
commit 31dfa2e01a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
20 changed files with 536 additions and 60 deletions

View File

@ -732,6 +732,8 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="code/SuperFeature/MultiDeviceAppDev/AdaptiveCapabilities/entry/src/main/resources/base/media/md_new.png" desc="Provided by code/SuperFeature/MultiDeviceAppDev/AdaptiveCapabilities"/>
<filteritem type="filepath" name="code/SuperFeature/MultiDeviceAppDev/AdaptiveCapabilities/entry/src/main/resources/base/media/sm_new.png" desc="Provided by code/SuperFeature/MultiDeviceAppDev/AdaptiveCapabilities"/>
<filteritem type="filepath" name="code/BasicFeature/Media/Image/screenshots/devices/decoding.jpeg" desc="Provided by code/BasicFeature/Media/Image"/>
<filteritem type="filepath" name="code/Solutions/InputMethod/KikaInputMethod/entry/src/main/resources/base/media/startIcon.png" desc="Provided by code/Solutions/InputMethod/KikaInputMethod"/>
<filteritem type="filepath" name="code/Solutions/InputMethod/KikaInputMethod/screenshots/devices/preview.jpg" desc="Provided by code/Solutions/InputMethod/KikaInputMethod"/>
</filefilter>
<filefilter name="defaultPolicyFilter" desc="License文件头校验策略的过滤条件" >
<filteritem type="filename" name="oh-package.json5" desc="OpenHarmony工程编译入口脚本无需添加License头"/>

View File

@ -5,9 +5,9 @@
### 效果预览
| 主键盘 | 菜单 | 编辑 |
| :---------------------------------------: | :---------------------------------------: | :--------------------------------------: |
| ![main](screenshots/devices/main.jpg) | ![util](screenshots/devices/menu.jpg) | ![convertxml](screenshots/devices/edit.jpg) |
| 主键盘 | 菜单 | 编辑 | 预上屏 |
| :---------------------------------------: | :---------------------------------------: | :--------------------------------------: |:--------------------------------------: |
| ![main](screenshots/devices/main.jpg) | ![util](screenshots/devices/menu.jpg) | ![convertxml](screenshots/devices/edit.jpg) | ![preview](screenshots/devices/preview.jpg)
使用说明
@ -23,6 +23,12 @@
6.编辑状态点击选择按钮,进入选择状态,点击方向键可以选中文本。
预上屏应用使用说明
1.安装应用首页点击kikainput切换输入法到当前应用;
2.文本框中输入预上屏触发字符'hel',触发输入法预上屏;
3.点击输入法的回车键,确认预上屏内容'hello world'替换文本框中的'hel';
上屏的内容后继续输入字符ahello world被替换就是没有确认上屏否则呈现内容是hello worlda的话就是内容已经确认预上屏。
### 工程目录
```
@ -35,8 +41,11 @@ KikaInput
│ │ ├── common
│ │ │ ├── StyleConfiguration.ets //适配不同设备下的键盘布局
│ │ ├── components //输入法软键盘自定义组件
│ │ ├── entryability //应用入口
│ │ │ ├── EntryAbility.ets //应用入口Ability
│ │ ├── pages
│ │ │ ├── Index.ets //输入法主页
│ │ │ ├── PrivatePreview.ets //预上屏主页
│ │ ├── model
│ │ │ ├── HardKeyUtils.ets //外接键盘KeyCode数据
│ │ │ ├── KeyboardController.ets //输入法键盘控制
@ -72,9 +81,9 @@ KikaInput
1.本示例仅支持标准系统上运行。
2.本示例适配API10版本SDKSDK版本号(API Version 10 Release),镜像版本号(4.0 Release)。
2.本示例适配API12版本SDKSDK版本号(API Version 12 Release),镜像版本号(5.0.0.25及以后版本)。
3.本示例需要使用DevEco Studio 版本号(4.0 Release)及以上版本才可编译运行。
3.本示例需要使用DevEco Studio 版本号(4.1 Release)及以上版本才可编译运行。
5.本示例需要使用@ohos.application.InputMethodExtensionAbility系统权限的系统接口。使用Full SDK时需要手动从镜像站点获取并在DevEco Studio中替换具体操作可参考[替换指南](https://docs.openharmony.cn/pages/v3.2/zh-cn/application-dev/quick-start/full-sdk-switch-guide.md/)。

View File

@ -15,13 +15,14 @@
{
"app": {
"signingConfigs": [],
"signingConfigs": [
],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 10,
"compatibleSdkVersion": 10,
"compileSdkVersion": 12,
"compatibleSdkVersion": 12,
"runtimeOS": "OpenHarmony"
}
]

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
@ -62,6 +62,7 @@ export struct ReturnItem {
.width(this.returnWidth)
.borderRadius(4)
.height('100%')
.id('returnItem')
.shadow({ radius: 1, color: $r('app.color.shadow'), offsetY: 3 })
.onClick(() => {
InputHandler.getInstance().sendKeyFunction();

View File

@ -0,0 +1,58 @@
/*
* 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 InputStyle 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';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
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/PrivatePreview', (err) => {
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.');
});
}
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

@ -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
@ -35,7 +35,7 @@ interface CursorInfo {
y: number;
height: number
}
const previewContent: string = 'hello world';
const InputMethodEngine: inputMethodEngine.InputMethodAbility = inputMethodEngine.getInputMethodAbility();
const TAG: string = 'KeyboardController->';
const isDebug: boolean = false;
@ -69,6 +69,7 @@ export class InputHandler {
private selectInfo: string = '';
private textInfo: string = '';
private inputInfo: string = '';
private intputText: string = '';
private constructor() {
this.mKbController = undefined;
@ -94,8 +95,28 @@ export class InputHandler {
this.mEditorAttribute = res;
AppStorage.setOrCreate('enterKeyType', res.enterKeyType);
AppStorage.setOrCreate('inputPattern', res.inputPattern);
this.setInputInfo('EditorInfoenterKeyType = ' + this.mEditorAttribute.enterKeyType + ';inputPattern = ' + this.mEditorAttribute.inputPattern);
this.setInputInfo('EditorInfoenterKeyType = ' + this.mEditorAttribute.enterKeyType + ';inputPattern = ' + this.mEditorAttribute.inputPattern +
'; isTextPreviewSupported = ' + this.mEditorAttribute.isTextPreviewSupported);
})
try {
this.addLog(`onInputStart sendPrivateCommand begin`);
let record: Record<string, inputMethodEngine.CommandDataType> = {
'previewTextStyle': 'underline'
};
this.mTextInputClient.sendPrivateCommand(record).then((err) => {
this.addLog(`insertText sendPrivateCommand success`);
}).catch((err:BusinessError) => {
if (err !== undefined) {
let error = err as BusinessError;
this.addLog(`insertText sendPrivateCommand catch error: ${error.code} ${error.message}`);
}
});
} catch (err) {
let error = err as BusinessError;
this.addLog(`insertText sendPrivateCommand catch error: ${error.code} ${error.message}`);
}
}
public hideKeyboardSelf(): void {
@ -111,6 +132,13 @@ export class InputHandler {
this.addLog('sendKeyFunction')
if (this.mTextInputClient && this.mEditorAttribute) {
this.mTextInputClient.sendKeyFunction(this.mEditorAttribute.enterKeyType);
//调用结束预上屏接口, 预上屏内容将被系统正式上屏
this.mTextInputClient.finishTextPreview().then(() => {
this.addLog('Succeeded in finishing text preview.');
}).catch((err: BusinessError) => {
console.error(`Failed to finishTextPreview: ${JSON.stringify(err)}`);
});
} else {
this.addLog('sendKeyFunction this.mTextInputClient is undefined');
}
@ -144,12 +172,66 @@ export class InputHandler {
this.addLog(`insertText = ${text}`);
if (this.mTextInputClient !== undefined) {
this.mTextInputClient.insertText(text);
let indexCursor: number = 0;
indexCursor = this.mTextInputClient.getTextIndexAtCursorSync();
this.intputText = this.mTextInputClient.getForwardSync(indexCursor);
this.intputText = this.intputText + text;
//设置预上屏数据
let length = 2;
let textPre: string = this.mTextInputClient.getForwardSync(length);
this.addLog('insertText textPre:' + textPre);
// 取出的内容为当前输入之前的字符,不包含当前的字符,需将当前字符加上
textPre = textPre + text;
if (textPre == 'hel') {
this.addLog('insertText hel');
try {
//把当前字符计算在内
let endRange: number = indexCursor + 1;
this.addLog('insertText start ' + (indexCursor - length).toString());
this.addLog('insertText end ' + (indexCursor).toString());
let range: inputMethodEngine.Range = { start: indexCursor - length, end: endRange };
this.mTextInputClient.setPreviewText(previewContent, range).then(() => {
this.addLog('insertText preViewText Succeeded in setting preview text.');
}).catch((err: BusinessError) => {
this.addLog(`insertText preViewText Failed to setPreviewText: ${JSON.stringify(err)}`);
});
} catch (err) {
this.addLog(`insertText preViewText Failed to setPreviewText: ${JSON.stringify(err)}`);
}
} else if (this.intputText.length > length + 1) {
this.addLog('insertText this.intputText ' + this.intputText);
let indexSubStrStart: number = this.intputText.lastIndexOf('hel');
this.addLog('insertText indexSubStrStart ' + indexSubStrStart.toString());
if (indexSubStrStart >= 0) {
// 当前文本框存在预上屏的部分内容
let subStr: string = this.intputText.substring(indexSubStrStart, indexCursor);
this.addLog('insertText indexSubStrStart subStr ' + subStr);
if((previewContent != subStr) && (previewContent.includes(subStr))) {
// 文本框的子串与预上屏内容吻合,则调用预上屏接口,替换文本框的子串
this.addLog('insertText previewContent indexSubStrStart ' + indexSubStrStart.toString());
this.addLog('insertText previewContent end ' + (indexCursor).toString());
let range: inputMethodEngine.Range = { start: indexSubStrStart, end: indexCursor + 1 };
this.mTextInputClient.setPreviewText(previewContent, range).then(() => {
this.addLog('insertText preViewText Succeeded in setting preview text.');
}).catch((err: BusinessError) => {
this.addLog(`insertText preViewText Failed to setPreviewText: ${JSON.stringify(err)}`);
});
}
}
}
} else {
this.addLog('insertText this.mTextInputClient is undefined');
}
if (isDebug) {
this.refreshInfo();
}
}
public addLog(message: string): void {
@ -436,6 +518,19 @@ class KeyboardController {
}
});
this.inputHandle.addLog('pre on privateCommand');
try {
InputMethodEngine.on('privateCommand', (record : Record<string, inputMethodEngine.CommandDataType>) => {
this.inputHandle.addLog('keyboard privateCommand' + JSON.stringify(record));
Object.keys(record).forEach((key: string) => {
this.inputHandle.addLog(`onPageShow private command key: ${key}, value: ${record[key]}`);
})
});
} catch (err) {
let error = err as BusinessError;
this.inputHandle.addLog(`on privateCommand sendPrivateCommand catch error: ${error.code} ${error.message}`);
}
this.mKeyboardDelegate = inputMethodEngine.getKeyboardDelegate();
this.mKeyboardDelegate.on('keyDown', (keyEvent: inputMethodEngine.KeyEvent) => {

View File

@ -0,0 +1,84 @@
/*
* 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 InputStyle KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import inputMethod from '@ohos.inputMethod';
import Log from '../model/Log';
import { BusinessError } from '@ohos.base';
const TAG: string = 'PrivatePreview->';
@Entry
@Component
struct PrivatePreview {
@State message: string = 'Hello World';
@State accountText: string = '';
@State preViewText: string = '';
@StorageLink('isTextPreviewSupported') isTextPreviewSupported: boolean = true;
controllerPrivate: TextInputController = new TextInputController();
controllerPreview: TextInputController = new TextInputController();
aboutToAppear() {
this.addLog(`private preview aboutToAppear begin!`);
inputMethod.getSetting().showOptionalInputMethods().then((data: boolean) => {
console.log('onPageShow Succeeded in showing optionalInputMethods.');
}).catch((err: BusinessError) => {
console.error(`onPageShow Failed to showOptionalInputMethods: ${JSON.stringify(err)}`);
})
}
onPageShow() {
this.addLog(`private command onPageShow!`);
}
addLog(message: string): void {
Log.showInfo(TAG, `kikaInput-new: ${message}`);
}
build() {
Column() {
Text($r('app.string.Preview_Text'))
.width('100%')
.height(56)
.fontFamily('HarmonyHeiTi-Medium')
.fontSize('16fp')
.fontColor('#182431')
.lineHeight(22)
.fontWeight(500)
TextInput({
text: this.preViewText,
placeholder: $r('app.string.Preview_tip'),
controller: this.controllerPreview
})
.placeholderFont({ size: 16, weight: 400 })
.width('100%')
.height(56)
.margin(10)
.fontSize(16)
.fontColor('#182431')
.backgroundColor('#FFFFFF')
.border({ width: 1, color: Color.Gray, radius: 18 })
.maxLength(50)
.onChange((value: string) => {
this.addLog('preViewText onChange.');
})
.onSubmit(() => {
this.addLog('preViewText onSubmit.');
})
}
.width('100%')
.padding(20)
}
}

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,7 +19,7 @@
"type": "entry",
"srcEntry": "./ets/Application/AbilityStage.ets",
"description": "$string:entry_desc",
"mainElement": "MainAbility",
"mainElement": "EntryAbility",
"deviceTypes": [
"default",
"tablet"
@ -42,6 +42,28 @@
"type": "inputMethod",
"exported": true
}
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}
}

View File

@ -43,6 +43,10 @@
{
"name": "key_item_normal_text",
"value": "#606060"
},
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -23,6 +23,30 @@
{
"name": "edit",
"value": "Edit"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
},
{
"name": "Private_data",
"value": "Private data"
},
{
"name": "Preview_Text",
"value": "Preview Text"
},
{
"name": "Private_tip",
"value": "Please input account number"
},
{
"name": "Preview_tip",
"value": "Please input preview content"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,5 +1,6 @@
{
"src": [
"pages/Index"
"pages/Index",
"pages/PrivatePreview"
]
}

View File

@ -23,6 +23,30 @@
{
"name": "edit",
"value": "Edit"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
},
{
"name": "Private_data",
"value": "Private data"
},
{
"name": "Preview_Text",
"value": "Preview Text"
},
{
"name": "Private_tip",
"value": "Please input account number"
},
{
"name": "Preview_tip",
"value": "Please input preview content"
}
]
}

View File

@ -23,6 +23,29 @@
{
"name": "edit",
"value": "编辑"
},{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
},
{
"name": "Private_data",
"value": "私有数据传递:"
},
{
"name": "Preview_Text",
"value": "预上屏:"
},
{
"name": "Private_tip",
"value": "请输入账号信息"
},
{
"name": "Preview_tip",
"value": "请输入预上屏内容"
}
]
}

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
@ -15,9 +15,10 @@
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import UIAbility from '@ohos.app.ability.UIAbility';
import { describe, it, expect } from '@ohos/hypium';
import { describe, it, expect, TestType } from '@ohos/hypium';
import { Driver, ON, MatchPattern } from '@ohos.UiTest';
import { logger } from '../util/Logger';
import inputMethod from '@ohos.inputMethod';
const TAG: string = 'Sample_KikaInput_Test';
const BUNDLE = 'KikaInput_';
@ -25,7 +26,7 @@ const BUNDLE = 'KikaInput_';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// 打开自绘编辑框应用
it(BUNDLE + 'StartAbility_001', 0, async (done: Function) => {
it('StartAbility_001',TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}StartAbility_001 begin`);
let driver: Driver = Driver.create();
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
@ -44,31 +45,28 @@ export default function abilityTest() {
})
// 切换输入法应用
it(BUNDLE + 'ChangeInputMethod_001', 0, async (done: Function) => {
logger.info(TAG, `${BUNDLE}ChangeInputMethod_001 begin`);
it('SwitchInputMethod_001',TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}SwitchInputMethod_001 begin`);
let driver: Driver = Driver.create();
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
await delegator.executeShellCommand('aa start ability -a InputMethod -b cn.openharmony.inputmethodchoosedialog')
.then(result => {
logger.info(TAG, `${BUNDLE}start ability finished, result = ${JSON.stringify(result)}`);
})
.catch((err: Error) => {
logger.info(TAG, `${BUNDLE}start ability failed, err = ${JSON.stringify(err)}`);
})
await inputMethod.getSetting().showOptionalInputMethods();
logger.info(TAG, `${BUNDLE}SwitchInputMethod_001 11`);
await driver.delayMs(1000);
await driver.assertComponentExist(ON.type('List'));
logger.info(TAG, `${BUNDLE}SwitchInputMethod_001 22`);
let list = await driver.findComponent(ON.type('List'));
let kikainput = await list.scrollSearch(ON.text('kikainput', MatchPattern.CONTAINS));
logger.info(TAG, `${BUNDLE}SwitchInputMethod_001 33 kikainput` + kikainput);
await driver.delayMs(1000);
let bound = await kikainput.getBounds();
await driver.click(bound.right - 10, bound.bottom - 10);
await driver.delayMs(1000);
logger.info(TAG, `${BUNDLE}ChangeInputMethod_001 end`);
logger.info(TAG, `${BUNDLE}SwitchInputMethod_001 end`);
done();
})
// 点击自绘编辑框拉起输入法,并输入内容
it(BUNDLE + 'ShowKeyboard_001', 0, async (done: Function) => {
it('ShowKeyboard_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}ShowKeyboard_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -84,6 +82,7 @@ export default function abilityTest() {
await keyboardMenu.click();
}
logger.info(TAG, `${BUNDLE}ShowKeyboard_001 11`);
// 如果当前是编辑页面,切换到主键盘
let btn_selection = await driver.findComponent(ON.id('btn_selection'));
if (btn_selection !== undefined && btn_selection !== null) {
@ -97,21 +96,36 @@ export default function abilityTest() {
if (charKey !== undefined && charKey !== null) {
await charKey.click();
}
logger.info(TAG, `${BUNDLE}ShowKeyboard_001 22`);
//点击等输入法弹出
await customInputText.click();
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('a', MatchPattern.CONTAINS));
let inputText = await driver.findComponent(ON.text('a', MatchPattern.CONTAINS));
await inputText.click();
await inputText.click();
await inputText.click();
let inputTexta = await driver.findComponent(ON.text('a', MatchPattern.CONTAINS));
await inputTexta.click();
await driver.delayMs(2000);
await driver.assertComponentExist(ON.text('c', MatchPattern.CONTAINS));
let inputTextc = await driver.findComponent(ON.text('c', MatchPattern.CONTAINS));
await inputTextc.click();
await driver.delayMs(2000);
await driver.assertComponentExist(ON.text('d', MatchPattern.CONTAINS));
let inputTextd = await driver.findComponent(ON.text('d', MatchPattern.CONTAINS));
await inputTextd.click();
await driver.delayMs(2000);
let inputContent = await driver.findComponent(ON.id('inputText'));
let inputString = await inputContent.getText();
expect(inputString === 'aaa').assertTrue();
await driver.delayMs(200);
expect(inputString === 'acd').assertTrue();
logger.info(TAG, `${BUNDLE}ShowKeyboard_001 end`);
done();
})
// 进入菜单
it(BUNDLE + 'EditModel_001', 0, async (done: Function) => {
it('EditModel_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}EditModel_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -129,7 +143,7 @@ export default function abilityTest() {
})
// 编辑界面,向左移动光标
it(BUNDLE + 'MoveCursor_001', 0, async (done: Function) => {
it('MoveCursor_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}MoveCursor_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -147,7 +161,7 @@ export default function abilityTest() {
})
// 编辑界面,向右移动光标
it(BUNDLE + 'MoveCursor_002', 0, async (done: Function) => {
it('MoveCursor_002', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}MoveCursor_002 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -165,7 +179,7 @@ export default function abilityTest() {
})
// 编辑界面,文本选中
it(BUNDLE + 'Selection_001', 0, async (done: Function) => {
it('Selection_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}Selection_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -190,7 +204,7 @@ export default function abilityTest() {
})
// 隐藏软键盘
it(BUNDLE + 'HideKeyboard_001', 0, async (done: Function) => {
it('HideKeyboard_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}HideKeyboard_001 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
@ -203,5 +217,117 @@ export default function abilityTest() {
logger.info(TAG, `${BUNDLE}HideKeyboard_001 end`);
done();
})
// 预上屏
it('PreviewText_001', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}PreviewText_001 begin`);
let driver: Driver = Driver.create();
let delegator = AbilityDelegatorRegistry.getAbilityDelegator();
await delegator.executeShellCommand('aa start ability -a EntryAbility -b com.samples.kikainput')
.then(result => {
logger.info(TAG, `${BUNDLE}start ability finished, result = ${JSON.stringify(result)}`);
})
.catch((err: Error) => {
logger.info(TAG, `${BUNDLE}start ability failed, err = ${JSON.stringify(err)}`);
})
logger.info(TAG, `${BUNDLE}PreviewText_001 11`);
await driver.delayMs(1000);
let kikaInputDown = await driver.findComponent(ON.text('kikainput', MatchPattern.CONTAINS));
await kikaInputDown.click();
await driver.delayMs(1000);
logger.info(TAG, `${BUNDLE}PreviewText_001 end`);
done();
})
it('PreviewText_002', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}PreviewText_002 begin`);
let driver: Driver = Driver.create();
await driver.delayMs(1000);
// 输入hel'触发预上屏'hello world'
await driver.assertComponentExist(ON.type('TextInput'));
let textInput = await driver.findComponent(ON.type('TextInput'));
await textInput.click();
await driver.delayMs(1000); // 等待输入法应用弹出
await driver.assertComponentExist(ON.text('h', MatchPattern.CONTAINS));
let inputTextH = await driver.findComponent(ON.text('h', MatchPattern.CONTAINS));
await inputTextH.click();
await driver.assertComponentExist(ON.text('e', MatchPattern.CONTAINS));
let inputTextE = await driver.findComponent(ON.text('e', MatchPattern.CONTAINS));
await inputTextE.click();
await driver.assertComponentExist(ON.text('l', MatchPattern.CONTAINS));
let inputTextL = await driver.findComponent(ON.text('l', MatchPattern.CONTAINS));
await inputTextL.click();
await driver.delayMs(2000);
// 点击回车键触发预上屏内容到编辑框
await driver.assertComponentExist(ON.id('returnItem')); // ON.type('ReturnItem')
let enterKey = await driver.findComponent(ON.id('returnItem')); // ON.type('ReturnItem')
await enterKey.click();
await driver.delayMs(1000);
// 校验文本框的内容为预上屏内容
let inputString = await textInput.getText();
expect(inputString === 'hello world').assertTrue();
logger.info(TAG, `${BUNDLE}PreviewText_002 end`);
done();
})
it('PreviewText_003', TestType.FUNCTION, async (done: Function) => {
logger.info(TAG, `${BUNDLE}PreviewText_003 begin`);
let driver: Driver = Driver.create();
// 输入abhel'触发预上屏'hello world'
await driver.assertComponentExist(ON.type('TextInput'));
let textInput = await driver.findComponent(ON.type('TextInput'));
await textInput.click();
await textInput.clearText();
await driver.delayMs(1000); // 等待输入法应用弹出
await driver.assertComponentExist(ON.text('a', MatchPattern.CONTAINS));
let inputText = await driver.findComponent(ON.text('a', MatchPattern.CONTAINS));
await inputText.click();
await driver.assertComponentExist(ON.text('b', MatchPattern.CONTAINS));
inputText = await driver.findComponent(ON.text('b', MatchPattern.CONTAINS));
await inputText.click();
await driver.assertComponentExist(ON.text('h', MatchPattern.CONTAINS));
let inputTextH = await driver.findComponent(ON.text('h', MatchPattern.CONTAINS));
await inputTextH.click();
await driver.assertComponentExist(ON.text('e', MatchPattern.CONTAINS));
let inputTextE = await driver.findComponent(ON.text('e', MatchPattern.CONTAINS));
await inputTextE.click();
await driver.assertComponentExist(ON.text('l', MatchPattern.CONTAINS));
let inputTextL = await driver.findComponent(ON.text('l', MatchPattern.CONTAINS));
await inputTextL.click();
await driver.delayMs(2000);
logger.info(TAG, `${BUNDLE}PreviewText_003 11`);
// 点击回车键触发预上屏内容到编辑框
await driver.assertComponentExist(ON.id('returnItem')); // ON.type('ReturnItem')
let enterKey = await driver.findComponent(ON.id('returnItem')); // ON.type('ReturnItem')
await enterKey.click();
await driver.delayMs(1000);
// 校验文本框的内容为预上屏内容
let inputString = await textInput.getText();
expect(inputString === 'abhello world').assertTrue();
logger.info(TAG, `${BUNDLE}PreviewText_003 end`);
done();
})
})
}

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
@ -16,5 +16,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest()
abilityTest();
}

View File

@ -1,6 +1,6 @@
{
"hvigorVersion": "3.0.2",
"hvigorVersion": "3.2.4",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "3.0.2"
"@ohos/hvigor-ohos-plugin": "3.2.4"
}
}

File diff suppressed because one or more lines are too long

View File

@ -2,16 +2,19 @@
## 用例表
|测试功能|预置条件|输入|预期输出|是否自动|测试结果|
|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------|
|拉起应用 | 输入法切换到kikaInput | 1、拉起测试应用主界面自绘编辑框显示 |1、成功拉起应用|是|Pass|
|切换输入法 | kikaInput输入法已安装 | 1、拉起切换输入法弹窗<br/>2、切换输入法到当前应用 |1、成功切换输入法|是|Pass|
|拉起输入法按键盘 | | 1、点击自绘编辑框 |1、拉起输入法键盘|是|Pass|
|输入内容| | 1、点击输入法键盘输入内容 |1、自绘编辑框成功输入内容|是|Pass|
|进入菜单| 输入法键盘弹起 | 1、点击左上角键盘按钮 |1、进入菜单页有编辑按钮|是|Pass|
|进入编辑状态| 位于菜单页 | 1、点击编辑按钮 | 1、进入编辑状态 | 是 |Pass|
|左移光标| 编辑状态 | 1、点击向左方向键 | 1、光标成功左移 | 是 |Pass|
|右移光标| 编辑状态 | 1、点击向右方向键 | 1、光标成功右移 | 是 |Pass|
|文本选中| 编辑状态 | 1、点击选择按钮<br/>2、点击左方向键<br/>3、点击向右方向键 | 1、变为选择状态<br/>2、向左选中一个字符<br/>3、第2步选中的字符取消选中 | 是 |Pass|
|隐藏键盘| 输入法键盘弹起 | 1、点击输入法键盘右上角down按钮 | 1、输入法键盘隐藏 | 是 |Pass|
|键盘切换| | 1、点击键盘中的主子键盘和符号键盘切换按钮 | 1、成功切换键盘键盘显示正常 | 否 |Pass|
| 测试功能 | 预置条件 | 输入 | 预期输出 |是否自动|测试结果|
|--------------|-----------------|------------------------------------|--------------------------------------------|--------------------------------|--------------------------------|
| 拉起应用 | 输入法切换到kikaInput | 1、拉起测试应用主界面自绘编辑框显示 | 1、成功拉起应用 |是|Pass|
| 切换输入法 | kikaInput输入法已安装 | 1、拉起切换输入法弹窗<br/>2、切换输入法到当前应用 | 1、成功切换输入法 |是|Pass|
| 拉起输入法按键盘 | | 1、点击自绘编辑框 | 1、拉起输入法键盘 |是|Pass|
| 输入内容 | | 1、点击输入法键盘输入内容 | 1、自绘编辑框成功输入内容 |是|Pass|
| 进入菜单 | 输入法键盘弹起 | 1、点击左上角键盘按钮 | 1、进入菜单页有编辑按钮 |是|Pass|
| 进入编辑状态 | 位于菜单页 | 1、点击编辑按钮 | 1、进入编辑状态 | 是 |Pass|
| 左移光标 | 编辑状态 | 1、点击向左方向键 | 1、光标成功左移 | 是 |Pass|
| 右移光标 | 编辑状态 | 1、点击向右方向键 | 1、光标成功右移 | 是 |Pass|
| 文本选中 | 编辑状态 | 1、点击选择按钮<br/>2、点击左方向键<br/>3、点击向右方向键 | 1、变为选择状态<br/>2、向左选中一个字符<br/>3、第2步选中的字符取消选中 | 是 |Pass|
| 隐藏键盘 | 输入法键盘弹起 | 1、点击输入法键盘右上角down按钮 | 1、输入法键盘隐藏 | 是 |Pass|
| 键盘切换 | | 1、点击键盘中的主子键盘和符号键盘切换按钮 | 1、成功切换键盘键盘显示正常 | 否 |Pass|
| 拉起预上屏Ability | | 1、拉起EntryAbility | 1、弹出的输入法选择弹框中选择kikainput | 是 |Pass|
| 文本头文本触发预上屏 | 输入法切换到kikaInput | 1、文本框中输入 'hel' | 1、输入法触发预上屏'hello world' | 是 |Pass|
| 中间文本触发预上屏 | 输入法切换到kikaInput | 1、文本框中输入 'abhel' | 1、输入法触发预上屏'hello world' | 是 |Pass|

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB