Text识别技术

对于一些较旧的技术开发的Windows应用程序,CukeTest对控件对象识别的支持可能有限。但通过GuiText插件,CukeTest增强了对使用Windows GDI绘图机制在屏幕上显示文本的控件的识别能力。

如果控件中的特定文本位置无法被识别为控件,那么可以通过使用文字对象(GuiText)文字表格对象(TextTable)来解决这个问题。

文字对象(GuiText)

文字对象(GuiText)允许您将界面上的文本视为可操作的对象,便于实现对特定文本的精确控制和操作。其实现原理是从图形渲染的底层机制入手,通过定位文本位置,在已有的控件树上实现更精确的定位。

添加文字对象

与其他测试对象一样,文字对象也需要在模型管理器中进行侦测、识别和管理。打开模型文件或模型管理器后,点击“添加文字对象”(位于“添加Windows对象”按钮的下拉列表中)来侦测和添加文字对象。

编辑属性

文字对象目前只有一个标识属性——text。该属性支持使用正则表达式进行匹配,详情请参考修改匹配模式

编辑父节点

在编辑文字对象的父节点时需谨慎,因为文字对象对其直接容器控件有特定要求。如果删除文字对象最近的容器控件(如Pane、Window、Tree、Menu等),可能会导致文字对象无法被正确识别。

文字对象的API

类型定义

JavaScript
Python
export interface IGuiTextControl {
    click(x?: number, y?: number, mousekey?: number): Promise<void>;
    dblClick(x?: number, y?: number, mousekey?: number): Promise<void>;
    exists(seconds?: number): Promise<boolean>;
    highlight(duration?: number);
    moveMouse(x?: number, y?: number, seconds?: number): Promise<void>;
    rect(): Promise<Rect>;
    text(): Promise<string>;
    takeScreenshot(filePath?: string): Promise<string>;
    modelImage(options?: {encoding: 'buffer' | 'base64'}): Promise<string | Buffer>;  //base64 is the default
    modelProperties(all?: boolean): {[x: string]: any};
}
class GuiTextControl(ControlBase):
    def click(x: Optional[int]=None, y: Optional[int]=None, mousekey: Optional[int]=None) -> None
    def dblClick(x: Optional[int]=None, y: Optional[int]=None, mousekey: Optional[int]=None) -> None
    def exists(seconds: Optional[int]=None) -> bool
    def highlight(duration: Optional[int]=None) -> None
    def moveMouse(x: Optional[int]=None, y: Optional[int]=None, seconds: Optional[int]=None) -> None
    def rect() -> Rect
    def text() -> str
    def takeScreenshot(filePath: Optional[str]=None) -> str
    def modelImage(encoding: Optional[str]=None) -> Union[str, bytearray]
    def modelProperties(all: Optional[bool]=None) -> TypedDict

操作方法

属性方法

需要注意的控件的属性方法都是异步的,在调用后CukeTest会与目标控件通信,获取控件当前的属性,即实时属性,而不是模型对象中的识别属性。下面列出的属性所有控件都支持,但不一定都有值,可以根据建议尝试类似的属性方法来获取目标属性。

文字表格对象(TextTable)

当您需要操作位于同一控件下的多个文本对象时,文字表格对象(TextTable)提供了一种高效的解决方案。如果在目标Windows控件下识别到多个同级的文字对象,CukeTest会在识别结果中提供一个特殊的节点——文字表格对象(TextTable)。通过将这个对象添加到控件树中,您可以像操作表格一样使用它,实现对多个文本对象的集中管理和操作。

GuiText文字表格

添加文字表格对象

在模型管理器中识别到多个同级文字对象时,CukeTest会自动提供添加文字表格对象的选项。选择“添加文字表格对象”后,CukeTest将这些同级文字对象组织成一个表格结构,便于您后续的测试操作。

通过这种方式,您可以避免单独操作每个文本对象,而是通过行列的方式直接访问所需的内容。例如:

  • 点击特定单元格。
  • 获取单元格的文本内容。
  • 验证单元格文本的正确性。
  • 在表格中搜索和比较数据。

表头设置

在处理表格数据时,表格的第一行有时用于显示列标题(表头),而非实际的数据内容。为了让 CukeTest 正确识别表格结构,您可以使用 header 属性进行配置:

  • header: false(默认行为):第一行会被视为普通的数据行。这意味着所有行都被当作数据来处理,索引从第一行开始计算。
  • header: true(启用表头):将表格的第一行识别为表头(列标题),实际的数据从第二行开始。这种设置下:

    • data() 方法:仅返回数据行,不包含表头行。这使得您可以直接对实际数据进行操作,而无需手动跳过表头。
    • 操作方法(如 clickCell()cellValue()rowData():这些方法在使用行索引时,会以数据的第一行作为索引的起点,表头行不会被包含在索引计算中。例如,如果表头存在,数据的第一行对应索引 0,表头不占用任何索引位置。

裁剪识别区域

在使用 TextTable 时,您可能只需要处理表格中的某些部分数据。裁剪识别区域 功能可以帮助您通过设置 clip 属性,精准指定需要识别的表格范围,从而专注于关心的部分。

clip参数

如何使用 clip 属性

您可以为 clip 属性传入一个对象,并根据需要设置以下参数之一或多个,以控制识别区域的边界:

  • left:目标识别区域左边距表格左侧的像素数。
  • top:目标识别区域顶部距离表格顶部的像素数。
  • right:目标识别区域右边距表格左侧的像素数。
  • bottom:目标识别区域底部距离表格顶部的像素数。

注意:裁剪区域是从表格的左上角(原点)开始计算的。lefttop 定义了裁剪区域的左上角起点,rightbottom 定义了右下角的边界。

裁剪得到的区域取决于应用内文本实际宽度,可能会因文本内容变化而导致裁剪区域的变化。因此,在实际操作时,您可能需要根据实际情况调整裁剪区域的大小,以确保能够完全识别需要的内容。

通过同时设置这些参数,您可以定义一个矩形区域,仅识别该区域内的内容。

示例说明

  1. 裁剪右下角的内容

     { left: 147, top: 98 }
    

    解释:该设置表示识别区域的左边距表格左侧 147 像素,顶部距表格顶部 98 像素。这样只会保留右下角的部分,忽略其他区域。

  2. 裁剪左侧内容

     { right: 147 }
    

    解释:该设置表示识别区域的右边距表格左侧 147 像素。这样只会保留左侧部分,忽略右侧内容。

  3. 定义一个矩形区域

     { left: 100, top: 70, right: 200, bottom: 140 }
    

    解释:该设置定义了一个矩形识别区域:

    • 左边距表格左侧 100 像素
    • 顶部距表格顶部 70 像素
    • 右边距表格左侧 200 像素
    • 底部距表格顶部 140 像素

      这样,只有位于该矩形区域内的内容会被识别。

编辑父节点

在编辑文字表格对象的父节点时需谨慎,因为文字表格对象对其直接容器控件有特定要求。如果删除文字表格对象最近的容器控件(如Pane、Window、Tree、Menu等),可能会导致对象无法被正确识别。

使用示例

假设您正在测试一个包含多个联系人信息的应用,每个联系人的信息(如姓名、电话、邮箱等)以列表形式显示。通过添加文字表格对象,您可以轻松地验证列表中每一行的联系人信息,或者查找特定联系人的信息。

JavaScript
(async function() {
    let textTable = await model.getTextTable("ContactsList");
    let contactInfo = await textTable.getCellText(1, 2); // 获取第1行第2列(假设为电话号码)的文本
    console.log(`联系人电话: ${contactInfo}`);
    // 执行其他文本验证或操作...
})();

文字表格对象的API

类型定义

JavaScript
Python
export interface ITextTable extends ITextGuiText {
    clickCell(rowIndex: number, columnNameOrIndex: string | number): Promise<void>;
    cellValue(rowIndex: number, columnNameOrIndex: string | number): Promise<string>;
    columnName(index: number): Promise<string>;
    columnHeaders(): Promise<string[]>;
    columnCount(): Promise<number>;
    data(): Promise<string[][]>;
    rowCount(): Promise<number>;
    rowData(rowIndex: number): Promise<string[]>;
}
class TextTableControl(ControlBase):
    def clickCell(rowIndex: int, columnNameOrIndex: Union[str, int]) -> None
    def cellValue(rowIndex: int, columnNameOrIndex: Union[str, int]) -> str
    def columnName(index: int) -> str
    def columnHeaders() -> List[str]
    def columnCount() -> int
    def data() -> List[List[str]]
    def rowCount() -> int
    def rowData(rowIndex: int) -> List[str]

操作方法

data(): Promise<string[][]>

获取表格中的所有内容,并以二维数组的形式返回。

  • 返回值: Promise<string[][]>类型,即二维的字符串数组。

假如表格数据如下:

学号 姓名 性别
0001 小王
0002 小明
0003 小红

那么data()方法返回的数组如下:

[  
    ['0001', '小王', '男'],  
    ['0002', '小明', '男'],  
    ['0003', '小红', '女']  
]

属性方法

results matching ""

    No results matching ""