Skip to content

Commit

Permalink
feat(Canvas): Use path+scope as VizNode ID
Browse files Browse the repository at this point in the history
Currently, when transforming a flow into `VisualizationNodes`, the
nodes `Id`s are randomly generated, causing that whenever there's a
change in the structure of the flow, previous `Id`s change.

This commit uses the `path` + `scope` so the `VisualizationNodes` IDs
are stable between interacting with the flow.
  • Loading branch information
lordrip committed Dec 18, 2024
1 parent c180445 commit 6a705f6
Show file tree
Hide file tree
Showing 26 changed files with 835 additions and 462 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@ describe('Test toolbar on hover actions', () => {
cy.get('[data-testid="step-toolbar-button-disable"]').click();

cy.openStepConfigurationTab('setHeader');

// Temporary workaround since the toolbar is updated but the config form is closed
cy.openStepConfigurationTab('setHeader');

cy.selectFormTab('All');
cy.checkConfigCheckboxObject('disabled', true);

cy.openStepConfigurationTab('setHeader');
cy.get('[data-testid="step-toolbar-button-disable"]').click();

cy.openStepConfigurationTab('setHeader');
cy.selectFormTab('All');

// Temporary workaround since the toolbar is updated but the config form is closed
cy.openStepConfigurationTab('setHeader');

cy.checkConfigCheckboxObject('disabled', false);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ describe('Test for Branching actions from the canvas', () => {
cy.chooseFromCatalog('component', 'activemq');

cy.checkNodeExist('activemq', 1);
cy.checkEdgeExists('setHeader', 'activemq');
cy.checkEdgeExists(
'template.from.steps.1.choice.when.0.steps.1.setHeader',
'template.from.steps.1.choice.when.0.steps.2.to',
);
});

it('User prepends a step in a branch from the canvas (first in the branch)', () => {
Expand All @@ -73,7 +76,10 @@ describe('Test for Branching actions from the canvas', () => {
cy.chooseFromCatalog('component', 'activemq');

cy.checkNodeExist('activemq', 1);
cy.checkEdgeExists('activemq', 'digitalocean');
cy.checkEdgeExists(
'template.from.steps.1.choice.when.0.steps.0.to',
'template.from.steps.1.choice.when.0.steps.1.to',
);
});

it('User prepends a step to a step whose previous step contains branches', () => {
Expand All @@ -85,6 +91,6 @@ describe('Test for Branching actions from the canvas', () => {
cy.chooseFromCatalog('component', 'activemq');

cy.checkNodeExist('activemq', 1);
cy.checkEdgeExists('activemq', 'filter');
cy.checkEdgeExists('template.from.steps.2.to', 'template.from.steps.3.filter');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('Test for missing config props canvas warnings', () => {

cy.checkNodeExist('github', 1);

cy.get('[data-id^="github"] g')
cy.get('[data-id^="camel-route|route.from.steps.1.to"] g')
.find('span[data-warning="true"].pf-v5-c-icon')
.should('have.attr', 'title', '3 required parameters are not yet configured: [ type,repoName,repoOwner ]');

Expand All @@ -21,7 +21,7 @@ describe('Test for missing config props canvas warnings', () => {
cy.interactWithConfigInputObject('parameters.repoName', 'test');
cy.closeStepConfigurationTab();

cy.get('[data-id^="github"] g')
cy.get('[data-id^="camel-route|route.from.steps.1.to"] g')
.find('span[data-warning="true"].pf-v5-c-icon')
.should('have.attr', 'title', '2 required parameters are not yet configured: [ type,repoOwner ]');
});
Expand All @@ -30,7 +30,7 @@ describe('Test for missing config props canvas warnings', () => {
cy.uploadFixture('flows/pipe/errorHandler.yaml');
cy.openDesignPage();

cy.get('[data-id^="delay-action"] g')
cy.get('[data-id^="webhook-binding|delay-action"] g')
.find('span[data-warning="true"].pf-v5-c-icon')
.should('have.attr', 'title', '1 required parameter is not yet configured: [ milliseconds ]');

Expand All @@ -39,6 +39,8 @@ describe('Test for missing config props canvas warnings', () => {
cy.interactWithConfigInputObject('milliseconds', '1000');
cy.closeStepConfigurationTab();

cy.get('[data-id^="delay-action"] g').find('span[data-warning="true"].pf-v5-c-icon').should('not.exist');
cy.get('[data-id^="webhook-binding|delay-action"] g')
.find('span[data-warning="true"].pf-v5-c-icon')
.should('not.exist');
});
});
4 changes: 2 additions & 2 deletions packages/ui-tests/cypress/support/next-commands/design.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ Cypress.Commands.add('checkNodeExist', (inputName, nodesCount) => {
});

Cypress.Commands.add('checkEdgeExists', (sourceName: string, targetName: string) => {
const idPattern = sourceName + '-\\d+-to-' + targetName + '-\\d+';
const idPattern = `${sourceName} >>> ${targetName}`;
// Check if an element with the matching id exists
cy.get('g').should(($elements) => {
// Use Cypress commands to check if any element matches the id pattern
const matchingElementExists = $elements.toArray().some((element) => {
const dataId = Cypress.$(element).attr('data-id');
return dataId && dataId.match(idPattern);
return dataId === idPattern;
});
// Assert that at least one matching element exists
expect(matchingElementExists).to.be.true;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Visualization/Canvas/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const Canvas: FunctionComponent<PropsWithChildren<CanvasProps>> = ({ enti

entities.forEach((entity) => {
if (visibleFlows[entity.id]) {
const { nodes: childNodes, edges: childEdges } = FlowService.getFlowDiagram(entity.toVizNode());
const { nodes: childNodes, edges: childEdges } = FlowService.getFlowDiagram(entity.id, entity.toVizNode());
nodes.push(...childNodes);
edges.push(...childEdges);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('CanvasSideBar', () => {
const camelResource = new CamelRouteResource();
camelResource.addNewEntity(EntityType.Route);
const visualEntity = camelResource.getVisualEntities()[0];
selectedNode = FlowService.getFlowDiagram(visualEntity.toVizNode()).nodes[0];
selectedNode = FlowService.getFlowDiagram('test', visualEntity.toVizNode()).nodes[0];
Provider = TestProvidersWrapper({ camelResource }).Provider;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('CanvasForm', () => {

beforeEach(() => {
camelRouteVisualEntity = new CamelRouteVisualEntity(camelRouteJson);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[2]; // choice
});

Expand Down Expand Up @@ -145,7 +145,7 @@ describe('CanvasForm', () => {
const flowId = camelRouteVisualEntity.id;
const dispatchSpy = jest.fn();
const visualFlowsApi = new VisualFlowsApi(dispatchSpy);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[nodes.length - 1];

render(
Expand Down Expand Up @@ -182,7 +182,7 @@ describe('CanvasForm', () => {
const flowId = camelRouteVisualEntity.id;
const dispatchSpy = jest.fn();
const visualFlowsApi = new VisualFlowsApi(dispatchSpy);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[nodes.length - 1];

render(
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('CanvasForm', () => {
const newName = 'MyNewId';
const dispatchSpy = jest.fn();
const visualFlowsApi = new VisualFlowsApi(dispatchSpy);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[nodes.length - 1];

render(
Expand Down Expand Up @@ -260,7 +260,7 @@ describe('CanvasForm', () => {
const newName = 'MyNewName';
const dispatchSpy = jest.fn();
const visualFlowsApi = new VisualFlowsApi(dispatchSpy);
const { nodes } = FlowService.getFlowDiagram(kameletVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', kameletVisualEntity.toVizNode());
selectedNode = nodes[nodes.length - 1];

render(
Expand Down Expand Up @@ -292,7 +292,7 @@ describe('CanvasForm', () => {
describe('should show the User-updated field under the modified tab', () => {
beforeEach(() => {
camelRouteVisualEntity = new CamelRouteVisualEntity(camelRouteJson);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[0]; // timer
});

Expand Down Expand Up @@ -629,7 +629,7 @@ describe('CanvasForm', () => {
describe('should show the Required field under the required tab', () => {
beforeEach(() => {
camelRouteVisualEntity = new CamelRouteVisualEntity(camelRouteJson);
const { nodes } = FlowService.getFlowDiagram(camelRouteVisualEntity.toVizNode());
const { nodes } = FlowService.getFlowDiagram('test', camelRouteVisualEntity.toVizNode());
selectedNode = nodes[0]; // timer
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ exports[`CanvasForm should render 1`] = `
>
<img
alt="icon"
class="form-header__icon-log-1234"
class="form-header__icon-test|route.from.steps.1.choice.when.0.steps.0.log"
src=""
/>
<h2
Expand Down
Loading

0 comments on commit 6a705f6

Please sign in to comment.