mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
test: Refactor page objects and reuse locators (#19191)
This commit is contained in:
92
packages/testing/playwright/pages/components/LogsPanel.ts
Normal file
92
packages/testing/playwright/pages/components/LogsPanel.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import type { Locator } from '@playwright/test';
|
||||
|
||||
import { RunDataPanel } from './RunDataPanel';
|
||||
|
||||
/**
|
||||
* Page object for the log view with configurable root element.
|
||||
*
|
||||
* @example
|
||||
* // Include in a page
|
||||
* class ExamplePage {
|
||||
* readonly logsPanel = new LogsPanel(this.page.getByTestId('logs-panel'));
|
||||
* }
|
||||
*
|
||||
* // Usage in a test
|
||||
* await expect(n8n.example.logsPage.getLogEntries()).toHaveCount(2);
|
||||
*/
|
||||
export class LogsPanel {
|
||||
readonly inputPanel = new RunDataPanel(this.root.getByTestId('log-details-input'));
|
||||
readonly outputPanel = new RunDataPanel(this.root.getByTestId('log-details-output'));
|
||||
|
||||
constructor(private root: Locator) {}
|
||||
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
|
||||
getOverviewStatus(): Locator {
|
||||
return this.root.getByTestId('logs-overview-status');
|
||||
}
|
||||
|
||||
getClearExecutionButton(): Locator {
|
||||
return this.root
|
||||
.getByTestId('logs-overview-header')
|
||||
.locator('button')
|
||||
.filter({ hasText: 'Clear execution' });
|
||||
}
|
||||
|
||||
getLogEntries(): Locator {
|
||||
return this.root.getByTestId('logs-overview-body').getByRole('treeitem');
|
||||
}
|
||||
|
||||
getSelectedLogEntry(): Locator {
|
||||
return this.root.getByTestId('logs-overview-body').getByRole('treeitem', { selected: true });
|
||||
}
|
||||
|
||||
getManualChatModal(): Locator {
|
||||
return this.root.getByTestId('canvas-chat');
|
||||
}
|
||||
|
||||
getManualChatInput(): Locator {
|
||||
return this.getManualChatModal().locator('.chat-inputs textarea');
|
||||
}
|
||||
|
||||
getManualChatMessages(): Locator {
|
||||
return this.getManualChatModal().locator('.chat-messages-list .chat-message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions
|
||||
*/
|
||||
|
||||
async open(): Promise<void> {
|
||||
await this.root.getByTestId('logs-overview-header').click();
|
||||
}
|
||||
|
||||
async clickLogEntryAtRow(rowIndex: number): Promise<void> {
|
||||
await this.getLogEntries().nth(rowIndex).click();
|
||||
}
|
||||
|
||||
async toggleInputPanel(): Promise<void> {
|
||||
await this.root.getByTestId('log-details-header').getByText('Input').click();
|
||||
}
|
||||
|
||||
async clickOpenNdvAtRow(rowIndex: number): Promise<void> {
|
||||
await this.getLogEntries().nth(rowIndex).hover();
|
||||
await this.getLogEntries().nth(rowIndex).getByLabel('Open...').click();
|
||||
}
|
||||
|
||||
async clickTriggerPartialExecutionAtRow(rowIndex: number): Promise<void> {
|
||||
await this.getLogEntries().nth(rowIndex).hover();
|
||||
await this.getLogEntries().nth(rowIndex).getByLabel('Execute step').click();
|
||||
}
|
||||
|
||||
async clearExecutionData(): Promise<void> {
|
||||
await this.root.getByTestId('clear-execution-data-button').click();
|
||||
}
|
||||
|
||||
async sendManualChatMessage(message: string): Promise<void> {
|
||||
await this.getManualChatInput().fill(message);
|
||||
await this.getManualChatModal().locator('.chat-input-send-button').click();
|
||||
}
|
||||
}
|
||||
125
packages/testing/playwright/pages/components/RunDataPanel.ts
Normal file
125
packages/testing/playwright/pages/components/RunDataPanel.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
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');
|
||||
}
|
||||
|
||||
getDataContainer() {
|
||||
return this.root.getByTestId('ndv-data-container');
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
getTbodyCell(row: number, col: number) {
|
||||
return this.root.locator('table tbody tr').nth(row).locator('td').nth(col);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
getNodeInputOptions() {
|
||||
return this.root.getByTestId('ndv-input-select');
|
||||
}
|
||||
|
||||
getLinkRun() {
|
||||
return this.root.getByTestId('link-run');
|
||||
}
|
||||
|
||||
getNodeErrorMessageHeader(): Locator {
|
||||
return this.root.getByTestId('node-error-message');
|
||||
}
|
||||
|
||||
async toggleInputRunLinking() {
|
||||
await this.root.getByTestId('link-run').click();
|
||||
}
|
||||
|
||||
async switchDisplayMode(mode: 'table' | 'ai' | 'json' | 'schema' | 'binary'): Promise<void> {
|
||||
await this.root.getByTestId(`radio-button-${mode}`).click();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user