mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-27 06:45:26 +02:00
test: Migrate cloud tests from cypress to playwright (#19925)
This commit is contained in:
parent
fd63f37e9a
commit
abfde2a334
|
|
@ -1,124 +0,0 @@
|
|||
import { overrideFeatureFlag } from '../../composables/featureFlags';
|
||||
import { expandSidebar } from '../../composables/sidebar';
|
||||
import planData from '../../fixtures/Plan_data_opt_in_trial.json';
|
||||
import {
|
||||
MainSidebar,
|
||||
WorkflowPage,
|
||||
visitPublicApiPage,
|
||||
getPublicApiUpgradeCTA,
|
||||
WorkflowsPage,
|
||||
} from '../../pages';
|
||||
|
||||
const NUMBER_OF_AI_CREDITS = 100;
|
||||
|
||||
const mainSidebar = new MainSidebar();
|
||||
const workflowPage = new WorkflowPage();
|
||||
const workflowsPage = new WorkflowsPage();
|
||||
|
||||
describe('Cloud', () => {
|
||||
before(() => {
|
||||
const now = new Date();
|
||||
const fiveDaysFromNow = new Date(now.getTime() + 5 * 24 * 60 * 60 * 1000);
|
||||
planData.expirationDate = fiveDaysFromNow.toJSON();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.overrideSettings({
|
||||
deployment: { type: 'cloud' },
|
||||
n8nMetadata: { userId: '1' },
|
||||
aiCredits: {
|
||||
enabled: true,
|
||||
credits: NUMBER_OF_AI_CREDITS,
|
||||
},
|
||||
});
|
||||
cy.intercept('GET', '/rest/admin/cloud-plan', planData).as('getPlanData');
|
||||
cy.intercept('GET', '/rest/cloud/proxy/user/me', {}).as('getCloudUserInfo');
|
||||
cy.intercept('GET', new RegExp('/rest/projects*')).as('projects');
|
||||
cy.intercept('GET', new RegExp('/rest/roles')).as('roles');
|
||||
});
|
||||
|
||||
function visitWorkflowPage() {
|
||||
cy.visit(workflowPage.url);
|
||||
cy.wait('@getPlanData');
|
||||
cy.wait('@projects');
|
||||
cy.wait('@roles');
|
||||
}
|
||||
|
||||
describe('BannerStack', () => {
|
||||
it('should not render trial banner on first visit', () => {
|
||||
// Clear localStorage to simulate first visit
|
||||
cy.clearLocalStorage();
|
||||
|
||||
visitWorkflowPage();
|
||||
|
||||
cy.getByTestId('banner-stack').should('not.be.visible');
|
||||
});
|
||||
|
||||
it('should render trial banner on subsequent visits', () => {
|
||||
// Set visit count to simulate returning user
|
||||
cy.window().then((win) => {
|
||||
win.localStorage.setItem('n8n-trial-visit-count', '1');
|
||||
});
|
||||
|
||||
visitWorkflowPage();
|
||||
expandSidebar();
|
||||
|
||||
cy.getByTestId('banner-stack').should('be.visible');
|
||||
|
||||
mainSidebar.actions.signout();
|
||||
|
||||
cy.getByTestId('banner-stack').should('not.be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Admin Home', () => {
|
||||
it('Should show admin button', () => {
|
||||
visitWorkflowPage();
|
||||
expandSidebar();
|
||||
|
||||
mainSidebar.getters.adminPanel().should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Public API', () => {
|
||||
it('Should show upgrade CTA for Public API if user is trialing', () => {
|
||||
visitPublicApiPage();
|
||||
cy.wait(['@loadSettings', '@projects', '@roles', '@getPlanData']);
|
||||
|
||||
getPublicApiUpgradeCTA().should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Easy AI workflow experiment', () => {
|
||||
it('should not show option to take you to the easy AI workflow if experiment is control', () => {
|
||||
overrideFeatureFlag('026_easy_ai_workflow', 'control');
|
||||
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
cy.getByTestId('easy-ai-workflow-card').should('not.exist');
|
||||
});
|
||||
|
||||
it('should show option to take you to the easy AI workflow if experiment is variant', () => {
|
||||
overrideFeatureFlag('026_easy_ai_workflow', 'variant');
|
||||
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
cy.getByTestId('easy-ai-workflow-card').should('to.exist');
|
||||
});
|
||||
|
||||
it('should show default instructions if free AI credits experiment is control', () => {
|
||||
overrideFeatureFlag('026_easy_ai_workflow', 'variant');
|
||||
|
||||
cy.visit(workflowsPage.url);
|
||||
|
||||
cy.getByTestId('easy-ai-workflow-card').click();
|
||||
|
||||
workflowPage.getters
|
||||
.stickies()
|
||||
.eq(0)
|
||||
.should(($el) => {
|
||||
expect($el).contains.text('Start by saying');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
28
packages/testing/playwright/fixtures/plan-data-trial.json
Normal file
28
packages/testing/playwright/fixtures/plan-data-trial.json
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"id": 200,
|
||||
"planId": 1,
|
||||
"pruneExecutionsInterval": 168,
|
||||
"monthlyExecutionsLimit": 1000,
|
||||
"activeWorkflowsLimit": 20,
|
||||
"credentialsLimit": 100,
|
||||
"supportTier": "community",
|
||||
"displayName": "Trial",
|
||||
"enabledFeatures": ["userManagement", "advancedExecutionFilters", "sharing"],
|
||||
"licenseFeatures": {
|
||||
"feat:sharing": true,
|
||||
"feat:advancedExecutionFilters": true,
|
||||
"quota:users": -1,
|
||||
"quota:maxVariables": -1,
|
||||
"feat:variables": true
|
||||
},
|
||||
"metadata": {
|
||||
"version": "v1",
|
||||
"group": "trial",
|
||||
"slug": "trial-2",
|
||||
"trial": {
|
||||
"length": 14,
|
||||
"gracePeriod": 3
|
||||
}
|
||||
},
|
||||
"expirationDate": "2023-08-30T15:47:27.611Z"
|
||||
}
|
||||
|
|
@ -124,4 +124,8 @@ export class SettingsPage extends BasePage {
|
|||
await this.getMfaCodeOrRecoveryCodeInput().fill(code);
|
||||
await this.getMfaSaveButton().click();
|
||||
}
|
||||
|
||||
getUpgradeCta(): Locator {
|
||||
return this.page.getByTestId('public-api-upgrade-cta');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,6 +56,14 @@ export class SidebarPage {
|
|||
return this.page.getByTestId('user-menu-item-logout');
|
||||
}
|
||||
|
||||
getAdminPanel(): Locator {
|
||||
return this.page.getByRole('menuitem', { name: 'Admin Panel' });
|
||||
}
|
||||
|
||||
getTrialBanner(): Locator {
|
||||
return this.page.getByTestId('banners-TRIAL');
|
||||
}
|
||||
|
||||
async openUserMenu(): Promise<void> {
|
||||
await this.getUserMenu().click();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ export class WorkflowsPage extends BasePage {
|
|||
return this.page.getByTestId('new-workflow-card');
|
||||
}
|
||||
|
||||
getEasyAiWorkflowCard() {
|
||||
return this.page.getByTestId('easy-ai-workflow-card');
|
||||
}
|
||||
|
||||
async clickEasyAiWorkflowCard() {
|
||||
await this.clickByTestId('easy-ai-workflow-card');
|
||||
}
|
||||
|
||||
async clearSearch() {
|
||||
await this.clickByTestId('resources-list-search');
|
||||
await this.page.getByTestId('resources-list-search').clear();
|
||||
|
|
|
|||
141
packages/testing/playwright/tests/ui/27-cloud.spec.ts
Normal file
141
packages/testing/playwright/tests/ui/27-cloud.spec.ts
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
import { test, expect } from '../../fixtures/base';
|
||||
import basePlanData from '../../fixtures/plan-data-trial.json';
|
||||
import type { n8nPage } from '../../pages/n8nPage';
|
||||
import type { TestRequirements } from '../../Types';
|
||||
|
||||
const fiveDaysFromNow = new Date(Date.now() + 5 * 24 * 60 * 60 * 1000);
|
||||
const planData = { ...basePlanData, expirationDate: fiveDaysFromNow.toJSON() };
|
||||
|
||||
const cloudTrialRequirements = {
|
||||
config: {
|
||||
settings: {
|
||||
deployment: { type: 'cloud' },
|
||||
n8nMetadata: { userId: '1' },
|
||||
aiCredits: {
|
||||
enabled: true,
|
||||
credits: 100,
|
||||
},
|
||||
banners: {
|
||||
dismissed: ['V1'], // Prevent V1 banner interference
|
||||
},
|
||||
},
|
||||
},
|
||||
intercepts: {
|
||||
'cloud-plan': {
|
||||
url: '**/rest/admin/cloud-plan',
|
||||
response: planData,
|
||||
},
|
||||
'cloud-user': {
|
||||
url: '**/rest/cloud/proxy/user/me',
|
||||
response: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const firstVisitRequirements: TestRequirements = {
|
||||
...cloudTrialRequirements,
|
||||
};
|
||||
|
||||
const subsequentVisitRequirements: TestRequirements = {
|
||||
...cloudTrialRequirements,
|
||||
storage: {
|
||||
'n8n-trial-visit-count': '1',
|
||||
},
|
||||
};
|
||||
|
||||
const setupCloudTest = async (
|
||||
n8n: n8nPage,
|
||||
setupRequirements: (requirements: TestRequirements) => Promise<void>,
|
||||
requirements: TestRequirements,
|
||||
) => {
|
||||
await setupRequirements(requirements);
|
||||
await n8n.page.waitForLoadState();
|
||||
};
|
||||
|
||||
test.describe('Cloud @db:reset @auth:owner', () => {
|
||||
test.describe('Trial Banner', () => {
|
||||
test('should not render trial banner on first visit', async ({ n8n, setupRequirements }) => {
|
||||
await setupCloudTest(n8n, setupRequirements, firstVisitRequirements);
|
||||
await n8n.start.fromBlankCanvas();
|
||||
await expect(n8n.sideBar.getTrialBanner()).toBeHidden();
|
||||
});
|
||||
|
||||
test('should render trial banner on subsequent visits', async ({ n8n, setupRequirements }) => {
|
||||
await setupCloudTest(n8n, setupRequirements, subsequentVisitRequirements);
|
||||
await n8n.start.fromBlankCanvas();
|
||||
await n8n.sideBar.expand();
|
||||
|
||||
await expect(n8n.sideBar.getTrialBanner()).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Admin Home', () => {
|
||||
test('should show admin button', async ({ n8n, setupRequirements }) => {
|
||||
await setupCloudTest(n8n, setupRequirements, cloudTrialRequirements);
|
||||
await n8n.start.fromBlankCanvas();
|
||||
await n8n.sideBar.expand();
|
||||
|
||||
await expect(n8n.sideBar.getAdminPanel()).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Public API', () => {
|
||||
test('should show upgrade CTA for Public API if user is trialing', async ({
|
||||
n8n,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await setupCloudTest(n8n, setupRequirements, cloudTrialRequirements);
|
||||
await n8n.navigate.toApiSettings();
|
||||
|
||||
await n8n.page.waitForLoadState();
|
||||
|
||||
await expect(n8n.settings.getUpgradeCta()).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Easy AI workflow experiment', () => {
|
||||
test('should not show option to take you to the easy AI workflow if experiment is control', async ({
|
||||
n8n,
|
||||
api,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await api.setEnvFeatureFlags({ '026_easy_ai_workflow': 'control' });
|
||||
|
||||
await setupCloudTest(n8n, setupRequirements, cloudTrialRequirements);
|
||||
await n8n.navigate.toWorkflows();
|
||||
|
||||
await expect(n8n.workflows.getEasyAiWorkflowCard()).toBeHidden();
|
||||
});
|
||||
|
||||
test('should show option to take you to the easy AI workflow if experiment is variant', async ({
|
||||
n8n,
|
||||
api,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await api.setEnvFeatureFlags({ '026_easy_ai_workflow': 'variant' });
|
||||
|
||||
await setupCloudTest(n8n, setupRequirements, cloudTrialRequirements);
|
||||
await n8n.navigate.toWorkflows();
|
||||
|
||||
await expect(n8n.workflows.getEasyAiWorkflowCard()).toBeVisible();
|
||||
});
|
||||
|
||||
test('should show default instructions if free AI credits experiment is control', async ({
|
||||
n8n,
|
||||
api,
|
||||
setupRequirements,
|
||||
}) => {
|
||||
await api.setEnvFeatureFlags({ '026_easy_ai_workflow': 'variant' });
|
||||
|
||||
await setupCloudTest(n8n, setupRequirements, cloudTrialRequirements);
|
||||
await n8n.navigate.toWorkflows();
|
||||
|
||||
await n8n.workflows.clickEasyAiWorkflowCard();
|
||||
|
||||
await n8n.page.waitForLoadState();
|
||||
|
||||
const firstSticky = n8n.canvas.sticky.getStickies().first();
|
||||
await expect(firstSticky).toContainText('Start by saying');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user