多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

188 lines
6.0 KiB

import BasePage from '../../Base';
import { GridPage } from './index';
import { RowPageObject } from './Row';
import { expect } from '@playwright/test';
import { DashboardPage } from '../index';
import { CellPageObject } from '../common/Cell';
export class GroupPageObject extends BasePage {
readonly grid: GridPage;
readonly rows: RowPageObject;
readonly cell: CellPageObject;
readonly dashboard: DashboardPage;
constructor(grid: GridPage) {
super(grid.rootPage);
this.grid = grid;
this.rows = new RowPageObject(grid);
this.cell = new CellPageObject(grid);
this.dashboard = grid.dashboard;
}
get({ indexMap }: { indexMap: Array<number> }) {
let query = '';
for (const n of indexMap) {
query = query + `.nc-group:nth-child(${n + 1}) `;
}
return this.rootPage.locator(query);
}
async openGroup({ indexMap }: { indexMap: number[] }) {
await this.rootPage.waitForTimeout(500);
let root = this.rootPage.locator('.nc-group');
for (const n of indexMap) {
await root.nth(n).click();
root = root.nth(n).locator('.nc-group');
}
await this.rootPage.waitForTimeout(500);
}
async verifyGroupHeader({ indexMap, count, title }: { indexMap: number[]; count: number; title: string }) {
const groupWrapper = this.get({ indexMap });
await expect(groupWrapper.locator('.nc-group-column-title')).toHaveText(title);
await expect(groupWrapper.locator('.nc-group-row-count')).toHaveText(`(Count: ${count})`);
}
async verifyPagination({ indexMap, count }: { indexMap: number[]; count: number }) {
const groupWrapper = this.get({ indexMap });
await expect(groupWrapper.locator('.nc-grid-row-count').first()).toHaveText(`${count} record`);
}
async verifyGroup({ indexMap, value }: { indexMap: number[]; value: string }) {
let query = '';
for (const n of indexMap) {
query += ` .nc-group:nth-child(${n + 1})`;
}
const groupWrapper = this.get({ indexMap });
await expect(groupWrapper.locator('.nc-group-value').first()).toHaveText(value);
await expect(this.rootPage.locator(`${query} .nc-group-value`).first()).toHaveText(value);
}
async verifyRow({ indexMap, rowIndex }: { indexMap: number[]; rowIndex: number }) {
const gridWrapper = this.get({ indexMap });
await gridWrapper.locator(`td[data-testid="cell-Title-${rowIndex}"]`).waitFor({ state: 'visible' });
await expect(gridWrapper.locator(`td[data-testid="cell-Title-${rowIndex}"]`)).toHaveCount(1);
}
async validateFirstRow({
indexMap,
rowIndex,
columnHeader,
value,
}: {
indexMap: number[];
rowIndex: number;
columnHeader: string;
value: string;
}) {
const gridWrapper = this.get({ indexMap });
await gridWrapper.scrollIntoViewIfNeeded();
await gridWrapper.locator('.nc-group-table').waitFor({ state: 'visible' });
await gridWrapper.locator(`.nc-group-table .nc-grid-row:nth-child(${rowIndex + 1})`).waitFor({ state: 'visible' });
await gridWrapper
.locator(`.nc-group-table .nc-grid-row:nth-child(${rowIndex + 1}) [data-title="${columnHeader}"]`)
.scrollIntoViewIfNeeded();
await expect(
gridWrapper.locator(`.nc-group-table .nc-grid-row:nth-child(${rowIndex + 1}) [data-title="${columnHeader}"]`)
).toHaveText(value);
}
async addNewRow({
indexMap,
index = 0,
columnHeader = 'Title',
value,
}: {
indexMap: number[];
index?: number;
columnHeader?: string;
value?: string;
}) {
const rowValue = value ?? `Row ${index}`;
// wait for render to complete before count
if (index !== 0) await this.get({ indexMap }).locator('.nc-grid-row').nth(0).waitFor({ state: 'attached' });
const addNewRowBtn = this.get({ indexMap }).locator('.nc-grid-add-new-row');
await addNewRowBtn.scrollIntoViewIfNeeded();
await (await addNewRowBtn.elementHandle()).waitForElementState('stable');
await this.rootPage.waitForTimeout(200);
await this.rootPage.waitForLoadState('networkidle');
await this.rootPage.waitForTimeout(200);
await this.rootPage.waitForLoadState('domcontentloaded');
await this.get({ indexMap }).locator('.nc-grid-add-new-row').click();
const rowCount = index + 1;
const isRowSaving = this.get({ indexMap }).getByTestId(`row-save-spinner-${rowCount}`);
// if required field is present then isRowSaving will be hidden (not present in DOM)
await isRowSaving?.waitFor({ state: 'hidden' });
// fallback
await this.rootPage.waitForTimeout(400);
await expect(this.get({ indexMap }).locator('.nc-grid-row')).toHaveCount(rowCount);
await this._fillRow({ indexMap, index, columnHeader, value: rowValue });
await this.dashboard.waitForLoaderToDisappear();
}
async deleteRow({ title, indexMap, rowIndex = 0 }: { title: string; indexMap: number[]; rowIndex?: number }) {
await this.get({ indexMap }).getByTestId(`cell-${title}-${rowIndex}`).click({
button: 'right',
});
// Click text=Delete Row
await this.rootPage.locator('.ant-dropdown-menu-item:has-text("Delete record")').click();
// todo: improve selector
await this.rootPage
.locator('span.ant-dropdown-menu-title-content > nc-base-menu-item')
.waitFor({ state: 'hidden' });
await this.rootPage.waitForTimeout(300);
await this.dashboard.waitForLoaderToDisappear();
}
async editRow({
indexMap,
rowIndex = 0,
columnHeader = 'Title',
value,
}: {
indexMap: number[];
rowIndex?: number;
columnHeader?: string;
value: string;
}) {
await this._fillRow({ indexMap, index: rowIndex, columnHeader, value });
await this.dashboard.waitForLoaderToDisappear();
}
private async _fillRow({
indexMap,
index,
columnHeader,
value,
}: {
indexMap: number[];
index: number;
columnHeader: string;
value: string;
}) {
const cell = this.cell.get({ indexMap, index, columnHeader });
await cell.waitFor({ state: 'visible' });
await this.cell.dblclick({
index,
columnHeader,
});
await cell.locator('input').fill(value);
}
}