테스트/린트 안정화: 버튼 쿼리 모호성 제거, 훅 deps 보강, vi.spyOn 모킹, 멀티선택 Moveable 간섭 방지 재확인, 스냅 우선순위 회귀 그린
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
||||
import { WysiwygBuilderPage } from '@/components/wysiwyg/WysiwygBuilderPage'
|
||||
|
||||
function getXY(el: HTMLElement) {
|
||||
const style = el.getAttribute('style') || ''
|
||||
const m = { left: /left:\s*(\d+)px/, top: /top:\s*(\d+)px/ }
|
||||
const left = Number((style.match(m.left)?.[1]) || '0')
|
||||
const top = Number((style.match(m.top)?.[1]) || '0')
|
||||
return { left, top }
|
||||
}
|
||||
|
||||
function getRotate(el: HTMLElement) {
|
||||
const style = el.getAttribute('style') || ''
|
||||
const m = /rotate\(([-\d.]+)deg\)/
|
||||
const v = Number((style.match(m)?.[1]) || '0')
|
||||
return v
|
||||
}
|
||||
|
||||
describe('WYSIWYG - group actions drag/resize/rotate with snapping', () => {
|
||||
it('drags two selected objects together with 8px snapping', async () => {
|
||||
render(<WysiwygBuilderPage />)
|
||||
// add two texts
|
||||
const addText = () => fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
|
||||
addText()
|
||||
addText()
|
||||
const objs = await screen.findAllByTestId(/obj-text-/)
|
||||
const a = objs[0]
|
||||
const b = objs[1]
|
||||
|
||||
// select both (click first then shift-click second)
|
||||
fireEvent.mouseDown(a, { clientX: 60, clientY: 60 })
|
||||
fireEvent.mouseUp(a)
|
||||
fireEvent.mouseDown(b, { clientX: 80, clientY: 80, shiftKey: true })
|
||||
// wait until selection reflects two items
|
||||
await screen.findByText(/선택 2개/)
|
||||
|
||||
const canvas = screen.getByTestId('wysiwyg-canvas')
|
||||
// drag second (selected) by ~13, expect snap to +16
|
||||
fireEvent.mouseDown(b, { clientX: 120, clientY: 120 })
|
||||
fireEvent.mouseMove(canvas, { clientX: 133, clientY: 133 })
|
||||
fireEvent.mouseUp(canvas)
|
||||
|
||||
await waitFor(() => {
|
||||
const xyA = getXY(a)
|
||||
const xyB = getXY(b)
|
||||
expect(xyA.left).toBe(76)
|
||||
expect(xyA.top).toBe(76)
|
||||
expect(xyB.left).toBe(76)
|
||||
expect(xyB.top).toBe(76)
|
||||
})
|
||||
})
|
||||
|
||||
it('resizes group from east handle; both widths increase with snapping', async () => {
|
||||
render(<WysiwygBuilderPage />)
|
||||
const addText = () => fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
|
||||
addText()
|
||||
addText()
|
||||
const objs = await screen.findAllByTestId(/obj-text-/)
|
||||
const a = objs[0]
|
||||
const b = objs[1]
|
||||
|
||||
// select both
|
||||
fireEvent.mouseDown(a, { clientX: 60, clientY: 60 })
|
||||
fireEvent.mouseUp(a)
|
||||
fireEvent.mouseDown(b, { clientX: 80, clientY: 80, shiftKey: true })
|
||||
|
||||
// drag east handle of second by ~13 -> snap width +16
|
||||
const idB = (b.getAttribute('data-testid') || '').replace('obj-', '')
|
||||
const handleE = await screen.findByTestId(`resize-handle-e-${idB}`)
|
||||
fireEvent.mouseDown(handleE, { clientX: 180, clientY: 80 })
|
||||
const canvas = screen.getByTestId('wysiwyg-canvas')
|
||||
fireEvent.mouseMove(canvas, { clientX: 193, clientY: 80 })
|
||||
fireEvent.mouseUp(canvas)
|
||||
|
||||
// widths reflected in inline style
|
||||
const styleA = a.getAttribute('style') || ''
|
||||
const styleB = b.getAttribute('style') || ''
|
||||
const wA = Number((styleA.match(/width:\s*(\d+)px/)?.[1]) || '0')
|
||||
const wB = Number((styleB.match(/width:\s*(\d+)px/)?.[1]) || '0')
|
||||
expect(wA).toBeGreaterThanOrEqual(176) // initial 160 -> +16
|
||||
expect(wB).toBeGreaterThanOrEqual(176)
|
||||
})
|
||||
|
||||
it('rotates group with 15deg snapping (no shift)', async () => {
|
||||
render(<WysiwygBuilderPage />)
|
||||
const addText = () => fireEvent.click(screen.getByRole('button', { name: /^Add Text$/i }))
|
||||
addText()
|
||||
addText()
|
||||
const objs = await screen.findAllByTestId(/obj-text-/)
|
||||
const a = objs[0]
|
||||
const b = objs[1]
|
||||
|
||||
// select both
|
||||
fireEvent.mouseDown(a)
|
||||
fireEvent.mouseUp(a)
|
||||
fireEvent.mouseDown(b, { shiftKey: true })
|
||||
fireEvent.mouseUp(b)
|
||||
|
||||
const idB2 = (b.getAttribute('data-testid') || '').replace('obj-', '')
|
||||
const rotateHandle = await screen.findByTestId(`rotate-handle-${idB2}`)
|
||||
fireEvent.mouseDown(rotateHandle, { clientX: 100, clientY: 10 })
|
||||
const canvas = screen.getByTestId('wysiwyg-canvas')
|
||||
fireEvent.mouseMove(canvas, { clientX: 130, clientY: 10 }) // +30 -> snap 30 (15 step)
|
||||
fireEvent.mouseUp(canvas)
|
||||
|
||||
const rA = getRotate(a)
|
||||
const rB = getRotate(b)
|
||||
expect(rA).toBe(30)
|
||||
expect(rB).toBe(30)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user