mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
add e2e tests
This commit is contained in:
parent
5f491fbde3
commit
40fd8b318b
29
cypress/composables/executions.ts
Normal file
29
cypress/composables/executions.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* Getters
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const getExecutionsSidebar = () => cy.getByTestId('executions-sidebar');
|
||||||
|
|
||||||
|
export const getWorkflowExecutionPreviewIframe = () => cy.getByTestId('workflow-preview-iframe');
|
||||||
|
|
||||||
|
export const getExecutionPreviewBody = () =>
|
||||||
|
getWorkflowExecutionPreviewIframe()
|
||||||
|
.its('0.contentDocument.body')
|
||||||
|
.then((el) => cy.wrap(el));
|
||||||
|
|
||||||
|
export const getExecutionPreviewBodyNodes = () =>
|
||||||
|
getExecutionPreviewBody().findChildByTestId('canvas-node');
|
||||||
|
|
||||||
|
export const getExecutionPreviewBodyNodesByName = (name: string) =>
|
||||||
|
getExecutionPreviewBody().findChildByTestId('canvas-node').filter(`[data-name="${name}"]`).eq(0);
|
||||||
|
|
||||||
|
export function getExecutionPreviewOutputPanelRelatedExecutionLink() {
|
||||||
|
return getExecutionPreviewBody().findChildByTestId('related-execution-link');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const openExecutionPreviewNode = (name: string) =>
|
||||||
|
getExecutionPreviewBodyNodesByName(name).dblclick();
|
|
@ -48,10 +48,38 @@ export function getOutputTableRow(row: number) {
|
||||||
return getOutputTableRows().eq(row);
|
return getOutputTableRows().eq(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getOutputTableHeaders() {
|
||||||
|
return getOutputPanelDataContainer().find('table thead th');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOutputTableHeaderByText(text: string) {
|
||||||
|
return getOutputTableHeaders().contains(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOutputTbodyCell(row: number, col: number) {
|
||||||
|
return getOutputTableRows().eq(row).find('td').eq(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOutputRunSelector() {
|
||||||
|
return getOutputPanel().findChildByTestId('run-selector');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOutputRunSelectorInput() {
|
||||||
|
return getOutputRunSelector().find('input');
|
||||||
|
}
|
||||||
|
|
||||||
export function getOutputPanelTable() {
|
export function getOutputPanelTable() {
|
||||||
return getOutputPanelDataContainer().get('table');
|
return getOutputPanelDataContainer().get('table');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getOutputPanelItemsCount() {
|
||||||
|
return getOutputPanel().getByTestId('ndv-items-count');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOutputPanelRelatedExecutionLink() {
|
||||||
|
return getOutputPanel().getByTestId('related-execution-link');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actions
|
* Actions
|
||||||
*/
|
*/
|
||||||
|
@ -90,3 +118,8 @@ export function setParameterSelectByContent(name: string, content: string) {
|
||||||
getParameterInputByName(name).realClick();
|
getParameterInputByName(name).realClick();
|
||||||
getVisibleSelect().find('.option-headline').contains(content).click();
|
getVisibleSelect().find('.option-headline').contains(content).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function changeOutputRunSelector(runName: string) {
|
||||||
|
getOutputRunSelector().click();
|
||||||
|
getVisibleSelect().find('.el-select-dropdown__item').contains(runName).click();
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,14 @@ export function getCanvasNodes() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSaveButton() {
|
||||||
|
return cy.getByTestId('workflow-save-button');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getZoomToFitButton() {
|
||||||
|
return cy.getByTestId('zoom-to-fit');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actions
|
* Actions
|
||||||
*/
|
*/
|
||||||
|
@ -170,3 +178,19 @@ export function clickManualChatButton() {
|
||||||
export function openNode(nodeName: string) {
|
export function openNode(nodeName: string) {
|
||||||
getNodeByName(nodeName).dblclick();
|
getNodeByName(nodeName).dblclick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function saveWorkflowOnButtonClick() {
|
||||||
|
cy.intercept('POST', '/rest/workflows').as('createWorkflow');
|
||||||
|
getSaveButton().should('contain', 'Save');
|
||||||
|
getSaveButton().click();
|
||||||
|
getSaveButton().should('contain', 'Saved');
|
||||||
|
cy.url().should('not.have.string', '/new');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pasteWorkflow(workflow: object) {
|
||||||
|
cy.get('body').paste(JSON.stringify(workflow));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clickZoomToFit() {
|
||||||
|
getZoomToFitButton().click();
|
||||||
|
}
|
||||||
|
|
140
cypress/e2e/47-subworkflow-debugging.cy.ts
Normal file
140
cypress/e2e/47-subworkflow-debugging.cy.ts
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
import {
|
||||||
|
getExecutionPreviewOutputPanelRelatedExecutionLink,
|
||||||
|
getExecutionsSidebar,
|
||||||
|
getWorkflowExecutionPreviewIframe,
|
||||||
|
openExecutionPreviewNode,
|
||||||
|
} from '../composables/executions';
|
||||||
|
import {
|
||||||
|
changeOutputRunSelector,
|
||||||
|
getOutputPanelItemsCount,
|
||||||
|
getOutputPanelRelatedExecutionLink,
|
||||||
|
getOutputRunSelectorInput,
|
||||||
|
getOutputTableHeaders,
|
||||||
|
getOutputTableRows,
|
||||||
|
getOutputTbodyCell,
|
||||||
|
} from '../composables/ndv';
|
||||||
|
import {
|
||||||
|
clickExecuteWorkflowButton,
|
||||||
|
clickZoomToFit,
|
||||||
|
getCanvasNodes,
|
||||||
|
navigateToNewWorkflowPage,
|
||||||
|
openNode,
|
||||||
|
pasteWorkflow,
|
||||||
|
saveWorkflowOnButtonClick,
|
||||||
|
} from '../composables/workflow';
|
||||||
|
import SUBWORKFLOW_DEBUGGING_EXAMPLE from '../fixtures/Subworkflow-debugging-execute-workflow.json';
|
||||||
|
|
||||||
|
describe('Subworkflow debugging', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
navigateToNewWorkflowPage();
|
||||||
|
pasteWorkflow(SUBWORKFLOW_DEBUGGING_EXAMPLE);
|
||||||
|
saveWorkflowOnButtonClick();
|
||||||
|
getCanvasNodes().should('have.length', 11);
|
||||||
|
clickZoomToFit();
|
||||||
|
|
||||||
|
clickExecuteWorkflowButton();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('can inspect sub executed workflow', () => {
|
||||||
|
it('(Run once with all items/ Wait for Sub-workflow completion) (default behavior)', () => {
|
||||||
|
openNode('Execute Workflow with param');
|
||||||
|
|
||||||
|
getOutputPanelItemsCount().should('contain.text', '2 items, 1 sub-execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('contain.text', 'Inspect Sub-Execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('have.attr', 'href');
|
||||||
|
|
||||||
|
// ensure workflow executed and waited on output
|
||||||
|
getOutputTableHeaders().should('have.length', 2);
|
||||||
|
getOutputTbodyCell(1, 0).should('have.text', 'world Natalie Moore');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('(Run once for each item/ Wait for Sub-workflow completion)', () => {
|
||||||
|
openNode('Execute Workflow with param1');
|
||||||
|
|
||||||
|
getOutputPanelItemsCount().should('contain.text', '2 items, 2 sub-execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('not.exist');
|
||||||
|
|
||||||
|
// ensure workflow executed and waited on output
|
||||||
|
getOutputTableHeaders().should('have.length', 3);
|
||||||
|
getOutputTbodyCell(1, 0).find('a').should('have.attr', 'href');
|
||||||
|
getOutputTbodyCell(1, 1).should('have.text', 'world Natalie Moore');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('(Run once with all items/ Wait for Sub-workflow completion)', () => {
|
||||||
|
openNode('Execute Workflow with param2');
|
||||||
|
|
||||||
|
getOutputPanelItemsCount().should('not.exist');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('contain.text', 'Inspect Sub-Execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('have.attr', 'href');
|
||||||
|
|
||||||
|
// ensure workflow executed but returned same data as input
|
||||||
|
getOutputRunSelectorInput().should('have.value', '2 of 2 (3 items, 1 sub-execution)');
|
||||||
|
getOutputTableHeaders().should('have.length', 6);
|
||||||
|
getOutputTableHeaders().eq(0).should('have.text', 'uid');
|
||||||
|
getOutputTableRows().should('have.length', 4);
|
||||||
|
getOutputTbodyCell(1, 1).should('include.text', 'Jon_Ebert@yahoo.com');
|
||||||
|
|
||||||
|
changeOutputRunSelector('1 of 2 (2 items, 1 sub-execution)');
|
||||||
|
getOutputRunSelectorInput().should('have.value', '1 of 2 (2 items, 1 sub-execution)');
|
||||||
|
getOutputTableHeaders().should('have.length', 6);
|
||||||
|
getOutputTableHeaders().eq(0).should('have.text', 'uid');
|
||||||
|
getOutputTableRows().should('have.length', 3);
|
||||||
|
getOutputTbodyCell(1, 1).should('include.text', 'Terry.Dach@hotmail.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('(Run once for each item/ Wait for Sub-workflow completion)', () => {
|
||||||
|
openNode('Execute Workflow with param3');
|
||||||
|
|
||||||
|
// ensure workflow executed but returned same data as input
|
||||||
|
getOutputRunSelectorInput().should('have.value', '2 of 2 (3 items, 3 sub-executions)');
|
||||||
|
getOutputTableHeaders().should('have.length', 7);
|
||||||
|
getOutputTableHeaders().eq(1).should('have.text', 'uid');
|
||||||
|
getOutputTableRows().should('have.length', 4);
|
||||||
|
getOutputTbodyCell(1, 0).find('a').should('have.attr', 'href');
|
||||||
|
getOutputTbodyCell(1, 2).should('include.text', 'Jon_Ebert@yahoo.com');
|
||||||
|
|
||||||
|
changeOutputRunSelector('1 of 2 (2 items, 2 sub-executions)');
|
||||||
|
getOutputRunSelectorInput().should('have.value', '1 of 2 (2 items, 2 sub-executions)');
|
||||||
|
getOutputTableHeaders().should('have.length', 7);
|
||||||
|
getOutputTableHeaders().eq(1).should('have.text', 'uid');
|
||||||
|
getOutputTableRows().should('have.length', 3);
|
||||||
|
|
||||||
|
getOutputTbodyCell(1, 0).find('a').should('have.attr', 'href');
|
||||||
|
getOutputTbodyCell(1, 2).should('include.text', 'Terry.Dach@hotmail.com');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can inspect parent executions', () => {
|
||||||
|
cy.url().then((workflowUrl) => {
|
||||||
|
openNode('Execute Workflow with param');
|
||||||
|
|
||||||
|
getOutputPanelItemsCount().should('contain.text', '2 items, 1 sub-execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('contain.text', 'Inspect Sub-Execution');
|
||||||
|
getOutputPanelRelatedExecutionLink().should('have.attr', 'href');
|
||||||
|
|
||||||
|
// ensure workflow executed and waited on output
|
||||||
|
getOutputTableHeaders().should('have.length', 2);
|
||||||
|
getOutputTbodyCell(1, 0).should('have.text', 'world Natalie Moore');
|
||||||
|
|
||||||
|
// cypress cannot handle new tabs so removing it
|
||||||
|
getOutputPanelRelatedExecutionLink().invoke('removeAttr', 'target').click();
|
||||||
|
|
||||||
|
getExecutionsSidebar().should('be.visible');
|
||||||
|
getWorkflowExecutionPreviewIframe().should('be.visible');
|
||||||
|
openExecutionPreviewNode('Execute Workflow Trigger');
|
||||||
|
|
||||||
|
getExecutionPreviewOutputPanelRelatedExecutionLink().should(
|
||||||
|
'include.text',
|
||||||
|
'Inspect Parent Execution',
|
||||||
|
);
|
||||||
|
|
||||||
|
getExecutionPreviewOutputPanelRelatedExecutionLink()
|
||||||
|
.invoke('removeAttr', 'target')
|
||||||
|
.click({ force: true });
|
||||||
|
|
||||||
|
cy.url().then((currentUrl) => {
|
||||||
|
expect(currentUrl === workflowUrl);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
354
cypress/fixtures/Subworkflow-debugging-execute-workflow.json
Normal file
354
cypress/fixtures/Subworkflow-debugging-execute-workflow.json
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
{
|
||||||
|
"meta": {
|
||||||
|
"instanceId": "08ce71ad998aeaade0abedb8dd96153d8eaa03fcb84cfccc1530095bf9ee478e"
|
||||||
|
},
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {},
|
||||||
|
"id": "4535ce3e-280e-49b0-8854-373472ec86d1",
|
||||||
|
"name": "When clicking ‘Test workflow’",
|
||||||
|
"type": "n8n-nodes-base.manualTrigger",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [80, 860]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"category": "randomData",
|
||||||
|
"randomDataSeed": "0",
|
||||||
|
"randomDataCount": 2
|
||||||
|
},
|
||||||
|
"id": "d7fba18a-d51f-4509-af45-68cd9425ac6b",
|
||||||
|
"name": "DebugHelper1",
|
||||||
|
"type": "n8n-nodes-base.debugHelper",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [280, 860]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"source": "parameter",
|
||||||
|
"workflowJson": "{\n \"meta\": {\n \"instanceId\": \"a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0\"\n },\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"00600a51-e63a-4b6e-93f5-f01d50a21e0c\",\n \"name\": \"Execute Workflow Trigger\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"87ff01af-2e28-48da-ae6c-304040200b15\",\n \"name\": \"hello\",\n \"value\": \"=world {{ $json.firstname }} {{ $json.lastname }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"includeOtherFields\": false,\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 280,\n 0\n ],\n \"id\": \"642219a1-d655-4a30-af5c-fcccbb690322\",\n \"name\": \"Edit Fields\"\n }\n ],\n \"connections\": {\n \"Execute Workflow Trigger\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {}\n}",
|
||||||
|
"mode": "each",
|
||||||
|
"options": {
|
||||||
|
"waitForSubWorkflow": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.executeWorkflow",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [680, 1540],
|
||||||
|
"id": "f90a25da-dd89-4bf8-8f5b-bf8ee1de0b70",
|
||||||
|
"name": "Execute Workflow with param3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "c93f26bd-3489-467b-909e-6462e1463707",
|
||||||
|
"name": "uid",
|
||||||
|
"value": "={{ $json.uid }}",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3dd706ce-d925-4219-8531-ad12369972fe",
|
||||||
|
"name": "email",
|
||||||
|
"value": "={{ $json.email }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [900, 1540],
|
||||||
|
"id": "3be57648-3be8-4b0f-abfa-8fdcafee804d",
|
||||||
|
"name": "Edit Fields8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"source": "parameter",
|
||||||
|
"workflowJson": "{\n \"meta\": {\n \"instanceId\": \"a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0\"\n },\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"00600a51-e63a-4b6e-93f5-f01d50a21e0c\",\n \"name\": \"Execute Workflow Trigger\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"87ff01af-2e28-48da-ae6c-304040200b15\",\n \"name\": \"hello\",\n \"value\": \"=world {{ $json.firstname }} {{ $json.lastname }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"includeOtherFields\": false,\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 280,\n 0\n ],\n \"id\": \"642219a1-d655-4a30-af5c-fcccbb690322\",\n \"name\": \"Edit Fields\"\n }\n ],\n \"connections\": {\n \"Execute Workflow Trigger\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {}\n}",
|
||||||
|
"options": {
|
||||||
|
"waitForSubWorkflow": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.executeWorkflow",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [620, 1220],
|
||||||
|
"id": "dabc2356-3660-4d17-b305-936a002029ba",
|
||||||
|
"name": "Execute Workflow with param2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "c93f26bd-3489-467b-909e-6462e1463707",
|
||||||
|
"name": "uid",
|
||||||
|
"value": "={{ $json.uid }}",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3dd706ce-d925-4219-8531-ad12369972fe",
|
||||||
|
"name": "email",
|
||||||
|
"value": "={{ $json.email }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [840, 1220],
|
||||||
|
"id": "9d2a9dda-e2a1-43e8-a66f-a8a555692e5f",
|
||||||
|
"name": "Edit Fields7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"source": "parameter",
|
||||||
|
"workflowJson": "{\n \"meta\": {\n \"instanceId\": \"a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0\"\n },\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"00600a51-e63a-4b6e-93f5-f01d50a21e0c\",\n \"name\": \"Execute Workflow Trigger\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"87ff01af-2e28-48da-ae6c-304040200b15\",\n \"name\": \"hello\",\n \"value\": \"=world {{ $json.firstname }} {{ $json.lastname }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"includeOtherFields\": false,\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 280,\n 0\n ],\n \"id\": \"642219a1-d655-4a30-af5c-fcccbb690322\",\n \"name\": \"Edit Fields\"\n }\n ],\n \"connections\": {\n \"Execute Workflow Trigger\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {}\n}",
|
||||||
|
"mode": "each",
|
||||||
|
"options": {
|
||||||
|
"waitForSubWorkflow": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.executeWorkflow",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [560, 900],
|
||||||
|
"id": "07e47f60-622a-484c-ab24-35f6f2280595",
|
||||||
|
"name": "Execute Workflow with param1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "c93f26bd-3489-467b-909e-6462e1463707",
|
||||||
|
"name": "uid",
|
||||||
|
"value": "={{ $json.uid }}",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3dd706ce-d925-4219-8531-ad12369972fe",
|
||||||
|
"name": "email",
|
||||||
|
"value": "={{ $json.email }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [760, 900],
|
||||||
|
"id": "80563d0a-0bab-444f-a04c-4041a505d78b",
|
||||||
|
"name": "Edit Fields6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"source": "parameter",
|
||||||
|
"workflowJson": "{\n \"meta\": {\n \"instanceId\": \"a786b722078489c1fa382391a9f3476c2784761624deb2dfb4634827256d51a0\"\n },\n \"nodes\": [\n {\n \"parameters\": {},\n \"type\": \"n8n-nodes-base.executeWorkflowTrigger\",\n \"typeVersion\": 1,\n \"position\": [\n 0,\n 0\n ],\n \"id\": \"00600a51-e63a-4b6e-93f5-f01d50a21e0c\",\n \"name\": \"Execute Workflow Trigger\"\n },\n {\n \"parameters\": {\n \"assignments\": {\n \"assignments\": [\n {\n \"id\": \"87ff01af-2e28-48da-ae6c-304040200b15\",\n \"name\": \"hello\",\n \"value\": \"=world {{ $json.firstname }} {{ $json.lastname }}\",\n \"type\": \"string\"\n }\n ]\n },\n \"includeOtherFields\": false,\n \"options\": {}\n },\n \"type\": \"n8n-nodes-base.set\",\n \"typeVersion\": 3.4,\n \"position\": [\n 280,\n 0\n ],\n \"id\": \"642219a1-d655-4a30-af5c-fcccbb690322\",\n \"name\": \"Edit Fields\"\n }\n ],\n \"connections\": {\n \"Execute Workflow Trigger\": {\n \"main\": [\n [\n {\n \"node\": \"Edit Fields\",\n \"type\": \"main\",\n \"index\": 0\n }\n ]\n ]\n }\n },\n \"pinData\": {}\n}",
|
||||||
|
"options": {
|
||||||
|
"waitForSubWorkflow": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.executeWorkflow",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [560, 580],
|
||||||
|
"id": "f04af481-f4d9-4d91-a60a-a377580e8393",
|
||||||
|
"name": "Execute Workflow with param"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"assignments": {
|
||||||
|
"assignments": [
|
||||||
|
{
|
||||||
|
"id": "c93f26bd-3489-467b-909e-6462e1463707",
|
||||||
|
"name": "uid",
|
||||||
|
"value": "={{ $json.uid }}",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3dd706ce-d925-4219-8531-ad12369972fe",
|
||||||
|
"name": "email",
|
||||||
|
"value": "={{ $json.email }}",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [760, 580],
|
||||||
|
"id": "80c10607-a0ac-4090-86a1-890da0a2aa52",
|
||||||
|
"name": "Edit Fields2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Execute Workflow (Run once with all items/ DONT Wait for Sub-workflow completion)",
|
||||||
|
"height": 254.84308966329985,
|
||||||
|
"width": 457.58120569815793
|
||||||
|
},
|
||||||
|
"id": "534ef523-3453-4a16-9ff0-8ac9f025d47d",
|
||||||
|
"name": "Sticky Note5",
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [500, 1080]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Execute Workflow (Run once with for each item/ DONT Wait for Sub-workflow completion) ",
|
||||||
|
"height": 284.59778445962905,
|
||||||
|
"width": 457.58120569815793
|
||||||
|
},
|
||||||
|
"id": "838f0fa3-5ee4-4d1a-afb8-42e009f1aa9e",
|
||||||
|
"name": "Sticky Note4",
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [580, 1400]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"category": "randomData",
|
||||||
|
"randomDataSeed": "1",
|
||||||
|
"randomDataCount": 3
|
||||||
|
},
|
||||||
|
"id": "86699a49-2aa7-488e-8ea9-828404c98f08",
|
||||||
|
"name": "DebugHelper",
|
||||||
|
"type": "n8n-nodes-base.debugHelper",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [320, 1120]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Execute Workflow (Run once with for each item/ Wait for Sub-workflow completion) ",
|
||||||
|
"height": 284.59778445962905,
|
||||||
|
"width": 457.58120569815793
|
||||||
|
},
|
||||||
|
"id": "885d35f0-8ae6-45ec-821b-a82c27e7577a",
|
||||||
|
"name": "Sticky Note3",
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [480, 760]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"content": "## Execute Workflow (Run once with all items/ Wait for Sub-workflow completion) (default behavior)",
|
||||||
|
"height": 254.84308966329985,
|
||||||
|
"width": 457.58120569815793
|
||||||
|
},
|
||||||
|
"id": "505bd7f2-767e-41b8-9325-77300aed5883",
|
||||||
|
"name": "Sticky Note2",
|
||||||
|
"type": "n8n-nodes-base.stickyNote",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [460, 460]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": {
|
||||||
|
"When clicking ‘Test workflow’": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "DebugHelper1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "DebugHelper",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"DebugHelper1": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param3",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param2",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Execute Workflow with param3": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields8",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Execute Workflow with param2": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields7",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Execute Workflow with param1": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields6",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Execute Workflow with param": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Edit Fields2",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"DebugHelper": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param2",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Execute Workflow with param3",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinData": {}
|
||||||
|
}
|
|
@ -12,8 +12,11 @@ import type { INodeExecutionData, ITaskData, ITaskMetadata } from 'n8n-workflow'
|
||||||
import { setActivePinia } from 'pinia';
|
import { setActivePinia } from 'pinia';
|
||||||
import { useNodeTypesStore } from '../stores/nodeTypes.store';
|
import { useNodeTypesStore } from '../stores/nodeTypes.store';
|
||||||
|
|
||||||
const { openRelatedExecution } = vi.hoisted(() => ({
|
const MOCK_EXECUTION_URL = 'execution.url/123';
|
||||||
openRelatedExecution: vi.fn(),
|
|
||||||
|
const { trackOpeningRelatedExecution, resolveRelatedExecutionUrl } = vi.hoisted(() => ({
|
||||||
|
trackOpeningRelatedExecution: vi.fn(),
|
||||||
|
resolveRelatedExecutionUrl: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('vue-router', () => {
|
vi.mock('vue-router', () => {
|
||||||
|
@ -26,7 +29,8 @@ vi.mock('vue-router', () => {
|
||||||
|
|
||||||
vi.mock('@/composables/useExecutionHelpers', () => ({
|
vi.mock('@/composables/useExecutionHelpers', () => ({
|
||||||
useExecutionHelpers: () => ({
|
useExecutionHelpers: () => ({
|
||||||
openRelatedExecution,
|
trackOpeningRelatedExecution,
|
||||||
|
resolveRelatedExecutionUrl,
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -42,6 +46,10 @@ const nodes = [
|
||||||
] as INodeUi[];
|
] as INodeUi[];
|
||||||
|
|
||||||
describe('RunData', () => {
|
describe('RunData', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
resolveRelatedExecutionUrl.mockReturnValue('execution.url/123');
|
||||||
|
});
|
||||||
|
|
||||||
it("should render pin button in output panel disabled when there's binary data", () => {
|
it("should render pin button in output panel disabled when there's binary data", () => {
|
||||||
const { getByTestId } = render({
|
const { getByTestId } = render({
|
||||||
defaultRunItems: [
|
defaultRunItems: [
|
||||||
|
@ -253,11 +261,13 @@ describe('RunData', () => {
|
||||||
|
|
||||||
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
||||||
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Sub-Execution 123');
|
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Sub-Execution 123');
|
||||||
|
expect(resolveRelatedExecutionUrl).toHaveBeenCalledWith(metadata);
|
||||||
|
expect(getByTestId('related-execution-link')).toHaveAttribute('href', MOCK_EXECUTION_URL);
|
||||||
|
|
||||||
expect(getByTestId('ndv-items-count')).toHaveTextContent('1 item, 1 sub-execution');
|
expect(getByTestId('ndv-items-count')).toHaveTextContent('1 item, 1 sub-execution');
|
||||||
|
|
||||||
getByTestId('related-execution-link').click();
|
getByTestId('related-execution-link').click();
|
||||||
expect(openRelatedExecution).toHaveBeenCalledWith(metadata, 'table');
|
expect(trackOpeningRelatedExecution).toHaveBeenCalledWith(metadata, 'table');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render parent-execution link in header', async () => {
|
it('should render parent-execution link in header', async () => {
|
||||||
|
@ -280,11 +290,13 @@ describe('RunData', () => {
|
||||||
|
|
||||||
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
||||||
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Parent Execution 123');
|
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Parent Execution 123');
|
||||||
|
expect(resolveRelatedExecutionUrl).toHaveBeenCalledWith(metadata);
|
||||||
|
expect(getByTestId('related-execution-link')).toHaveAttribute('href', MOCK_EXECUTION_URL);
|
||||||
|
|
||||||
expect(getByTestId('ndv-items-count')).toHaveTextContent('1 item');
|
expect(getByTestId('ndv-items-count')).toHaveTextContent('1 item');
|
||||||
|
|
||||||
getByTestId('related-execution-link').click();
|
getByTestId('related-execution-link').click();
|
||||||
expect(openRelatedExecution).toHaveBeenCalledWith(metadata, 'table');
|
expect(trackOpeningRelatedExecution).toHaveBeenCalledWith(metadata, 'table');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render sub-execution link in header with multiple items', async () => {
|
it('should render sub-execution link in header with multiple items', async () => {
|
||||||
|
@ -311,11 +323,13 @@ describe('RunData', () => {
|
||||||
|
|
||||||
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
expect(getByTestId('related-execution-link')).toBeInTheDocument();
|
||||||
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Sub-Execution 123');
|
expect(getByTestId('related-execution-link')).toHaveTextContent('Inspect Sub-Execution 123');
|
||||||
|
expect(resolveRelatedExecutionUrl).toHaveBeenCalledWith(metadata);
|
||||||
|
expect(getByTestId('related-execution-link')).toHaveAttribute('href', MOCK_EXECUTION_URL);
|
||||||
|
|
||||||
expect(getByTestId('ndv-items-count')).toHaveTextContent('2 items, 3 sub-executions');
|
expect(getByTestId('ndv-items-count')).toHaveTextContent('2 items, 3 sub-executions');
|
||||||
|
|
||||||
getByTestId('related-execution-link').click();
|
getByTestId('related-execution-link').click();
|
||||||
expect(openRelatedExecution).toHaveBeenCalledWith(metadata, 'json');
|
expect(trackOpeningRelatedExecution).toHaveBeenCalledWith(metadata, 'json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render sub-execution link in header with multiple runs', async () => {
|
it('should render sub-execution link in header with multiple runs', async () => {
|
||||||
|
@ -359,7 +373,7 @@ describe('RunData', () => {
|
||||||
expect(getByTestId('run-selector')).toBeInTheDocument();
|
expect(getByTestId('run-selector')).toBeInTheDocument();
|
||||||
|
|
||||||
getByTestId('related-execution-link').click();
|
getByTestId('related-execution-link').click();
|
||||||
expect(openRelatedExecution).toHaveBeenCalledWith(metadata, 'json');
|
expect(trackOpeningRelatedExecution).toHaveBeenCalledWith(metadata, 'json');
|
||||||
});
|
});
|
||||||
|
|
||||||
const render = ({
|
const render = ({
|
||||||
|
|
|
@ -182,7 +182,7 @@ const nodeHelpers = useNodeHelpers();
|
||||||
const externalHooks = useExternalHooks();
|
const externalHooks = useExternalHooks();
|
||||||
const telemetry = useTelemetry();
|
const telemetry = useTelemetry();
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const { openRelatedExecution } = useExecutionHelpers();
|
const { trackOpeningRelatedExecution, resolveRelatedExecutionUrl } = useExecutionHelpers();
|
||||||
|
|
||||||
const node = toRef(props, 'node');
|
const node = toRef(props, 'node');
|
||||||
|
|
||||||
|
@ -1414,7 +1414,9 @@ defineExpose({ enterEditMode });
|
||||||
"
|
"
|
||||||
:class="$style.relatedExecutionInfo"
|
:class="$style.relatedExecutionInfo"
|
||||||
data-test-id="related-execution-link"
|
data-test-id="related-execution-link"
|
||||||
@click.stop="openRelatedExecution(activeTaskMetadata, displayMode)"
|
:href="resolveRelatedExecutionUrl(activeTaskMetadata)"
|
||||||
|
target="_blank"
|
||||||
|
@click.stop="trackOpeningRelatedExecution(activeTaskMetadata, displayMode)"
|
||||||
>
|
>
|
||||||
<N8nIcon icon="external-link-alt" size="xsmall" />
|
<N8nIcon icon="external-link-alt" size="xsmall" />
|
||||||
{{ getExecutionLinkLabel(activeTaskMetadata) }}
|
{{ getExecutionLinkLabel(activeTaskMetadata) }}
|
||||||
|
@ -1496,7 +1498,9 @@ defineExpose({ enterEditMode });
|
||||||
"
|
"
|
||||||
:class="$style.relatedExecutionInfo"
|
:class="$style.relatedExecutionInfo"
|
||||||
data-test-id="related-execution-link"
|
data-test-id="related-execution-link"
|
||||||
@click.stop="openRelatedExecution(activeTaskMetadata, displayMode)"
|
:href="resolveRelatedExecutionUrl(activeTaskMetadata)"
|
||||||
|
target="_blank"
|
||||||
|
@click.stop="trackOpeningRelatedExecution(activeTaskMetadata, displayMode)"
|
||||||
>
|
>
|
||||||
<N8nIcon icon="external-link-alt" size="xsmall" />
|
<N8nIcon icon="external-link-alt" size="xsmall" />
|
||||||
{{ getExecutionLinkLabel(activeTaskMetadata) }}
|
{{ getExecutionLinkLabel(activeTaskMetadata) }}
|
||||||
|
|
|
@ -32,7 +32,7 @@ const props = defineProps<{
|
||||||
const nodeTypesStore = useNodeTypesStore();
|
const nodeTypesStore = useNodeTypesStore();
|
||||||
const workflowsStore = useWorkflowsStore();
|
const workflowsStore = useWorkflowsStore();
|
||||||
|
|
||||||
const { openRelatedExecution } = useExecutionHelpers();
|
const { trackOpeningRelatedExecution, resolveRelatedExecutionUrl } = useExecutionHelpers();
|
||||||
|
|
||||||
type TokenUsageData = {
|
type TokenUsageData = {
|
||||||
completionTokens: number;
|
completionTokens: number;
|
||||||
|
@ -140,7 +140,11 @@ const outputError = computed(() => {
|
||||||
</n8n-tooltip>
|
</n8n-tooltip>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="runMeta?.subExecution">
|
<li v-if="runMeta?.subExecution">
|
||||||
<a @click.stop="openRelatedExecution(runMeta, 'ai')">
|
<a
|
||||||
|
:href="resolveRelatedExecutionUrl(runMeta)"
|
||||||
|
target="_blank"
|
||||||
|
@click.stop="trackOpeningRelatedExecution(runMeta, 'ai')"
|
||||||
|
>
|
||||||
<N8nIcon icon="external-link-alt" size="xsmall" />
|
<N8nIcon icon="external-link-alt" size="xsmall" />
|
||||||
{{
|
{{
|
||||||
$locale.baseText('runData.openSubExecution', {
|
$locale.baseText('runData.openSubExecution', {
|
||||||
|
|
|
@ -64,7 +64,7 @@ const workflowsStore = useWorkflowsStore();
|
||||||
|
|
||||||
const i18n = useI18n();
|
const i18n = useI18n();
|
||||||
const telemetry = useTelemetry();
|
const telemetry = useTelemetry();
|
||||||
const { openRelatedExecution } = useExecutionHelpers();
|
const { trackOpeningRelatedExecution, resolveRelatedExecutionUrl } = useExecutionHelpers();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
hoveringItem,
|
hoveringItem,
|
||||||
|
@ -455,7 +455,9 @@ watch(focusedMappableInput, (curr) => {
|
||||||
icon="external-link-alt"
|
icon="external-link-alt"
|
||||||
data-test-id="debug-sub-execution"
|
data-test-id="debug-sub-execution"
|
||||||
size="mini"
|
size="mini"
|
||||||
@click="openRelatedExecution(tableData.metadata.data[index1], 'table')"
|
:href="resolveRelatedExecutionUrl(tableData.metadata.data[index1])"
|
||||||
|
target="_blank"
|
||||||
|
@click="trackOpeningRelatedExecution(tableData.metadata.data[index1], 'table')"
|
||||||
/>
|
/>
|
||||||
</N8nTooltip>
|
</N8nTooltip>
|
||||||
</td>
|
</td>
|
||||||
|
@ -582,15 +584,20 @@ watch(focusedMappableInput, (curr) => {
|
||||||
placement="left"
|
placement="left"
|
||||||
:hide-after="0"
|
:hide-after="0"
|
||||||
>
|
>
|
||||||
<N8nIconButton
|
<a
|
||||||
v-if="tableData.metadata.data[index1]"
|
v-if="tableData.metadata.data[index1]"
|
||||||
v-show="showExecutionLink(index1)"
|
v-show="showExecutionLink(index1)"
|
||||||
type="secondary"
|
:href="resolveRelatedExecutionUrl(tableData.metadata.data[index1])"
|
||||||
icon="external-link-alt"
|
target="_blank"
|
||||||
data-test-id="debug-sub-execution"
|
@click="trackOpeningRelatedExecution(tableData.metadata.data[index1], 'table')"
|
||||||
size="mini"
|
>
|
||||||
@click="openRelatedExecution(tableData.metadata.data[index1], 'table')"
|
<N8nIconButton
|
||||||
/>
|
type="secondary"
|
||||||
|
icon="external-link-alt"
|
||||||
|
data-test-id="debug-sub-execution"
|
||||||
|
size="mini"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
</N8nTooltip>
|
</N8nTooltip>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
|
|
|
@ -84,7 +84,24 @@ export function useExecutionHelpers() {
|
||||||
window.open(route.href, '_blank');
|
window.open(route.href, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
function openRelatedExecution(
|
function resolveRelatedExecutionUrl(metadata: {
|
||||||
|
parentExecution?: RelatedExecution;
|
||||||
|
subExecution?: RelatedExecution;
|
||||||
|
}): string {
|
||||||
|
const info = metadata.parentExecution || metadata.subExecution;
|
||||||
|
if (!info) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const { workflowId, executionId } = info;
|
||||||
|
|
||||||
|
return router.resolve({
|
||||||
|
name: VIEWS.EXECUTION_PREVIEW,
|
||||||
|
params: { name: workflowId, executionId },
|
||||||
|
}).fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trackOpeningRelatedExecution(
|
||||||
metadata: { parentExecution?: RelatedExecution; subExecution?: RelatedExecution },
|
metadata: { parentExecution?: RelatedExecution; subExecution?: RelatedExecution },
|
||||||
view: IRunDataDisplayMode,
|
view: IRunDataDisplayMode,
|
||||||
) {
|
) {
|
||||||
|
@ -93,8 +110,6 @@ export function useExecutionHelpers() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openExecutionInNewTab(info.executionId, info.workflowId);
|
|
||||||
|
|
||||||
telemetry.track(
|
telemetry.track(
|
||||||
metadata.parentExecution
|
metadata.parentExecution
|
||||||
? 'User clicked parent execution button'
|
? 'User clicked parent execution button'
|
||||||
|
@ -110,6 +125,7 @@ export function useExecutionHelpers() {
|
||||||
formatDate,
|
formatDate,
|
||||||
isExecutionRetriable,
|
isExecutionRetriable,
|
||||||
openExecutionInNewTab,
|
openExecutionInNewTab,
|
||||||
openRelatedExecution,
|
trackOpeningRelatedExecution,
|
||||||
|
resolveRelatedExecutionUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue