diff --git a/packages/excalidraw/element/duplicate.test.ts b/packages/excalidraw/element/duplicate.test.tsx
similarity index 65%
rename from packages/excalidraw/element/duplicate.test.ts
rename to packages/excalidraw/element/duplicate.test.tsx
index e330ef95e..bb3478f6e 100644
--- a/packages/excalidraw/element/duplicate.test.ts
+++ b/packages/excalidraw/element/duplicate.test.tsx
@@ -1,17 +1,27 @@
+import React from "react";
import { pointFrom } from "@excalidraw/math";
import type { LocalPoint } from "@excalidraw/math";
-import { FONT_FAMILY, ROUNDNESS } from "../constants";
+import { FONT_FAMILY, ORIG_ID, ROUNDNESS } from "../constants";
import { API } from "../tests/helpers/api";
import { isPrimitive } from "../utils";
+import { act, assertElements, render } from "../tests/test-utils";
+import { Excalidraw } from "..";
+import { actionDuplicateSelection } from "../actions";
+
+import { Keyboard, Pointer } from "../tests/helpers/ui";
+
import { mutateElement } from "./mutateElement";
import { duplicateElement, duplicateElements } from "./duplicate";
import type { ExcalidrawLinearElement } from "./types";
+const { h } = window;
+const mouse = new Pointer("mouse");
+
const assertCloneObjects = (source: any, clone: any) => {
for (const key in clone) {
if (clone.hasOwnProperty(key) && !isPrimitive(clone[key])) {
@@ -381,3 +391,210 @@ describe("duplicating multiple elements", () => {
});
});
});
+
+describe("duplication z-order", () => {
+ beforeEach(async () => {
+ await render();
+ });
+
+ it("duplication z order with Cmd+D for the lowest z-ordered element should be +1 for the clone", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+ API.setSelectedElements([rectangle1]);
+
+ act(() => {
+ h.app.actionManager.executeAction(actionDuplicateSelection);
+ });
+
+ assertElements(h.elements, [
+ { id: rectangle1.id },
+ { [ORIG_ID]: rectangle1.id, selected: true },
+ { id: rectangle2.id },
+ { id: rectangle3.id },
+ ]);
+ });
+
+ it("duplication z order with Cmd+D for the highest z-ordered element should be +1 for the clone", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+ API.setSelectedElements([rectangle3]);
+
+ act(() => {
+ h.app.actionManager.executeAction(actionDuplicateSelection);
+ });
+
+ assertElements(h.elements, [
+ { id: rectangle1.id },
+ { id: rectangle2.id },
+ { id: rectangle3.id },
+ { [ORIG_ID]: rectangle3.id, selected: true },
+ ]);
+ });
+
+ it("duplication z order with alt+drag for the lowest z-ordered element should be +1 for the clone", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+
+ mouse.select(rectangle1);
+ Keyboard.withModifierKeys({ alt: true }, () => {
+ mouse.down(rectangle1.x + 5, rectangle1.y + 5);
+ mouse.up(rectangle1.x + 5, rectangle1.y + 5);
+ });
+
+ assertElements(h.elements, [
+ { [ORIG_ID]: rectangle1.id },
+ { id: rectangle1.id, selected: true },
+ { id: rectangle2.id },
+ { id: rectangle3.id },
+ ]);
+ });
+
+ it("duplication z order with alt+drag for the highest z-ordered element should be +1 for the clone", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+
+ mouse.select(rectangle3);
+ Keyboard.withModifierKeys({ alt: true }, () => {
+ mouse.down(rectangle3.x + 5, rectangle3.y + 5);
+ mouse.up(rectangle3.x + 5, rectangle3.y + 5);
+ });
+
+ assertElements(h.elements, [
+ { id: rectangle1.id },
+ { id: rectangle2.id },
+ { [ORIG_ID]: rectangle3.id },
+ { id: rectangle3.id, selected: true },
+ ]);
+ });
+
+ it("duplication z order with alt+drag for the lowest z-ordered element should be +1 for the clone", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+
+ mouse.select(rectangle1);
+ Keyboard.withModifierKeys({ alt: true }, () => {
+ mouse.down(rectangle1.x + 5, rectangle1.y + 5);
+ mouse.up(rectangle1.x + 5, rectangle1.y + 5);
+ });
+
+ assertElements(h.elements, [
+ { [ORIG_ID]: rectangle1.id },
+ { id: rectangle1.id, selected: true },
+ { id: rectangle2.id },
+ { id: rectangle3.id },
+ ]);
+ });
+
+ it("duplication z order with alt+drag with grouped elements should consider the group together when determining z-index", () => {
+ const rectangle1 = API.createElement({
+ type: "rectangle",
+ x: 0,
+ y: 0,
+ groupIds: ["group1"],
+ });
+ const rectangle2 = API.createElement({
+ type: "rectangle",
+ x: 10,
+ y: 10,
+ groupIds: ["group1"],
+ });
+ const rectangle3 = API.createElement({
+ type: "rectangle",
+ x: 20,
+ y: 20,
+ groupIds: ["group1"],
+ });
+
+ API.setElements([rectangle1, rectangle2, rectangle3]);
+
+ mouse.select(rectangle1);
+ Keyboard.withModifierKeys({ alt: true }, () => {
+ mouse.down(rectangle1.x + 5, rectangle1.y + 5);
+ mouse.up(rectangle1.x + 15, rectangle1.y + 15);
+ });
+
+ assertElements(h.elements, [
+ { [ORIG_ID]: rectangle1.id },
+ { [ORIG_ID]: rectangle2.id },
+ { [ORIG_ID]: rectangle3.id },
+ { id: rectangle1.id, selected: true },
+ { id: rectangle2.id, selected: true },
+ { id: rectangle3.id, selected: true },
+ ]);
+ });
+});
diff --git a/packages/excalidraw/tests/regressionTests.test.tsx b/packages/excalidraw/tests/regressionTests.test.tsx
index b34706afd..42d726f1d 100644
--- a/packages/excalidraw/tests/regressionTests.test.tsx
+++ b/packages/excalidraw/tests/regressionTests.test.tsx
@@ -1,20 +1,16 @@
import React from "react";
import { vi } from "vitest";
-import { FONT_FAMILY, ORIG_ID } from "../constants";
+import { FONT_FAMILY } from "../constants";
import { Excalidraw } from "../index";
import { CODES, KEYS } from "../keys";
import { reseed } from "../random";
import * as StaticScene from "../renderer/staticScene";
import { setDateTimeForTests } from "../utils";
-import { actionDuplicateSelection } from "../actions";
-
import { API } from "./helpers/api";
import { Keyboard, Pointer, UI } from "./helpers/ui";
import {
- act,
- assertElements,
assertSelectedElements,
fireEvent,
render,
@@ -1189,209 +1185,6 @@ it(
},
);
-describe("duplication z-order", () => {
- beforeEach(async () => {
- await render();
- });
-
- it("duplication z order with Cmd+D for the lowest z-ordered element should be +1 for the clone", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
- API.setSelectedElements([rectangle1]);
-
- act(() => {
- h.app.actionManager.executeAction(actionDuplicateSelection);
- });
-
- assertElements(h.elements, [
- { id: rectangle1.id },
- { [ORIG_ID]: rectangle1.id, selected: true },
- { id: rectangle2.id },
- { id: rectangle3.id },
- ]);
- });
-
- it("duplication z order with Cmd+D for the highest z-ordered element should be +1 for the clone", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
- API.setSelectedElements([rectangle3]);
-
- act(() => {
- h.app.actionManager.executeAction(actionDuplicateSelection);
- });
-
- assertElements(h.elements, [
- { id: rectangle1.id },
- { id: rectangle2.id },
- { id: rectangle3.id },
- { [ORIG_ID]: rectangle3.id, selected: true },
- ]);
- });
-
- it("duplication z order with alt+drag for the lowest z-ordered element should be +1 for the clone", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
-
- mouse.select(rectangle1);
- Keyboard.withModifierKeys({ alt: true }, () => {
- mouse.down(rectangle1.x + 5, rectangle1.y + 5);
- mouse.up(rectangle1.x + 5, rectangle1.y + 5);
- });
-
- assertElements(h.elements, [
- { [ORIG_ID]: rectangle1.id },
- { id: rectangle1.id, selected: true },
- { id: rectangle2.id },
- { id: rectangle3.id },
- ]);
- });
-
- it("duplication z order with alt+drag for the highest z-ordered element should be +1 for the clone", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
-
- mouse.select(rectangle3);
- Keyboard.withModifierKeys({ alt: true }, () => {
- mouse.down(rectangle3.x + 5, rectangle3.y + 5);
- mouse.up(rectangle3.x + 5, rectangle3.y + 5);
- });
-
- assertElements(h.elements, [
- { id: rectangle1.id },
- { id: rectangle2.id },
- { [ORIG_ID]: rectangle3.id },
- { id: rectangle3.id, selected: true },
- ]);
- });
-
- it("duplication z order with alt+drag for the lowest z-ordered element should be +1 for the clone", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
-
- mouse.select(rectangle1);
- Keyboard.withModifierKeys({ alt: true }, () => {
- mouse.down(rectangle1.x + 5, rectangle1.y + 5);
- mouse.up(rectangle1.x + 5, rectangle1.y + 5);
- });
-
- assertElements(h.elements, [
- { [ORIG_ID]: rectangle1.id },
- { id: rectangle1.id, selected: true },
- { id: rectangle2.id },
- { id: rectangle3.id },
- ]);
- });
-
- it("duplication z order with alt+drag with grouped elements should consider the group together when determining z-index", () => {
- const rectangle1 = API.createElement({
- type: "rectangle",
- x: 0,
- y: 0,
- groupIds: ["group1"],
- });
- const rectangle2 = API.createElement({
- type: "rectangle",
- x: 10,
- y: 10,
- groupIds: ["group1"],
- });
- const rectangle3 = API.createElement({
- type: "rectangle",
- x: 20,
- y: 20,
- groupIds: ["group1"],
- });
-
- API.setElements([rectangle1, rectangle2, rectangle3]);
-
- mouse.select(rectangle1);
- Keyboard.withModifierKeys({ alt: true }, () => {
- mouse.down(rectangle1.x + 5, rectangle1.y + 5);
- mouse.up(rectangle1.x + 15, rectangle1.y + 15);
- });
-
- assertElements(h.elements, [
- { [ORIG_ID]: rectangle1.id },
- { [ORIG_ID]: rectangle2.id },
- { [ORIG_ID]: rectangle3.id },
- { id: rectangle1.id, selected: true },
- { id: rectangle2.id, selected: true },
- { id: rectangle3.id, selected: true },
- ]);
- });
-});
+//
+// DEPRECATED: DO NOT ADD TESTS HERE
+//