mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
test: Migrate sticky test from Cypress -> Playwright (#19185)
This commit is contained in:
56
packages/testing/playwright/migration.md
Normal file
56
packages/testing/playwright/migration.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Cypress to Playwright Migration Guide
|
||||
|
||||
## Migration Process
|
||||
|
||||
### 1. Review Original Test
|
||||
- Examine the Cypress test file to understand what functionality it's testing
|
||||
- Note the test structure, assertions, and user interactions
|
||||
- Identify any special setup or teardown requirements
|
||||
|
||||
### 2. Scaffold New Test
|
||||
- Create Playwright test file with exact same test names as Cypress
|
||||
- Add commented descriptions of what each test is trying to achieve
|
||||
- Keep the same test structure and organization
|
||||
|
||||
### 3. Analyze Dependencies
|
||||
- Review what page models, composables, and helpers the Cypress test uses
|
||||
- Check existing Playwright infrastructure in `composables/`, `helpers/`, `pages/`
|
||||
- Identify which components are already available vs need to be created
|
||||
|
||||
### 4. Study Building Blocks
|
||||
- Review existing Playwright tests to understand correct patterns
|
||||
- Check how similar functionality is implemented in other migrated tests
|
||||
- Follow established conventions for page objects and test structure
|
||||
|
||||
### 5. Plan Migration Approach
|
||||
- Determine the best strategy for translating Cypress commands to Playwright
|
||||
- Plan any new page objects or helpers needed
|
||||
- Consider test data requirements and setup
|
||||
|
||||
### 6. Execute Migration
|
||||
- Migrate tests one at a time
|
||||
- Maintain original test intent and coverage
|
||||
- Follow Playwright best practices and n8n conventions
|
||||
|
||||
### 7. Verify Results
|
||||
- Test using `pnpm test:local --grep "test-name" --reporter=line`
|
||||
- Ensure all assertions pass and behavior matches original
|
||||
- Validate test runs reliably and consistently
|
||||
|
||||
## Key Differences: Cypress vs Playwright
|
||||
|
||||
- **Selectors**: Cypress uses `cy.get()` → Playwright uses `page.locator()`
|
||||
- **Assertions**: Cypress auto-waits → Playwright uses `expect()` with built-in waiting
|
||||
- **Page Navigation**: `cy.visit()` → `page.goto()`
|
||||
- **Element Interaction**: `cy.click()` → `locator.click()`
|
||||
- **Text Content**: `cy.contains()` → `expect(locator).toContainText()`
|
||||
|
||||
## Testing Commands
|
||||
|
||||
```bash
|
||||
# Run specific test with grep
|
||||
pnpm --filter n8n-playwright test:local --grep "test-name" --reporter=line
|
||||
|
||||
# Run full test suite in directory
|
||||
pnpm --filter n8n-playwright test:local --reporter=line
|
||||
```
|
||||
@@ -4,8 +4,11 @@ import { nanoid } from 'nanoid';
|
||||
import { BasePage } from './BasePage';
|
||||
import { ROUTES } from '../config/constants';
|
||||
import { resolveFromRoot } from '../utils/path-helper';
|
||||
import { StickyComponent } from './components/StickyComponent';
|
||||
|
||||
export class CanvasPage extends BasePage {
|
||||
readonly sticky = new StickyComponent(this.page);
|
||||
|
||||
saveWorkflowButton(): Locator {
|
||||
return this.page.getByRole('button', { name: 'Save' });
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { Locator, Page } from '@playwright/test';
|
||||
|
||||
import { BasePage } from '../BasePage';
|
||||
|
||||
/**
|
||||
* Sticky note component for canvas interactions.
|
||||
* Used within CanvasPage as `n8n.canvas.sticky.*`
|
||||
*
|
||||
* @example
|
||||
* // Access via canvas page
|
||||
* await n8n.canvas.sticky.addSticky();
|
||||
* await expect(n8n.canvas.sticky.getStickies()).toHaveCount(1);
|
||||
*/
|
||||
export class StickyComponent extends BasePage {
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
getAddButton(): Locator {
|
||||
return this.page.getByTestId('add-sticky-button');
|
||||
}
|
||||
|
||||
getStickies(): Locator {
|
||||
return this.page.getByTestId('sticky');
|
||||
}
|
||||
|
||||
getStickyByIndex(index: number): Locator {
|
||||
return this.getStickies().nth(index);
|
||||
}
|
||||
|
||||
async addSticky(): Promise<void> {
|
||||
await this.getAddButton().click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sticky from the context menu, targets top left corner of canvas, so could fail if it's covered
|
||||
* @param canvasPane - The canvas pane locator
|
||||
*/
|
||||
async addFromContextMenu(canvasPane: Locator): Promise<void> {
|
||||
await canvasPane.click({
|
||||
button: 'right',
|
||||
position: { x: 10, y: 10 },
|
||||
});
|
||||
await this.page.getByText('Add sticky note').click();
|
||||
}
|
||||
|
||||
getDefaultStickyGuideLink(): Locator {
|
||||
return this.getStickies().first().getByRole('link', { name: 'Guide' });
|
||||
}
|
||||
}
|
||||
29
packages/testing/playwright/tests/ui/25-stickies.spec.ts
Normal file
29
packages/testing/playwright/tests/ui/25-stickies.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { test, expect } from '../../fixtures/base';
|
||||
|
||||
test.describe('Canvas Actions', () => {
|
||||
test('adds sticky to canvas with default text and position', async ({ n8n }) => {
|
||||
await n8n.start.fromBlankCanvas();
|
||||
await expect(n8n.canvas.sticky.getAddButton()).toBeVisible();
|
||||
|
||||
await n8n.canvas.sticky.addSticky();
|
||||
|
||||
const firstSticky = n8n.canvas.sticky.getStickies().first();
|
||||
await expect(firstSticky).toHaveCSS('height', '160px');
|
||||
await expect(firstSticky).toHaveCSS('width', '240px');
|
||||
|
||||
await n8n.canvas.deselectAll();
|
||||
await n8n.canvas.sticky.addFromContextMenu(n8n.canvas.canvasPane());
|
||||
await n8n.page.keyboard.press('Shift+s');
|
||||
|
||||
await expect(n8n.canvas.sticky.getStickies()).toHaveCount(3);
|
||||
|
||||
await n8n.page.keyboard.press('ControlOrMeta+Shift+s');
|
||||
await expect(n8n.canvas.sticky.getStickies()).toHaveCount(3);
|
||||
|
||||
await expect(n8n.canvas.sticky.getStickies().first()).toHaveText(
|
||||
'I’m a note\nDouble click to edit me. Guide\n',
|
||||
);
|
||||
const guideLink = n8n.canvas.sticky.getDefaultStickyGuideLink();
|
||||
await expect(guideLink).toHaveAttribute('href');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user