mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
test: Migrate NPS from Cypress -> Playwright (#18535)
This commit is contained in:
@@ -423,4 +423,15 @@ export class CanvasPage extends BasePage {
|
||||
await this.canvasPane().focus();
|
||||
await this.page.keyboard.press(keyMap[direction]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit the workflow page with a specific timestamp for NPS survey testing.
|
||||
* Uses Playwright's clock API to set a fixed time.
|
||||
*/
|
||||
async visitWithTimestamp(timestamp: number): Promise<void> {
|
||||
// Set fixed time using Playwright's clock API
|
||||
await this.page.clock.setFixedTime(timestamp);
|
||||
|
||||
await this.page.goto('/workflow/new');
|
||||
}
|
||||
}
|
||||
|
||||
57
packages/testing/playwright/pages/NpsSurveyPage.ts
Normal file
57
packages/testing/playwright/pages/NpsSurveyPage.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import type { Locator, Page } from '@playwright/test';
|
||||
|
||||
import { BasePage } from './BasePage';
|
||||
|
||||
export class NpsSurveyPage extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
getNpsSurveyModal(): Locator {
|
||||
return this.page.getByTestId('nps-survey-modal');
|
||||
}
|
||||
|
||||
getNpsSurveyRatings(): Locator {
|
||||
return this.page.getByTestId('nps-survey-ratings');
|
||||
}
|
||||
|
||||
getNpsSurveyFeedback(): Locator {
|
||||
return this.page.getByTestId('nps-survey-feedback');
|
||||
}
|
||||
|
||||
getNpsSurveySubmitButton(): Locator {
|
||||
return this.page.getByTestId('nps-survey-feedback-button');
|
||||
}
|
||||
|
||||
getNpsSurveyCloseButton(): Locator {
|
||||
return this.getNpsSurveyModal().locator('button.el-drawer__close-btn');
|
||||
}
|
||||
|
||||
getRatingButton(rating: number): Locator {
|
||||
return this.getNpsSurveyRatings().locator('button').nth(rating);
|
||||
}
|
||||
|
||||
getFeedbackTextarea(): Locator {
|
||||
return this.getNpsSurveyFeedback().locator('textarea');
|
||||
}
|
||||
|
||||
async clickRating(rating: number): Promise<void> {
|
||||
await this.getRatingButton(rating).click();
|
||||
}
|
||||
|
||||
async fillFeedback(feedback: string): Promise<void> {
|
||||
await this.getFeedbackTextarea().fill(feedback);
|
||||
}
|
||||
|
||||
async clickSubmitButton(): Promise<void> {
|
||||
await this.getNpsSurveySubmitButton().click();
|
||||
}
|
||||
|
||||
async closeSurvey(): Promise<void> {
|
||||
await this.getNpsSurveyCloseButton().click();
|
||||
}
|
||||
|
||||
async getRatingButtonCount(): Promise<number> {
|
||||
return await this.getNpsSurveyRatings().locator('button').count();
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { ExecutionsPage } from './ExecutionsPage';
|
||||
import { IframePage } from './IframePage';
|
||||
import { NodeDisplayViewPage } from './NodeDisplayViewPage';
|
||||
import { NotificationsPage } from './NotificationsPage';
|
||||
import { NpsSurveyPage } from './NpsSurveyPage';
|
||||
import { ProjectSettingsPage } from './ProjectSettingsPage';
|
||||
import { SettingsPage } from './SettingsPage';
|
||||
import { SidebarPage } from './SidebarPage';
|
||||
@@ -31,6 +32,7 @@ export class n8nPage {
|
||||
|
||||
readonly iframe: IframePage;
|
||||
readonly ndv: NodeDisplayViewPage;
|
||||
readonly npsSurvey: NpsSurveyPage;
|
||||
readonly projectSettings: ProjectSettingsPage;
|
||||
readonly settings: SettingsPage;
|
||||
readonly versions: VersionsPage;
|
||||
@@ -60,6 +62,7 @@ export class n8nPage {
|
||||
|
||||
this.iframe = new IframePage(page);
|
||||
this.ndv = new NodeDisplayViewPage(page);
|
||||
this.npsSurvey = new NpsSurveyPage(page);
|
||||
this.projectSettings = new ProjectSettingsPage(page);
|
||||
this.settings = new SettingsPage(page);
|
||||
this.versions = new VersionsPage(page);
|
||||
|
||||
144
packages/testing/playwright/tests/ui/42-nps-survey.spec.ts
Normal file
144
packages/testing/playwright/tests/ui/42-nps-survey.spec.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { test, expect } from '../../fixtures/base';
|
||||
import type { TestRequirements } from '../../Types';
|
||||
|
||||
const NOW = Date.now();
|
||||
const ONE_DAY = 24 * 60 * 60 * 1000;
|
||||
const THREE_DAYS = ONE_DAY * 3;
|
||||
const SEVEN_DAYS = ONE_DAY * 7;
|
||||
const ABOUT_SIX_MONTHS = ONE_DAY * 30 * 6 + ONE_DAY;
|
||||
|
||||
const ACTIVATED_USER_SETTINGS = {
|
||||
userActivated: true,
|
||||
userActivatedAt: NOW - THREE_DAYS - 1000,
|
||||
};
|
||||
|
||||
const getNpsTestRequirements: TestRequirements = {
|
||||
config: {
|
||||
settings: {
|
||||
telemetry: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
intercepts: {
|
||||
npsSurveyApi: {
|
||||
url: '**/rest/user-settings/nps-survey',
|
||||
response: { success: true },
|
||||
},
|
||||
telemetryTest: {
|
||||
url: '**/test/telemetry',
|
||||
response: { status: 'ok' },
|
||||
},
|
||||
telemetryProxy: {
|
||||
url: '**/rest/telemetry/proxy',
|
||||
response: { status: 'ok' },
|
||||
},
|
||||
telemetryRudderstack: {
|
||||
url: '**/rest/telemetry/rudderstack',
|
||||
response: { status: 'ok' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
test.describe('NPS Survey', () => {
|
||||
test.beforeEach(async ({ n8n }) => {
|
||||
await n8n.page.route('**/rest/login', async (route) => {
|
||||
const response = await route.fetch();
|
||||
const originalJson = await response.json();
|
||||
|
||||
const modifiedData = {
|
||||
...originalJson,
|
||||
data: {
|
||||
...originalJson.data,
|
||||
settings: {
|
||||
...originalJson.data?.settings,
|
||||
...ACTIVATED_USER_SETTINGS,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
await route.fulfill({
|
||||
status: response.status(),
|
||||
headers: response.headers(),
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(modifiedData),
|
||||
});
|
||||
});
|
||||
|
||||
await n8n.goHome();
|
||||
});
|
||||
|
||||
test('shows nps survey to recently activated user and can submit feedback', async ({
|
||||
n8n,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await setupRequirements(getNpsTestRequirements);
|
||||
await n8n.canvas.visitWithTimestamp(NOW);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
expect(await n8n.npsSurvey.getRatingButtonCount()).toBe(11);
|
||||
|
||||
await n8n.npsSurvey.clickRating(0);
|
||||
await n8n.npsSurvey.fillFeedback('n8n is the best');
|
||||
await n8n.npsSurvey.clickSubmitButton();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + ONE_DAY);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + ABOUT_SIX_MONTHS);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
});
|
||||
|
||||
test('allows user to ignore survey 3 times before stopping to show until 6 months later', async ({
|
||||
n8n,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await setupRequirements(getNpsTestRequirements);
|
||||
await n8n.canvas.visitWithTimestamp(NOW);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await n8n.notifications.quickCloseAll();
|
||||
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
await n8n.npsSurvey.closeSurvey();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + ONE_DAY);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + SEVEN_DAYS + 10000);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await n8n.notifications.quickCloseAll();
|
||||
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
await n8n.npsSurvey.closeSurvey();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + SEVEN_DAYS + 10000);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + (SEVEN_DAYS + 10000) * 2 + ONE_DAY);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await n8n.notifications.quickCloseAll();
|
||||
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
await n8n.npsSurvey.closeSurvey();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + (SEVEN_DAYS + 10000) * 2 + ONE_DAY * 2);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + (SEVEN_DAYS + 10000) * 3 + ONE_DAY * 3);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeHidden();
|
||||
|
||||
await n8n.canvas.visitWithTimestamp(NOW + (SEVEN_DAYS + 10000) * 3 + ABOUT_SIX_MONTHS);
|
||||
await n8n.canvas.clickSaveWorkflowButton();
|
||||
await expect(n8n.npsSurvey.getNpsSurveyModal()).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user