diff --git a/tests/e2e/wysiwyg-group-rotate-resize.e2e.ts b/tests/e2e/wysiwyg-group-rotate-resize.e2e.ts new file mode 100644 index 0000000..0cbf639 --- /dev/null +++ b/tests/e2e/wysiwyg-group-rotate-resize.e2e.ts @@ -0,0 +1,114 @@ +import { test, expect } from '@playwright/test' + +const wysiwygUrl = '/en/wysiwyg' + +async function getBox(page: import('@playwright/test').Page, nth: number) { + const el = page.locator('[data-testid^="obj-text-"]').nth(nth) + const left = await el.evaluate((n) => parseInt((n as HTMLElement).style.left || '0', 10)) + const top = await el.evaluate((n) => parseInt((n as HTMLElement).style.top || '0', 10)) + const width = await el.evaluate((n) => parseInt((n as HTMLElement).style.width || '0', 10)) + const height = await el.evaluate((n) => parseInt((n as HTMLElement).style.height || '0', 10)) + return { left, top, width, height } +} + +function snap8(v: number) { return Math.round(v / 8) * 8 } + +test.describe('WYSIWYG - Group rotate then resize (E/W) with snap', () => { + test('rotate ~15°, then group resize E by +16 (snap) — widths grow equally, left unchanged', async ({ page }) => { + await page.goto(wysiwygUrl) + const canvas = page.getByTestId('wysiwyg-canvas') + await expect(canvas).toBeVisible() + + const addText = page.getByRole('button', { name: /^Add Text$/i }) + await addText.click() + await addText.click() + + // marquee select both + const cbox = await canvas.boundingBox() + if (!cbox) throw new Error('canvas not found') + await page.mouse.move(cbox.x + 40, cbox.y + 40) + await page.mouse.down() + await page.mouse.move(cbox.x + 260, cbox.y + 160) + await page.mouse.up() + + // rotate via handle to ~15° + const rotateHandle = page.locator('[data-testid^="rotate-handle-"]').first() + const hbox = await rotateHandle.boundingBox() + if (!hbox) throw new Error('rotate handle not found') + await page.mouse.move(hbox.x + 5, hbox.y + 5) + await page.mouse.down() + await page.mouse.move(hbox.x + 40, hbox.y + 5) + await page.mouse.up() + + const b0 = await getBox(page, 0) + const b1 = await getBox(page, 1) + + // resize east handle of the second by +16px (should snap to +16) + const target = page.locator('[data-testid^="obj-text-"]').nth(1) + const tbox = await target.boundingBox() + if (!tbox) throw new Error('target not found') + await page.mouse.move(tbox.x + tbox.width - 5, tbox.y + 5) + await page.mouse.down() + await page.mouse.move(tbox.x + tbox.width + 16, tbox.y + 5) + await page.mouse.up() + + const a0 = await getBox(page, 0) + const a1 = await getBox(page, 1) + + const dw = snap8(b1.width + 16) - b1.width + expect(a0.left).toBe(b0.left) + expect(a1.left).toBe(b1.left) + expect(a0.width).toBe(b0.width + dw) + expect(a1.width).toBe(b1.width + dw) + }) + + test('rotate ~15°, then group resize W by +16 (snap) — widths grow equally, left shifts equally', async ({ page }) => { + await page.goto(wysiwygUrl) + const canvas = page.getByTestId('wysiwyg-canvas') + await expect(canvas).toBeVisible() + + const addText = page.getByRole('button', { name: /^Add Text$/i }) + await addText.click() + await addText.click() + + // marquee select both + const cbox = await canvas.boundingBox() + if (!cbox) throw new Error('canvas not found') + await page.mouse.move(cbox.x + 40, cbox.y + 40) + await page.mouse.down() + await page.mouse.move(cbox.x + 260, cbox.y + 160) + await page.mouse.up() + + // rotate via handle to ~15° + const rotateHandle = page.locator('[data-testid^="rotate-handle-"]').first() + const hbox = await rotateHandle.boundingBox() + if (!hbox) throw new Error('rotate handle not found') + await page.mouse.move(hbox.x + 5, hbox.y + 5) + await page.mouse.down() + await page.mouse.move(hbox.x + 40, hbox.y + 5) + await page.mouse.up() + + const b0 = await getBox(page, 0) + const b1 = await getBox(page, 1) + + // resize west handle of the first by -16px (drag left) + const first = page.locator('[data-testid^="obj-text-"]').first() + const fbox = await first.boundingBox() + if (!fbox) throw new Error('first not found') + await page.mouse.move(fbox.x + 5, fbox.y + 5) // move inside to be safe + await page.mouse.move(fbox.x + 2, fbox.y + 5) + await page.mouse.down() + await page.mouse.move(fbox.x - 16, fbox.y + 5) + await page.mouse.up() + + const a0 = await getBox(page, 0) + const a1 = await getBox(page, 1) + + const dw = snap8(b0.width + 16) - b0.width + const dx = a0.left - b0.left + expect(a0.width).toBe(b0.width + dw) + expect(a1.width).toBe(b1.width + dw) + expect(dx).toBeLessThanOrEqual(-16) + expect(a1.left - b1.left).toBe(dx) + }) +})