import type { Locator } from '@playwright/test'; /** * Page object for the run data view with configurable root element. * * @example * // Include in a page * class ExamplePage { * readonly runDataPanel = new RunDataPanel(this.page.getByTestId('run-data')); * } * * // Usage in a test * await n8n.example.runDataPanel.getRunSelector().click(); */ export class RunDataPanel { constructor(private root: Locator) {} get() { return this.root; } getRunSelector() { return this.root.getByTestId('run-selector'); } getRunSelectorInput() { return this.root.locator('[data-test-id="run-selector"] input'); } getItemsCount() { return this.root.getByTestId('ndv-items-count'); } getSearchInput() { return this.root.getByTestId('ndv-search'); } getSearchContainer() { return this.root.getByTestId('ndv-search-container'); } getDataContainer() { return this.root.getByTestId('ndv-data-container'); } getPagination() { return this.root.getByTestId('ndv-data-pagination'); } getPaginationPages() { return this.getPagination().locator('li'); } getHighlightMarks() { return this.getDataContainer().locator('mark'); } getBranchTab(name: string | RegExp) { return this.root.getByText(name); } getItemsCountText(text: string | RegExp) { return this.getItemsCount().filter({ hasText: text }); } getActiveDisplayMode() { return this.root.locator('[class*="active"]'); } getPinDataButton() { return this.root.getByTestId('ndv-pin-data'); } getTable() { return this.root.locator('table'); } getTableHeaders() { return this.root.locator('table th'); } getTableHeader(index: number) { return this.root.locator('table th').nth(index); } getTableRows() { return this.root.locator('tr'); } getTableRow(index: number) { return this.root.locator('tr').nth(index); } getTableRowHighlights(index: number) { return this.getTableRow(index).locator('mark'); } getTableCellByText(text: string) { return this.getTable().locator(`text=${text}`); } getTbodyCell(row: number, col: number) { return this.root.locator('table tbody tr').nth(row).locator('td').nth(col); } getTbodyCellLink(row: number, col: number) { return this.getTbodyCell(row, col).locator('a'); } getTableCellSpan(row: number, col: number, dataName: string) { return this.getTbodyCell(row, col).locator(`span[data-name="${dataName}"]`).first(); } getJsonDataContainer() { return this.root.locator('.json-data'); } getJsonProperty(propertyName: string) { return this.root .locator('.json-data') .locator('span') .filter({ hasText: new RegExp(`^"${propertyName}"$`) }) .first(); } getJsonPropertyContaining(text: string) { return this.root .locator('.json-data') .locator('span') .filter({ hasText: `"${text}"` }) .first(); } getSchemaItems() { return this.root.getByTestId('run-data-schema-item'); } getSchemaItem(text: string) { return this.getSchemaItems().filter({ hasText: text }).first(); } getSchemaItemText(text: string) { return this.getSchemaItems().locator('span').filter({ hasText: text }).first(); } getSchemaItemToggle(text: string) { return this.getSchemaItem(text).locator('.toggle'); } getSchemaItemPill(text: string) { return this.getSchemaItemText(text).locator('span'); } getNodeInputOptions() { return this.root.getByTestId('ndv-input-select'); } getLinkRun() { return this.root.getByTestId('link-run'); } getRelatedExecutionLink() { return this.root.getByTestId('related-execution-link'); } getHoveringItems() { return this.root.getByTestId('hovering-item'); } getNodeErrorMessageHeader(): Locator { return this.root.getByTestId('node-error-message'); } getErrorMessage(): Locator { return this.getNodeErrorMessageHeader().first(); } async toggleInputRunLinking() { await this.root.getByTestId('link-run').click(); } getNoInputDataMessage() { return this.root.getByText('No input data'); } getContentEditableEditor() { return this.root.locator('[contenteditable="true"]'); } getFirstLink() { return this.root.locator('a').first(); } async switchDisplayMode(mode: 'table' | 'ai' | 'json' | 'schema' | 'binary'): Promise { await this.root.getByTestId(`radio-button-${mode}`).click(); } }