HarmonyOS鸿蒙Next中UITest在模拟器上找不到控件

HarmonyOS鸿蒙Next中UITest在模拟器上找不到控件 cke_201.png

cke_445.png

环境:车机中控模拟器

找不到text为“允许”的控件


更多关于HarmonyOS鸿蒙Next中UITest在模拟器上找不到控件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

代码分析(顶部截图)

测试逻辑

// 等待页面加载
await ScanUtils.waitLoad(8000);
console.log(TAG, 'start find button.');

// 尝试查找"允许"按钮
let permissionButton = await driver.findComponent(ON.text('允许', MatchPattern.EQUALS));
console.log(TAG, 'permissionButton is ${permissionButton}.');

// 尝试查找"始终允许"按钮(API 26版本变更)
let permissionButton_new = await driver.findComponent(ON.text('始终允许', MatchPattern.EQUALS)); 

// 根据查找结果进行点击操作
if (permissionButton != null) {
  console.log(TAG, 'Find permissionButton.');
  await permissionButton.click();
} else if (permissionButton_new != null) {
  console.log(TAG, 'Find permissionButton_new.');
  await permissionButton_new.click();
} else {
  console.error(TAG, 'Do not find permissionButton');
}

问题点

  1. 控件查找失败:测试日志显示permissionButton is null,说明未能找到文本为"允许"的按钮
  2. API版本差异:代码注释提到"API26版本,相机权限弹窗发生变更",表明不同API版本的权限弹窗UI可能有变化
  3. 测试环境特殊:在"车机中控模拟器"环境下,UI元素的定位方式可能与普通手机模拟器不同

模拟器截图分析(底部截图)

实际界面情况

  • 显示了一个相机权限请求弹窗:允许'HctsScanNoCameraTest'访问你的相机?
  • 弹窗底部有两个按钮:不允许允许
  • 测试代码明确指出找不到"允许"按钮

环境说明

  • 测试环境:车机中控模拟器
  • 问题:找不到text为"允许"的控件

问题原因分析

  1. 权限弹窗实现差异
    • 在车机系统中,权限弹窗可能是系统级组件,其内部文本元素可能不是直接以"允许"为可识别文本
    • 车机系统可能使用了不同于手机系统的权限请求UI实现
  2. 文本匹配问题
    • 虽然按钮显示"允许",但实际控件的文本属性可能包含额外空格、标点或隐藏字符
    • 可能需要使用MatchPattern.CONTAINS而不是MatchPattern.EQUALS进行匹配
  3. 控件层次结构
    • 权限弹窗可能是系统级对话框,测试代码可能无法直接访问其内部元素
    • 可能需要通过其他方式(如坐标定位)来操作
  4. API版本适配问题
    • 代码注释明确提到"API26版本,相机权限弹窗发生变更",说明不同API版本的权限弹窗实现有差异
    • 测试代码可能未正确适配当前车机系统的API版本

解决方案建议

1. 改进控件定位策略

// 尝试使用更灵活的匹配方式
let permissionButton = await driver.findComponent(ON.text('允许', MatchPattern.CONTAINS));

2. 增加多版本适配

// 检查系统API版本,使用不同的定位策略
const apiVersion = await driver.getSystemVersion();
if (apiVersion >= 26) {
  // API 26+的定位策略
  permissionButton = await driver.findComponent(ON.text('始终允许', MatchPattern.EQUALS));
} else {
  // 旧版本定位策略
  permissionButton = await driver.findComponent(ON.text('允许', MatchPattern.EQUALS));
}

3. 使用坐标定位作为备选方案

// 如果文本定位失败,尝试使用坐标定位
if (!permissionButton) {
  // 根据屏幕尺寸计算大概位置
  const screen = await driver.getDisplaySize();
  const x = screen.width * 0.7; // 假设"允许"按钮在屏幕右侧70%位置
  const y = screen.height * 0.6; // 假设在屏幕下方60%位置
  
  await driver.click(x, y);
}

4. 检查车机系统特殊实现

  • 查阅车机系统的UI测试文档,了解车机特有的权限弹窗实现方式
  • 可能需要使用车机系统特定的UI测试API

5. 增加等待时间

// 增加等待时间,确保弹窗完全加载
await ScanUtils.waitLoad(10000);

总结

该问题主要由车机系统中权限弹窗的特殊实现测试代码的定位策略不匹配导致。在车机系统环境中,权限请求弹窗可能采用不同于普通手机系统的UI实现,导致基于文本的控件查找失败。解决方案应包括:

  1. 调整文本匹配策略
  2. 增加API版本适配
  3. 考虑使用坐标定位作为备选方案
  4. 针对车机系统特性进行专门适配

对于车机系统UI测试,需要特别注意其与普通手机系统的差异,可能需要使用特定的测试策略和API。

更多关于HarmonyOS鸿蒙Next中UITest在模拟器上找不到控件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


系统权限弹窗不在应用的 UI 树上的,你代码中的UITest 的 driver.findComponent 只能找到你自己应用的组件,而系统权限弹窗是系统进程渲染的,所以应用侧的控件树根本看不到它的

试试在测试环境进行预先授予权限吧

在运行UI测试前,通过权限管理接口提前授予应用所需的敏感权限,避免系统弹窗在测试过程中弹出。你可以使用abilityAccessCtrl.AtManager的接口来检查或模拟权限状态。在测试初始化阶段调用权限授予逻辑:

import { abilityAccessCtrl, Context, common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
let context: Context = getContext(this) as common.UIAbilityContext;
atManager.requestPermissionsFromUser(context, ['ohos.permission.CAMERA'], (err: BusinessError, data) => {
  // 处理授权结果
});

对于系统级弹框,UiTest的findComponent找不到。 findComponent只能找本应用层面的控件。 试试Driver的click(x: number, y: number): Promise<void>

这个授权弹窗,是系统弹窗吧,不是自己的代码,有点击允许按钮后的回调事件

cke_1991.png

参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/request-user-authorization#%E5%BC%80%E5%8F%91%E6%AD%A5%E9%AA%A4

在HarmonyOS Next 模拟器中,UITest 找不到控件通常因为:

  • 控件未完全渲染时即执行查找,需确认页面加载完成。
  • 使用错误的资源ID或文本属性(部分模拟器ID与真机不同)。
  • 模拟器本身对某些组件(如自定义组件)的反射支持不完整。 请确认测试脚本使用了正确的 ohos.idohos.text 定位,并检查控件是否存在于当前路由。

在模拟器上执行 UITest 时,系统权限弹窗(如“允许”按钮)不属于被测应用进程的 UI 树,因此直接通过 on.text("允许") 等 API 无法定位。
解决方法:测试前使用 hdc shell 提前授予所需权限,避免弹窗出现。例如:

hdc shell app_grant_permission -p <bundleName> -a ohos.permission.LOCATION

如果因场景必须处理弹窗,可尝试用 UiDriverpressBack() 或坐标点击模拟操作,但稳定性和兼容性较差。推荐在测试脚本中封装权限预置步骤。

回到顶部