Files
codexpi/frontend/e2e/codexpi.spec.ts
CodexPi 995b17a6e2
Some checks are pending
Qualité / tests (push) Waiting to run
feat: publish CodexPi contest snapshot
2026-11-14 20:23:59 +01:00

76 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import AxeBuilder from '@axe-core/playwright'
import { expect, Page, test } from '@playwright/test'
const projects=[
{id:'project-tv',name:'TV Hub',path:'/home/tv-hub',owner_id:'owner',owner_username:'alice',kind:'local',archived:0,full_access:0,git_available:true,execution_group:'',groups:[]},
{id:'project-player',name:'Lecteur TV',path:'/home/tv-player',owner_id:'owner',owner_username:'alice',kind:'local',archived:0,full_access:0,git_available:true,execution_group:'',groups:[]},
{id:'project-remote',name:'Télécommande',path:'/home/tv-remote',owner_id:'owner',owner_username:'alice',kind:'local',archived:0,full_access:0,git_available:true,execution_group:'',groups:[]},
]
async function mockApi(page:Page){
let groups:any[]=[]
await page.route('**/api/**',async route=>{
const request=route.request(),url=new URL(request.url()),path=url.pathname,method=request.method()
let body:unknown={}
if(path==='/api/bootstrap')body={setup_required:false,csrf_token:'csrf'}
else if(path==='/api/auth/me')body={username:'alice',is_admin:true,csrf_token:'csrf'}
else if(path==='/api/projects'&&url.searchParams.get('archived')==='true')body=[]
else if(path==='/api/projects')body=projects
else if(path==='/api/projects/activity')body={running_project_ids:['project-player']}
else if(path==='/api/application/preferences')body={auto_compact_context:false,interface_type:'dashboard',theme:'dark'}
else if(path==='/api/duck/preferences')body={enabled:true,reminder_minutes:30}
else if(path==='/api/activity')body={cards:[],counts:{running:0,waiting:0,review:0},observed_at:'2026-11-12T20:00:00Z'}
else if(path==='/api/dashboard')body={connected:true,hostname:'NasPi',platform:'Linux',cpu_percent:17,cpu_count:4,ram_percent:42,ram_used:4_000_000_000,ram_total:8_000_000_000,temperature_c:48,disk_percent:55,disk_used:55_000_000_000,disk_total:100_000_000_000,uptime_seconds:86400,active_sessions:1,total_sessions:3,docker:{available:true,version:'27'},codex:{available:true,version:'1'},git:{available:true,version:'2.47'},codex_quota:{available:false}}
else if(path==='/api/project-groups'&&method==='GET')body=groups
else if(path==='/api/project-groups'&&method==='POST'){
const input=request.postDataJSON()
groups=[{id:'group-tv',key:'tv',owner_id:'owner',owner_username:'alice',name:input.name,description:input.description,member_count:input.project_ids.length,members:projects.filter(item=>input.project_ids.includes(item.id)),updates:[],created_at:'2026-11-12T20:00:00Z',updated_at:'2026-11-12T20:00:00Z'}]
body=groups[0]
}else if(path==='/api/search')body=[]
return route.fulfill({status:200,contentType:'application/json',body:JSON.stringify(body)})
})
}
test.beforeEach(async({page})=>{
await mockApi(page)
await page.goto('/?view=company')
await expect(page.getByRole('heading',{name:'Qui fait quoi ?'})).toBeVisible()
})
test('crée un groupe à partir de plusieurs projets existants',async({page})=>{
await page.getByRole('button',{name:'+ Groupe'}).first().click()
await page.getByLabel('Nom du groupe').fill('TV')
await page.getByLabel('Objectif commun').fill('Applications qui communiquent avec la télévision.')
await page.locator('label').filter({hasText:'TV Hub'}).click()
await page.locator('label').filter({hasText:'Lecteur TV'}).click()
const requestPromise=page.waitForRequest(request=>request.url().endsWith('/api/project-groups')&&request.method()==='POST')
await page.getByRole('button',{name:'Créer le groupe'}).click()
const request=await requestPromise
expect(request.postDataJSON().project_ids.sort()).toEqual(['project-player','project-tv'])
await expect(page.locator('.company-groups article>header b').filter({hasText:/^TV$/})).toBeVisible()
})
test('conserve la vue dans l’URL, au retour et au rechargement',async({page})=>{
await page.getByRole('button',{name:'Projets',exact:true}).click()
await expect(page).toHaveURL(/view=dashboard/)
await expect(page.getByRole('heading',{name:'Projets et chefs d’équipe'})).toBeVisible()
await page.goBack()
await expect(page).toHaveURL(/view=company/)
await page.reload()
await expect(page.getByRole('heading',{name:'Qui fait quoi ?'})).toBeVisible()
})
test('le lanceur est utilisable au clavier et la vue ne présente pas de violation axe sérieuse',async({page})=>{
await page.keyboard.press('Control+K')
const dialog=page.getByRole('dialog',{name:'Rechercher et ouvrir'})
await expect(dialog).toBeVisible()
await page.keyboard.press('Escape')
await expect(dialog).toBeHidden()
const results=await new AxeBuilder({page}).withTags(['wcag2a','wcag2aa','wcag21a','wcag21aa']).analyze()
expect(results.violations.filter(item=>item.impact==='critical'||item.impact==='serious')).toEqual([])
})
test('capture la vue Organisation de référence',async({page})=>{
await expect(page).toHaveScreenshot('organisation.png',{fullPage:true})
})