This commit is contained in:
94
tests/e2e/poi-dom-labels.spec.ts
Normal file
94
tests/e2e/poi-dom-labels.spec.ts
Normal file
@@ -0,0 +1,94 @@
|
||||
import { expect, test, type Page } from '@playwright/test'
|
||||
|
||||
interface PoiCandidate {
|
||||
poiId: string
|
||||
floorId: string
|
||||
name: string
|
||||
primaryCategory: string
|
||||
positionGltf: [number, number, number]
|
||||
}
|
||||
|
||||
interface GuideDiagnostics {
|
||||
isInitialModelReady: () => boolean
|
||||
getFloors: () => Array<{ floorId: string }>
|
||||
getReport: () => { floorId: string; activeFocusPoiId: string }
|
||||
resetToViewBaseline: (options: { view: 'floor'; floorId: string; reason: 'floor-reset' }) => Promise<unknown>
|
||||
getFloorPois: (floorId: string) => Promise<PoiCandidate[]>
|
||||
focusTargetPoi: (request: PoiCandidate & { requestId: string }) => Promise<unknown>
|
||||
clearTargetFocus: () => void
|
||||
}
|
||||
|
||||
const openGuide = async (page: Page) => {
|
||||
await page.goto('/')
|
||||
await page.waitForURL(/tab=guide/, { timeout: 30_000 })
|
||||
await expect.poll(async () => page.evaluate(() => (
|
||||
(window as Window & { __GUIDE_3D_VISUAL_STABILITY__?: GuideDiagnostics })
|
||||
.__GUIDE_3D_VISUAL_STABILITY__?.isInitialModelReady() || false
|
||||
)), { timeout: 180_000 }).toBe(true)
|
||||
}
|
||||
|
||||
const resetToActiveFloor = async (page: Page) => page.evaluate(async () => {
|
||||
const api = (window as Window & { __GUIDE_3D_VISUAL_STABILITY__?: GuideDiagnostics })
|
||||
.__GUIDE_3D_VISUAL_STABILITY__
|
||||
if (!api) throw new Error('ThreeMap diagnostics unavailable')
|
||||
await api.resetToViewBaseline({ view: 'floor', floorId: api.getReport().floorId, reason: 'floor-reset' })
|
||||
return api.getReport().floorId
|
||||
})
|
||||
|
||||
for (const deviceScaleFactor of [1, 3]) {
|
||||
test.describe(`POI DOM labels at DPR ${deviceScaleFactor}`, () => {
|
||||
test.use({ viewport: { width: 390, height: 844 }, deviceScaleFactor })
|
||||
|
||||
test('renders measured native labels and clears focused labels without residue', async ({ page }, testInfo) => {
|
||||
await openGuide(page)
|
||||
const floorId = await resetToActiveFloor(page)
|
||||
const labels = page.locator('[data-poi-label-kind="ambient"]:visible')
|
||||
await expect(labels.first()).toBeVisible({ timeout: 30_000 })
|
||||
|
||||
const hall = page.locator('[data-poi-label-kind="ambient"].three-poi-dom-label--hall:visible').first()
|
||||
const facility = page.locator('[data-poi-label-kind="ambient"].three-poi-dom-label--service').first()
|
||||
await expect(hall).toBeVisible()
|
||||
|
||||
for (const locator of [hall, facility]) {
|
||||
await expect(locator).toHaveCSS('pointer-events', 'none')
|
||||
const fontSize = await locator.evaluate((element) => Number.parseFloat(getComputedStyle(element).fontSize))
|
||||
expect(fontSize).toBeGreaterThanOrEqual(locator === hall ? 14 : 13)
|
||||
}
|
||||
|
||||
for (const locator of [hall]) {
|
||||
const box = await locator.boundingBox()
|
||||
expect(box).not.toBeNull()
|
||||
expect(box!.x).toBeGreaterThanOrEqual(0)
|
||||
expect(box!.y).toBeGreaterThanOrEqual(0)
|
||||
expect(box!.x + box!.width).toBeLessThanOrEqual(390)
|
||||
expect(box!.y + box!.height).toBeLessThanOrEqual(844)
|
||||
}
|
||||
|
||||
const poiId = await facility.getAttribute('data-poi-id')
|
||||
expect(poiId).toBeTruthy()
|
||||
await page.evaluate(async ({ floorId: targetFloorId, targetPoiId }) => {
|
||||
const api = (window as Window & { __GUIDE_3D_VISUAL_STABILITY__?: GuideDiagnostics })
|
||||
.__GUIDE_3D_VISUAL_STABILITY__
|
||||
if (!api) throw new Error('ThreeMap diagnostics unavailable')
|
||||
const poi = (await api.getFloorPois(targetFloorId)).find((candidate) => candidate.poiId === targetPoiId)
|
||||
if (!poi) throw new Error(`missing POI ${targetPoiId}`)
|
||||
await api.focusTargetPoi({ ...poi, requestId: `poi-dom-label-${targetPoiId}` })
|
||||
}, { floorId, targetPoiId: poiId! })
|
||||
|
||||
const focus = page.locator('[data-poi-label-kind="focus"][data-focus-label="active"]')
|
||||
await expect(focus).toBeVisible({ timeout: 20_000 })
|
||||
await expect(focus).toHaveCSS('pointer-events', 'none')
|
||||
await expect(focus.locator('.three-poi-dom-label__title')).toHaveCSS('font-size', '16px')
|
||||
await expect(focus.locator('.three-poi-dom-label__meta')).toHaveCSS('font-size', '13px')
|
||||
await page.screenshot({ path: testInfo.outputPath(`poi-dom-labels-dpr-${deviceScaleFactor}-focus.png`) })
|
||||
|
||||
await page.evaluate(() => {
|
||||
const api = (window as Window & { __GUIDE_3D_VISUAL_STABILITY__?: GuideDiagnostics })
|
||||
.__GUIDE_3D_VISUAL_STABILITY__
|
||||
api?.clearTargetFocus()
|
||||
})
|
||||
await expect(focus).toHaveCount(0)
|
||||
await page.screenshot({ path: testInfo.outputPath(`poi-dom-labels-dpr-${deviceScaleFactor}-ambient.png`) })
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user