diff --git a/e2e/board.smoke.spec.ts b/e2e/board.smoke.spec.ts index 802566b..149a1f5 100644 --- a/e2e/board.smoke.spec.ts +++ b/e2e/board.smoke.spec.ts @@ -28,17 +28,18 @@ test('move, folder expansion, empty-board pan, desktop wheel zoom, mobile pinch, await page.goto('/?level=e2e-level&edit=1') await expect(page.getByRole('heading', { name: 'Browser Safety Test' })).toBeVisible() await expect(page.getByRole('button', { name: 'ADMIN', exact: true })).toBeVisible() - expect((await page.locator('.menubar nav > button, .menubar nav > .admin-menu > button').allTextContents()).map(label => label.replace(/\d+$/, ''))).toEqual(['EVIDENCE', 'CASE BRIEF', 'TIMELINE', 'HELP', 'ADMIN']) + expect((await page.locator('.menubar nav > button, .menubar nav > .admin-menu > button').allTextContents()).map(label => label.replace(/\d+$/, ''))).toEqual(['EVIDENCE', 'BRIEF', 'HELP', 'ADMIN']) + await expect(page.getByRole('button', { name: 'Timeline settings', exact: true })).toBeVisible() const temporalLayering = await page.evaluate(() => ({ links: Number.parseInt(getComputedStyle(document.querySelector('.temporal-links')!).zIndex, 10), timeline: Number.parseInt(getComputedStyle(document.querySelector('.timeline')!).zIndex, 10), })) expect(temporalLayering.links).toBeGreaterThan(temporalLayering.timeline) expect(await page.locator('.timeline .year').first().evaluate(element => Number.parseFloat(getComputedStyle(element).fontSize))).toBeGreaterThanOrEqual(12) - expect(await page.locator('.timeline-label button').evaluate(element => Number.parseFloat(getComputedStyle(element).fontSize))).toBeGreaterThanOrEqual(11) + expect(await page.locator('.timeline-range').evaluate(element => Number.parseFloat(getComputedStyle(element).fontSize))).toBeGreaterThanOrEqual(11) await expect(page.locator('.documents-panel')).toHaveClass(/\bclosed\b/) await expect(page.locator('.brief-panel')).toBeVisible() - await expect(page.getByRole('button', { name: 'Case brief', exact: true })).toContainText('2') + await expect(page.getByRole('button', { name: 'Brief', exact: true })).toContainText('2') await page.getByRole('button', { name: 'Minimize brief', exact: true }).click() await expect(page.locator('.brief-panel')).toHaveClass(/\bminimized\b/) await expect(page.locator('.brief-panel > p')).toBeHidden() @@ -157,7 +158,7 @@ test('move, folder expansion, empty-board pan, desktop wheel zoom, mobile pinch, await boardViewport.dispatchEvent('pointerup', { pointerId: 42, pointerType: 'touch', isPrimary: false, button: 0, clientX: touchOrigin.x + 150, clientY: touchOrigin.y }) await boardViewport.dispatchEvent('pointerup', { pointerId: 41, pointerType: 'touch', isPrimary: true, button: 0, clientX: touchOrigin.x, clientY: touchOrigin.y }) - await page.getByRole('button', { name: 'Case brief', exact: true }).click() + await page.getByRole('button', { name: 'Brief', exact: true }).click() await expect(page.locator('.brief-panel')).toContainText('Ada Lovelace') const personConcept = page.locator('.brief-concepts section').filter({ hasText: 'Ada Lovelace' }) await waitForSave(page, () => personConcept.getByRole('button', { name: 'PERSON', exact: true }).click()) @@ -265,6 +266,6 @@ test('hides the admin menu without a verified admin JWT', async ({ browser }) => await page.goto('/?level=e2e-level&edit=1') await expect(page.getByRole('heading', { name: 'Browser Safety Test' })).toBeVisible() await expect(page.getByRole('button', { name: 'ADMIN', exact: true })).toHaveCount(0) - expect((await page.locator('.menubar nav > button').allTextContents()).map(label => label.replace(/\d+$/, ''))).toEqual(['EVIDENCE', 'CASE BRIEF', 'TIMELINE', 'HELP']) + expect((await page.locator('.menubar nav > button').allTextContents()).map(label => label.replace(/\d+$/, ''))).toEqual(['EVIDENCE', 'BRIEF', 'HELP']) await context.close() }) diff --git a/e2e/mystery.acceptance.spec.ts b/e2e/mystery.acceptance.spec.ts index 5bc92fc..8236913 100644 --- a/e2e/mystery.acceptance.spec.ts +++ b/e2e/mystery.acceptance.spec.ts @@ -17,7 +17,7 @@ async function waitForSave(page: Page, action: () => Promise) { } async function classify(page: Page, name: string, kind: 'PERSON' | 'ORGANIZATION', summary: string) { - if (!await page.locator('.brief-panel').isVisible()) await page.getByRole('button', { name: 'Case brief', exact: true }).click() + if (!await page.locator('.brief-panel').isVisible()) await page.getByRole('button', { name: 'Brief', exact: true }).click() const concept = page.locator('.brief-concepts section').filter({ hasText: name }) await waitForSave(page, () => concept.getByRole('button', { name: kind, exact: true }).click()) await expect(page.locator('.brief-panel')).toBeVisible() @@ -50,7 +50,7 @@ test('a cloned Glass Harbor level can be solved without modifying its template', await page.goto(`/?level=${playable.id}`) await expect(page.getByRole('heading', { name: 'The Glass Harbor Diversion' })).toBeVisible() await expect(page.locator('.documents-panel')).toHaveClass(/\bclosed\b/) - await page.locator('.open-files').click() + await page.getByRole('button', { name: 'EVIDENCE', exact: true }).click() await page.getByRole('searchbox', { name: 'Search inside documents', exact: true }).fill('Elias') await expect(page.locator('.doc-row')).toHaveCount(1) await expect(page.locator('.doc-row')).toContainText('Carrier Dispatch Manifest · H&F 14') @@ -59,18 +59,18 @@ test('a cloned Glass Harbor level can be solved without modifying its template', await page.getByRole('button', { name: 'Close documents', exact: true }).click() await expect(page.locator('.evidence-card.folder')).toHaveCount(3) await expect(page.locator('.timeline .marker')).toHaveCount(8) - await expect(page.locator('.timeline-label button')).toHaveText('1987-10-01 — 1987-10-31') + await expect(page.locator('.timeline-range')).toHaveText('1987-10-01 — 1987-10-31') const dispatchMarker = await page.getByRole('button', { name: '1987-10-16 — Carrier Dispatch Manifest · H&F 14', exact: true }).boundingBox() const auctionMarker = await page.getByRole('button', { name: '1987-10-24 — Meridian Maritime Auction · Lot 117', exact: true }).boundingBox() expect(dispatchMarker).not.toBeNull() expect(auctionMarker).not.toBeNull() expect(auctionMarker!.x - dispatchMarker!.x).toBeGreaterThan(100) - await page.getByRole('button', { name: 'TIMELINE', exact: true }).click() + await page.getByRole('button', { name: 'Timeline settings', exact: true }).click() await page.getByLabel('Timeline start date').fill('1987-10-10') await page.getByLabel('Timeline end date').fill('1987-10-26') await waitForSave(page, () => page.getByRole('button', { name: 'APPLY RANGE', exact: true }).click()) - await expect(page.locator('.timeline-label button')).toHaveText('1987-10-10 — 1987-10-26') + await expect(page.locator('.timeline-range')).toHaveText('1987-10-10 — 1987-10-26') await classify(page, 'Mara Voss', 'PERSON', 'Restoration project officer who sponsored the Warehouse 3 access pass.') await classify(page, 'Elias Vale', 'PERSON', 'Driver of H&F 14; transported CO-771 to Warehouse 3.') diff --git a/e2e/scene7.acceptance.spec.ts b/e2e/scene7.acceptance.spec.ts index d52c4d2..95ed0a6 100644 --- a/e2e/scene7.acceptance.spec.ts +++ b/e2e/scene7.acceptance.spec.ts @@ -94,7 +94,7 @@ test('pasting, connecting, and citing one patent screenshot completes the Scene await page.getByLabel('Thread tag').fill('Proof that Nils Aall Barricelli is named as inventor on patent GB695913A.') await page.getByRole('button',{ name:'ADD TAG & TIGHTEN' }).click() - await page.getByRole('button',{ name:'Case report' }).click() + await page.getByRole('button',{ name:'Report' }).click() await expect(page.locator('.case-report')).toBeVisible() await expect(page.locator('.report-claim')).toContainText('Nils Aall Barricelli was an inventor') await expect(page.locator('.report-evidence')).toContainText('Exhibit 1') diff --git a/src/App.tsx b/src/App.tsx index c13d612..e102ec2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' -import { BookOpen, Building2, CalendarClock, Camera, Check, ChevronRight, CircleHelp, ClipboardCheck, FileText, FolderOpen, Hand, Image as ImageIcon, Images, Info, Link2, Minus, MousePointer2, Network, Newspaper, NotebookPen, Pencil, Plus, RotateCcw, Search, Trash2, Upload, UserRound, X, ZoomIn, ZoomOut } from 'lucide-react' +import { BookOpen, Building2, CalendarClock, Camera, Check, ChevronRight, CircleHelp, ClipboardCheck, FileText, FolderOpen, Hand, Image as ImageIcon, Images, Info, Link2, Minus, MousePointer2, Network, Newspaper, NotebookPen, Pencil, Plus, RotateCcw, Search, Settings2, Trash2, Upload, UserRound, X, ZoomIn, ZoomOut } from 'lucide-react' import type { BriefConcept, CaseDocument, CaseReport, CaseReportSubmissionInput, CaseState, Connection, DocumentCaptureKind, DocumentSemanticAnalysis, EventExhibit, Evidence, EvidenceMatchRuleDefinition, Exhibit, ExhibitRelation, FolderExhibit, LevelBrief, LevelFlag, LevelGoal, NotePresentation, OrganizationKind, PartyExhibit, PartyKind, SourceFileType, TimelineRange, TimelineView, UploadedCaseDocument } from './types' import { AdminPanel } from './admin' import { audio } from './audio' @@ -549,7 +549,6 @@ export function App() { const pendingGoalCount = caseState.goals.filter(goal => goal.status === 'pending').length const briefAttentionCount = unresolvedConceptCount + pendingGoalCount const reportAttentionCount = caseState.report?.requiredForCompletion && caseState.report.status !== 'accepted' ? 1 : 0 - const activeGoal = caseState.goals.find(goal => goal.status === 'pending') || caseState.goals[0] const canAuthor = isAdmin && requestedEditMode && Boolean(caseState.editingAllowed) const temporalItems: TemporalItem[] = caseState.exhibits.flatMap(exhibit => { const widget=exhibitWidget(exhibit.type) @@ -576,9 +575,8 @@ export function App() {
GUOSINT BOARD / {requestedEditMode && caseState.editingAllowed ? 'LEVEL EDITOR' : 'CASE TERMINAL'}