表格类型对象
针对被测应用中的表格提供的对象,CukeTest提供了三个控件:
Table: 表格控件,作为表格外部容器控件,也是CukeTest推荐使用的;TableRow: 表格行控件,代表表格中的一行数据,可以进一步获取其中的单元格,也就是TableCell控件;TableCell: 单元格控件,代表表格中的最小控件单元,这些单元格包含数据,并且在很多时候都是可以双击切换到编辑状态进行编辑的。
这个三个不同的控件互相配合就可以完美完成针对表格应用的自动化。
事实上CukeTest还提供了另一个表格控件
DataGrid,它与Table控件的区别在于:Table和DataGrid两个控件是针对两种不同的框架在表格实现上不一致准备的: 在WinForm、WPF框架的应用中,表格会被识别为DataGrid控件;而Qt框架中为Table控件。
表格控件: Table
用于描述表格视图控件的对象类型——Table。
| 方法名 | 描述 |
|---|---|
| clickCell | 按行索引和列名单击单元格,列名可以按名称或索引,索引从 0 开始。 |
| cellValue | 按行索引和列名获取单元格值,列名可以按名称或索引,索引从 0 开始。 |
| setCellValue | 按行索引和列名设置单元格值,列名可以按名称或索引,索引从 0 开始。 |
| showHeader | 将某列头滚动到当前视图,并返回该对象。 |
| select | 选择控件,可以根据控件的索引值选择(例如0,3),也可以使用name属性。 |
| scrollTo | 滚动到指定的项。 |
| scrollLeft | 滚动到表格最左侧。 |
| scrollToTop | 滚动到表格顶部。 |
| scrollToBottom | 滚动到表格底部。 |
| findItemInColumn | 某一列搜索对应值,并返回该列单元格对象。未搜索到返回null。value参考可为被搜索值,或为每个值的回调函数。模型管理器中会选中对象。代码中需调用select方法选中。 |
| columnName | 通过索引值获取列表名字。 |
| columnHeaders | 返回表格列标题的数组。 |
| columnCount | 获取列表列数。 |
| rowCount | 获取列表行数。 |
| row | 返回索引定位的行。 |
| rowData | 返回索引所在的行数据。 |
在大多数情况下,由于表格中的单元格能够提供的识别属性较少,并且在操作单元格之前一一识别被操作的单元格也不是一种合适的自动化方式。因此CukeTest将大部分表格及表格内的操作、属性方法都包含了,针对表格的自动化直接在Table对象上完成即可。比如:
假设有在第2行第3列位置有个单元格,需要修改该单元格内的值为targetValue,如果按照常规的自动化开发流程,应该是如下:
// 在识别单元格为`TargetCell`后
await model.getTableCell('TargetCell').set(targetValue);# 在识别单元格为`TargetCell`后
model.getTableCell('TargetCell').set(targetValue)而建议的方法是这样的:
await model.getTable('Table').setCellValue(1, 2, targetValue);model.getTable('Table').setCellValue(1, 2, targetValue)通过这种方式,能够在不用识别被操作单元格的前提下操作单元格,使得你只需要知道表格的行、列数量,就可以遍历整张表中的所有单元格了。这就是为什么建议你在Table对象上进行操作而不是在单元格的对象上。
类型定义
export interface IWinTable extends IWinControl {
clickCell(rowIndex: number, columnNameOrIndex: string | number): Promise<void>;
cellValue(rowIndex: number, columnNameOrIndex: string | number): Promise<string>;
setCellValue(rowIndex: number, columnNameOrIndex: string | number, value: string): Promise<void>;
showHeader(nameOrIndex: string | number): Promise<IWinTableCell>;
select(rowIndex: number, columnName: string | number): Promise<IWinTableCell>;
scrollTo(rowIndex: number, columnName: string | number): Promise<IWinTableCell>;
scrollLeft(): Promise<void>;
scrollToTop(): Promise<void>;
scrollToBottom(): Promise<void>;
findItemInColumn(columnNameOrIndex: string | number,
valueOrListener: string | ((element) => Promise<boolean>))
: Promise<IWinTableCell>
columnName(index: number): Promise<string>;
columnHeaders(): Promise<string[]>;
columnCount(): Promise<number>;
rowCount(): Promise<number>;
row(rowIndex: number): Promise<IWinTableRow>;
rowData(rowIndex: number): Promise<string[]>;
}
export interface IWinDataGrid extends IWinTable {
}class WinTable(WinControl):
def clickCell(rowIndex: int, columnNameOrIndex: Union[str, int]) -> None
def cellValue(rowIndex: int, columnNameOrIndex: Union[str, int]) -> str
def setCellValue(rowIndex: int, columnNameOrIndex: Union[str, int], value: str) -> None
def showHeader(nameOrIndex: Union[str, int]) -> "WinTableCell"
def select(rowIndex: int, columnNameOrIndex: Union[str, int]) -> "WinTableCell"
def scrollTo(rowIndex: int, columnNameOrIndex: Union[str, int]) -> "WinTableCell"
def scrollLeft() -> None
def scrollToTop() -> None
def scrollToBottom() -> None
def findItemInColumn(columnNameOrIndex: Union[str, int], valueOrListener: str) -> "WinTableCell"
def columnName(index: int) -> str
def columnHeaders() -> List[str]
def columnCount() -> int
def rowCount() -> int
def row(rowIndex: int) -> "WinTableRow"
def rowData(rowIndex: int) -> List[str]
class WinDataGrid(WinTable):
...对象操作API介绍
clickCell(rowIndex, columnNameOrIndex)
单击目标索引位置的单元格。如果目标位置还不在屏幕内,会将其滚动到可见位置并点击。
参数
- rowIndex:
number类型,代表目标单元格的行位置索引,从0开始计算位置。 - columnNameOrIndex:
number类型或string类型,代表目标单元格的列位置索引(从0开始)或列名。
返回值
- 不返回任何值的异步方法。
示例代码
// 点击第2行第3列的单元格
await model.getTable('Table').clickCell(1, 2);
// 点击第2行ID列的单元格
await model.getTable('Table').clickCell(1, 'ID');# 点击第2行第3列的单元格
model.getTable('Table').clickCell(1, 2)
# 点击第2行ID列的单元格
model.getTable('Table').clickCell(1, 'ID')showHeader(nameOrIndex)
将目标表头(列头)滚动到可视位置,并返回目标位置的单元格对象。比columnHeader()方法多出了滚动到目标表头的操作,并且返回的是对象而不是值。
参数
- nameOrIndex:
number类型或string类型,代表列的索引或列的名称,从0开始计算位置。
返回值
Promise<IWinTableCell>类型,异步的返回该表头的单元格对象。
示例代码
// 滚动到第2列的表头
await model.getTable('Table').showHeader(1);
// 滚动到ID列的表头
await model.getTable('Table').showHeader('ID');# 滚动到第2列的表头
model.getTable('Table').showHeader(1)
# 滚动到ID列的表头
model.getTable('Table').showHeader('ID')select(rowIndex, columnNameOrIndex)
点击目标单元格,并返回该单元格的TableCell对象,相比于下面的scrollTo()方法,这个方法多出了一个实际点击/选中单元格的操作。
参数
- rowIndex:
number类型,代表目标单元格的行位置索引,从0开始计算位置。 - columnNameOrIndex:
number类型或string类型,代表目标单元格的列位置索引(从0开始)或列名。
返回值
Promise<IWinTableCell>类型,异步的返回目标位置单元格的对象。
示例代码
// 选中第2行第3列的单元格
await model.getTable('Table').select(1, 2);
// 选中第2行ID列的单元格
await model.getTable('Table').select(1, 'ID');# 选中第2行第3列的单元格
model.getTable('Table').select(1, 2)
# 选中第2行ID列的单元格
model.getTable('Table').select(1, 'ID')scrollTo(rowIndex, columnNameOrIndex)
滚动到目标索引位置,并返回目标位置的单元格对象。如果目标位置还未加载,会一直加载到目标索引位置加载为止。
参数
- rowIndex:
number类型,代表目标单元格的行位置索引,从0开始计算位置。 - columnNameOrIndex:
number类型或string类型,代表目标单元格的列位置索引(从0开始)或列名。
返回值
Promise<IWinTableCell>类型,异步的返回目标位置单元格的对象。
示例代码
// 滚动到第2行第3列的单元格
await model.getTable('Table').scrollTo(1, 2);# 滚动到第2行第3列的单元格
model.getTable('Table').scrollTo(1, 2)scrollLeft()
滚动到表格最左侧。
返回值
- 不返回任何值的异步方法。
示例代码
// 滚动到表格最左侧
await model.getTable('Table').scrollLeft();# 滚动到表格最左侧
model.getTable('Table').scrollLeft()scrollToTop()
滚动到表格顶部。
返回值
- 不返回任何值的异步方法。
示例代码
// 滚动到表格顶部
await model.getTable('Table').scrollToTop();# 滚动到表格顶部
model.getTable('Table').scrollToTop()scrollToBottom()
滚动到表格底部。
返回值
- 不返回任何值的异步方法。
示例代码
// 滚动到表格底部
await model.getTable('Table').scrollToBottom();# 滚动到表格底部
model.getTable('Table').scrollToBottom()cellValue(rowIndex, columnNameOrIndex)
获取目标行列单元格的值,可以理解为setCellValue()方法相对的Getter方法。
参数
- rowIndex:
number类型,代表目标单元格的行位置索引,从0开始计算位置。 - columnNameOrIndex:
number类型或者string类型,代表目标单元格的列位置索引,从0开始计算位置;也可以传入表头中目标列的名字,比如"Name"、"ID"之类的。
返回值
Promise<string>类型,异步的返回string类型的结果,无论目标单元格内是什么内容。如果行列位置超出,或者传入的列名不存在,则会抛出1006: OutOfRange。
示例代码
// 获取第1行第2列的值
let value = await model.getTable('Table').cellValue(0, 1);
// 获取第1行 'Name' 列的值
await model.getTable('Table').cellValue(0, 'Name');# 获取第1行第2列的值
value = model.getTable('Table').cellValue(0, 1)
# 获取第1行 'Name' 列的值
model.getTable('Table').cellValue(0, 'Name')setCellValue(rowIndex, columnNameOrIndex, value)
编辑目标行列单元格的值,列位置也可以传入字符串,如果这么做,则会在表头中寻找相应的列位置。
参数
- rowIndex:
number类型,代表目标单元格的行位置索引,从0开始计算位置。 - columnNameOrIndex:
number类型或者string类型,代表目标单元格的列位置索引,从0开始计算位置;也可以传入表头中目标列的名字,比如"Name"、"ID"之类的。 - value:
string类型或number类型,期望的单元格值。
返回值
- 不返回任何值的异步方法。如果行列位置超出,或者传入的列名不存在,则会抛出
1006: OutOfRange。
示例代码
// 设置第1行第2列的值
await model.getTable('Table').setCellValue(0, 1, 'Hello World');
// 设置第1行 'Name' 列的值
await model.getTable('Table').setCellValue(0, 'Name', 'Hello World');# 设置第1行第2列的值
model.getTable('Table').setCellValue(0, 1, 'Hello World')
# 设置第1行 'Name' 列的值
model.getTable('Table').setCellValue(0, 'Name', 'Hello World')findItemInColumn(columnNameOrIndex, valueOrListener)
搜索目标列中符合条件的单元格。可以根据单元格名称来搜索,也可以使用测试函数callback来完成更复杂的查找。
参数
- columnNameOrIndex:
string类型或number类型,代表目标列的名称或索引。 - valueOrListener:
string类型或函数类型。如果传入的是字符串,则会自动的搜索与该字符串值相等的单元格。如果是函数,则会将当前列表项的值传入到函数中进行测试:- callback: 测试函数,用于测试输入的内容。
- value: 输入参数,
string类型,在表格中被调用时,会自动的往callback函数中传入当前单元格的值。 - 返回值: 测试函数运行的结果,
boolean类型,当返回值为false时会继续下一个测试;否则回调就会结束并退出。
- value: 输入参数,
- callback: 测试函数,用于测试输入的内容。
返回值
Promise<IWinTableCell>类型,异步的返回符合条件的单元格对象。
示例代码
// 在第2列中查找值为 'RossettiRae' 的单元格
await model.getTable("Table").findItemInColumn(1, 'RossettiRae');
// 在 'Name' 列中查找值为 'RossettiRae' 的单元格
await model.getTable("Table").findItemInColumn('Name', 'RossettiRae');# 在第2列中查找值为 'RossettiRae' 的单元格
model.getTable("Table").findItemInColumn(1, 'RossettiRae')
# 在 'Name' 列中查找值为 'RossettiRae' 的单元格
model.getTable("Table").findItemInColumn('Name', 'RossettiRae')columnName(index)
获取目标表头(列头)的值。
参数
- index:
number类型,代表列的索引,从0开始计算位置。
返回值
Promise<string>类型,异步的返回该表头的名称。
示例代码
// 获取第1列的列名
let name = await model.getTable('Table').columnName(0);
assert.equal(name, 'Name');# 获取第1列的列名
name = model.getTable('Table').columnName(0)
assert name == 'Name'columnHeaders()
获取表头的内容,并以字符串数组的形式返回。
返回值
Promise<string[]>类型,异步的返回string类型的数组,无论表头中是什么内容。
示例代码
// 获取所有列头
let headers = await model.getTable('Table').columnHeaders();
assert.deepEqual(JSON.stringify(headers), "['Name', 'ID', 'Age']");# 获取所有列头
headers = model.getTable('Table').columnHeaders()
assert headers == ['Name', 'ID', 'Age']columnCount()
获取所有表头的数量。数值等于columnHeaders()返回数组的长度。
返回值
Promise<number>类型,异步的返回表头的数量。
示例代码
// 获取列数
let count = await model.getTable('Table').columnCount();
assert.equal(count, 3);# 获取列数
count = model.getTable('Table').columnCount()
assert count == 3rowCount()
获取整个表的行数,会自动滚动到表格底部以加载全部数据。
返回值
Promise<number>类型,异步的返回表的行数。
示例代码
// 获取行数
let count = await model.getTable('Table').rowCount();
assert.equal(count, 100);# 获取行数
count = model.getTable('Table').rowCount()
assert count == 100row(rowIndex)
获取目标行的对象,返回目标行的TableRow对象。
参数
- rowIndex:
number类型,代表行的索引,从0开始计算位置。
返回值
Promise<TableRow>类型,异步的目标行的对象。
示例代码
// 获取第一行对象
let row = await model.getTable('Table').row(0);# 获取第一行对象
row = model.getTable('Table').row(0)rowData(rowIndex)
获取表格某一行中的所有内容,以字符串数组的形式返回。
参数
- rowIndex:
number类型,代表行的索引,从0开始计算位置。
返回值
Promise<string[]>类型,异步的返回string类型的数组,无论表头中是什么内容。
示例代码
// 获取第一行的数据
let row = await model.getTable('Table').rowData(0);
assert.deepEqual(JSON.stringify(row), "['RossettiRae', '1', '25']");# 获取第一行的数据
row = model.getTable('Table').rowData(0)
assert row == ['RossettiRae', '1', '25']表格行控件TableRow
用于描述表格中的行的控件,通常由识别,或者由Table对象的row()方法返回。由于提供了类似双向链表的前后表格行对象获取方法next()和previous(),在遍历数据时(比如遍历的获取每一行数据)能够发挥非常好的效果。
| 方法名 | 描述 |
|---|---|
| next | 获取相邻的下一个行控件。 |
| previous | 获取相邻的上一个行控件。 |
| cell | 获取行中的单元格控件。 |
| rowData | 获取行数据。 |
类型定义
export interface IWinTableRow {
next(): Promise<IWinTableRow>;
previous(): Promise<IWinTableRow>;
cell(index: number): Promise<IWinTableCell>;
rowData(): Promise<string[]>;
}class WinTableRow(WinControl):
def cell(index: int) -> "WinTableCell"
def rowData() -> List[str]
def scrollIntoView() -> None对象操作API
next()
获取相邻的下一个行控件,也就是下一行的TableRow对象。
返回值
Promise<TableRow>,异步的返回下一行的TableRow对象。
示例代码
// 获取当前行的下一行
let row = await model.getTable('Table').row(0);
await row.next();# 获取当前行的下一行
row = model.getTable('Table').row(0).next()previous()
获取相邻的上一个行控件,也就是上一行的TableRow对象。与next()方法正好相反。
返回值
Promise<TableRow>,异步的返回上一行的TableRow对象。
示例代码
// 获取当前行的上一行
let row = await model.getTable('Table').row(0);
await row.previous();# 获取当前行的上一行
row = model.getTable('Table').row(0).previous()cell(index)
获取当前行中指定索引的单元格。就像Table对象有获取行对象的row方法一样,TableRow对象也有获取单元格对象的cell方法。
参数
- index:
number类型,代表单元格的索引,从0开始计算位置。
返回值
Promise<TableCell>类型,异步的返回该单元格的对象。
示例代码
// 获取当前行的第一个单元格,并验证值
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
assert.equal(await cell.value(), 'RossettiRae');# 获取当前行的第一个单元格,并验证值
cell = model.getTable('Table').row(0).cell(0)
assert cell.value() == 'RossettiRae'rowData()
获取当前行的所有数据,并以字符串数组的形式返回。
返回值
Promise<string[]>,异步的返回行中的所有数据。
示例代码
// 获取当前行数据
let row = await model.getTable('Table').row(0);
assert.deepEqual(JSON.stringify(await row.rowData()), "['RossettiRae', '1', '25']");# 获取当前行数据
row = model.getTable('Table').row(0).rowData()
assert row == ['RossettiRae', '1', '25']单元格控件: TableCell
针对单元格控件的定义和方法。
| 方法名 | 描述 |
|---|---|
| value | 获取单元格的值。 |
| select | 选中目标单元格。并且会将目标单元格滚动到可视区域内。 |
| set | 设置单元格的值。 |
| row | 获取目标单元格所在行的对象。 |
| scrollIntoView | 将目标单元格滚动到可视区域内。 |
类型定义
export interface IWinTableCell {
value(): Promise<string>;
select(): Promise<void>;
set(value: string): Promise<void>;
row(): Promise<IWinTableRow>;
scrollIntoView(): Promise<void>;
}class WinTableCell(WinControl):
def value() -> str
def select() -> None
def set(value: str) -> None
def row() -> Union[WinTableRow, WinTreeItem]
def scrollIntoView() -> None对象操作API
下面是TableCell控件的对象方法。
select()
选中目标单元格。并且会将目标单元格滚动到可视区域内。
返回值
- 不返回任何值的异步方法。
示例代码
// 选中当前单元格
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
await cell.select();# 选中当前单元格
model.getTable('Table').row(0).cell(0).select()set(value)
直接修改单元格的值。
参数
- value:
string类型,期望的单元格值。
返回值
- 不返回任何值的异步方法。
示例代码
// 修改单元格的值
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
await cell.set('RossettiRae');# 修改单元格的值
model.getTable('Table').row(0).cell(0).set('RossettiRae')value()
获取单元格的值。
返回值
Promise<string>类型,目标单元格中的值。
示例代码
// 获取单元格的值
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
assert.equal(await cell.value(), 'RossettiRae');# 获取单元格的值
cell = model.getTable('Table').row(0).cell(0)
assert cell.value() == 'RossettiRae'row()
获取目标单元格所在行的对象,也就是它的父对象,返回所在行的TableRow对象。
返回值
Promise<TableRow>类型,异步的目标行的对象。
示例代码
// 获取单元格所在行
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
let rowAgain = await cell.row();# 获取单元格所在行
cell = model.getTable('Table').row(0).cell(0)
row = cell.row()scrollIntoView()
滚动到目标单元格位置。
返回值
- 不返回任何值的异步方法。
示例代码
// 滚动到单元格
let row = await model.getTable('Table').row(0);
let cell = await row.cell(0);
await cell.scrollIntoView();# 滚动到单元格
model.getTable('Table').row(0).cell(0).scrollIntoView()