- 添加项目配置文件和环境变量设置 - 创建测试用例目录结构和命名规范 - 实现基础测试 fixture 和页面对象模型 - 添加示例测试用例和数据生成器 - 配置 playwright 和 gitignore 文件
209 lines
6.4 KiB
TypeScript
209 lines
6.4 KiB
TypeScript
import { type Locator, type Page } from 'playwright';
|
|
|
|
export class TablePage {
|
|
page: Page;
|
|
private readonly _$headerTable: Locator;
|
|
private readonly _$bodyTable: Locator;
|
|
private readonly _$fixedLeftTable: Locator;
|
|
private readonly _$fixedRightTable: Locator;
|
|
private readonly _$$bodyTrTable: Locator;
|
|
|
|
/**
|
|
* Initializes a new instance of the TablePage class.
|
|
*
|
|
* @param page - The Playwright Page object used to interact with the table elements on the page.
|
|
*/
|
|
constructor(page: Page) {
|
|
this.page = page;
|
|
this._$headerTable = page.locator('.m-table__header-wrapper');
|
|
this._$bodyTable = page.locator('.m-table__body-wrapper');
|
|
this._$fixedLeftTable = page.locator('.m-table__fixed-left');
|
|
this._$fixedRightTable = page.locator('.m-table__fixed-right');
|
|
this._$$bodyTrTable = this._$bodyTable.locator('.main-table-body_tr');
|
|
}
|
|
|
|
get fixedRightTable() {
|
|
return this._$fixedRightTable;
|
|
}
|
|
|
|
get fixedLeftTable() {
|
|
return this._$fixedLeftTable;
|
|
}
|
|
|
|
get bodyTable() {
|
|
return this._$bodyTable;
|
|
}
|
|
|
|
get bodyTrTable() {
|
|
return this._$$bodyTrTable;
|
|
}
|
|
|
|
get headerTable() {
|
|
return this._$headerTable;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param text
|
|
* @param options
|
|
* @returns
|
|
*/
|
|
getFirstHeaderTableIndex = async (text: string, options?: { repeat: number }) => {
|
|
const $tr = this._$headerTable.locator('tr').first();
|
|
const $$th = $tr.locator('th');
|
|
await $$th.first().waitFor();
|
|
const firstHeaderText = await $$th.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(firstHeaderText, text, options.repeat);
|
|
}
|
|
|
|
return firstHeaderText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param text
|
|
* @param options
|
|
* @returns
|
|
*/
|
|
getSecondHeaderTableIndex = async (text: string, options?: { repeat: number }) => {
|
|
const $tr = this._$headerTable.locator('tr').nth(1);
|
|
const $$th = $tr.locator('th');
|
|
await $$th.first().waitFor();
|
|
const secondHeaderText = await $$th.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(secondHeaderText, text, options.repeat);
|
|
}
|
|
|
|
return secondHeaderText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param text
|
|
* @param options
|
|
* @returns
|
|
*/
|
|
getLeftTableHeaderIndex = async (text: string, options?: { repeat: number }) => {
|
|
const $tr = this._$fixedLeftTable.locator('.m-table-fixed-header').locator('thead tr').first();
|
|
const $$th = $tr.locator('th');
|
|
await $$th.first().waitFor();
|
|
const leftTableHeaderText = await $$th.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(leftTableHeaderText, text, options.repeat);
|
|
}
|
|
|
|
return leftTableHeaderText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
* 异步获取左侧固定列中指定文本的行索引
|
|
* 此函数用于在页面中,根据文本内容查找对应的行索引
|
|
* 它首先定位到左侧固定列的<tbody>元素,然后遍历<tr>元素,等待第一个<tr>元素出现,
|
|
* 获取所有<tr>元素的文本内容,最后返回包含指定文本的行索引
|
|
* 如果未找到匹配的文本,返回-1
|
|
* @param text
|
|
* @param index getLeftTableHeaderIndex
|
|
* @returns
|
|
*/
|
|
getLeftTableBodyIndex = async (text: string, index: number, options?: { repeat: number }) => {
|
|
const $$tr = this._$fixedLeftTable.locator('.m-table-fixed-body').locator('tbody tr');
|
|
const $$td = $$tr.locator(`td:nth-child(${index + 1})`);
|
|
await $$td.first().waitFor();
|
|
const leftTableBodyTdText = await $$td.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(leftTableBodyTdText, text, options.repeat);
|
|
}
|
|
|
|
return leftTableBodyTdText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param text
|
|
* @param options
|
|
* @returns
|
|
*/
|
|
getRightTableHeaderIndex = async (text: string, options?: { repeat: number }) => {
|
|
const $tr = this._$fixedRightTable.locator('.m-table-fixed-header').locator('thead tr').first();
|
|
const $$th = $tr.locator('th');
|
|
await $$th.first().waitFor();
|
|
const rightTableHeaderText = await $$th.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(rightTableHeaderText, text, options.repeat);
|
|
}
|
|
|
|
return rightTableHeaderText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param text
|
|
* @param index
|
|
* @param options
|
|
* @returns
|
|
*/
|
|
getRightTableBodyIndex = async (text: string, index: number, options?: { repeat: number }) => {
|
|
const $$tr = this._$fixedRightTable.locator('.m-table-fixed-body').locator('tbody tr');
|
|
const $$td = $$tr.locator(`tr:nth-child(${index})`);
|
|
await $$td.first().waitFor();
|
|
const rightTableBodyTdText = await $$td.allInnerTexts();
|
|
|
|
if (options?.repeat) {
|
|
return this.findNthIndex(rightTableBodyTdText, text, options.repeat);
|
|
}
|
|
|
|
return rightTableBodyTdText.findIndex(item => item === text);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param keywords
|
|
* @returns
|
|
*/
|
|
getBodyTableIndex = async (keywords: string[]) => {
|
|
const $$tr = this._$bodyTable.locator('tbody tr');
|
|
await $$tr.first().waitFor();
|
|
|
|
const textArrayCount = await $$tr.count();
|
|
for (let i = 0; i < textArrayCount; i++) {
|
|
const temp = await $$tr.nth(i).locator('td').allInnerTexts();
|
|
|
|
const allInnerTexts = keywords.every(text => temp.includes(text));
|
|
|
|
if (allInnerTexts) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
/**
|
|
* 在数组中查找第n个指定值的索引
|
|
* @param arr 要查找的字符串数组
|
|
* @param value 要查找的值
|
|
* @param n 第几次出现该值
|
|
* @returns 找到的索引,未找到则返回-1
|
|
*/
|
|
private findNthIndex(arr: string[], value: string, n: number) {
|
|
let count = 0;
|
|
let result = -1;
|
|
|
|
arr.some((item, index) => {
|
|
if (item === value) count++;
|
|
if (count === n) {
|
|
result = index;
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
return result;
|
|
}
|
|
}
|