Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(editor): Debug execution #6834

Merged
merged 71 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
96083ca
feat(editor): Debug execution
cstuncsik Aug 2, 2023
093a1cd
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 2, 2023
0d9508d
test: add workflow routes tests
cstuncsik Aug 2, 2023
25fd6aa
fix(editor): debug route name
cstuncsik Aug 2, 2023
dfc0943
feat(editor): pin execution data
cstuncsik Aug 3, 2023
5bb5889
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 3, 2023
d374bb4
fix(editor): type fix
cstuncsik Aug 3, 2023
a84d7f7
fix(editor): make debugging a composable
cstuncsik Aug 3, 2023
d1f9326
fix(editor): remove lint changes to reduce PR cognitive load
cstuncsik Aug 3, 2023
75eadfb
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 3, 2023
cf1a444
fix(editor): remove lint changes to reduce PR cognitive load
cstuncsik Aug 3, 2023
bc74f1a
fix(editor): remove lint changes to reduce PR cognitive load
cstuncsik Aug 3, 2023
71bdc77
fix(editor): remove lint changes to reduce PR cognitive load
cstuncsik Aug 3, 2023
977fc06
fix(editor): extend comment
cstuncsik Aug 3, 2023
3d1258c
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 3, 2023
cfc6a14
fix(editor): replaces spaces to tab!?
cstuncsik Aug 4, 2023
d6bf0ae
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 4, 2023
2a21149
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 7, 2023
6322488
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 8, 2023
31a7ba5
fix(editor): adding Debug button
cstuncsik Aug 8, 2023
c16e211
fix(editor): adding Debug button
cstuncsik Aug 8, 2023
f41ea04
fix(editor): update Debug button
cstuncsik Aug 9, 2023
b52717e
fix(editor): remove unused code
cstuncsik Aug 9, 2023
667fecf
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 9, 2023
37cdf46
fix(editor): update debug button
cstuncsik Aug 9, 2023
824c57b
fix(editor): update router to deny debug route if feature is not enabled
cstuncsik Aug 9, 2023
0bb1aa6
fix(editor): apply execution data first to debug
cstuncsik Aug 9, 2023
24c43ef
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 9, 2023
e1e1889
fix(editor): checking feature
cstuncsik Aug 9, 2023
13ace63
fix(editor): confirm unpinning
cstuncsik Aug 10, 2023
1fb7a30
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 10, 2023
08800e6
fix(editor): pin root nodes
cstuncsik Aug 10, 2023
498a872
fix(editor): remove unnecessary code
cstuncsik Aug 10, 2023
cce377a
fix(editor): add toast messages
cstuncsik Aug 10, 2023
436929b
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 10, 2023
1eb1bcb
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 11, 2023
430cd16
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 14, 2023
7d369d3
fix(editor): enable moving nodes in debug mode
cstuncsik Aug 14, 2023
ffb6063
fix(editor): update debug button and unpin tooltip
cstuncsik Aug 14, 2023
98e6e2d
fix(editor): update button text color
cstuncsik Aug 14, 2023
cbfc04a
fix(editor): change debug data loading strategy
cstuncsik Aug 14, 2023
45e76ea
fix(editor): change debug data loading strategy
cstuncsik Aug 14, 2023
ac33cdc
fix(editor): change debug data loading strategy
cstuncsik Aug 15, 2023
eaf5f99
fix(editor): remove unnecessary async
cstuncsik Aug 15, 2023
6b8a904
fix(editor): load back execution when cancelling pinning confirmation
cstuncsik Aug 15, 2023
80338aa
fix(editor): load back execution when cancelling pinning confirmation
cstuncsik Aug 15, 2023
f30b86a
Revert "fix(editor): load back execution when cancelling pinning conf…
cstuncsik Aug 15, 2023
06dcc67
fix(editor): load back execution when cancelling pinning confirmation
cstuncsik Aug 15, 2023
8b40850
fix(editor): fix pinned data reactivity in workflows store
cstuncsik Aug 15, 2023
7611d46
Revert "fix(editor): fix pinned data reactivity in workflows store"
cstuncsik Aug 15, 2023
e9bed4e
fix(editor): fix pinned data reactivity in workflows store
cstuncsik Aug 15, 2023
818865a
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 15, 2023
34bcc4e
fix(editor): add comment
cstuncsik Aug 15, 2023
451cd00
fix(editor): fix button and add paywall modal
cstuncsik Aug 16, 2023
da4b76f
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 16, 2023
2e5ef26
fix(editor): move debug button click handler into composable
cstuncsik Aug 16, 2023
23a9a7b
fix(editor): remove unused store
cstuncsik Aug 16, 2023
731c39f
fix(editor): remove unused store
cstuncsik Aug 16, 2023
345bdab
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 18, 2023
fa4376a
test: E2E debug button
cstuncsik Aug 18, 2023
e8a66f3
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 18, 2023
65a53d1
test: E2E debugging
cstuncsik Aug 18, 2023
0c94d46
test: E2E debugging
cstuncsik Aug 18, 2023
d416c05
test: extend E2E debugging
cstuncsik Aug 20, 2023
8bd0443
fix(editor): update debug link and add unit test
cstuncsik Aug 20, 2023
98fd63a
test: update debug link unit test
cstuncsik Aug 20, 2023
6d7b0d6
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 20, 2023
cfb7ac6
fix(editor): use Vue render function to produce confirm message
cstuncsik Aug 21, 2023
234f107
fix(editor): remove unused import
cstuncsik Aug 21, 2023
2432bb3
Merge remote-tracking branch 'origin/master' into pay-668-debug-mode
cstuncsik Aug 21, 2023
646b277
chore: merge master
krynble Aug 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions cypress/e2e/28-debug.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import {
HTTP_REQUEST_NODE_NAME, IF_NODE_NAME,
INSTANCE_OWNER,
MANUAL_TRIGGER_NODE_NAME,
SET_NODE_NAME,
} from '../constants';
import { WorkflowPage, NDV, WorkflowExecutionsTab } from '../pages';

const workflowPage = new WorkflowPage();
const ndv = new NDV();
const executionsTab = new WorkflowExecutionsTab();

describe('Debug', () => {
it('should be able to debug executions', () => {
cy.intercept('GET', '/rest/settings', (req) => {
req.on('response', (res) => {
res.send({
data: { ...res.body.data, enterprise: { debugInEditor: true } },
});
});
}).as('loadSettings');
cy.intercept('GET', '/rest/executions?filter=*').as('getExecutions');
cy.intercept('GET', '/rest/executions/*').as('getExecution');
cy.intercept('GET', '/rest/executions-current?filter=*').as('getCurrentExecutions');
cy.intercept('POST', '/rest/workflows/run').as('postWorkflowRun');

cy.signin({ email: INSTANCE_OWNER.email, password: INSTANCE_OWNER.password });

workflowPage.actions.visit();

workflowPage.actions.addInitialNodeToCanvas(MANUAL_TRIGGER_NODE_NAME);
workflowPage.actions.addNodeToCanvas(HTTP_REQUEST_NODE_NAME);
workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
ndv.actions.typeIntoParameterInput('url', 'https://foo.bar');
ndv.actions.close();

workflowPage.actions.addNodeToCanvas(SET_NODE_NAME, true);

workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
workflowPage.actions.executeWorkflow();

cy.wait(['@postWorkflowRun']);

executionsTab.actions.switchToExecutionsTab();

cy.wait(['@getExecutions', '@getCurrentExecutions']);

executionsTab.getters.executionDebugButton().should('have.text', 'Debug in editor').click();
cy.get('.el-notification').contains('Execution data imported').should('be.visible');
cy.get('.matching-pinned-nodes-confirmation').should('not.exist');


workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
ndv.actions.clearParameterInput('url');
ndv.actions.typeIntoParameterInput('url', 'https://postman-echo.com/get?foo1=bar1&foo2=bar2');
ndv.actions.close();

workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
workflowPage.actions.executeWorkflow();

cy.wait(['@postWorkflowRun']);

workflowPage.actions.openNode(HTTP_REQUEST_NODE_NAME);
ndv.actions.pinData();
ndv.actions.close();

executionsTab.actions.switchToExecutionsTab();

cy.wait(['@getExecutions', '@getCurrentExecutions']);

executionsTab.getters.executionListItems().should('have.length', 2).first().click();
cy.wait(['@getExecution']);

executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();

let confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
confirmDialog.find('li').should('have.length', 2);
confirmDialog.get('.btn--cancel').click();

cy.wait(['@getExecutions', '@getCurrentExecutions']);

executionsTab.getters.executionListItems().should('have.length', 2).first().click();
cy.wait(['@getExecution']);

executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();

confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
confirmDialog.find('li').should('have.length', 2);
confirmDialog.get('.btn--confirm').click();

workflowPage.getters.canvasNodes().first().should('have.descendants', '.node-pin-data-icon');
workflowPage.getters.canvasNodes().not(':first').should('not.have.descendants', '.node-pin-data-icon');

cy.reload(true);
cy.wait(['@getExecution']);

confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
confirmDialog.find('li').should('have.length', 1);
confirmDialog.get('.btn--confirm').click();

workflowPage.getters.canvasNodePlusEndpointByName(SET_NODE_NAME).click();
workflowPage.actions.addNodeToCanvas(IF_NODE_NAME, false);
workflowPage.actions.saveWorkflowUsingKeyboardShortcut();

executionsTab.actions.switchToExecutionsTab();
cy.wait(['@getExecutions', '@getCurrentExecutions']);
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();

confirmDialog = cy.get('.matching-pinned-nodes-confirmation').filter(':visible');
confirmDialog.find('li').should('have.length', 1);
confirmDialog.get('.btn--confirm').click();
workflowPage.getters.canvasNodes().last().find('.node-info-icon').should('be.empty');

workflowPage.getters.canvasNodes().first().dblclick();
ndv.getters.pinDataButton().click();
ndv.actions.close();

workflowPage.actions.saveWorkflowUsingKeyboardShortcut();
workflowPage.actions.executeWorkflow();
workflowPage.actions.deleteNode(IF_NODE_NAME);

executionsTab.actions.switchToExecutionsTab();
cy.wait(['@getExecutions', '@getCurrentExecutions']);
executionsTab.getters.executionListItems().should('have.length', 3).first().click();
cy.wait(['@getExecution']);
executionsTab.getters.executionDebugButton().should('have.text', 'Copy to editor').click();
cy.get('.el-notification').contains('Some execution data wasn\'t imported').should('be.visible');
});
});
1 change: 1 addition & 0 deletions cypress/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from './settings-log-streaming';
export * from './sidebar';
export * from './ndv';
export * from './bannerStack';
export * from './workflow-executions-tab';
export * from './signin';
1 change: 1 addition & 0 deletions cypress/pages/workflow-executions-tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class WorkflowExecutionsTab extends BasePage {
this.getters.executionPreviewDetails().find('[data-test-id="execution-preview-label"]'),
executionPreviewId: () =>
this.getters.executionPreviewDetails().find('[data-test-id="execution-preview-id"]'),
executionDebugButton: () => cy.getByTestId('execution-debug-button'),
};
actions = {
toggleNodeEnabled: (nodeName: string) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ export interface ITimeoutHMS {
seconds: number;
}

export type WorkflowTitleStatus = 'EXECUTING' | 'IDLE' | 'ERROR';
export type WorkflowTitleStatus = 'EXECUTING' | 'IDLE' | 'ERROR' | 'DEBUG';

export type ExtractActionKeys<T> = T extends SimplifiedNodeType ? T['name'] : never;

Expand Down Expand Up @@ -897,6 +897,7 @@ export interface WorkflowsState {
workflowExecutionData: IExecutionResponse | null;
workflowExecutionPairedItemMappings: { [itemId: string]: Set<string> };
workflowsById: IWorkflowsMap;
isInDebugMode?: boolean;
}

export interface RootState {
Expand Down
31 changes: 31 additions & 0 deletions packages/editor-ui/src/__tests__/router.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createPinia, setActivePinia } from 'pinia';
import { createComponentRenderer } from '@/__tests__/render';
import router from '@/router';
import { VIEWS } from '@/constants';

const App = {
template: '<div />',
};
const renderComponent = createComponentRenderer(App);

describe('router', () => {
beforeAll(() => {
const pinia = createPinia();
setActivePinia(pinia);
renderComponent({ pinia });
});

test.each([
['/', VIEWS.WORKFLOWS],
['/workflow', VIEWS.NEW_WORKFLOW],
['/workflow/new', VIEWS.NEW_WORKFLOW],
['/workflow/R9JFXwkUCL1jZBuw', VIEWS.WORKFLOW],
['/workflow/R9JFXwkUCL1jZBuw/executions/29021', VIEWS.EXECUTION_PREVIEW],
['/workflow/R9JFXwkUCL1jZBuw/debug/29021', VIEWS.EXECUTION_DEBUG],
['/workflows/templates/R9JFXwkUCL1jZBuw', VIEWS.TEMPLATE_IMPORT],
['/workflows/demo', VIEWS.DEMO],
])('should resolve %s to %s', async (path, name) => {
await router.push(path);
expect(router.currentRoute.value.name).toBe(name);
});
});
40 changes: 40 additions & 0 deletions packages/editor-ui/src/components/DebugPaywallModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script lang="ts" setup>
import { useI18n } from '@/composables';
import Modal from '@/components/Modal.vue';

const props = defineProps<{
modalName: string;
data: { title: string; footerButtonAction: () => void };
}>();

const i18n = useI18n();
</script>

<template>
<Modal width="500px" :title="props.data.title" :name="props.modalName">
<template #content>
<n8n-text>
{{ i18n.baseText('executionsList.debug.paywall.content') }}
<br />
<n8n-link :to="i18n.baseText('executionsList.debug.paywall.link.url')">
{{ i18n.baseText('executionsList.debug.paywall.link.text') }}
</n8n-link>
</n8n-text>
</template>
<template #footer>
<div :class="$style.footer">
<n8n-button @click="props.data.footerButtonAction">
{{ i18n.baseText('generic.seePlans') }}
</n8n-button>
</div>
</template>
</Modal>
</template>

<style module lang="scss">
.footer {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,29 @@
</n8n-text>
</div>
<div>
<n8n-button
size="large"
:type="debugButtonData.type"
:class="{
[$style.debugLink]: true,
[$style.secondary]: debugButtonData.type === 'secondary',
}"
>
<router-link
:to="{
name: VIEWS.EXECUTION_DEBUG,
params: {
name: activeExecution.workflowId,
executionId: activeExecution.id,
},
}"
>
<span @click="handleDebugLinkClick" data-test-id="execution-debug-button">{{
debugButtonData.text
}}</span>
</router-link>
</n8n-button>

<el-dropdown
v-if="executionUIDetails?.name === 'error'"
trigger="click"
Expand Down Expand Up @@ -128,13 +151,12 @@

<script lang="ts">
import { defineComponent } from 'vue';

import { useMessage } from '@/composables';
import { ElDropdown } from 'element-plus';
import { useExecutionDebugging, useMessage } from '@/composables';
import WorkflowPreview from '@/components/WorkflowPreview.vue';
import type { IExecutionUIData } from '@/mixins/executionsHelpers';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { MODAL_CONFIRM, VIEWS } from '@/constants';
import { ElDropdown } from 'element-plus';

type RetryDropdownRef = InstanceType<typeof ElDropdown> & { hide: () => void };

Expand All @@ -153,6 +175,7 @@ export default defineComponent({
setup() {
return {
...useMessage(),
...useExecutionDebugging(),
};
},
computed: {
Expand All @@ -162,6 +185,17 @@ export default defineComponent({
executionMode(): string {
return this.activeExecution?.mode || '';
},
debugButtonData(): Record<string, string> {
return this.activeExecution?.status === 'success'
? {
text: this.$locale.baseText('executionsList.debug.button.copyToEditor'),
type: 'secondary',
}
: {
text: this.$locale.baseText('executionsList.debug.button.debugInEditor'),
type: 'primary',
};
},
},
methods: {
async onDeleteExecution(): Promise<void> {
Expand Down Expand Up @@ -212,9 +246,15 @@ export default defineComponent({
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
transition: all 150ms ease-in-out;
pointer-events: none;

> div:last-child {
display: flex;
align-items: center;
}

& * {
pointer-events: all;
}
Expand Down Expand Up @@ -254,4 +294,21 @@ export default defineComponent({
margin-top: var(--spacing-l);
text-align: center;
}

.debugLink {
padding: 0;
margin-right: var(--spacing-xs);

&.secondary {
a span {
color: var(--color-primary-shade-1);
}
}

a span {
display: block;
padding: var(--spacing-xs) var(--spacing-m);
color: var(--color-text-xlight);
}
}
</style>
Loading