test: Ignore fixme tests in distribution script (#24068)

This commit is contained in:
Declan Carroll
2026-01-09 09:51:02 +00:00
committed by GitHub
parent 4879db8f43
commit 86c593dc3c
32 changed files with 632 additions and 573 deletions
+344 -344
View File
@@ -1,27 +1,27 @@
{
"updatedAt": "2026-01-07T15:01:28.087Z",
"updatedAt": "2026-01-09T07:59:21.296Z",
"source": "currents",
"projectId": "I0yzoc",
"specs": {
"tests/e2e/workflows/list/workflows.spec.ts": {
"avgDuration": 116976,
"testCount": 9,
"flakyRate": 0.0064
"avgDuration": 84066,
"testCount": 8,
"flakyRate": 0.0067
},
"tests/e2e/workflows/templates/templates.spec.ts": {
"avgDuration": 20348,
"avgDuration": 26010,
"testCount": 9,
"flakyRate": 0.0013
"flakyRate": 0.0003
},
"tests/e2e/workflows/editor/tags.spec.ts": {
"avgDuration": 38264,
"avgDuration": 40311,
"testCount": 7,
"flakyRate": 0.0011
"flakyRate": 0.0003
},
"tests/e2e/chat-hub/chat-hub-workflow-agent.spec.ts": {
"avgDuration": 33470,
"avgDuration": 34349,
"testCount": 2,
"flakyRate": 0.0515
"flakyRate": 0.0597
},
"tests/e2e/workflows/editor/workflow-actions/settings.spec.ts": {
"avgDuration": 60000,
@@ -29,9 +29,9 @@
"flakyRate": 0
},
"tests/e2e/workflows/editor/subworkflows/workflow-selector.spec.ts": {
"avgDuration": 27294,
"avgDuration": 27472,
"testCount": 5,
"flakyRate": 0.0011
"flakyRate": 0.0009
},
"tests/e2e/workflows/editor/workflow-actions/save.spec.ts": {
"avgDuration": 60000,
@@ -44,19 +44,19 @@
"flakyRate": 0
},
"tests/e2e/workflows/editor/workflow-actions/publish.spec.ts": {
"avgDuration": 22021,
"testCount": 8,
"avgDuration": 60000,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/workflows/checklist/production-checklist.spec.ts": {
"avgDuration": 28284,
"testCount": 7,
"flakyRate": 0.001
"avgDuration": 35265,
"testCount": 8,
"flakyRate": 0
},
"tests/e2e/workflows/executions/list.spec.ts": {
"avgDuration": 72832,
"testCount": 11,
"flakyRate": 0.0097
"avgDuration": 98412,
"testCount": 12,
"flakyRate": 0.0234
},
"tests/e2e/workflows/editor/workflow-actions/duplicate.spec.ts": {
"avgDuration": 60000,
@@ -69,9 +69,9 @@
"flakyRate": 0
},
"tests/e2e/ai/workflow-builder.spec.ts": {
"avgDuration": 35981,
"testCount": 5,
"flakyRate": 0.0147
"avgDuration": 49525,
"testCount": 6,
"flakyRate": 0.031
},
"tests/e2e/workflows/editor/workflow-actions/archive.spec.ts": {
"avgDuration": 60000,
@@ -79,289 +79,289 @@
"flakyRate": 0
},
"tests/e2e/settings/workers/workers.spec.ts": {
"avgDuration": 5849,
"avgDuration": 7519,
"testCount": 4,
"flakyRate": 0.0008
"flakyRate": 0
},
"tests/e2e/nodes/webhook.spec.ts": {
"avgDuration": 62761,
"avgDuration": 73447,
"testCount": 9,
"flakyRate": 0.0021
"flakyRate": 0.001
},
"tests/e2e/api/webhook-isolation.spec.ts": {
"avgDuration": 14289,
"avgDuration": 45310,
"testCount": 14,
"flakyRate": 0.0004
},
"tests/e2e/app-config/versions.spec.ts": {
"avgDuration": 9988,
"testCount": 2,
"flakyRate": 0.0011
},
"tests/e2e/settings/environments/variables.spec.ts": {
"avgDuration": 16339,
"testCount": 7,
"flakyRate": 0.0002
},
"tests/e2e/settings/users/users.spec.ts": {
"avgDuration": 13201,
"testCount": 4,
"flakyRate": 0.0117
},
"tests/e2e/building-blocks/user-service.spec.ts": {
"avgDuration": 6708,
"testCount": 4,
"flakyRate": 0.0004
},
"tests/e2e/workflows/editor/canvas/undo-redo.spec.ts": {
"avgDuration": 69974,
"testCount": 14,
"flakyRate": 0.0139
},
"tests/e2e/building-blocks/workflow-entry-points.spec.ts": {
"avgDuration": 14437,
"testCount": 5,
"flakyRate": 0.0004
},
"tests/e2e/chat-hub/chat-hub-tools.spec.ts": {
"avgDuration": 7488,
"tests/e2e/app-config/versions.spec.ts": {
"avgDuration": 15770,
"testCount": 1,
"flakyRate": 0.0043
},
"tests/e2e/capabilities/task-runner.spec.ts": {
"avgDuration": 83257,
"tests/e2e/settings/environments/variables.spec.ts": {
"avgDuration": 19134,
"testCount": 7,
"flakyRate": 0
},
"tests/e2e/settings/users/users.spec.ts": {
"avgDuration": 15152,
"testCount": 5,
"flakyRate": 0.0991
"flakyRate": 0.0004
},
"tests/e2e/building-blocks/user-service.spec.ts": {
"avgDuration": 8125,
"testCount": 4,
"flakyRate": 0
},
"tests/e2e/workflows/editor/canvas/undo-redo.spec.ts": {
"avgDuration": 78769,
"testCount": 14,
"flakyRate": 0.0003
},
"tests/e2e/building-blocks/workflow-entry-points.spec.ts": {
"avgDuration": 16894,
"testCount": 5,
"flakyRate": 0
},
"tests/e2e/chat-hub/chat-hub-tools.spec.ts": {
"avgDuration": 7170,
"testCount": 1,
"flakyRate": 0.0045
},
"tests/e2e/capabilities/task-runner.spec.ts": {
"avgDuration": 72137,
"testCount": 4,
"flakyRate": 0.0053
},
"tests/e2e/workflows/editor/subworkflows/debugging.spec.ts": {
"avgDuration": 14585,
"avgDuration": 19329,
"testCount": 4,
"flakyRate": 0.0006
},
"tests/e2e/workflows/editor/subworkflows/extraction.spec.ts": {
"avgDuration": 43942,
"testCount": 3,
"flakyRate": 0.0007
"avgDuration": 41234,
"testCount": 2,
"flakyRate": 0
},
"tests/e2e/workflows/editor/subworkflows/subworkflow-version-resolution.spec.ts": {
"avgDuration": 1630,
"avgDuration": 1716,
"testCount": 4,
"flakyRate": 0
},
"tests/e2e/settings/environments/source-control.spec.ts": {
"avgDuration": 89074,
"avgDuration": 60210,
"testCount": 5,
"flakyRate": 0.0842
"flakyRate": 0.0275
},
"tests/e2e/auth/signin.spec.ts": {
"avgDuration": 90558,
"testCount": 3,
"avgDuration": 4660,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/chat-hub/chat-hub-settings.spec.ts": {
"avgDuration": 29832,
"avgDuration": 26516,
"testCount": 2,
"flakyRate": 0.0353
"flakyRate": 0.0185
},
"tests/e2e/app-config/security-notifications.spec.ts": {
"avgDuration": 14961,
"avgDuration": 17773,
"testCount": 5,
"flakyRate": 0.0004
"flakyRate": 0
},
"tests/e2e/workflows/editor/ndv/schema-preview.spec.ts": {
"avgDuration": 5321,
"avgDuration": 6453,
"testCount": 1,
"flakyRate": 0.0014
"flakyRate": 0
},
"tests/e2e/nodes/schedule-trigger-node.spec.ts": {
"avgDuration": 3842,
"avgDuration": 4640,
"testCount": 1,
"flakyRate": 0.0006
"flakyRate": 0
},
"tests/e2e/regression/SUG-38-inline-expression-preview.spec.ts": {
"avgDuration": 5065,
"avgDuration": 5992,
"testCount": 1,
"flakyRate": 0.0006
"flakyRate": 0
},
"tests/e2e/regression/SUG-121-fields-reset-after-closing-ndv.spec.ts": {
"avgDuration": 6117,
"testCount": 1,
"flakyRate": 0.0027
"avgDuration": 27786,
"testCount": 2,
"flakyRate": 0.0064
},
"tests/e2e/workflows/editor/routing.spec.ts": {
"avgDuration": 30230,
"avgDuration": 39084,
"testCount": 6,
"flakyRate": 0.0041
"flakyRate": 0.0042
},
"tests/e2e/workflows/editor/ndv/resource-mapper.spec.ts": {
"avgDuration": 18752,
"avgDuration": 22857,
"testCount": 4,
"flakyRate": 0.0004
"flakyRate": 0
},
"tests/e2e/workflows/editor/ndv/resource-locator.spec.ts": {
"avgDuration": 36144,
"avgDuration": 37290,
"testCount": 7,
"flakyRate": 0.0005
"flakyRate": 0
},
"tests/e2e/ai/rag-callout.spec.ts": {
"avgDuration": 13411,
"avgDuration": 35852,
"testCount": 2,
"flakyRate": 0.0005
"flakyRate": 0.0021
},
"tests/e2e/source-control/push.spec.ts": {
"avgDuration": 135139,
"avgDuration": 93322,
"testCount": 4,
"flakyRate": 0.2508
"flakyRate": 0.1582
},
"tests/e2e/source-control/pull.spec.ts": {
"avgDuration": 52727,
"avgDuration": 38086,
"testCount": 2,
"flakyRate": 0.0489
"flakyRate": 0.0231
},
"tests/e2e/capabilities/proxy-server.spec.ts": {
"avgDuration": 30243,
"avgDuration": 31619,
"testCount": 4,
"flakyRate": 0.0024
"flakyRate": 0.0016
},
"tests/e2e/projects/project-settings.spec.ts": {
"avgDuration": 47299,
"avgDuration": 47128,
"testCount": 8,
"flakyRate": 0.0005
"flakyRate": 0.0003
},
"tests/e2e/chat-hub/chat-hub-personal-agent.spec.ts": {
"avgDuration": 105584,
"testCount": 4,
"flakyRate": 0.0279
"avgDuration": 20621,
"testCount": 2,
"flakyRate": 0.0157
},
"tests/e2e/settings/personal/personal.spec.ts": {
"avgDuration": 41362,
"testCount": 9,
"flakyRate": 0.0004
"avgDuration": 27177,
"testCount": 2,
"flakyRate": 0
},
"tests/e2e/auth/password-reset.spec.ts": {
"avgDuration": 19366,
"avgDuration": 21445,
"testCount": 1,
"flakyRate": 0.0017
"flakyRate": 0.0043
},
"tests/e2e/workflows/editor/subworkflows/wait.spec.ts": {
"avgDuration": 31716,
"avgDuration": 4423,
"testCount": 4,
"flakyRate": 0.2052
"flakyRate": 0.0091
},
"tests/e2e/nodes/pdf-node.spec.ts": {
"avgDuration": 6508,
"avgDuration": 10992,
"testCount": 1,
"flakyRate": 0.0062
"flakyRate": 0.0284
},
"tests/e2e/auth/oidc.spec.ts": {
"avgDuration": 50452,
"avgDuration": 58464,
"testCount": 1,
"flakyRate": 0.0067
"flakyRate": 0.0066
},
"tests/e2e/credentials/oauth.spec.ts": {
"avgDuration": 9461,
"avgDuration": 22139,
"testCount": 1,
"flakyRate": 0.0017
"flakyRate": 0
},
"tests/e2e/workflows/editor/ndv/io-filter.spec.ts": {
"avgDuration": 12605,
"avgDuration": 12638,
"testCount": 2,
"flakyRate": 0.0031
"flakyRate": 0.0011
},
"tests/e2e/building-blocks/node-details-configuration.spec.ts": {
"avgDuration": 34886,
"avgDuration": 42800,
"testCount": 7,
"flakyRate": 0.0004
"flakyRate": 0.0003
},
"tests/e2e/node-creator/workflows.spec.ts": {
"avgDuration": 6753,
"avgDuration": 8914,
"testCount": 2,
"flakyRate": 0
},
"tests/e2e/node-creator/vector-stores.spec.ts": {
"avgDuration": 12566,
"avgDuration": 19889,
"testCount": 3,
"flakyRate": 0.0011
"flakyRate": 0
},
"tests/e2e/node-creator/special-nodes.spec.ts": {
"avgDuration": 13040,
"avgDuration": 13334,
"testCount": 3,
"flakyRate": 0.0009
"flakyRate": 0
},
"tests/e2e/node-creator/navigation.spec.ts": {
"avgDuration": 15715,
"avgDuration": 16931,
"testCount": 4,
"flakyRate": 0.0001
"flakyRate": 0
},
"tests/e2e/node-creator/categories.spec.ts": {
"avgDuration": 17438,
"avgDuration": 24718,
"testCount": 5,
"flakyRate": 0.0021
},
"tests/e2e/node-creator/actions.spec.ts": {
"avgDuration": 13661,
"testCount": 4,
"flakyRate": 0.0003
},
"tests/e2e/app-config/nps-survey.spec.ts": {
"avgDuration": 38094,
"testCount": 2,
"flakyRate": 0.0022
},
"tests/e2e/workflows/editor/ndv/ndv-parameters.spec.ts": {
"avgDuration": 49204,
"testCount": 9,
"flakyRate": 0.0009
},
"tests/e2e/workflows/editor/ndv/paired-item.spec.ts": {
"avgDuration": 35600,
"testCount": 5,
"flakyRate": 0.0007
},
"tests/e2e/workflows/editor/ndv/ndv-floating-nodes.spec.ts": {
"avgDuration": 25613,
"testCount": 4,
"flakyRate": 0.0032
},
"tests/e2e/workflows/editor/ndv/ndv-data-display.spec.ts": {
"avgDuration": 69295,
"testCount": 11,
"flakyRate": 0.0039
},
"tests/e2e/workflows/editor/ndv/ndv-core.spec.ts": {
"avgDuration": 68481,
"testCount": 16,
"flakyRate": 0.0007
},
"tests/e2e/workflows/editor/execution/partial.spec.ts": {
"avgDuration": 8721,
"testCount": 2,
"flakyRate": 0.0003
},
"tests/e2e/workflows/editor/execution/logs.spec.ts": {
"avgDuration": 51779,
"testCount": 9,
"flakyRate": 0.0004
},
"tests/e2e/settings/log-streaming/log-streaming-observability.spec.ts": {
"avgDuration": 42545,
"testCount": 2,
"flakyRate": 0.0015
},
"tests/e2e/settings/log-streaming/log-streaming-ui-e2e.spec.ts": {
"avgDuration": 15856,
"testCount": 1,
"flakyRate": 0.0029
},
"tests/e2e/settings/log-streaming/log-streaming.spec.ts": {
"avgDuration": 14785,
"tests/e2e/node-creator/actions.spec.ts": {
"avgDuration": 22239,
"testCount": 5,
"flakyRate": 0
},
"tests/e2e/app-config/nps-survey.spec.ts": {
"avgDuration": 48492,
"testCount": 2,
"flakyRate": 0.0011
},
"tests/e2e/workflows/editor/ndv/ndv-parameters.spec.ts": {
"avgDuration": 54346,
"testCount": 9,
"flakyRate": 0.0005
},
"tests/e2e/workflows/editor/ndv/paired-item.spec.ts": {
"avgDuration": 54762,
"testCount": 5,
"flakyRate": 0.0009
},
"tests/e2e/workflows/editor/ndv/ndv-floating-nodes.spec.ts": {
"avgDuration": 31589,
"testCount": 4,
"flakyRate": 0
},
"tests/e2e/workflows/editor/ndv/ndv-data-display.spec.ts": {
"avgDuration": 78185,
"testCount": 11,
"flakyRate": 0.002
},
"tests/e2e/workflows/editor/ndv/ndv-core.spec.ts": {
"avgDuration": 95927,
"testCount": 15,
"flakyRate": 0.0013
},
"tests/e2e/workflows/editor/execution/partial.spec.ts": {
"avgDuration": 10652,
"testCount": 2,
"flakyRate": 0
},
"tests/e2e/workflows/editor/execution/logs.spec.ts": {
"avgDuration": 66986,
"testCount": 10,
"flakyRate": 0.0003
},
"tests/e2e/settings/log-streaming/log-streaming-observability.spec.ts": {
"avgDuration": 43748,
"testCount": 2,
"flakyRate": 0.0023
},
"tests/e2e/settings/log-streaming/log-streaming-ui-e2e.spec.ts": {
"avgDuration": 4682,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/settings/log-streaming/log-streaming.spec.ts": {
"avgDuration": 17715,
"testCount": 5,
"flakyRate": 0.0004
},
"tests/e2e/ai/langchain-agents.spec.ts": {
"avgDuration": 72659,
"avgDuration": 82823,
"testCount": 7,
"flakyRate": 0.0018
"flakyRate": 0.0015
},
"tests/e2e/ai/langchain-tools.spec.ts": {
"avgDuration": 60000,
@@ -374,89 +374,89 @@
"flakyRate": 0
},
"tests/e2e/ai/langchain-chains.spec.ts": {
"avgDuration": 43134,
"avgDuration": 51787,
"testCount": 4,
"flakyRate": 0.0016
"flakyRate": 0.0021
},
"tests/e2e/ai/langchain-vectorstores.spec.ts": {
"avgDuration": 36408,
"avgDuration": 33063,
"testCount": 2,
"flakyRate": 0.013
"flakyRate": 0.0075
},
"tests/e2e/workflows/editor/expressions/inline.spec.ts": {
"avgDuration": 31921,
"testCount": 7,
"flakyRate": 0.0004
"avgDuration": 39139,
"testCount": 8,
"flakyRate": 0.0019
},
"tests/e2e/workflows/editor/execution/inject-previous.spec.ts": {
"avgDuration": 13450,
"avgDuration": 16902,
"testCount": 2,
"flakyRate": 0.0003
},
"tests/e2e/workflows/list/import.spec.ts": {
"avgDuration": 15798,
"testCount": 5,
"flakyRate": 0.0002
},
"tests/e2e/nodes/if-node.spec.ts": {
"avgDuration": 9703,
"testCount": 2,
"flakyRate": 0.0008
},
"tests/e2e/nodes/http-request-node.spec.ts": {
"avgDuration": 9613,
"testCount": 2,
"flakyRate": 0.0008
},
"tests/e2e/regression/GHC-5776-ai-sessions-metadata-license-error.spec.ts": {
"avgDuration": 2848,
"testCount": 1,
"flakyRate": 0.0006
},
"tests/e2e/nodes/form-trigger-node.spec.ts": {
"avgDuration": 33239,
"testCount": 5,
"flakyRate": 0.0005
},
"tests/e2e/projects/folders-operations.spec.ts": {
"avgDuration": 53282,
"testCount": 14,
"flakyRate": 0.0008
},
"tests/e2e/projects/folders-basic.spec.ts": {
"avgDuration": 29375,
"testCount": 11,
"flakyRate": 0.0005
},
"tests/e2e/projects/folders-advanced.spec.ts": {
"avgDuration": 28880,
"testCount": 6,
"flakyRate": 0.0006
},
"tests/e2e/workflows/editor/canvas/focus-panel.spec.ts": {
"avgDuration": 4180,
"testCount": 1,
"flakyRate": 0.0011
},
"tests/e2e/workflows/list/import.spec.ts": {
"avgDuration": 20064,
"testCount": 5,
"flakyRate": 0
},
"tests/e2e/nodes/if-node.spec.ts": {
"avgDuration": 17121,
"testCount": 2,
"flakyRate": 0.0032
},
"tests/e2e/nodes/http-request-node.spec.ts": {
"avgDuration": 11371,
"testCount": 2,
"flakyRate": 0
},
"tests/e2e/regression/GHC-5776-ai-sessions-metadata-license-error.spec.ts": {
"avgDuration": 3862,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/nodes/form-trigger-node.spec.ts": {
"avgDuration": 39999,
"testCount": 5,
"flakyRate": 0
},
"tests/e2e/projects/folders-operations.spec.ts": {
"avgDuration": 65837,
"testCount": 14,
"flakyRate": 0.0003
},
"tests/e2e/projects/folders-basic.spec.ts": {
"avgDuration": 36164,
"testCount": 11,
"flakyRate": 0.0004
},
"tests/e2e/projects/folders-advanced.spec.ts": {
"avgDuration": 47830,
"testCount": 6,
"flakyRate": 0.0007
},
"tests/e2e/workflows/editor/canvas/focus-panel.spec.ts": {
"avgDuration": 4886,
"testCount": 1,
"flakyRate": 0.0022
},
"tests/e2e/chat-hub/chat-hub-attachment.spec.ts": {
"avgDuration": 39013,
"avgDuration": 39512,
"testCount": 3,
"flakyRate": 0.0146
"flakyRate": 0.0123
},
"tests/e2e/api/webhook-external.spec.ts": {
"avgDuration": 15077,
"avgDuration": 26917,
"testCount": 4,
"flakyRate": 0.0452
"flakyRate": 0.0021
},
"tests/e2e/workflows/editor/expressions/modal.spec.ts": {
"avgDuration": 41868,
"avgDuration": 46286,
"testCount": 6,
"flakyRate": 0.0006
"flakyRate": 0.0007
},
"tests/e2e/workflows/editor/execution/execution.spec.ts": {
"avgDuration": 50486,
"testCount": 14,
"flakyRate": 0.0001
"avgDuration": 59473,
"testCount": 19,
"flakyRate": 0.0003
},
"tests/e2e/workflows/editor/execution/previous-nodes.spec.ts": {
"avgDuration": 60000,
@@ -469,202 +469,202 @@
"flakyRate": 0
},
"tests/e2e/app-config/env-feature-flags.spec.ts": {
"avgDuration": 6926,
"avgDuration": 21284,
"testCount": 2,
"flakyRate": 0.0005
"flakyRate": 0.0021
},
"tests/e2e/nodes/email-send-node.spec.ts": {
"avgDuration": 18776,
"avgDuration": 6100,
"testCount": 1,
"flakyRate": 0.004
"flakyRate": 0
},
"tests/e2e/workflows/editor/code/editors.spec.ts": {
"avgDuration": 50522,
"avgDuration": 60827,
"testCount": 11,
"flakyRate": 0.0004
"flakyRate": 0
},
"tests/e2e/workflows/editor/editor-after-route-changes.spec.ts": {
"avgDuration": 16293,
"avgDuration": 19932,
"testCount": 1,
"flakyRate": 0.0158
"flakyRate": 0
},
"tests/e2e/app-config/demo.spec.ts": {
"avgDuration": 20606,
"avgDuration": 36251,
"testCount": 4,
"flakyRate": 0.0209
"flakyRate": 0.0299
},
"tests/e2e/workflows/editor/execution/debug.spec.ts": {
"avgDuration": 48873,
"avgDuration": 57612,
"testCount": 4,
"flakyRate": 0.0035
"flakyRate": 0.0054
},
"tests/e2e/workflows/editor/expressions/transformation.spec.ts": {
"avgDuration": 32594,
"avgDuration": 38885,
"testCount": 6,
"flakyRate": 0.0001
"flakyRate": 0
},
"tests/e2e/workflows/editor/ndv/pinning.spec.ts": {
"avgDuration": 35020,
"testCount": 9,
"flakyRate": 0.0004
"avgDuration": 48122,
"testCount": 10,
"flakyRate": 0
},
"tests/e2e/data-tables/tables.spec.ts": {
"avgDuration": 71827,
"avgDuration": 80513,
"testCount": 7,
"flakyRate": 0.0008
"flakyRate": 0.0003
},
"tests/e2e/data-tables/details.spec.ts": {
"avgDuration": 74035,
"testCount": 11,
"flakyRate": 0.0005
},
"tests/e2e/workflows/editor/expressions/mapping.spec.ts": {
"avgDuration": 43090,
"testCount": 10,
"flakyRate": 0.0036
},
"tests/e2e/credentials/crud.spec.ts": {
"avgDuration": 78088,
"testCount": 14,
"flakyRate": 0.0009
},
"tests/e2e/building-blocks/credentials.spec.ts": {
"avgDuration": 28816,
"testCount": 6,
"flakyRate": 0.0008
},
"tests/e2e/credentials/api-operations.spec.ts": {
"avgDuration": 1400,
"testCount": 5,
"avgDuration": 84521,
"testCount": 12,
"flakyRate": 0.0002
},
"tests/e2e/workflows/editor/expressions/mapping.spec.ts": {
"avgDuration": 47938,
"testCount": 11,
"flakyRate": 0
},
"tests/e2e/credentials/crud.spec.ts": {
"avgDuration": 96851,
"testCount": 14,
"flakyRate": 0
},
"tests/e2e/building-blocks/credentials.spec.ts": {
"avgDuration": 38060,
"testCount": 6,
"flakyRate": 0.0021
},
"tests/e2e/credentials/api-operations.spec.ts": {
"avgDuration": 6073,
"testCount": 4,
"flakyRate": 0
},
"tests/e2e/settings/community-nodes/community-nodes.spec.ts": {
"avgDuration": 4220,
"avgDuration": 5043,
"testCount": 1,
"flakyRate": 0.0006
"flakyRate": 0
},
"tests/e2e/nodes/community-nodes.spec.ts": {
"avgDuration": 14807,
"avgDuration": 20283,
"testCount": 3,
"flakyRate": 0.0004
"flakyRate": 0
},
"tests/e2e/workflows/editor/code/code-node.spec.ts": {
"avgDuration": 80958,
"avgDuration": 98032,
"testCount": 12,
"flakyRate": 0.022
"flakyRate": 0.0186
},
"tests/e2e/chat-hub/chat-hub-chat-user.spec.ts": {
"avgDuration": 24375,
"avgDuration": 21523,
"testCount": 1,
"flakyRate": 0.0084
"flakyRate": 0.0112
},
"tests/e2e/ai/chat-session.spec.ts": {
"avgDuration": 12636,
"avgDuration": 33634,
"testCount": 1,
"flakyRate": 0.0188
"flakyRate": 0.0616
},
"tests/e2e/workflows/editor/canvas/canvas-zoom.spec.ts": {
"avgDuration": 57975,
"testCount": 12,
"flakyRate": 0.0008
"avgDuration": 75892,
"testCount": 13,
"flakyRate": 0.002
},
"tests/e2e/workflows/editor/canvas/canvas-nodes.spec.ts": {
"avgDuration": 67208,
"avgDuration": 77749,
"testCount": 8,
"flakyRate": 0.0042
"flakyRate": 0.0038
},
"tests/e2e/building-blocks/canvas-actions.spec.ts": {
"avgDuration": 31673,
"avgDuration": 36285,
"testCount": 9,
"flakyRate": 0.0005
"flakyRate": 0
},
"tests/e2e/workflows/editor/canvas/actions.spec.ts": {
"avgDuration": 88202,
"testCount": 21,
"flakyRate": 0.0005
"avgDuration": 99122,
"testCount": 19,
"flakyRate": 0.0001
},
"tests/e2e/workflows/editor/canvas/stickies.spec.ts": {
"avgDuration": 3092,
"avgDuration": 4087,
"testCount": 1,
"flakyRate": 0.0011
"flakyRate": 0
},
"tests/e2e/regression/CAT-726-canvas-node-connectors-not-rendered-when-nodes-inserted.spec.ts": {
"avgDuration": 5487,
"avgDuration": 6956,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/chat-hub/chat-hub-basic.spec.ts": {
"avgDuration": 103191,
"testCount": 4,
"flakyRate": 0.0212
"avgDuration": 55285,
"testCount": 3,
"flakyRate": 0.0119
},
"tests/e2e/auth/authenticated.spec.ts": {
"avgDuration": 12809,
"avgDuration": 16270,
"testCount": 5,
"flakyRate": 0.0001
"flakyRate": 0.0013
},
"tests/e2e/auth/admin-smoke.spec.ts": {
"avgDuration": 2437,
"avgDuration": 3093,
"testCount": 1,
"flakyRate": 0.0016
"flakyRate": 0.0021
},
"tests/e2e/regression/AI-812-partial-execs-broken-when-using-chat-trigger.spec.ts": {
"avgDuration": 9000,
"avgDuration": 10116,
"testCount": 2,
"flakyRate": 0.0008
"flakyRate": 0
},
"tests/e2e/regression/AI-716-correctly-set-up-agent-model-shows-error.spec.ts": {
"avgDuration": 5040,
"avgDuration": 6703,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/regression/AI-1401-sub-nodes-input-panel.spec.ts": {
"avgDuration": 5298,
"avgDuration": 6616,
"testCount": 1,
"flakyRate": 0.0006
"flakyRate": 0
},
"tests/e2e/ai/assistant-basic.spec.ts": {
"avgDuration": 58488,
"testCount": 10,
"flakyRate": 0.0003
},
"tests/e2e/ai/assistant-support-chat.spec.ts": {
"avgDuration": 19908,
"testCount": 3,
"avgDuration": 84198,
"testCount": 11,
"flakyRate": 0.0004
},
"tests/e2e/ai/assistant-support-chat.spec.ts": {
"avgDuration": 43579,
"testCount": 3,
"flakyRate": 0.0007
},
"tests/e2e/ai/assistant-credential-help.spec.ts": {
"avgDuration": 25493,
"avgDuration": 49687,
"testCount": 4,
"flakyRate": 0.0008
"flakyRate": 0.0005
},
"tests/e2e/ai/assistant-code-help.spec.ts": {
"avgDuration": 22559,
"avgDuration": 56712,
"testCount": 2,
"flakyRate": 0.0011
"flakyRate": 0.0032
},
"tests/e2e/regression/ADO-2929-can-load-old-switch-node-workflows.spec.ts": {
"avgDuration": 4371,
"avgDuration": 5657,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/regression/ADO-2372-prevent-clipping-params.spec.ts": {
"avgDuration": 8209,
"avgDuration": 9109,
"testCount": 2,
"flakyRate": 0.0003
"flakyRate": 0
},
"tests/e2e/regression/ADO-2270-opening-webhook-ndv-marks-workflow-as-unsaved.spec.ts": {
"avgDuration": 3830,
"avgDuration": 4660,
"testCount": 1,
"flakyRate": 0.0012
"flakyRate": 0
},
"tests/e2e/regression/ADO-2230-ndv-reset-data-pagination.spec.ts": {
"avgDuration": 4108,
"avgDuration": 4884,
"testCount": 1,
"flakyRate": 0
},
"tests/e2e/regression/ADO-1338-ndv-missing-input-panel.spec.ts": {
"avgDuration": 9443,
"avgDuration": 8068,
"testCount": 1,
"flakyRate": 0
}
@@ -36,7 +36,7 @@ jobs:
- name: Run Container Coverage Tests
id: coverage-tests
run: |
pnpm --filter n8n-playwright test:container:standard \
pnpm --filter n8n-playwright test:container:sqlite \
--workers=${{ env.PLAYWRIGHT_WORKERS }}
env:
BUILD_WITH_COVERAGE: 'true'
@@ -43,7 +43,7 @@ export const taskRunner: Service<TaskRunnerResult> = {
N8N_RUNNERS_LAUNCHER_LOG_LEVEL: 'debug',
N8N_RUNNERS_TASK_BROKER_URI: taskBrokerUri,
N8N_RUNNERS_MAX_CONCURRENCY: '5',
N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT: '15',
N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT: '0', // Disabled in tests to prevent cold-start delays
})
.withWaitStrategy(Wait.forListeningPorts())
.withLabels({
+7 -2
View File
@@ -130,8 +130,13 @@ export async function createN8NStack(config: N8NConfig = {}): Promise<N8NStack>
const levelPromises = level.map(async (name) => {
const service = SERVICE_REGISTRY[name];
const options = service.getOptions?.(ctx);
const result = await service.start(network, uniqueProjectName, options, ctx);
return { name, service, result };
try {
const result = await service.start(network, uniqueProjectName, options, ctx);
return { name, service, result };
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Service "${service.description}" (${name}) failed to start: ${message}`);
}
});
const results = await Promise.all(levelPromises);
@@ -6,7 +6,7 @@ Capability-aware test distribution across CI shards.
| Step | What Happens |
|------|--------------|
| 1. Discovery | `pnpm playwright test --list --project="multi-main:e2e"` |
| 1. Discovery | `pnpm playwright test --list --project="multi-main:e2e" --grep-invert "@fixme"` |
| 2. Metrics | Get `avgDuration` per spec from Currents (last 30 days) |
| 3. Default | Missing specs get **60s** default (accounts for container startup) |
| 4. Group | Group specs by `@capability:xxx` tag for worker reuse |
@@ -94,6 +94,30 @@ test('Multi-main logs @capability:observability @mode:multi-main', ...);
Both `@capability:X` and `@mode:X` tests are skipped in local mode (they require containers).
## Temporarily Disabling Tests with @fixme
Tests tagged with `@fixme` are **excluded from CI distribution**. Use this for flaky or broken tests that need fixing.
```typescript
// Individual test
test.fixme('broken test @fixme', async ({ n8n }) => {
// This test won't run in CI
});
// Entire describe block
test.describe('Feature @fixme', () => {
test.fixme(); // Marks all tests in this block
test('test 1', async ({ n8n }) => { ... });
test('test 2', async ({ n8n }) => { ... });
});
```
**Why @fixme instead of test.skip?**
- `test.skip()` tests still appear in `--list` output and get distributed to shards
- `@fixme` tests are filtered out via `--grep-invert`, saving CI resources
- `test.fixme()` semantically indicates "needs fixing" vs "not applicable"
## Refreshing Metrics
```bash
@@ -131,3 +155,4 @@ node scripts/distribute-tests.mjs 14 0
| Specs not running | Check path matches `playwright test --list` output |
| Unbalanced shards | Refresh metrics - durations may have drifted |
| Worker not reused | Use string capabilities like `'proxy'`, not inline objects |
| Skipped test still distributed | Use `@fixme` tag instead of `test.skip()` |
@@ -71,7 +71,7 @@ export class WorkflowsPage extends BasePage {
async deleteWorkflow(workflowItem: Locator) {
await workflowItem.getByTestId('workflow-card-actions').click();
await this.page.getByRole('menuitem', { name: 'Delete' }).click();
await this.page.getByTestId('action-delete').click();
await this.page.getByRole('button', { name: 'delete' }).click();
}
@@ -49,7 +49,7 @@ if (!shards || shards < 1) {
* @returns {{path: string, capabilities: string[]}[]} Array of spec info
*/
function getSpecsFromPlaywright() {
const output = execSync(`pnpm playwright test --list --project="${E2E_PROJECT}"`, {
const output = execSync(`pnpm playwright test --list --project="${E2E_PROJECT}" --grep-invert "@fixme"`, {
cwd: PLAYWRIGHT_DIR,
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
@@ -33,14 +33,14 @@ async function fetchAllTests(apiKey) {
let page = 0;
let hasMore = true;
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
while (hasMore && page < 200) {
const url = new URL(`${CURRENTS_API}/tests/${PROJECT_ID}`);
url.searchParams.set('limit', '50');
url.searchParams.set('page', page.toString());
url.searchParams.set('date_start', thirtyDaysAgo.toISOString());
url.searchParams.set('date_start', sevenDaysAgo.toISOString());
url.searchParams.set('date_end', new Date().toISOString());
const res = await fetch(url, {
@@ -10,17 +10,18 @@ test.describe('Evaluations @capability:proxy', () => {
});
// @AI team to look at this
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should load evaluations workflow and execute twice', async ({ n8n, proxyServer }) => {
await proxyServer.loadExpectations('evaluations');
test.fixme(
'should load evaluations workflow and execute twice @fixme',
async ({ n8n, proxyServer }) => {
await proxyServer.loadExpectations('evaluations');
await n8n.api.credentials.createCredentialFromDefinition({
name: 'Test Google Sheets',
type: 'googleApi',
data: {
email: 'email@quickstart-1234.iam.gserviceaccount.com',
// mock private key
privateKey: `-----BEGIN PRIVATE KEY-----
await n8n.api.credentials.createCredentialFromDefinition({
name: 'Test Google Sheets',
type: 'googleApi',
data: {
email: 'email@quickstart-1234.iam.gserviceaccount.com',
// mock private key
privateKey: `-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDx1//AaoSkyHYl
npqS3+uaePYhJXKD/T1h6zGThAUooN7ZzWK46nNcU1vghQMTlPMHfUTbl4xzZxEL
OYjyTPOKpwJvhmy44MU+zTQYJuUaU4dQuOCnnC61CL91Xy+8GJd7PvdUeVRWENWu
@@ -48,41 +49,43 @@ nmfqICLWEc/UZSxmxau1rOz71GJiiHgXFmQgiZtpf3Qp3wKKtoFkf+sJ6zP2VX35
2tJcTO9lKm6kNa3eaveE/NJrkH5a0IpxrvDT1TvmnapaNEKuGZJAX5BNaggDrfEJ
m82JpEptTfAxFHtd8+Sb0U2G
-----END PRIVATE KEY-----`,
},
});
},
});
await n8n.navigate.toWorkflow('new');
// Import the evaluations workflow
await n8n.canvas.importWorkflow('evaluations_loop.json', 'Evaluations');
await n8n.navigate.toWorkflow('new');
// Import the evaluations workflow
await n8n.canvas.importWorkflow('evaluations_loop.json', 'Evaluations');
// Open each node to ensure credentials are set
await n8n.canvas.openNode('When fetching a dataset row');
await n8n.page.keyboard.press('Escape');
// Open each node to ensure credentials are set
await n8n.canvas.openNode('When fetching a dataset row');
await n8n.page.keyboard.press('Escape');
// Open each node to ensure credentials are set
await n8n.canvas.openNode('Set outputs');
await n8n.page.keyboard.press('Escape');
// Open each node to ensure credentials are set
await n8n.canvas.openNode('Set outputs');
await n8n.page.keyboard.press('Escape');
// Execute workflow from canvas - first execution
await n8n.canvas.clickExecuteWorkflowButton();
// Execute workflow from canvas - first execution
await n8n.canvas.clickExecuteWorkflowButton();
// wait for first run to finish
await n8n.notifications.waitForNotificationAndClose('Successful', { timeout: 10000 });
// wait for first run to finish
await n8n.notifications.waitForNotificationAndClose('Successful', { timeout: 10000 });
// wait for second run to finish
await n8n.notifications.waitForNotificationAndClose('Successful', { timeout: 10000 });
// wait for second run to finish
await n8n.notifications.waitForNotificationAndClose('Successful', { timeout: 10000 });
// 💡 To update recordings, remove stored expectations, set real credentials above and rerecord here.
// await proxyServer.recordExpectations('evaluations', { host: 'google', dedupe: true });
// 💡 To update recordings, remove stored expectations, set real credentials above and rerecord here.
// await proxyServer.recordExpectations('evaluations', { host: 'google', dedupe: true });
const batchUpdateRequests = (await proxyServer.getAllRequestsMade()).filter((request) => {
const path = request.httpRequest?.path;
const method = request.httpRequest?.method;
const batchUpdateRequests = (await proxyServer.getAllRequestsMade()).filter((request) => {
const path = request.httpRequest?.path;
const method = request.httpRequest?.method;
return method === 'POST' && typeof path === 'string' && path.endsWith('/values:batchUpdate');
});
return (
method === 'POST' && typeof path === 'string' && path.endsWith('/values:batchUpdate')
);
});
/**
/**
* Original Table in Google Sheets
* The loop should execute twice over both rows here
* Incrementing each value by 1 (expression in Set Output node)
@@ -92,25 +95,26 @@ m82JpEptTfAxFHtd8+Sb0U2G
hello wolrd 104
*/
// Set output node was called twice in a loop, updating Google sheets output value
expect(batchUpdateRequests.length).toEqual(2);
expect((batchUpdateRequests[0]?.httpRequest?.body as { json: object })?.json).toEqual({
data: [
{
range: 'Sheet2!C2',
values: [[11]],
},
],
valueInputOption: 'RAW',
});
expect((batchUpdateRequests[1]?.httpRequest?.body as { json: object })?.json).toEqual({
data: [
{
range: 'Sheet2!C3',
values: [[105]],
},
],
valueInputOption: 'RAW',
});
});
// Set output node was called twice in a loop, updating Google sheets output value
expect(batchUpdateRequests.length).toEqual(2);
expect((batchUpdateRequests[0]?.httpRequest?.body as { json: object })?.json).toEqual({
data: [
{
range: 'Sheet2!C2',
values: [[11]],
},
],
valueInputOption: 'RAW',
});
expect((batchUpdateRequests[1]?.httpRequest?.body as { json: object })?.json).toEqual({
data: [
{
range: 'Sheet2!C3',
values: [[105]],
},
],
valueInputOption: 'RAW',
});
},
);
});
@@ -57,8 +57,9 @@ test.describe('Langchain Integration @capability:proxy', () => {
});
// Create a ticket for this for AI team to fix
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Error Handling and Logs Display', () => {
test.describe('Error Handling and Logs Display @fixme', () => {
test.fixme();
// Helper function to set up the agent workflow with Postgres error configuration
async function setupAgentWorkflowWithPostgresError(n8n: n8nPage) {
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
@@ -60,8 +60,9 @@ test.describe('Langchain Integration @capability:proxy', () => {
});
// @AI team to look at this
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Tool Usage Notifications', () => {
test.describe('Tool Usage Notifications @fixme', () => {
test.fixme();
test('should show tool info notice if no existing tools were used during execution', async ({
n8n,
}) => {
@@ -58,8 +58,7 @@ test.describe('Workflow Builder @auth:owner @ai @capability:proxy', () => {
});
// @AI team to look at this
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should build workflow from suggested prompt', async ({ n8n }) => {
test.fixme('should build workflow from suggested prompt @fixme', async ({ n8n }) => {
await n8n.page.goto('/workflow/new');
await openBuilderAndClickSuggestion(n8n, 'YouTube video chapters');
@@ -352,8 +352,7 @@ test.describe('Data Table details view', () => {
expect(initialName).not.toEqual(newName);
});
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Should filter correctly using column filters', async ({ n8n }) => {
test.fixme('Should filter correctly using column filters @fixme', async ({ n8n }) => {
await expect(n8n.dataTableDetails.getPageWrapper()).toBeVisible();
await n8n.dataTableDetails.setPageSize('10');
@@ -19,7 +19,9 @@ async function saveSettings(n8n: n8nPage) {
// Skipped: These tests are flaky. Re-enable when PAY-4365 is resolved.
// https://linear.app/n8n/issue/PAY-4365/bug-source-control-operations-fail-in-multi-main-deployment
test.describe.skip('Source Control Settings @capability:source-control', () => {
test.describe('Source Control Settings @capability:source-control @fixme', () => {
test.fixme();
let repoUrl: string;
let repoName: string;
@@ -13,7 +13,9 @@ async function expectPullSuccess(n8n: n8nPage) {
// Skipped: These tests are flaky. Re-enable when PAY-4365 is resolved.
// https://linear.app/n8n/issue/PAY-4365/bug-source-control-operations-fail-in-multi-main-deployment
test.describe.skip('Pull resources from Git @capability:source-control', () => {
test.describe('Pull resources from Git @capability:source-control @fixme', () => {
test.fixme();
let gitRepo: GitRepoHelper;
test.beforeEach(async ({ n8n, n8nContainer }) => {
@@ -19,7 +19,9 @@ async function expectNoChangesToCommit(n8n: n8nPage) {
// Skipped: These tests are flaky. Re-enable when PAY-4365 is resolved.
// https://linear.app/n8n/issue/PAY-4365/bug-source-control-operations-fail-in-multi-main-deployment
test.describe.skip('Push resources to Git @capability:source-control', () => {
test.describe('Push resources to Git @capability:source-control @fixme', () => {
test.fixme();
let gitRepo: GitRepoHelper;
test.beforeEach(async ({ n8n, n8nContainer }) => {
@@ -103,8 +103,8 @@ test.describe('Workflow Production Checklist', () => {
await expect(n8n.canvas.getTimeSavedActionItem()).toBeVisible();
});
// eslint-disable-next-line n8n-local-rules/no-skipped-tests -- Flaky in multi-main mode
test.skip('should show completed state for configured actions', async ({ n8n, api }) => {
// Flaky in multi-main mode
test.fixme('should show completed state for configured actions @fixme', async ({ n8n, api }) => {
const errorWorkflow = await api.workflows.createWorkflow({
name: 'Error Handler',
nodes: [
@@ -221,9 +221,12 @@ test.describe('Canvas Zoom Functionality', () => {
await expect(n8n.ndv.getNodesWithIssues()).toHaveCount(1);
});
test.skip('should open and close the about modal on keyboard shortcut', async ({ n8n }) => {
await n8n.sideBar.openAboutModalViaShortcut();
await expect(n8n.sideBar.getAboutModal()).toBeVisible();
await n8n.sideBar.closeAboutModal();
});
test.fixme(
'should open and close the about modal on keyboard shortcut @fixme',
async ({ n8n }) => {
await n8n.sideBar.openAboutModalViaShortcut();
await expect(n8n.sideBar.getAboutModal()).toBeVisible();
await n8n.sideBar.closeAboutModal();
},
);
});
@@ -86,8 +86,8 @@ test.describe('Execution', () => {
await expect(n8n.canvas.clearExecutionDataButton()).toBeHidden();
});
// eslint-disable-next-line playwright/no-skipped-test -- Failing/flaky in multi-main
test.skip('should test manual workflow stop', async ({ n8n }) => {
// Failing/flaky in multi-main
test.fixme('should test manual workflow stop @fixme', async ({ n8n }) => {
await n8n.start.fromImportedWorkflow('Manual_wait_set.json');
await expect(n8n.canvas.getExecuteWorkflowButton()).toBeVisible();
@@ -226,8 +226,9 @@ test.describe('Execution', () => {
/**
* @TODO New Canvas: Different classes for pinned states on edges and nodes
*/
// eslint-disable-next-line n8n-local-rules/no-skipped-tests
test.describe.skip('connections should be colored differently for pinned data', () => {
test.describe('connections should be colored differently for pinned data @fixme', () => {
test.fixme();
test('when executing the workflow', async () => {
// Not yet migrated - waiting for New Canvas implementation
});
@@ -88,53 +88,55 @@ test.describe('Logs', () => {
});
// TODO: make it possible to test workflows with AI model end-to-end
test.skip('should show input and output data in the selected display mode', async ({
n8n,
setupRequirements,
}) => {
await setupRequirements({ workflow: 'Workflow_ai_agent.json' });
test.fixme(
'should show input and output data in the selected display mode @fixme',
async ({ n8n, setupRequirements }) => {
await setupRequirements({ workflow: 'Workflow_ai_agent.json' });
await n8n.canvas.clickZoomToFitButton();
await n8n.canvas.logsPanel.open();
await n8n.canvas.logsPanel.sendManualChatMessage('Hi!');
await n8n.workflowComposer.executeWorkflowAndWaitForNotification('Successful');
await expect(n8n.canvas.logsPanel.getManualChatMessages().nth(0)).toContainText('Hi!');
await expect(n8n.canvas.logsPanel.getManualChatMessages().nth(1)).toContainText(
'Hello from e2e model!!!',
);
await expect(n8n.canvas.logsPanel.getLogEntries().nth(2)).toHaveText('E2E Chat Model');
await n8n.canvas.logsPanel.getLogEntries().nth(2).click();
await n8n.canvas.clickZoomToFitButton();
await n8n.canvas.logsPanel.open();
await n8n.canvas.logsPanel.sendManualChatMessage('Hi!');
await n8n.workflowComposer.executeWorkflowAndWaitForNotification('Successful');
await expect(n8n.canvas.logsPanel.getManualChatMessages().nth(0)).toContainText('Hi!');
await expect(n8n.canvas.logsPanel.getManualChatMessages().nth(1)).toContainText(
'Hello from e2e model!!!',
);
await expect(n8n.canvas.logsPanel.getLogEntries().nth(2)).toHaveText('E2E Chat Model');
await n8n.canvas.logsPanel.getLogEntries().nth(2).click();
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText('Hello from e2e model!!!');
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('table');
await expect(n8n.canvas.logsPanel.outputPanel.getTbodyCell(0, 0)).toContainText(
'text:Hello from **e2e** model!!!',
);
await expect(n8n.canvas.logsPanel.outputPanel.getTbodyCell(0, 1)).toContainText(
'completionTokens:20',
);
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('schema');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText('generations[0]');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText(
'Hello from **e2e** model!!!',
);
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('json');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText(
'[{"response": {"generations": [',
);
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText('Hello from e2e model!!!');
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('table');
await expect(n8n.canvas.logsPanel.outputPanel.getTbodyCell(0, 0)).toContainText(
'text:Hello from **e2e** model!!!',
);
await expect(n8n.canvas.logsPanel.outputPanel.getTbodyCell(0, 1)).toContainText(
'completionTokens:20',
);
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('schema');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText('generations[0]');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText(
'Hello from **e2e** model!!!',
);
await n8n.canvas.logsPanel.outputPanel.switchDisplayMode('json');
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText(
'[{"response": {"generations": [',
);
await n8n.canvas.logsPanel.toggleInputPanel();
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('Human: Hi!');
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('table');
await expect(n8n.canvas.logsPanel.inputPanel.getTbodyCell(0, 0)).toContainText('0:Human: Hi!');
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('schema');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('messages[0]');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('Human: Hi!');
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('json');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText(
'[{"messages": ["Human: Hi!"],',
);
});
await n8n.canvas.logsPanel.toggleInputPanel();
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('Human: Hi!');
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('table');
await expect(n8n.canvas.logsPanel.inputPanel.getTbodyCell(0, 0)).toContainText(
'0:Human: Hi!',
);
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('schema');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('messages[0]');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText('Human: Hi!');
await n8n.canvas.logsPanel.inputPanel.switchDisplayMode('json');
await expect(n8n.canvas.logsPanel.inputPanel.get()).toContainText(
'[{"messages": ["Human: Hi!"],',
);
},
);
test('should show input and output data of correct run index and branch', async ({
n8n,
@@ -206,7 +208,7 @@ test.describe('Logs', () => {
});
// TODO: make it possible to test workflows with AI model end-to-end
test.skip('should show logs for a past execution', async ({ n8n, setupRequirements }) => {
test.fixme('should show logs for a past execution @fixme', async ({ n8n, setupRequirements }) => {
await setupRequirements({ workflow: 'Workflow_ai_agent.json' });
await n8n.canvas.clickZoomToFitButton();
@@ -1,7 +1,9 @@
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line n8n-local-rules/no-skipped-tests -- Flaky in multi-main mode: "execute previous nodes" also executes the current node
test.describe.skip('Execute previous nodes', () => {
// Flaky in multi-main mode: "execute previous nodes" also executes the current node
test.describe('Execute previous nodes @fixme', () => {
test.fixme();
test('should execute only previous nodes and not the current node', async ({ n8n }) => {
// Import workflow with Manual Trigger -> Code1 -> Code2
await n8n.start.fromImportedWorkflow('execute-previous-nodes.json');
@@ -31,28 +31,30 @@ test.describe('Inline expression editor', () => {
await expect(n8n.ndv.getInlineExpressionEditorOutput()).toBeHidden();
});
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should switch between expression and fixed using keyboard', async ({ n8n }) => {
await n8n.canvas.addNode(EDIT_FIELDS_SET_NODE_NAME);
test.fixme(
'should switch between expression and fixed using keyboard @fixme',
async ({ n8n }) => {
await n8n.canvas.addNode(EDIT_FIELDS_SET_NODE_NAME);
// Should switch to expression with =
await n8n.ndv.getAssignmentCollectionAdd('assignments').click();
await n8n.ndv.fillParameterInputByName('value', '=');
// Should switch to expression with =
await n8n.ndv.getAssignmentCollectionAdd('assignments').click();
await n8n.ndv.fillParameterInputByName('value', '=');
// Should complete {{ --> {{ | }}
await n8n.ndv.getInlineExpressionEditorInput().click();
await n8n.ndv.typeInExpressionEditor('{{');
await expect(n8n.ndv.getInlineExpressionEditorInput()).toHaveText('{{ }}');
// Should complete {{ --> {{ | }}
await n8n.ndv.getInlineExpressionEditorInput().click();
await n8n.ndv.typeInExpressionEditor('{{');
await expect(n8n.ndv.getInlineExpressionEditorInput()).toHaveText('{{ }}');
// Should switch back to fixed with backspace on empty expression
await n8n.ndv.clearExpressionEditor('value');
await expect(n8n.ndv.getParameterInputHint()).toContainText('empty');
const parameterInput = n8n.ndv.getParameterInput('value').getByRole('textbox');
await parameterInput.click();
await parameterInput.focus();
await parameterInput.press('Backspace');
await expect(n8n.ndv.getInlineExpressionEditorInput()).toBeHidden();
});
// Should switch back to fixed with backspace on empty expression
await n8n.ndv.clearExpressionEditor('value');
await expect(n8n.ndv.getParameterInputHint()).toContainText('empty');
const parameterInput = n8n.ndv.getParameterInput('value').getByRole('textbox');
await parameterInput.click();
await parameterInput.focus();
await parameterInput.press('Backspace');
await expect(n8n.ndv.getInlineExpressionEditorInput()).toBeHidden();
},
);
});
test.describe('Static data', () => {
@@ -258,8 +258,7 @@ test.describe('Data Mapping', () => {
});
// There is an issue here sometimes, when dragging to the target it prepends the last value that was in the window even if it was cleared
// eslint-disable-next-line playwright/no-skipped-test
test.skip('maps expressions to updated fields correctly', async ({ n8n }) => {
test.fixme('maps expressions to updated fields correctly @fixme', async ({ n8n }) => {
await n8n.start.fromImportedWorkflow('Test_workflow_3.json');
await n8n.canvas.openNode('Set');
@@ -199,21 +199,21 @@ test.describe('Data pinning', () => {
await expect(n8n.ndv.outputPanel.getTableRow(1)).toContainText('pin-overwritten');
});
// eslint-disable-next-line n8n-local-rules/no-skipped-tests -- Flaky in multi-main mode due to webhook registration timing issues
test.skip('should not use pin data in production webhook executions', async ({
n8n,
setupRequirements,
}) => {
await setupRequirements(webhookTestRequirements);
await expect(n8n.canvas.getWorkflowSaveButton()).toContainText('Saved');
await n8n.canvas.publishWorkflow();
const webhookUrl = '/webhook/b0d79ddb-df2d-49b1-8555-9fa2b482608f';
const response = await n8n.ndv.makeWebhookRequest(webhookUrl);
expect(response.status(), 'Webhook response is: ' + (await response.text())).toBe(200);
// Flaky in multi-main mode due to webhook registration timing issues
test.fixme(
'should not use pin data in production webhook executions @fixme',
async ({ n8n, setupRequirements }) => {
await setupRequirements(webhookTestRequirements);
await expect(n8n.canvas.getWorkflowSaveButton()).toContainText('Saved');
await n8n.canvas.publishWorkflow();
const webhookUrl = '/webhook/b0d79ddb-df2d-49b1-8555-9fa2b482608f';
const response = await n8n.ndv.makeWebhookRequest(webhookUrl);
expect(response.status(), 'Webhook response is: ' + (await response.text())).toBe(200);
const responseBody = await response.json();
expect(responseBody).toEqual({ nodeData: 'pin' });
});
const responseBody = await response.json();
expect(responseBody).toEqual({ nodeData: 'pin' });
},
);
test('should not show pinned data tooltip', async ({ n8n, setupRequirements }) => {
await setupRequirements(pinnedWebhookRequirements);
@@ -27,8 +27,9 @@ async function goToWorkflow(n8n: n8nPage, workflowId: string): Promise<void> {
await loadResponsePromise;
}
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Archive', () => {
test.describe('Workflow Archive @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -69,8 +70,8 @@ test.skip('Workflow Archive', () => {
await expect(n8n.page).toHaveURL(/\/workflows$/);
});
// eslint-disable-next-line n8n-local-rules/no-skipped-tests -- Flaky in multi-main mode
test.skip('should archive published workflow and then delete it', async ({ n8n }) => {
// Flaky in multi-main mode
test.fixme('should archive published workflow and then delete it @fixme', async ({ n8n }) => {
await n8n.canvas.addNode(SCHEDULE_TRIGGER_NODE_NAME, { closeNDV: true });
const workflowId = await saveWorkflowAndGetId(n8n);
await n8n.canvas.publishWorkflow();
@@ -139,7 +140,7 @@ test.skip('Workflow Archive', () => {
});
// TODO: flaky test - 18 similar failures across 10 branches in last 14 days
test.skip('should unpublish a published workflow', async ({ n8n }) => {
test.fixme('should unpublish a published workflow @fixme', async ({ n8n }) => {
await n8n.canvas.addNode(SCHEDULE_TRIGGER_NODE_NAME, { closeNDV: true });
await n8n.canvas.publishWorkflow();
await n8n.page.keyboard.press('Escape');
@@ -156,8 +157,8 @@ test.skip('Workflow Archive', () => {
await expect(n8n.canvas.getPublishedIndicator()).not.toBeVisible();
});
// eslint-disable-next-line n8n-local-rules/no-skipped-tests -- Flaky in multi-main mode
test.skip('should unpublish published workflow on archive', async ({ n8n }) => {
// Flaky in multi-main mode
test.fixme('should unpublish published workflow on archive @fixme', async ({ n8n }) => {
await n8n.canvas.addNode(SCHEDULE_TRIGGER_NODE_NAME, { closeNDV: true });
const workflowId = await saveWorkflowAndGetId(n8n);
await n8n.canvas.publishWorkflow();
@@ -4,8 +4,9 @@ import { CODE_NODE_NAME, SCHEDULE_TRIGGER_NODE_NAME } from '../../../../../confi
import { test, expect } from '../../../../../fixtures/base';
import { resolveFromRoot } from '../../../../../utils/path-helper';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Copy Paste', () => {
test.describe('Workflow Copy Paste @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -3,8 +3,9 @@ import { nanoid } from 'nanoid';
import { MANUAL_TRIGGER_NODE_NAME } from '../../../../../config/constants';
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Duplicate', () => {
test.describe('Workflow Duplicate @fixme', () => {
test.fixme();
const DUPLICATE_WORKFLOW_NAME = 'Duplicated workflow';
test.beforeEach(async ({ n8n }) => {
@@ -5,8 +5,9 @@ import {
} from '../../../../../config/constants';
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Publish', () => {
test.describe('Workflow Publish @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -4,8 +4,9 @@ import {
} from '../../../../../config/constants';
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Run', () => {
test.describe('Workflow Run @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -4,8 +4,9 @@ import {
} from '../../../../../config/constants';
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Save', () => {
test.describe('Workflow Save @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -1,7 +1,8 @@
import { test, expect } from '../../../../../fixtures/base';
// eslint-disable-next-line playwright/no-skipped-test
test.skip('Workflow Settings', () => {
test.describe('Workflow Settings @fixme', () => {
test.fixme();
test.beforeEach(async ({ n8n }) => {
await n8n.start.fromBlankCanvas();
});
@@ -8,48 +8,50 @@ test.describe('Executions Filter', () => {
// There is flakiness in this test. When the dropdown is opened, at times it appears to automatically close even without user interaction.
// Manual timeouts have been added to try to mitigate this, but it still happens.
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should keep popover open when selecting from dropdown inside it', async ({ n8n }) => {
// Regression test: Element Plus dropdowns are teleported to body, causing
// Reka UI's DismissableLayer to detect clicks as "outside" and close the popover.
// This test verifies the popover stays open during and after dropdown selection.
test.fixme(
'should keep popover open when selecting from dropdown inside it @fixme',
async ({ n8n }) => {
// Regression test: Element Plus dropdowns are teleported to body, causing
// Reka UI's DismissableLayer to detect clicks as "outside" and close the popover.
// This test verifies the popover stays open during and after dropdown selection.
// Create some executions first
await n8n.executionsComposer.createExecutions(2);
// Create some executions first
await n8n.executionsComposer.createExecutions(2);
// Go to executions tab
await n8n.canvas.clickExecutionsTab();
await expect(n8n.executions.getExecutionItems().first()).toBeVisible();
// Go to executions tab
await n8n.canvas.clickExecutionsTab();
await expect(n8n.executions.getExecutionItems().first()).toBeVisible();
// Open filter popover
await n8n.executions.openFilter();
const filterForm = n8n.executions.getFilterForm();
await n8n.page.waitForTimeout(1500);
await expect(filterForm).toBeVisible();
// Open filter popover
await n8n.executions.openFilter();
const filterForm = n8n.executions.getFilterForm();
await n8n.page.waitForTimeout(1500);
await expect(filterForm).toBeVisible();
// Click to open the status dropdown
await n8n.executions.getStatusSelect().click();
// Verify popover is still open while dropdown is open
await expect(filterForm).toBeVisible();
// Click to open the status dropdown
await n8n.executions.getStatusSelect().click();
// Verify popover is still open while dropdown is open
await expect(filterForm).toBeVisible();
// Set up listener for the filtered executions request
const filterRequestPromise = n8n.page.waitForRequest(
(request) =>
request.url().includes('/rest/executions?filter=') && request.url().includes('success'),
);
// Set up listener for the filtered executions request
const filterRequestPromise = n8n.page.waitForRequest(
(request) =>
request.url().includes('/rest/executions?filter=') && request.url().includes('success'),
);
await n8n.page.waitForTimeout(500);
// Select an option from the dropdown
await n8n.page.getByRole('option', { name: 'Success' }).click();
await n8n.page.waitForTimeout(500);
// Select an option from the dropdown
await n8n.page.getByRole('option', { name: 'Success' }).click();
// Verify the filter request was sent to the backend (confirms selection worked)
const filterRequest = await filterRequestPromise;
expect(filterRequest.url()).toContain('status');
expect(filterRequest.url()).toContain('success');
// Verify the filter request was sent to the backend (confirms selection worked)
const filterRequest = await filterRequestPromise;
expect(filterRequest.url()).toContain('status');
expect(filterRequest.url()).toContain('success');
// KEY ASSERTION: Verify the popover did NOT close after selecting from dropdown
await expect(filterForm).toBeVisible();
});
// KEY ASSERTION: Verify the popover did NOT close after selecting from dropdown
await expect(filterForm).toBeVisible();
},
);
});
const ERROR_MESSAGES = {
@@ -193,12 +195,13 @@ test.describe('Workflow Executions', () => {
await expect(errorNotification).toBeVisible();
});
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should show workflow data in executions tab after hard reload and modify name and tags', async () => {
// TODO: Migrate from Cypress
});
// eslint-disable-next-line playwright/no-skipped-test
test.skip('should load items and auto scroll after filter change', async () => {
test.fixme(
'should show workflow data in executions tab after hard reload and modify name and tags @fixme',
async () => {
// TODO: Migrate from Cypress
},
);
test.fixme('should load items and auto scroll after filter change @fixme', async () => {
// TODO: This should be a component test
});