import { AlbumResponseDto, AssetMediaResponseDto, LoginResponseDto, SharedLinkResponseDto, SharedLinkType, createAlbum, } from '@immich/sdk'; import { expect, test } from '@playwright/test'; import { asBearerAuth, utils } from 'src/utils'; test.describe('Shared Links', () => { let admin: LoginResponseDto; let asset: AssetMediaResponseDto; let album: AlbumResponseDto; let sharedLink: SharedLinkResponseDto; let sharedLinkPassword: SharedLinkResponseDto; test.beforeAll(async () => { utils.initSdk(); await utils.resetDatabase(); admin = await utils.adminSetup(); asset = await utils.createAsset(admin.accessToken); album = await createAlbum( { createAlbumDto: { albumName: 'Test Album', assetIds: [asset.id], }, }, { headers: asBearerAuth(admin.accessToken) }, ); sharedLink = await utils.createSharedLink(admin.accessToken, { type: SharedLinkType.Album, albumId: album.id, }); sharedLinkPassword = await utils.createSharedLink(admin.accessToken, { type: SharedLinkType.Album, albumId: album.id, password: 'test-password', }); }); test('download from a shared link', async ({ page }) => { await page.goto(`/share/${sharedLink.key}`); await page.getByRole('heading', { name: 'Test Album' }).waitFor(); await page.locator(`[data-asset-id="${asset.id}"]`).hover(); await page.waitForSelector('[data-group] svg'); await page.getByRole('checkbox').click(); await page.getByRole('button', { name: 'Download' }).click(); await page.waitForEvent('download'); }); test('download all from shared link', async ({ page }) => { await page.goto(`/share/${sharedLink.key}`); await page.getByRole('heading', { name: 'Test Album' }).waitFor(); await page.getByRole('button', { name: 'Download' }).click(); await page.waitForEvent('download'); }); test('enter password for a shared link', async ({ page }) => { await page.goto(`/share/${sharedLinkPassword.key}`); await page.getByPlaceholder('Password').fill('test-password'); await page.getByRole('button', { name: 'Submit' }).click(); await page.getByRole('heading', { name: 'Test Album' }).waitFor(); }); test('show-password button visible', async ({ page }) => { await page.goto(`/share/${sharedLinkPassword.key}`); await page.getByPlaceholder('Password').fill('test-password'); await page.getByRole('button', { name: 'Show password' }).waitFor(); }); test('view password for shared link', async ({ page }) => { await page.goto(`/share/${sharedLinkPassword.key}`); const input = page.getByPlaceholder('Password'); await input.fill('test-password'); await page.getByRole('button', { name: 'Show password' }).click(); // await page.getByText('test-password', { exact: true }).waitFor(); await expect(input).toHaveAttribute('type', 'text'); }); test('hide-password button visible', async ({ page }) => { await page.goto(`/share/${sharedLinkPassword.key}`); const input = page.getByPlaceholder('Password'); await input.fill('test-password'); await page.getByRole('button', { name: 'Show password' }).click(); await page.getByRole('button', { name: 'Hide password' }).waitFor(); }); test('hide password for shared link', async ({ page }) => { await page.goto(`/share/${sharedLinkPassword.key}`); const input = page.getByPlaceholder('Password'); await input.fill('test-password'); await page.getByRole('button', { name: 'Show password' }).click(); await page.getByRole('button', { name: 'Hide password' }).click(); await expect(input).toHaveAttribute('type', 'password'); }); test('show error for invalid shared link', async ({ page }) => { await page.goto('/share/invalid'); await page.getByRole('heading', { name: 'Invalid share key' }).waitFor(); }); test('auth on navigation from shared link to timeline', async ({ context, page }) => { await utils.setAuthCookies(context, admin.accessToken); await page.goto(`/share/${sharedLink.key}`); await page.getByRole('heading', { name: 'Test Album' }).waitFor(); await page.locator('a[href="/"]').click(); await page.waitForURL('/photos'); await page.locator(`[data-asset-id="${asset.id}"]`).waitFor(); }); });