diff options
| author | kj_sh604 | 2026-03-15 16:19:35 -0400 |
|---|---|---|
| committer | kj_sh604 | 2026-03-15 16:19:35 -0400 |
| commit | 6ec259a0e71174651bae95d4628138bf6fd68742 (patch) | |
| tree | 5e33c6a5ec091ecabfcb257fdc7b6a88ed8754ac /packages/excalidraw/tests/align.test.tsx | |
| parent | 16c8578b15c727f22921f8a80a56ee4d4e7f2272 (diff) | |
refactor: packages/
Diffstat (limited to 'packages/excalidraw/tests/align.test.tsx')
| -rw-r--r-- | packages/excalidraw/tests/align.test.tsx | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/packages/excalidraw/tests/align.test.tsx b/packages/excalidraw/tests/align.test.tsx new file mode 100644 index 0000000..47624e8 --- /dev/null +++ b/packages/excalidraw/tests/align.test.tsx @@ -0,0 +1,579 @@ +import React from "react"; +import { act, unmountComponent, render } from "./test-utils"; +import { Excalidraw } from "../index"; +import { defaultLang, setLanguage } from "../i18n"; +import { UI, Pointer, Keyboard } from "./helpers/ui"; +import { API } from "./helpers/api"; +import { KEYS } from "../keys"; +import { + actionAlignVerticallyCentered, + actionAlignHorizontallyCentered, + actionGroup, + actionAlignTop, + actionAlignBottom, + actionAlignLeft, + actionAlignRight, +} from "../actions"; + +const mouse = new Pointer("mouse"); + +const createAndSelectTwoRectangles = () => { + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(10, 10); + mouse.up(100, 100); + + // Select the first element. + // The second rectangle is already reselected because it was the last element created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); +}; + +const createAndSelectTwoRectanglesWithDifferentSizes = () => { + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(10, 10); + mouse.up(110, 110); + + // Select the first element. + // The second rectangle is already reselected because it was the last element created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); +}; + +describe("aligning", () => { + beforeEach(async () => { + unmountComponent(); + mouse.reset(); + + await act(() => { + return setLanguage(defaultLang); + }); + await render(<Excalidraw handleKeyboardGlobally={true} />); + }); + + it("aligns two objects correctly to the top", () => { + createAndSelectTwoRectangles(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => { + Keyboard.keyPress(KEYS.ARROW_UP); + }); + + // Check if x position did not change + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(0); + }); + + it("aligns two objects correctly to the bottom", () => { + createAndSelectTwoRectangles(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => { + Keyboard.keyPress(KEYS.ARROW_DOWN); + }); + + // Check if x position did not change + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(110); + expect(API.getSelectedElements()[1].y).toEqual(110); + }); + + it("aligns two objects correctly to the left", () => { + createAndSelectTwoRectangles(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => { + Keyboard.keyPress(KEYS.ARROW_LEFT); + }); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(0); + + // Check if y position did not change + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + }); + + it("aligns two objects correctly to the right", () => { + createAndSelectTwoRectangles(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + Keyboard.withModifierKeys({ ctrl: true, shift: true }, () => { + Keyboard.keyPress(KEYS.ARROW_RIGHT); + }); + + expect(API.getSelectedElements()[0].x).toEqual(110); + expect(API.getSelectedElements()[1].x).toEqual(110); + + // Check if y position did not change + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + }); + + it("centers two objects with different sizes correctly vertically", () => { + createAndSelectTwoRectanglesWithDifferentSizes(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + API.executeAction(actionAlignVerticallyCentered); + + // Check if x position did not change + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(60); + expect(API.getSelectedElements()[1].y).toEqual(55); + }); + + it("centers two objects with different sizes correctly horizontally", () => { + createAndSelectTwoRectanglesWithDifferentSizes(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(110); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + + API.executeAction(actionAlignHorizontallyCentered); + + expect(API.getSelectedElements()[0].x).toEqual(60); + expect(API.getSelectedElements()[1].x).toEqual(55); + + // Check if y position did not change + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(110); + }); + + const createAndSelectGroupAndRectangle = () => { + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(0, 0); + mouse.up(100, 100); + + // Select the first element. + // The second rectangle is already reselected because it was the last element created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + + API.executeAction(actionGroup); + + mouse.reset(); + UI.clickTool("rectangle"); + mouse.down(200, 200); + mouse.up(100, 100); + + // Add the created group to the current selection + mouse.restorePosition(0, 0); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + }; + + it("aligns a group with another element correctly to the top", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + + API.executeAction(actionAlignTop); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(0); + }); + + it("aligns a group with another element correctly to the bottom", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + + API.executeAction(actionAlignBottom); + + expect(API.getSelectedElements()[0].y).toEqual(100); + expect(API.getSelectedElements()[1].y).toEqual(200); + expect(API.getSelectedElements()[2].y).toEqual(200); + }); + + it("aligns a group with another element correctly to the left", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + + API.executeAction(actionAlignLeft); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(0); + }); + + it("aligns a group with another element correctly to the right", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + + API.executeAction(actionAlignRight); + + expect(API.getSelectedElements()[0].x).toEqual(100); + expect(API.getSelectedElements()[1].x).toEqual(200); + expect(API.getSelectedElements()[2].x).toEqual(200); + }); + + it("centers a group with another element correctly vertically", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + + API.executeAction(actionAlignVerticallyCentered); + + expect(API.getSelectedElements()[0].y).toEqual(50); + expect(API.getSelectedElements()[1].y).toEqual(150); + expect(API.getSelectedElements()[2].y).toEqual(100); + }); + + it("centers a group with another element correctly horizontally", () => { + createAndSelectGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + + API.executeAction(actionAlignHorizontallyCentered); + + expect(API.getSelectedElements()[0].x).toEqual(50); + expect(API.getSelectedElements()[1].x).toEqual(150); + expect(API.getSelectedElements()[2].x).toEqual(100); + }); + + const createAndSelectTwoGroups = () => { + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(0, 0); + mouse.up(100, 100); + + // Select the first element. + // The second rectangle is already selected because it was the last element created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + + API.executeAction(actionGroup); + + mouse.reset(); + UI.clickTool("rectangle"); + mouse.down(200, 200); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + mouse.restorePosition(200, 200); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + + API.executeAction(actionGroup); + + // Select the first group. + // The second group is already selected because it was the last group created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + }; + + it("aligns two groups correctly to the top", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignTop); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(0); + expect(API.getSelectedElements()[3].y).toEqual(100); + }); + + it("aligns two groups correctly to the bottom", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignBottom); + + expect(API.getSelectedElements()[0].y).toEqual(200); + expect(API.getSelectedElements()[1].y).toEqual(300); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + }); + + it("aligns two groups correctly to the left", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignLeft); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(0); + expect(API.getSelectedElements()[3].x).toEqual(100); + }); + + it("aligns two groups correctly to the right", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignRight); + + expect(API.getSelectedElements()[0].x).toEqual(200); + expect(API.getSelectedElements()[1].x).toEqual(300); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + }); + + it("centers two groups correctly vertically", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignVerticallyCentered); + + expect(API.getSelectedElements()[0].y).toEqual(100); + expect(API.getSelectedElements()[1].y).toEqual(200); + expect(API.getSelectedElements()[2].y).toEqual(100); + expect(API.getSelectedElements()[3].y).toEqual(200); + }); + + it("centers two groups correctly horizontally", () => { + createAndSelectTwoGroups(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignHorizontallyCentered); + + expect(API.getSelectedElements()[0].x).toEqual(100); + expect(API.getSelectedElements()[1].x).toEqual(200); + expect(API.getSelectedElements()[2].x).toEqual(100); + expect(API.getSelectedElements()[3].x).toEqual(200); + }); + + const createAndSelectNestedGroupAndRectangle = () => { + UI.clickTool("rectangle"); + mouse.down(); + mouse.up(100, 100); + + UI.clickTool("rectangle"); + mouse.down(0, 0); + mouse.up(100, 100); + + // Select the first element. + // The second rectangle is already reselected because it was the last element created + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + + // Create first group of rectangles + API.executeAction(actionGroup); + + mouse.reset(); + UI.clickTool("rectangle"); + mouse.down(200, 200); + mouse.up(100, 100); + + // Add group to current selection + mouse.restorePosition(0, 0); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + + // Create the nested group + API.executeAction(actionGroup); + + mouse.reset(); + UI.clickTool("rectangle"); + mouse.down(300, 300); + mouse.up(100, 100); + + // Select the nested group, the rectangle is already selected + mouse.reset(); + Keyboard.withModifierKeys({ shift: true }, () => { + mouse.click(); + }); + }; + + it("aligns nested group and other element correctly to the top", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignTop); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(0); + }); + + it("aligns nested group and other element correctly to the bottom", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignBottom); + + expect(API.getSelectedElements()[0].y).toEqual(100); + expect(API.getSelectedElements()[1].y).toEqual(200); + expect(API.getSelectedElements()[2].y).toEqual(300); + expect(API.getSelectedElements()[3].y).toEqual(300); + }); + + it("aligns nested group and other element correctly to the left", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignLeft); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(0); + }); + + it("aligns nested group and other element correctly to the right", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignRight); + + expect(API.getSelectedElements()[0].x).toEqual(100); + expect(API.getSelectedElements()[1].x).toEqual(200); + expect(API.getSelectedElements()[2].x).toEqual(300); + expect(API.getSelectedElements()[3].x).toEqual(300); + }); + + it("centers nested group and other element correctly vertically", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].y).toEqual(0); + expect(API.getSelectedElements()[1].y).toEqual(100); + expect(API.getSelectedElements()[2].y).toEqual(200); + expect(API.getSelectedElements()[3].y).toEqual(300); + + API.executeAction(actionAlignVerticallyCentered); + + expect(API.getSelectedElements()[0].y).toEqual(50); + expect(API.getSelectedElements()[1].y).toEqual(150); + expect(API.getSelectedElements()[2].y).toEqual(250); + expect(API.getSelectedElements()[3].y).toEqual(150); + }); + + it("centers nested group and other element correctly horizontally", () => { + createAndSelectNestedGroupAndRectangle(); + + expect(API.getSelectedElements()[0].x).toEqual(0); + expect(API.getSelectedElements()[1].x).toEqual(100); + expect(API.getSelectedElements()[2].x).toEqual(200); + expect(API.getSelectedElements()[3].x).toEqual(300); + + API.executeAction(actionAlignHorizontallyCentered); + + expect(API.getSelectedElements()[0].x).toEqual(50); + expect(API.getSelectedElements()[1].x).toEqual(150); + expect(API.getSelectedElements()[2].x).toEqual(250); + expect(API.getSelectedElements()[3].x).toEqual(150); + }); +}); |
