115 lines
4.3 KiB
TypeScript
115 lines
4.3 KiB
TypeScript
|
|
import { test, expect } from '../../fixtures/base';
|
|||
|
|
import type { n8nPage } from '../../pages/n8nPage';
|
|||
|
|
|
|||
|
|
// Example of using helper functions inside a test
|
|||
|
|
test.describe('Debug mode', () => {
|
|||
|
|
// Constants to avoid magic strings
|
|||
|
|
const URLS = {
|
|||
|
|
FAILING: 'https://foo.bar',
|
|||
|
|
SUCCESS: 'https://postman-echo.com/get?foo1=bar1&foo2=bar2',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const NOTIFICATIONS = {
|
|||
|
|
WORKFLOW_CREATED: 'Workflow successfully created',
|
|||
|
|
EXECUTION_IMPORTED: 'Execution data imported',
|
|||
|
|
PROBLEM_IN_NODE: 'Problem in node',
|
|||
|
|
SUCCESSFUL: 'Successful',
|
|||
|
|
DATA_NOT_IMPORTED: "Some execution data wasn't imported",
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
test.beforeEach(async ({ api, n8n }) => {
|
|||
|
|
await api.enableFeature('debugInEditor');
|
|||
|
|
await n8n.goHome();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Helper function to create basic workflow
|
|||
|
|
async function createBasicWorkflow(n8n: n8nPage, url = URLS.FAILING) {
|
|||
|
|
await n8n.workflows.clickAddWorkflowButton();
|
|||
|
|
await n8n.canvas.addNode('Manual Trigger');
|
|||
|
|
await n8n.canvas.addNode('HTTP Request');
|
|||
|
|
await n8n.ndv.fillParameterInput('URL', url);
|
|||
|
|
await n8n.ndv.close();
|
|||
|
|
await n8n.canvas.clickSaveWorkflowButton();
|
|||
|
|
await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.WORKFLOW_CREATED);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Helper function to import execution for debugging
|
|||
|
|
async function importExecutionForDebugging(n8n: n8nPage) {
|
|||
|
|
await n8n.canvas.clickExecutionsTab();
|
|||
|
|
await n8n.executions.clickDebugInEditorButton();
|
|||
|
|
await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.EXECUTION_IMPORTED);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
test('should enter debug mode for failed executions', async ({ n8n }) => {
|
|||
|
|
await createBasicWorkflow(n8n, URLS.FAILING);
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.PROBLEM_IN_NODE);
|
|||
|
|
await importExecutionForDebugging(n8n);
|
|||
|
|
expect(n8n.page.url()).toContain('/debug');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('should exit debug mode after successful execution', async ({ n8n }) => {
|
|||
|
|
await createBasicWorkflow(n8n, URLS.FAILING);
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.PROBLEM_IN_NODE);
|
|||
|
|
await importExecutionForDebugging(n8n);
|
|||
|
|
|
|||
|
|
await n8n.canvas.openNode('HTTP Request');
|
|||
|
|
await n8n.ndv.fillParameterInput('URL', URLS.SUCCESS);
|
|||
|
|
await n8n.ndv.close();
|
|||
|
|
await n8n.canvas.clickSaveWorkflowButton();
|
|||
|
|
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL);
|
|||
|
|
expect(n8n.page.url()).not.toContain('/debug');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('should handle pinned data conflicts during execution import', async ({ n8n }) => {
|
|||
|
|
await createBasicWorkflow(n8n, URLS.SUCCESS);
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL);
|
|||
|
|
await n8n.canvasComposer.pinNodeData('HTTP Request');
|
|||
|
|
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification('Successful');
|
|||
|
|
|
|||
|
|
// Go to executions and try to copy execution to editor
|
|||
|
|
await n8n.canvas.clickExecutionsTab();
|
|||
|
|
await n8n.executions.clickLastExecutionItem();
|
|||
|
|
await n8n.executions.clickCopyToEditorButton();
|
|||
|
|
|
|||
|
|
// Test CANCEL dialog
|
|||
|
|
await n8n.executions.handlePinnedNodesConfirmation('Cancel');
|
|||
|
|
|
|||
|
|
// Try again and CONFIRM
|
|||
|
|
await n8n.executions.clickLastExecutionItem();
|
|||
|
|
await n8n.executions.clickCopyToEditorButton();
|
|||
|
|
await n8n.executions.handlePinnedNodesConfirmation('Unpin');
|
|||
|
|
|
|||
|
|
expect(n8n.page.url()).toContain('/debug');
|
|||
|
|
|
|||
|
|
// Verify pinned status
|
|||
|
|
const pinnedNodeNames = await n8n.canvas.getPinnedNodeNames();
|
|||
|
|
expect(pinnedNodeNames).not.toContain('HTTP Request');
|
|||
|
|
expect(pinnedNodeNames).toContain('When clicking ‘Execute workflow’');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
test('should show error for pinned data mismatch', async ({ n8n }) => {
|
|||
|
|
// Create workflow, execute, and pin data
|
|||
|
|
await createBasicWorkflow(n8n, URLS.SUCCESS);
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL);
|
|||
|
|
|
|||
|
|
await n8n.canvasComposer.pinNodeData('HTTP Request');
|
|||
|
|
await n8n.workflowComposer.executeWorkflowAndWaitForNotification(NOTIFICATIONS.SUCCESSFUL);
|
|||
|
|
|
|||
|
|
// Delete node to create mismatch
|
|||
|
|
await n8n.canvas.deleteNodeByName('HTTP Request');
|
|||
|
|
|
|||
|
|
// Try to copy execution and verify error
|
|||
|
|
await attemptCopyToEditor(n8n);
|
|||
|
|
await n8n.notifications.waitForNotificationAndClose(NOTIFICATIONS.DATA_NOT_IMPORTED);
|
|||
|
|
expect(n8n.page.url()).toContain('/debug');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
async function attemptCopyToEditor(n8n: n8nPage) {
|
|||
|
|
await n8n.canvas.clickExecutionsTab();
|
|||
|
|
await n8n.executions.clickLastExecutionItem();
|
|||
|
|
await n8n.executions.clickCopyToEditorButton();
|
|||
|
|
}
|
|||
|
|
});
|