fix(e2e): map feature tests, maplibre external styles loading

Co-authored-by: Afonso Mendonça Ribeiro <afonso.mendonca.ribeiro@tecnico.ulisboa.pt>
pull/28676/head
Miguel Raposo 2026-05-29 15:45:34 +01:00
parent b7893e53b8
commit 19db9390b2
3 changed files with 22 additions and 7 deletions

View File

@ -141,12 +141,11 @@ test.describe('Map - Cluster Auto-Zoom', () => {
test('multiple clusters can be clicked sequentially', async ({ page }) => {
await mapUtils.navigateToMap(page);
const clusters = mapUtils.getClusters(page);
const clusterCount = await clusters.count();
const clusterCount = await mapUtils.getClusters(page).count();
const clickCount = Math.min(2, clusterCount);
for (let i = 0; i < clickCount; i++) {
const cluster = clusters.nth(i);
const cluster = mapUtils.getFirstCluster(page);
await mapUtils.clickCluster(page, cluster);
await mapUtils.expectMapVisible(page);
}

View File

@ -9,7 +9,7 @@ export const mapUtils = {
* Get all visible cluster on the map
*/
getClusters(page: Page) {
return page.locator('[class*="rounded-full"][class*="bg-immich-primary"]');
return page.locator('[class*="rounded-full"][class*="bg-immich-primary"]').filter({ hasText: /\d+/ });
},
/**
@ -24,8 +24,10 @@ export const mapUtils = {
*/
async getClusterCount(page: Page, clusterElement?: Locator) {
const element = clusterElement || this.getFirstCluster(page);
await expect(element).toBeVisible();
await expect(element).toHaveText(/\d+/);
const text = await element.textContent();
return Number.parseInt(text || '0', 10);
return Number.parseInt((text ?? '').replaceAll(/[^\d]/g, ''), 10);
},
/**
@ -33,7 +35,8 @@ export const mapUtils = {
*/
async clickCluster(page: Page, clusterElement?: Locator, waitMs = 1500) {
const element = clusterElement || this.getFirstCluster(page);
await element.click();
await element.scrollIntoViewIfNeeded();
await element.click({ force: true });
await page.waitForTimeout(waitMs);
},
@ -120,7 +123,12 @@ export const mapUtils = {
const errors: string[] = [];
const handler = (msg: ConsoleMessage) => {
if (msg.type() === 'error') {
errors.push(msg.text());
const text = msg.text();
// Ignore expected MapLibre external styles 401 in ci/cd
if (text.includes('401 (Unauthorized)')) {
return;
}
errors.push(text);
}
};

View File

@ -431,6 +431,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('map_settings')}
aria-label={$t('map_settings')}
onclick={handleSettingsClick}
>
<Icon icon={mdiCog} size="24" />
@ -442,6 +443,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={isGlobeView ? $t('switch_to_flat_map') : $t('switch_to_globe_map')}
aria-label={isGlobeView ? $t('switch_to_flat_map') : $t('switch_to_globe_map')}
aria-pressed={isGlobeView}
onclick={toggleMapProjection}
>
@ -452,6 +454,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={isFullscreen ? $t('exit_fullscreen') : $t('fullscreen')}
aria-label={isFullscreen ? $t('exit_fullscreen') : $t('fullscreen')}
onclick={toggleFullscreen}
>
<Icon icon={isFullscreen ? mdiFullscreenExit : mdiFullscreen} size="24" />
@ -463,6 +466,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('open_in_map_view')}
aria-label={$t('open_in_map_view')}
onclick={() => void onOpenInMapView()}
>
<Icon icon={mdiMap} size="24" />
@ -474,6 +478,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('timeline')}
aria-label={$t('timeline')}
onclick={() => onToggleTimeline?.()}
>
<Icon
@ -498,6 +503,7 @@
type="button"
class="flex size-11 items-center justify-center rounded-full border border-white/20 bg-white/70 text-black/80 shadow-lg backdrop-blur-md transition-all hover:bg-white/90 dark:border-white/10 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('geolocate')}
aria-label={$t('geolocate')}
onclick={handleLocate}
>
<Icon icon={mdiCrosshairsGps} size="24" />
@ -510,6 +516,7 @@
type="button"
class="flex size-11 items-center justify-center bg-white/70 text-black/80 transition-all hover:bg-white/90 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('zoom_in')}
aria-label={$t('zoom_in')}
onclick={() => map.zoomIn()}
>
<Icon icon={mdiPlus} size="24" />
@ -519,6 +526,7 @@
type="button"
class="flex size-11 items-center justify-center bg-white/70 text-black/80 transition-all hover:bg-white/90 dark:bg-immich-dark-gray/70 dark:text-white/80 dark:hover:bg-immich-dark-gray/90"
title={$t('zoom_out')}
aria-label={$t('zoom_out')}
onclick={() => map.zoomOut()}
>
<Icon icon={mdiMinus} size="24" />