import { test, expect, Page } from '@playwright/test'; import { HS, ensureUser, hsReachable, loginUI, TestUser, uniq } from './localHs'; // [Gitea #110, #123] The device-security nudge. A fresh account has no key // backup and no cross-signing → "Set up key backup", but only after the 24 h // grace period on this device; "Not now" snoozes it. const strip = (page: Page) => page.getByRole('status').filter({ hasText: /encryption keys/ }); /** Back-date this device's first-seen record past the 24 h grace period, then reload. */ async function pastGrace(page: Page) { await page.evaluate(() => { const { deviceId } = JSON.parse(localStorage.getItem('cinny_session_v1') ?? '{}'); localStorage.setItem( `lotus-security-nudge-${deviceId}`, JSON.stringify({ firstSeen: Date.now() - 2 * 86_400_000, dismissals: {} }), ); }); await page.reload(); } /** The nudge waits until sync has settled (after "Connecting…"). */ async function settled(page: Page) { await page .getByText('Connecting...') .first() .waitFor({ timeout: 30_000 }) .catch(() => undefined); await page.getByText('Connecting...').first().waitFor({ state: 'detached', timeout: 90_000 }); await page.waitForTimeout(2000); } test.describe('security nudge (#110, #123)', () => { let user: TestUser; test.beforeAll(async () => { test.skip(!(await hsReachable()), `no local homeserver at ${HS} (set E2E_LOCAL_HS)`); }); test.beforeEach(async () => { user = await ensureUser(uniq('e2e_nudge_')); }); test('nothing during the first 24 h on a device', async ({ page }) => { test.setTimeout(150_000); await loginUI(page, user); await settled(page); // Past the point where the nudge shows once the grace period is over (~5 s). await page.waitForTimeout(8000); await expect(strip(page)).toHaveCount(0); }); test('no key backup: "Set up key backup" opens Settings → Devices', async ({ page }) => { test.setTimeout(150_000); await loginUI(page, user); await pastGrace(page); await settled(page); const nudge = strip(page); await expect(nudge).toContainText("Your encryption keys aren't backed up"); await nudge.getByRole('button', { name: 'Set up' }).click(); await expect(page.getByText('Device Verification').first()).toBeVisible(); }); test('"Not now" snoozes it across a reload', async ({ page }) => { test.setTimeout(200_000); await loginUI(page, user); await pastGrace(page); await settled(page); await strip(page).getByRole('button', { name: 'Not now' }).click(); await expect(strip(page)).toHaveCount(0); await page.reload(); await settled(page); await expect(strip(page)).toHaveCount(0); }); });