86 lines
2.6 KiB
TypeScript
Executable file
86 lines
2.6 KiB
TypeScript
Executable file
import { expect, test, type Page } from '@playwright/test'
|
|
import { gotoAppRoute } from './helpers/navigation'
|
|
|
|
function json(body: unknown) {
|
|
return {
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify(body),
|
|
}
|
|
}
|
|
|
|
async function mockShellApis(page: Page) {
|
|
await page.route('**/api/auth/session/refresh', async (route) => {
|
|
await route.fulfill({
|
|
status: 401,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ ok: false, error: 'no_active_session' }),
|
|
})
|
|
})
|
|
|
|
await page.route('**/api/auth/me', async (route) => {
|
|
await route.fulfill(json({
|
|
user: {
|
|
id: 'u1',
|
|
email: 'tutorial.operator@example.test',
|
|
name: 'Tutorial Operator',
|
|
plan: 'free',
|
|
auth_method: 'email',
|
|
},
|
|
mode: 'email_fallback',
|
|
}))
|
|
})
|
|
|
|
await page.route('**/api/corpus/projects**', async (route) => {
|
|
await route.fulfill(json({
|
|
ok: true,
|
|
projects: [
|
|
{
|
|
id: 'proj-tutorial',
|
|
name: 'Tutorial Project',
|
|
description: 'Tutorial coverage shell project',
|
|
status: 'active',
|
|
member_count: 1,
|
|
current_user_role: 'owner',
|
|
metadata: {
|
|
owner_email: 'tutorial.operator@example.test',
|
|
updated_at: new Date('2026-04-22T10:00:00.000Z').toISOString(),
|
|
},
|
|
},
|
|
],
|
|
}))
|
|
})
|
|
}
|
|
|
|
test.describe('tutorial mode shell overlays', () => {
|
|
test('can be enabled from the account menu and shows contextual help on shell controls', async ({ page }) => {
|
|
await mockShellApis(page)
|
|
await gotoAppRoute(page, '/app')
|
|
|
|
const accountButton = page.getByRole('button', { name: 'Open account menu' })
|
|
await expect(accountButton).toBeVisible()
|
|
|
|
await accountButton.click()
|
|
await page.getByRole('menuitem', { name: 'Enable Tutorial Mode' }).click()
|
|
|
|
await expect.poll(async () => (
|
|
page.evaluate(() => window.localStorage.getItem('scriptorium.tutorial-mode.v1'))
|
|
)).toBe('true')
|
|
|
|
await page.getByRole('button', { name: 'File' }).hover()
|
|
await expect(
|
|
page.locator('[role="tooltip"]').filter({
|
|
hasText: 'Project entry, document lifecycle actions, export, cache clearing, and settings.',
|
|
})
|
|
).toBeVisible()
|
|
|
|
await accountButton.click()
|
|
const documentationItem = page.getByRole('menuitem', { name: 'Documentation' })
|
|
await documentationItem.hover()
|
|
await expect(
|
|
page.locator('[role="tooltip"]').filter({
|
|
hasText: 'Open the public documentation landing page and feature-oriented orientation material.',
|
|
})
|
|
).toBeVisible()
|
|
})
|
|
})
|