ConusAI vendor 81941888f
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import AxeBuilder from '@axe-core/playwright'
|
||||
import { expect, test, type Page } from '@playwright/test'
|
||||
|
||||
// The end-to-end run of the showcase (plan S4.8): a note, an attachment, the audit
|
||||
// entry and usage on the platform, the enable cards, accessibility and the Core Web
|
||||
// Vitals budgets. The platform is the fake in e2e/fake-platform.mjs.
|
||||
|
||||
const platform = 'http://127.0.0.1:4010'
|
||||
|
||||
type PlatformState = {
|
||||
audit: Array<{ action: string; resource_id: string | null }>
|
||||
usage: Array<{ idempotency_key: string; meter: string }>
|
||||
}
|
||||
|
||||
async function platformState(): Promise<PlatformState> {
|
||||
const response = await fetch(`${platform}/__e2e/state`)
|
||||
return (await response.json()) as PlatformState
|
||||
}
|
||||
|
||||
function uniqueTitle(label: string): string {
|
||||
return `${label} ${Date.now()}-${Math.random().toString(36).slice(2, 7)}`
|
||||
}
|
||||
|
||||
async function createNote(page: Page, title: string): Promise<void> {
|
||||
await page.goto('/')
|
||||
await page.getByLabel('Title').fill(title)
|
||||
await page.getByLabel('Body').fill('written by the end-to-end run')
|
||||
await page.getByRole('button', { name: 'Create note' }).click()
|
||||
await expect(page.getByRole('heading', { name: title })).toBeVisible()
|
||||
}
|
||||
|
||||
test('a note is audited on the platform and listed on the audit page', async ({ page }) => {
|
||||
const title = uniqueTitle('audited')
|
||||
await createNote(page, title)
|
||||
|
||||
await expect
|
||||
.poll(async () => (await platformState()).audit.some((event) => event.action === 'note.created'), { timeout: 15_000 })
|
||||
.toBe(true)
|
||||
|
||||
await page.goto('/audit')
|
||||
await expect(page.getByText('note.created').first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('an attachment moves the usage meter and is metered on the platform', async ({ page }) => {
|
||||
const title = uniqueTitle('attached')
|
||||
await createNote(page, title)
|
||||
|
||||
const meter = page.getByText(/uploads, \d+ bytes stored/)
|
||||
await expect(meter).toHaveText(/^0 uploads, 0 bytes stored$/)
|
||||
const usageBefore = (await platformState()).usage.length
|
||||
|
||||
const note = page.getByRole('listitem').filter({ hasText: title })
|
||||
await note.getByLabel('Attachment').setInputFiles({
|
||||
name: 'notes.txt',
|
||||
mimeType: 'text/plain',
|
||||
buffer: Buffer.from('sixteen bytes!!!'),
|
||||
})
|
||||
await note.getByRole('button', { name: 'Attach', exact: true }).click()
|
||||
|
||||
await expect(meter).toHaveText(/^1 uploads, 16 bytes stored$/)
|
||||
await expect
|
||||
.poll(async () => (await platformState()).usage.length, { timeout: 15_000 })
|
||||
.toBeGreaterThan(usageBefore)
|
||||
})
|
||||
|
||||
test('each optional module without its variables shows its enable card', async ({ page }) => {
|
||||
await page.goto('/')
|
||||
|
||||
await expect(page.getByText(/to enable this\.$/)).toHaveCount(5)
|
||||
await expect(page.getByText('Link Redis to enable this.')).toBeVisible()
|
||||
await expect(page.getByText(/uploads left this minute/)).toHaveCount(0)
|
||||
})
|
||||
|
||||
for (const path of ['/', '/audit', '/platform']) {
|
||||
test(`axe finds no serious or critical issues on ${path}`, async ({ page }) => {
|
||||
await page.goto(path)
|
||||
const results = await new AxeBuilder({ page }).analyze()
|
||||
const blocking = results.violations
|
||||
.filter((violation) => violation.impact === 'serious' || violation.impact === 'critical')
|
||||
.map((violation) => `${violation.id} (${violation.nodes.length} node(s))`)
|
||||
expect(blocking).toEqual([])
|
||||
})
|
||||
}
|
||||
|
||||
test('the dashboard meets the Core Web Vitals budgets: LCP at most 2.5 s, INP at most 200 ms', async ({ page }) => {
|
||||
await page.addInitScript(() => {
|
||||
const vitals = window as unknown as { lcp: number; inp: number }
|
||||
vitals.lcp = 0
|
||||
vitals.inp = 0
|
||||
new PerformanceObserver((list) => {
|
||||
for (const entry of list.getEntries()) vitals.lcp = entry.startTime
|
||||
}).observe({ type: 'largest-contentful-paint', buffered: true })
|
||||
// Event Timing entries carry the interaction id and the duration INP is built from.
|
||||
new PerformanceObserver((list) => {
|
||||
for (const entry of list.getEntries() as Array<PerformanceEntry & { interactionId?: number }>) {
|
||||
if ((entry.interactionId ?? 0) > 0) vitals.inp = Math.max(vitals.inp, entry.duration)
|
||||
}
|
||||
}).observe({ type: 'event', buffered: true, durationThreshold: 16 } as PerformanceObserverInit)
|
||||
})
|
||||
|
||||
await page.goto('/', { waitUntil: 'load' })
|
||||
await page.getByLabel('Title').fill(uniqueTitle('vitals'))
|
||||
await page.getByLabel('Body').fill('an interaction for the input delay budget')
|
||||
await page.getByRole('button', { name: 'Create note' }).click()
|
||||
await expect(page.getByText('an interaction for the input delay budget')).toBeVisible()
|
||||
|
||||
const vitals = await page.evaluate(() => {
|
||||
const measured = window as unknown as { lcp: number; inp: number }
|
||||
return { lcp: measured.lcp, inp: measured.inp }
|
||||
})
|
||||
expect(vitals.lcp).toBeGreaterThan(0)
|
||||
expect(vitals.lcp).toBeLessThanOrEqual(2500)
|
||||
expect(vitals.inp).toBeLessThanOrEqual(200)
|
||||
})
|
||||
Reference in New Issue
Block a user