diff --git a/e2e/helpers/konva-testing.helpers.ts b/e2e/helpers/konva-testing.helpers.ts index 93c8ad89..d4ba4e3d 100644 --- a/e2e/helpers/konva-testing.helpers.ts +++ b/e2e/helpers/konva-testing.helpers.ts @@ -5,6 +5,8 @@ import { Group } from 'konva/lib/Group'; import { E2E_CanvasItemKeyAttrs } from './types/e2e-types'; import { getCanvasBoundingBox } from './position.helpers'; +// MAIN CANVAS HELPERS + const getLayer = async (page: Page): Promise => await page.evaluate(() => { return window.__TESTING_KONVA_LAYER__; @@ -50,6 +52,50 @@ export const getByShapeType = async ( } }; +// THUMB HELPERS + +const getThumbLayer = async (page: Page, pageIndex: number): Promise => + await page.evaluate(index => { + return window.__TESTING_KONVA_THUMB_LAYERS__?.[index]; + }, pageIndex); + +const getThumbChildren = async (page: Page, pageIndex: number) => { + const layer = await getThumbLayer(page, pageIndex); + return layer?.children || []; +}; + +// Waits for a thumb to finish rendering (until it has at least one child) + +export const waitForThumbToRender = async ( + page: Page, + pageIndex: number, + timeout = 5000 +) => { + await page.waitForFunction( + async index => { + const layer = window.__TESTING_KONVA_THUMB_LAYERS__?.[index]; + if (!layer) return false; + + const children = layer.children || []; + return children && children.length > 0; + }, + pageIndex, + { timeout } + ); +}; + +export const getByShapeTypeInThumb = async ( + page: Page, + pageIndex: number, + shape: string +): Promise => { + await waitForThumbToRender(page, pageIndex); + + // Search for the shape + const children = await getThumbChildren(page, pageIndex); + return children?.find(child => child.attrs.shapeType === shape); +}; + export const getTransformer = async (page: Page): Promise => { const layer = await getLayer(page); const transformer = layer?.children.find((child: any) => { diff --git a/e2e/thumb-pages/dropped-button-visible-on-thumb.spec.ts b/e2e/thumb-pages/dropped-button-visible-on-thumb.spec.ts new file mode 100644 index 00000000..f414c844 --- /dev/null +++ b/e2e/thumb-pages/dropped-button-visible-on-thumb.spec.ts @@ -0,0 +1,25 @@ +import { test, expect } from '@playwright/test'; +import { + dragAndDrop, + getByShapeTypeInThumb, + getLocatorPosition, +} from '../helpers'; + +test('drop button in canvas, ensure is visible on thumb', async ({ page }) => { + await page.goto(''); + + // Drag & drop button in canvas + const button = page.getByAltText('Button', { exact: true }); + await expect(button).toBeVisible(); + + const position = await getLocatorPosition(button); + const targetPosition = { x: position.x + 500, y: position.y }; + await dragAndDrop(page, position, targetPosition); + + // Open Pages panel + await page.getByText('Pages').click(); + + // Verify button is visible in thumb + const buttonInThumb = await getByShapeTypeInThumb(page, 0, 'button'); + expect(buttonInThumb).toBeDefined(); +}); diff --git a/global.d.ts b/global.d.ts index a54a40ab..97c66570 100644 --- a/global.d.ts +++ b/global.d.ts @@ -3,5 +3,6 @@ import Konva from 'konva'; declare global { interface Window { __TESTING_KONVA_LAYER__: Konva.Layer; + __TESTING_KONVA_THUMB_LAYERS__: Konva.Layer[]; } } diff --git a/src/pods/thumb-pages/components/thumb-page.tsx b/src/pods/thumb-pages/components/thumb-page.tsx index 64719202..4334ef57 100644 --- a/src/pods/thumb-pages/components/thumb-page.tsx +++ b/src/pods/thumb-pages/components/thumb-page.tsx @@ -12,6 +12,8 @@ import classes from './thumb-page.module.css'; import React from 'react'; import { useDragDropThumb } from './drag-drop-thumb.hook'; +import Konva from 'konva'; +import { ENV } from '@/core/constants'; interface Props { pageIndex: number; @@ -35,6 +37,7 @@ export const ThumbPage: React.FunctionComponent = props => { }); const divRef = useRef(null); + const layerRef = useRef(null); const [key, setKey] = React.useState(0); const { dragging, isDraggedOver } = useDragDropThumb(divRef, pageIndex); @@ -52,6 +55,15 @@ export const ThumbPage: React.FunctionComponent = props => { }, 100); }; + // Exposing thumb layer for testing + + if (typeof window !== 'undefined' && ENV.IS_TEST_ENV && layerRef.current) { + if (!window.__TESTING_KONVA_THUMB_LAYERS__) { + window.__TESTING_KONVA_THUMB_LAYERS__ = []; + } + window.__TESTING_KONVA_THUMB_LAYERS__[pageIndex] = layerRef.current; + } + React.useLayoutEffect(() => { handleResizeAndForceRedraw(); }, []); @@ -105,7 +117,7 @@ export const ThumbPage: React.FunctionComponent = props => { scaleX={finalScale} scaleY={finalScale} > - + {shapes.map(shape => { if (!fakeShapeRefs.current[shape.id]) { fakeShapeRefs.current[shape.id] = createRef();