mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
test: Migrate 3 specs from Cypress - Playwright (#19269)
This commit is contained in:
@@ -76,6 +76,10 @@ export class CanvasPage extends BasePage {
|
||||
await this.nodeCreatorItemByName(text).click();
|
||||
}
|
||||
|
||||
async clickAddToWorkflowButton(): Promise<void> {
|
||||
await this.page.getByText('Add to workflow').click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a node to the canvas with flexible options
|
||||
* @param nodeName - The name of the node to search for and add
|
||||
|
||||
121
packages/testing/playwright/pages/CommunityNodesPage.ts
Normal file
121
packages/testing/playwright/pages/CommunityNodesPage.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import type { Locator } from '@playwright/test';
|
||||
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class CommunityNodesPage extends BasePage {
|
||||
// Element getters
|
||||
getCommunityCards(): Locator {
|
||||
return this.page.getByTestId('community-package-card');
|
||||
}
|
||||
|
||||
getActionBox(): Locator {
|
||||
return this.page.getByTestId('action-box');
|
||||
}
|
||||
|
||||
getInstallButton(): Locator {
|
||||
// Try action box first (empty state), fallback to header install button
|
||||
const actionBoxButton = this.getActionBox().locator('button');
|
||||
const headerInstallButton = this.page.getByRole('button', { name: 'Install' });
|
||||
|
||||
return actionBoxButton.or(headerInstallButton);
|
||||
}
|
||||
|
||||
getInstallModal(): Locator {
|
||||
return this.page.getByTestId('communityPackageInstall-modal');
|
||||
}
|
||||
|
||||
getConfirmModal(): Locator {
|
||||
return this.page.getByTestId('communityPackageManageConfirm-modal');
|
||||
}
|
||||
|
||||
getPackageNameInput(): Locator {
|
||||
return this.getInstallModal().locator('input').first();
|
||||
}
|
||||
|
||||
getUserAgreementCheckbox(): Locator {
|
||||
return this.page.getByTestId('user-agreement-checkbox');
|
||||
}
|
||||
|
||||
getInstallPackageButton(): Locator {
|
||||
return this.page.getByTestId('install-community-package-button');
|
||||
}
|
||||
|
||||
getActionToggle(): Locator {
|
||||
return this.page.getByTestId('action-toggle');
|
||||
}
|
||||
|
||||
getUninstallAction(): Locator {
|
||||
return this.page.getByTestId('action-uninstall');
|
||||
}
|
||||
|
||||
getUpdateButton(): Locator {
|
||||
return this.getCommunityCards().first().locator('button');
|
||||
}
|
||||
|
||||
getConfirmUpdateButton(): Locator {
|
||||
return this.getConfirmModal().getByRole('button', { name: 'Confirm update' });
|
||||
}
|
||||
|
||||
getConfirmUninstallButton(): Locator {
|
||||
return this.getConfirmModal().getByRole('button', { name: 'Confirm uninstall' });
|
||||
}
|
||||
|
||||
// Simple actions
|
||||
async clickInstallButton(): Promise<void> {
|
||||
await this.getInstallButton().click();
|
||||
}
|
||||
|
||||
async fillPackageName(packageName: string): Promise<void> {
|
||||
await this.getPackageNameInput().fill(packageName);
|
||||
}
|
||||
|
||||
async clickUserAgreementCheckbox(): Promise<void> {
|
||||
await this.getUserAgreementCheckbox().click();
|
||||
}
|
||||
|
||||
async clickInstallPackageButton(): Promise<void> {
|
||||
await this.getInstallPackageButton().click();
|
||||
}
|
||||
|
||||
async clickActionToggle(): Promise<void> {
|
||||
await this.getActionToggle().click();
|
||||
}
|
||||
|
||||
async clickUninstallAction(): Promise<void> {
|
||||
await this.getUninstallAction().click();
|
||||
}
|
||||
|
||||
async clickUpdateButton(): Promise<void> {
|
||||
await this.getUpdateButton().click();
|
||||
}
|
||||
|
||||
async clickConfirmUpdate(): Promise<void> {
|
||||
await this.getConfirmUpdateButton().click();
|
||||
}
|
||||
|
||||
async clickConfirmUninstall(): Promise<void> {
|
||||
await this.getConfirmUninstallButton().click();
|
||||
}
|
||||
|
||||
// Helper methods for common workflows
|
||||
async installPackage(packageName: string): Promise<void> {
|
||||
await this.clickInstallButton();
|
||||
await this.fillPackageName(packageName);
|
||||
await this.clickUserAgreementCheckbox();
|
||||
await this.clickInstallPackageButton();
|
||||
|
||||
// Wait for install modal to close
|
||||
await this.getInstallModal().waitFor({ state: 'hidden' });
|
||||
}
|
||||
|
||||
async updatePackage(): Promise<void> {
|
||||
await this.clickUpdateButton();
|
||||
await this.clickConfirmUpdate();
|
||||
}
|
||||
|
||||
async uninstallPackage(): Promise<void> {
|
||||
await this.clickActionToggle();
|
||||
await this.clickUninstallAction();
|
||||
await this.clickConfirmUninstall();
|
||||
}
|
||||
}
|
||||
@@ -725,4 +725,7 @@ export class NodeDetailsViewPage extends BasePage {
|
||||
getInputSelect() {
|
||||
return this.page.getByTestId('ndv-input-select').locator('input');
|
||||
}
|
||||
getCredentialLabel(credentialType: string) {
|
||||
return this.page.getByText(credentialType);
|
||||
}
|
||||
}
|
||||
|
||||
96
packages/testing/playwright/pages/VariablesPage.ts
Normal file
96
packages/testing/playwright/pages/VariablesPage.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { expect, type Locator } from '@playwright/test';
|
||||
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class VariablesPage extends BasePage {
|
||||
getUnavailableResourcesList() {
|
||||
return this.page.getByTestId('unavailable-resources-list');
|
||||
}
|
||||
|
||||
getResourcesList() {
|
||||
return this.page.getByTestId('resources-list');
|
||||
}
|
||||
|
||||
getEmptyResourcesList() {
|
||||
return this.page.getByTestId('empty-resources-list');
|
||||
}
|
||||
|
||||
getEmptyResourcesListNewVariableButton() {
|
||||
return this.getEmptyResourcesList().locator('button');
|
||||
}
|
||||
|
||||
getSearchBar() {
|
||||
return this.page.getByTestId('resources-list-search');
|
||||
}
|
||||
|
||||
getCreateVariableButton() {
|
||||
return this.page.getByTestId('resources-list-add');
|
||||
}
|
||||
|
||||
getVariablesRows() {
|
||||
return this.page.getByTestId('variables-row');
|
||||
}
|
||||
|
||||
getVariablesEditableRows() {
|
||||
return this.page.getByTestId('variables-row').filter({ has: this.page.locator('input') });
|
||||
}
|
||||
|
||||
getVariableRow(key: string) {
|
||||
return this.getVariablesRows().filter({ hasText: key });
|
||||
}
|
||||
|
||||
getEditableRowCancelButton(row: Locator) {
|
||||
return row.getByTestId('variable-row-cancel-button');
|
||||
}
|
||||
|
||||
getEditableRowSaveButton(row: Locator) {
|
||||
return row.getByTestId('variable-row-save-button');
|
||||
}
|
||||
|
||||
async createVariable(key: string, value: string) {
|
||||
await this.getCreateVariableButton().click();
|
||||
|
||||
const editingRow = this.getVariablesEditableRows().first();
|
||||
await this.setRowValue(editingRow, 'key', key);
|
||||
await this.setRowValue(editingRow, 'value', value);
|
||||
await this.saveRowEditing(editingRow);
|
||||
}
|
||||
|
||||
async createVariableFromEmptyState(key: string, value: string) {
|
||||
await this.getEmptyResourcesListNewVariableButton().click();
|
||||
|
||||
const editingRow = this.getVariablesEditableRows().first();
|
||||
await this.setRowValue(editingRow, 'key', key);
|
||||
await this.setRowValue(editingRow, 'value', value);
|
||||
await this.saveRowEditing(editingRow);
|
||||
}
|
||||
|
||||
async deleteVariable(key: string) {
|
||||
const row = this.getVariableRow(key);
|
||||
await row.getByTestId('variable-row-delete-button').click();
|
||||
|
||||
// Use a more specific selector to avoid strict mode violation with other dialogs
|
||||
const modal = this.page.getByRole('dialog').filter({ hasText: 'Delete variable' });
|
||||
await expect(modal).toBeVisible();
|
||||
await modal.locator('.btn--confirm').click();
|
||||
}
|
||||
|
||||
async editRow(key: string) {
|
||||
const row = this.getVariableRow(key);
|
||||
await row.getByTestId('variable-row-edit-button').click();
|
||||
}
|
||||
|
||||
async setRowValue(row: Locator, field: 'key' | 'value', value: string) {
|
||||
const input = row.getByTestId(`variable-row-${field}-input`).locator('input, textarea');
|
||||
await input.selectText();
|
||||
await input.fill(value);
|
||||
}
|
||||
|
||||
async saveRowEditing(row: Locator) {
|
||||
await this.getEditableRowSaveButton(row).click();
|
||||
}
|
||||
|
||||
async cancelRowEditing(row: Locator) {
|
||||
await this.getEditableRowCancelButton(row).click();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import type { Page } from '@playwright/test';
|
||||
import { AIAssistantPage } from './AIAssistantPage';
|
||||
import { BecomeCreatorCTAPage } from './BecomeCreatorCTAPage';
|
||||
import { CanvasPage } from './CanvasPage';
|
||||
import { CommunityNodesPage } from './CommunityNodesPage';
|
||||
import { CredentialsPage } from './CredentialsPage';
|
||||
import { DemoPage } from './DemoPage';
|
||||
import { ExecutionsPage } from './ExecutionsPage';
|
||||
@@ -14,6 +15,7 @@ import { NpsSurveyPage } from './NpsSurveyPage';
|
||||
import { ProjectSettingsPage } from './ProjectSettingsPage';
|
||||
import { SettingsPage } from './SettingsPage';
|
||||
import { SidebarPage } from './SidebarPage';
|
||||
import { VariablesPage } from './VariablesPage';
|
||||
import { VersionsPage } from './VersionsPage';
|
||||
import { WorkerViewPage } from './WorkerViewPage';
|
||||
import { WorkflowActivationModal } from './WorkflowActivationModal';
|
||||
@@ -24,6 +26,7 @@ import { CanvasComposer } from '../composables/CanvasComposer';
|
||||
import { ProjectComposer } from '../composables/ProjectComposer';
|
||||
import { TestEntryComposer } from '../composables/TestEntryComposer';
|
||||
import { WorkflowComposer } from '../composables/WorkflowComposer';
|
||||
import { NavigationHelper } from '../helpers/NavigationHelper';
|
||||
import type { ApiHelpers } from '../services/api-helper';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
@@ -35,6 +38,7 @@ export class n8nPage {
|
||||
readonly aiAssistant: AIAssistantPage;
|
||||
readonly becomeCreatorCTA: BecomeCreatorCTAPage;
|
||||
readonly canvas: CanvasPage;
|
||||
readonly communityNodes: CommunityNodesPage;
|
||||
readonly demo: DemoPage;
|
||||
readonly iframe: IframePage;
|
||||
readonly interactions: InteractionsPage;
|
||||
@@ -42,6 +46,7 @@ export class n8nPage {
|
||||
readonly npsSurvey: NpsSurveyPage;
|
||||
readonly projectSettings: ProjectSettingsPage;
|
||||
readonly settings: SettingsPage;
|
||||
readonly variables: VariablesPage;
|
||||
readonly versions: VersionsPage;
|
||||
readonly workerView: WorkerViewPage;
|
||||
readonly workflows: WorkflowsPage;
|
||||
@@ -61,6 +66,9 @@ export class n8nPage {
|
||||
readonly canvasComposer: CanvasComposer;
|
||||
readonly start: TestEntryComposer;
|
||||
|
||||
// Helpers
|
||||
readonly navigate: NavigationHelper;
|
||||
|
||||
constructor(page: Page, api: ApiHelpers) {
|
||||
this.page = page;
|
||||
this.api = api;
|
||||
@@ -69,6 +77,7 @@ export class n8nPage {
|
||||
this.aiAssistant = new AIAssistantPage(page);
|
||||
this.becomeCreatorCTA = new BecomeCreatorCTAPage(page);
|
||||
this.canvas = new CanvasPage(page);
|
||||
this.communityNodes = new CommunityNodesPage(page);
|
||||
this.demo = new DemoPage(page);
|
||||
this.iframe = new IframePage(page);
|
||||
this.interactions = new InteractionsPage(page);
|
||||
@@ -76,6 +85,7 @@ export class n8nPage {
|
||||
this.npsSurvey = new NpsSurveyPage(page);
|
||||
this.projectSettings = new ProjectSettingsPage(page);
|
||||
this.settings = new SettingsPage(page);
|
||||
this.variables = new VariablesPage(page);
|
||||
this.versions = new VersionsPage(page);
|
||||
this.workerView = new WorkerViewPage(page);
|
||||
this.workflows = new WorkflowsPage(page);
|
||||
@@ -94,6 +104,9 @@ export class n8nPage {
|
||||
this.projectComposer = new ProjectComposer(this);
|
||||
this.canvasComposer = new CanvasComposer(this);
|
||||
this.start = new TestEntryComposer(this);
|
||||
|
||||
// Helpers
|
||||
this.navigate = new NavigationHelper(page);
|
||||
}
|
||||
|
||||
async goHome() {
|
||||
|
||||
Reference in New Issue
Block a user