ljmotta commented on code in PR #3556:
URL:
https://github.com/apache/incubator-kie-tools/pull/3556#discussion_r3259324623
##########
packages/bpmn-editor/src/diagram/nodes/Nodes.tsx:
##########
@@ -987,6 +992,7 @@ export const SubProcessNode = React.memo(
</svg>
<PositionalNodeHandles isTargeted={isTargeted &&
isValidConnectionTarget} nodeId={id} />
<div
+ data-testid="kie-tools--bpmn-editor--node-subprocess"
Review Comment:
```suggestion
data-testid="kie-tools--bpmn-editor--node-sub-process"
```
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/intermediateEventPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/sequenceFlowPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/endEventPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/startEventPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/taskPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/edges.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/palette.ts:
##########
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Page } from "@playwright/test";
+import { Diagram } from "./diagram";
+import { DefaultNodeName, Nodes, NodeType } from "./nodes";
+
+export class Palette {
+ constructor(
+ public page: Page,
+ public diagram: Diagram,
+ public nodes: Nodes
+ ) {}
+
+ public async dragNewNode(args: { type: NodeType; targetPosition: { x:
number; y: number }; thenRenameTo?: string }) {
+ const { title, nodeName } = this.getNewNodeProperties(args.type);
+
+ await this.page
+ .getByTestId("rf__wrapper")
Review Comment:
We shouldn't rely on properties from other libraries.
##########
packages/bpmn-editor/tests-e2e/__fixtures__/edges.ts:
##########
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Locator, Page } from "@playwright/test";
+import { Diagram } from "./diagram";
+import { Nodes } from "./nodes";
+
+export enum EdgeType {
+ SEQUENCE_FLOW = "edge_sequenceFlow",
+ ASSOCIATION = "edge_association",
+}
+
+export class Edges {
+ constructor(
+ public page: Page,
+ public nodes: Nodes,
+ public diagram: Diagram
+ ) {}
+
+ public async get(args: { from: string; to: string }): Promise<Locator> {
+ const fromId = args.from.startsWith("_") ? args.from : await
this.nodes.getId({ name: args.from });
+
+ const toId = args.to.startsWith("_") ? args.to : await this.nodes.getId({
name: args.to });
+
+ await this.page.locator(".react-flow__edge").first().waitFor({ state:
"attached" });
Review Comment:
We shouldn't rely on anything from a 3rd party library.
##########
packages/bpmn-editor/tests-e2e/__fixtures__/jsonModel.ts:
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { Page } from "@playwright/test";
+
+export class JsonModel {
+ constructor(
+ public page: Page,
+ public baseURL?: string
+ ) {}
+
+ public async getModel(): Promise<any> {
+ const modelElement =
this.page.locator('[data-testid="storybook--bpmn-editor-model"]');
Review Comment:
Should use the `getByTestId`
##########
packages/bpmn-editor/tests-e2e/flowElements/addCallActivity.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addCustomTasks.spec.ts:
##########
Review Comment:
Review this file:
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addIntermediateCatchEvent.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addSubProcess.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addStartEvent.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeLaneProperties.spec.ts:
##########
Review Comment:
Review this file:
- if block
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeSequenceFlowProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
- if block
- throw error
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeEndEventProperties.spec.ts:
##########
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { test, expect } from "../__fixtures__/base";
+import { NodeType } from "../__fixtures__/nodes";
+
+test.beforeEach(async ({ editor, page }) => {
+ await editor.open();
+ await page.setViewportSize({ width: 1920, height: 1080 });
+});
+
+test.describe("Change Properties - End Event", () => {
+ test.beforeEach(async ({ palette, page }) => {
+ await palette.dragNewNode({ type: NodeType.END_EVENT, targetPosition: { x:
100, y: 100 } });
+
+ const endEvent =
page.getByTestId("kie-tools--bpmn-editor--node-end-event").first();
+ await expect(endEvent).toBeVisible();
+
+ await endEvent.click();
+ });
+
+ test("should change the End Event name", async ({ endEventPropertiesPanel })
=> {
+ await endEventPropertiesPanel.nameProperties.setName({ newName: "Process
Completed" });
+
+ expect(await
endEventPropertiesPanel.nameProperties.getName()).toBe("Process Completed");
+ });
+
+ test("should change the End Event documentation", async ({
endEventPropertiesPanel }) => {
+ await endEventPropertiesPanel.documentationProperties.setDocumentation({
+ newDocumentation: "This event ends the process successfully",
+ });
+
+ expect(await
endEventPropertiesPanel.documentationProperties.getDocumentation()).toBe(
+ "This event ends the process successfully"
+ );
+ });
+
+ test("should configure Terminate event definition", async ({
endEventPropertiesPanel, page }) => {
+ const endEvent =
page.getByTestId("kie-tools--bpmn-editor--node-end-event").first();
+
+ await endEventPropertiesPanel.setTerminateDefinition({
+ endEventLocator: endEvent,
+ });
Review Comment:
Inline variables that are not re-used
##########
packages/bpmn-editor/tests-e2e/__fixtures__/customTasks.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/gatewayPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeTaskProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
- CSS locator
##########
packages/bpmn-editor/tests-e2e/__fixtures__/propertiesPanel/subProcessPropertiesPanel.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/jsonModel.ts:
##########
Review Comment:
Review this file.
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/editor.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/nodes.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/__fixtures__/palette.ts:
##########
Review Comment:
Review this file.
- CSS locator
- `waitFor` usage
##########
packages/bpmn-editor/tests-e2e/flowElements/addGateway.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addBoundaryEvent.spec.ts:
##########
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { test, expect } from "../__fixtures__/base";
+import { NodeType, DefaultNodeName } from "../__fixtures__/nodes";
+
+test.beforeEach(async ({ editor }) => {
+ await editor.open();
+});
+
+test.describe("Add Boundary Event", () => {
+ test.describe("Basic attachment", () => {
+ test("should attach intermediate catch event to task", async ({ palette,
jsonModel, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeAttached();
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+
+ test("should attach intermediate catch event to subprocess", async ({
palette, jsonModel, page }) => {
+ await palette.dragNewNode({ type: NodeType.SUB_PROCESS, targetPosition:
{ x: 100, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 550, y: 350 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeAttached();
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+
+ test("should attach multiple boundary events to same task", async ({
palette, jsonModel, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 300, y: 280 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 350, y: 350 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("attach-multiple-boundary-events-to-task.png");
+
+ const process = await jsonModel.getProcess();
+ const boundaryEvents = process.flowElement?.filter(
+ (e: { __$$element: string }) => e.__$$element === "boundaryEvent"
+ );
+ expect(boundaryEvents?.length).toBe(3);
+ boundaryEvents?.forEach((event: { __$$element: string;
"@_attachedToRef"?: string }) => {
+ expect(event.__$$element).toBe("boundaryEvent");
+ expect(event["@_attachedToRef"]).toBeDefined();
+ });
+ });
+ });
+
+ test.describe("Detachment", () => {
+ test("should detach boundary event back to intermediate catch event",
async ({
+ palette,
+ jsonModel,
+ diagram,
+ page,
+ }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeVisible();
+
+ await boundaryEventNode.dragTo(diagram.get(), { targetPosition: { x:
500, y: 100 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("detach-boundary-event-from-task.png");
+
+ const detachedEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(detachedEvent.__$$element).toBe("intermediateCatchEvent");
+ expect(detachedEvent["@_attachedToRef"]).toBeUndefined();
+ });
+ });
+
+ test.describe("Interrupting vs Non-interrupting", () => {
+ test("should create interrupting boundary event by default", async ({
palette, jsonModel, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("interrupting-boundary-event.png");
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ expect(boundaryEvent["@_cancelActivity"]).not.toBe(false);
+ });
+
+ test("should create non-interrupting boundary event", async ({
+ palette,
+ jsonModel,
+ diagram,
+ page,
+ intermediateEventPropertiesPanel,
+ }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeVisible();
+ await boundaryEventNode.click();
+
+ await intermediateEventPropertiesPanel.setCancelActivity({
cancelActivity: false });
+
+ await expect
+ .poll(async () => {
+ return await jsonModel.getFlowElement({ elementIndex: 1 });
+ })
+ .toMatchObject({
+ __$$element: "boundaryEvent",
+ "@_attachedToRef": expect.stringMatching(/.+/),
+ "@_cancelActivity": false,
+ });
+
+ await
expect(diagram.get()).toHaveScreenshot("non-interrupting-boundary-event.png");
+ });
+ });
+
+ test.describe("Activity types", () => {
+ test("should attach to user task", async ({ palette, nodes, jsonModel,
page, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+
+ const task = page.locator(`[data-nodelabel="${DefaultNodeName.TASK}"]`);
Review Comment:
CSS locator
##########
packages/bpmn-editor/tests-e2e/flowElements/addBoundaryEvent.spec.ts:
##########
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { test, expect } from "../__fixtures__/base";
+import { NodeType, DefaultNodeName } from "../__fixtures__/nodes";
+
+test.beforeEach(async ({ editor }) => {
+ await editor.open();
+});
+
+test.describe("Add Boundary Event", () => {
+ test.describe("Basic attachment", () => {
+ test("should attach intermediate catch event to task", async ({ palette,
jsonModel, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeAttached();
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+
+ test("should attach intermediate catch event to subprocess", async ({
palette, jsonModel, page }) => {
+ await palette.dragNewNode({ type: NodeType.SUB_PROCESS, targetPosition:
{ x: 100, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 550, y: 350 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeAttached();
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+
+ test("should attach multiple boundary events to same task", async ({
palette, jsonModel, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 300, y: 280 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 350, y: 350 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("attach-multiple-boundary-events-to-task.png");
+
+ const process = await jsonModel.getProcess();
+ const boundaryEvents = process.flowElement?.filter(
+ (e: { __$$element: string }) => e.__$$element === "boundaryEvent"
+ );
+ expect(boundaryEvents?.length).toBe(3);
+ boundaryEvents?.forEach((event: { __$$element: string;
"@_attachedToRef"?: string }) => {
+ expect(event.__$$element).toBe("boundaryEvent");
+ expect(event["@_attachedToRef"]).toBeDefined();
+ });
+ });
+ });
+
+ test.describe("Detachment", () => {
+ test("should detach boundary event back to intermediate catch event",
async ({
+ palette,
+ jsonModel,
+ diagram,
+ page,
+ }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeVisible();
+
+ await boundaryEventNode.dragTo(diagram.get(), { targetPosition: { x:
500, y: 100 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("detach-boundary-event-from-task.png");
+
+ const detachedEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(detachedEvent.__$$element).toBe("intermediateCatchEvent");
+ expect(detachedEvent["@_attachedToRef"]).toBeUndefined();
+ });
+ });
+
+ test.describe("Interrupting vs Non-interrupting", () => {
+ test("should create interrupting boundary event by default", async ({
palette, jsonModel, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("interrupting-boundary-event.png");
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ expect(boundaryEvent["@_cancelActivity"]).not.toBe(false);
+ });
+
+ test("should create non-interrupting boundary event", async ({
+ palette,
+ jsonModel,
+ diagram,
+ page,
+ intermediateEventPropertiesPanel,
+ }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeVisible();
+ await boundaryEventNode.click();
+
+ await intermediateEventPropertiesPanel.setCancelActivity({
cancelActivity: false });
+
+ await expect
+ .poll(async () => {
+ return await jsonModel.getFlowElement({ elementIndex: 1 });
+ })
+ .toMatchObject({
+ __$$element: "boundaryEvent",
+ "@_attachedToRef": expect.stringMatching(/.+/),
+ "@_cancelActivity": false,
+ });
+
+ await
expect(diagram.get()).toHaveScreenshot("non-interrupting-boundary-event.png");
+ });
+ });
+
+ test.describe("Activity types", () => {
+ test("should attach to user task", async ({ palette, nodes, jsonModel,
page, diagram }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+
+ const task = page.locator(`[data-nodelabel="${DefaultNodeName.TASK}"]`);
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: "User task"
});
+
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("attach-boundary-event-to-user-task.png");
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+
+ test("should attach to call activity", async ({ palette, jsonModel,
diagram }) => {
+ await palette.dragNewNode({ type: NodeType.CALL_ACTIVITY,
targetPosition: { x: 300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ await
expect(diagram.get()).toHaveScreenshot("attach-boundary-event-to-call-activity.png");
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1
});
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+ });
+ });
+
+ test.describe("Operations", () => {
+ test("should delete boundary event", async ({ palette, jsonModel, page })
=> {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEventNode =
page.getByTestId("kie-tools--bpmn-editor--node-intermediate-catch-event").first();
+ await expect(boundaryEventNode).toBeVisible();
+ await boundaryEventNode.click();
+ await boundaryEventNode.press("Delete");
+
+ await expect(boundaryEventNode).not.toBeAttached();
+
+ const process = await jsonModel.getProcess();
+ expect(
+ process.flowElement?.find((e: { __$$element: string }) =>
e.__$$element === "boundaryEvent")
+ ).toBeUndefined();
+ expect(process.flowElement?.find((e: { __$$element: string }) =>
e.__$$element === "task")).toBeDefined();
+ });
+
+ test.skip("should delete task with boundary event", async ({ palette,
nodes, jsonModel, diagram }) => {
+ // TODO: Enable when boundary event deletion logic is implemented
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ await nodes.delete({ name: DefaultNodeName.TASK });
+
+ const process = await jsonModel.getProcess();
+ expect(process.flowElement?.filter((e: { __$$element: string }) =>
e.__$$element === "task").length).toBe(0);
+ expect(
+ process.flowElement?.filter((e: { __$$element: string }) =>
e.__$$element === "boundaryEvent").length
+ ).toBe(0);
+
+ await
expect(diagram.get()).toHaveScreenshot("delete-task-with-boundary-event.png");
+ });
+
+ test("should move task with boundary event", async ({ palette, jsonModel,
diagram, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const taskNode =
page.getByTestId("kie-tools--bpmn-editor--node-task").first();
+ await expect(taskNode).toBeAttached();
+ await taskNode.scrollIntoViewIfNeeded();
+
+ const taskBox = await taskNode.boundingBox();
+ if (!taskBox) throw new Error("Task bounding box not found");
Review Comment:
A test shouldn't have conditions or throw errors.
##########
packages/bpmn-editor/tests-e2e/flowElements/addTask.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
- `waitFor` usage
- using `let`
##########
packages/bpmn-editor/tests-e2e/flowElements/addEndEvent.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addIntermediateThrowEvent.spec.ts:
##########
Review Comment:
Review this file:
- CSS locator
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/boundaryEventCompensation.spec.ts:
##########
Review Comment:
Review this file:
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/flowElements/addTask.spec.ts:
##########
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { TestAnnotations } from "@kie-tools/playwright-base/annotations";
+import { test, expect } from "../__fixtures__/base";
+import { DefaultNodeName, NodeType, NodePosition } from
"../__fixtures__/nodes";
+
+test.beforeEach(async ({ editor }) => {
+ await editor.open();
+});
+
+test.describe("Add node - Task", () => {
+ test.describe("Add from palette", () => {
+ test("should add Task node from palette", async ({ palette, nodes,
jsonModel }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
100, y: 100 } });
+
+ await expect(nodes.get({ name: DefaultNodeName.TASK })).toBeAttached();
+
+ const task = await jsonModel.getFlowElement({ elementIndex: 0 });
+ expect(task.__$$element).toBe("task");
+ });
+
+ test("should add two Task nodes from palette in a row", async ({ palette,
nodes, diagram }) => {
+ test.info().annotations.push({ type: TestAnnotations.REGRESSION });
+
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
100, y: 100 }, thenRenameTo: "Task A" });
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 }, thenRenameTo: "Task B" });
+
+ await diagram.resetFocus();
+
+ await expect(nodes.get({ name: "Task A" })).toBeAttached();
+ await expect(nodes.get({ name: "Task B" })).toBeAttached();
+ });
+ });
+
+ test.describe("Task type morphing", () => {
+ const singleMorphCases = [
+ { morphType: "User task", expectedElement: "userTask", screenshot:
"morph-task-to-user-task.png" },
+ { morphType: "Service task", expectedElement: "serviceTask", screenshot:
"morph-task-to-service-task.png" },
+ { morphType: "Script task", expectedElement: "scriptTask", screenshot:
"morph-task-to-script-task.png" },
+ {
+ morphType: "Business Rule task",
+ expectedElement: "businessRuleTask",
+ screenshot: "morph-task-to-business-rule-task.png",
+ },
+ ];
+
+ for (const { morphType, expectedElement, screenshot } of singleMorphCases)
{
+ test(`should morph Task to ${morphType}`, async ({ jsonModel, palette,
nodes, diagram, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+
+ await nodes.select({ name: DefaultNodeName.TASK, position:
NodePosition.CENTER });
+
+ const task =
page.locator(`[data-nodelabel="${DefaultNodeName.TASK}"]`);
+ await task.waitFor({ state: "attached" });
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: morphType
});
+
+ const result = await jsonModel.getFlowElement({ elementIndex: 0 });
+ expect(result.__$$element).toBe(expectedElement);
+ expect(result["@_name"]).toBe(DefaultNodeName.TASK);
+
+ await expect(diagram.get()).toHaveScreenshot(screenshot);
+ });
+ }
+
+ test("should morph User Task to Service Task", async ({ jsonModel,
palette, nodes, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+
+ await nodes.select({ name: DefaultNodeName.TASK, position:
NodePosition.CENTER });
+
+ const task = page.locator(`[data-nodelabel="${DefaultNodeName.TASK}"]`);
+ await task.waitFor({ state: "attached" });
+
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: "User task"
});
+
+ let taskElement = await jsonModel.getFlowElement({ elementIndex: 0 });
+ expect(taskElement.__$$element).toBe("userTask");
+
+ await page.mouse.move(0, 0);
+
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: "Service
task" });
+
+ taskElement = await jsonModel.getFlowElement({ elementIndex: 0 });
+ expect(taskElement.__$$element).toBe("serviceTask");
+ expect(taskElement["@_name"]).toBe(DefaultNodeName.TASK);
+ });
+
+ test("should morph Script Task back to generic Task", async ({ jsonModel,
palette, nodes, page }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x:
300, y: 300 } });
+
+ await nodes.select({ name: DefaultNodeName.TASK, position:
NodePosition.CENTER });
+
+ const task = page.locator(`[data-nodelabel="${DefaultNodeName.TASK}"]`);
+ await task.waitFor({ state: "attached" });
+
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: "Script
task" });
+
+ let taskElement = await jsonModel.getFlowElement({ elementIndex: 0 });
+ expect(taskElement.__$$element).toBe("scriptTask");
+
+ await page.mouse.move(0, 0);
+
+ await nodes.morphNode({ nodeLocator: task, targetMorphType: "Task",
exact: true });
+
+ taskElement = await jsonModel.getFlowElement({ elementIndex: 0 });
Review Comment:
Unnecessary?
##########
packages/bpmn-editor/tests-e2e/flowElements/addTextAnnotation.spec.ts:
##########
Review Comment:
Review this file:
- If block
- throw error
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeStartEventProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
- if block
- throw error
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeIntermediateEventProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeSubProcessProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
##########
packages/bpmn-editor/tests-e2e/propertiesPanel/changeEndEventProperties.spec.ts:
##########
Review Comment:
Review this file:
- remove variables that are not re-used
##########
packages/bpmn-editor/tests-e2e/flowElements/boundaryEventCompensation.spec.ts:
##########
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { test, expect } from "../__fixtures__/base";
+import { NodeType } from "../__fixtures__/nodes";
+
+test.beforeEach(async ({ editor }) => {
+ await editor.open();
+});
+
+test.describe("Compensation Boundary Events", () => {
+ test("should create compensation boundary event on task", async ({
+ palette,
+ jsonModel,
+ page,
+ intermediateEventPropertiesPanel,
+ }) => {
+ await palette.dragNewNode({ type: NodeType.TASK, targetPosition: { x: 300,
y: 300 } });
+ await palette.dragNewNode({ type: NodeType.INTERMEDIATE_CATCH_EVENT,
targetPosition: { x: 450, y: 300 } });
+
+ const boundaryEvent = await jsonModel.getFlowElement({ elementIndex: 1 });
+ expect(boundaryEvent.__$$element).toBe("boundaryEvent");
+ expect(boundaryEvent["@_attachedToRef"]).toBeDefined();
+
+ const eventNode =
page.locator(".kie-bpmn-editor--intermediate-catch-event-node").first();
+ await eventNode.click();
+
+ await intermediateEventPropertiesPanel.setCompensationDefinition({});
+ await intermediateEventPropertiesPanel.setCancelActivity({ cancelActivity:
false });
+
+ await expect
+ .poll(
+ async () => {
+ return await jsonModel.getFlowElement({ elementIndex: 1 });
+ },
+ { timeout: 10000 }
+ )
+ .toMatchObject({
+ __$$element: "boundaryEvent",
+ "@_attachedToRef": expect.stringMatching(/.+/),
+ "@_cancelActivity": false,
+ eventDefinition: [{ __$$element: "compensateEventDefinition" }],
+ });
+
+ const cancelActivity = await
intermediateEventPropertiesPanel.getCancelActivity();
+ expect(cancelActivity).toBe(false);
+ });
+
+ test.skip("should not allow incoming sequence flows to compensation boundary
event", async ({
+ // TODO: Enable when compensation boundary event validation is implemented
Review Comment:
Please link the issue into the test with `test.annotation`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]