import { AssetMediaResponseDto, LoginResponseDto, SharedLinkType } from '@immich/sdk'; import { expect, test } from '@playwright/test'; import type { Socket } from 'socket.io-client'; import { utils } from 'src/utils'; test.describe('Detail Panel', () => { let admin: LoginResponseDto; let asset: AssetMediaResponseDto; let websocket: Socket; test.beforeAll(async () => { utils.initSdk(); await utils.resetDatabase(); admin = await utils.adminSetup(); asset = await utils.createAsset(admin.accessToken); websocket = await utils.connectWebsocket(admin.accessToken); }); test.afterAll(() => { utils.disconnectWebsocket(websocket); }); test('can be opened for shared links', async ({ page }) => { const sharedLink = await utils.createSharedLink(admin.accessToken, { type: SharedLinkType.Individual, assetIds: [asset.id], }); await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`); await page.waitForSelector('#immich-asset-viewer'); await expect(page.getByRole('button', { name: 'Info' })).toBeVisible(); await page.keyboard.press('i'); await expect(page.locator('#detail-panel')).toBeVisible(); await page.keyboard.press('i'); await expect(page.locator('#detail-panel')).toHaveCount(0); }); test('cannot be opened for shared links with hidden metadata', async ({ page }) => { const sharedLink = await utils.createSharedLink(admin.accessToken, { type: SharedLinkType.Individual, assetIds: [asset.id], showMetadata: false, }); await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`); await page.waitForSelector('#immich-asset-viewer'); await expect(page.getByRole('button', { name: 'Info' })).toHaveCount(0); await page.keyboard.press('i'); await expect(page.locator('#detail-panel')).toHaveCount(0); await page.keyboard.press('i'); await expect(page.locator('#detail-panel')).toHaveCount(0); }); test('description is visible for owner on shared links', async ({ context, page }) => { const sharedLink = await utils.createSharedLink(admin.accessToken, { type: SharedLinkType.Individual, assetIds: [asset.id], }); await utils.setAuthCookies(context, admin.accessToken); await page.goto(`/share/${sharedLink.key}/photos/${asset.id}`); const textarea = page.getByRole('textbox', { name: 'Add a description' }); await page.getByRole('button', { name: 'Info' }).click(); await expect(textarea).toBeVisible(); await expect(textarea).not.toBeDisabled(); }); test('description changes are visible after reopening', async ({ context, page }) => { await utils.setAuthCookies(context, admin.accessToken); await page.goto(`/photos/${asset.id}`); await page.waitForSelector('#immich-asset-viewer'); await page.getByRole('button', { name: 'Info' }).click(); const textarea = page.getByRole('textbox', { name: 'Add a description' }); await textarea.fill('new description'); await expect(textarea).toHaveValue('new description'); await page.getByRole('button', { name: 'Info' }).click(); await expect(textarea).not.toBeVisible(); await page.getByRole('button', { name: 'Info' }).click(); await expect(textarea).toBeVisible(); await utils.waitForWebsocketEvent({ event: 'assetUpdate', id: asset.id }); await expect(textarea).toHaveValue('new description'); }); });