Skip to content

Commit 2ebbef9

Browse files
committed
FIX: flaky Chromium assets-dock test
1 parent 55c6d68 commit 2ebbef9

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

tests/e2e/assets-dock.spec.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
import { expect, test } from '@playwright/test';
22
import { createEmptyProject } from '../../src/model/emptyProject';
3-
import { dismissViewHint, dispatchAction, dragAssetToCanvas, dragDropByTestIdAtClientPoint, dropAssetOnTestId, entityClientCenter, getEntitySpriteWorldRect, getSceneSnapshot, getState, hitTestAtClientPoint, openSceneScope, panByScreenDelta, seedProject, triggerUndo, waitForViewportToSettle, worldToClient } from './helpers';
3+
import { dismissViewHint, dispatchAction, dragAssetToCanvas, dropAssetAtClientPoint, dropAssetOnTestId, entityClientCenter, getEntitySpriteWorldRect, getSceneSnapshot, getState, hitTestAtClientPoint, openSceneScope, panByScreenDelta, seedProject, triggerUndo, waitForViewportToSettle, worldToClient } from './helpers';
44

55
test.describe('Assets dock', () => {
66
test.describe.configure({ timeout: 120000 });
77

8+
async function normalizedEntityPosition(page: Parameters<typeof entityClientCenter>[0], entityId: string) {
9+
const canvas = page.locator('#game-container canvas');
10+
await expect(canvas).toBeVisible();
11+
const canvasBox = await canvas.boundingBox();
12+
if (!canvasBox) throw new Error('Canvas bounding box unavailable');
13+
14+
const center = await entityClientCenter(page, entityId);
15+
return {
16+
x: (center.x - canvasBox.x) / canvasBox.width,
17+
y: (center.y - canvasBox.y) / canvasBox.height,
18+
};
19+
}
20+
821
test('imports an image and drags to canvas to create an entity with asset ref @critical @browser', async ({ page }) => {
922
await seedProject(page, createEmptyProject());
1023
await dismissViewHint(page);
@@ -91,7 +104,7 @@ test.describe('Assets dock', () => {
91104
return markerId;
92105
}).toBeTruthy();
93106
if (typeof markerId !== 'string') throw new Error('Failed to create marker entity');
94-
const markerClientBefore = await entityClientCenter(page, markerId);
107+
const markerNormalizedBefore = await normalizedEntityPosition(page, markerId);
95108

96109
// Use the same drag/drop path across browsers. Our helper uses a synthetic HTML5 drop for WebKit
97110
// to avoid flakiness from native `dragTo` while still exercising the real drop handler.
@@ -103,13 +116,15 @@ test.describe('Assets dock', () => {
103116

104117
// Minor subpixel/camera rounding differences are acceptable; ensure the viewport is effectively preserved.
105118
expect(Math.abs((after.zoom ?? 0) - (before.zoom ?? 0))).toBeLessThanOrEqual(1e-3);
106-
const markerClientAfter = await entityClientCenter(page, markerId);
107-
expect(
108-
Math.max(
109-
Math.abs(markerClientAfter.x - markerClientBefore.x),
110-
Math.abs(markerClientAfter.y - markerClientBefore.y),
111-
),
112-
).toBeLessThanOrEqual(5);
119+
await expect
120+
.poll(async () => {
121+
const markerNormalizedAfter = await normalizedEntityPosition(page, markerId!);
122+
return Math.max(
123+
Math.abs(markerNormalizedAfter.x - markerNormalizedBefore.x),
124+
Math.abs(markerNormalizedAfter.y - markerNormalizedBefore.y),
125+
);
126+
})
127+
.toBeLessThanOrEqual(0.02);
113128
});
114129

115130
test('dragging an image asset onto an existing sprite replaces its asset @critical @browser', async ({ page }, testInfo) => {
@@ -206,9 +221,10 @@ test.describe('Assets dock', () => {
206221
target: { kind: 'entity-sprite', sceneId, entityId: createdEntityId },
207222
} as any);
208223
} else {
209-
// Prefer a real drag gesture so Playwright supplies a stable `dataTransfer` payload across engines (Firefox
210-
// can intermittently drop synthetic DragEvent `dataTransfer` in CI).
211-
await dragDropByTestIdAtClientPoint(page, 'assets-dock-item-image-meteor-large', 'game-container', clientPoint);
224+
// Chromium can intermittently route a native drag to the canvas as "create entity" instead of
225+
// replacing the sprite under the pointer. Use a targeted HTML5 drop at the hit-tested client point
226+
// so we still exercise the real drop handler with a deterministic payload.
227+
await dropAssetAtClientPoint(page, { assetKind: 'image', assetId: 'meteor-large' }, 'game-container', clientPoint);
212228
}
213229

214230
try {

0 commit comments

Comments
 (0)