Files

67 lines
6.1 KiB
JavaScript
Raw Permalink 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.
const { chromium } = await import(process.env.PLAYWRIGHT_MODULE || 'playwright');
import assert from 'node:assert/strict';
const browser = await chromium.launch({...(process.env.CHROME_PATH ? {executablePath:process.env.CHROME_PATH} : {}),headless:true});
const context = await browser.newContext({viewport:{width:1024,height:600},permissions:['geolocation'],geolocation:{latitude:48.85,longitude:2.35,accuracy:10}});
const page = await context.newPage(), errors=[];
page.on('pageerror',e=>errors.push(e.message));
// Never load public OSM tiles from automated QA.
await context.route('https://tile.openstreetmap.org/**',r=>r.fulfill({status:200,contentType:'image/png',body:Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+j1ioAAAAASUVORK5CYII=','base64')}));
await page.route('**/api/weather?*',r=>r.fulfill({json:{source:'Open-Meteo',temperature:18,code:2,wind:8,min:12,max:22,observedAt:'2026-09-12T09:00'}}));
await page.route('**/api/search?*',r=>r.fulfill({json:[{lat:48.86,lon:2.36,label:'Destination de test'}]}));
await page.route('**/api/route?*',r=>r.fulfill({json:{source:'OSRM',distance:1500,duration:300,geometry:{type:'LineString',coordinates:[[2.35,48.85],[2.355,48.855],[2.36,48.86]]},steps:[{distance:700,duration:140,name:'Rue A',maneuver:{type:'depart',location:[2.35,48.85]}},{distance:800,duration:160,name:'Rue B',maneuver:{type:'turn',modifier:'left',location:[2.355,48.855]}},{distance:0,duration:0,name:'',maneuver:{type:'arrive',location:[2.36,48.86]}}]}}));
await page.goto(process.env.CARIA_URL || 'http://127.0.0.1:8080');
await page.getByText('● Démonstration',{exact:true}).waitFor();
await page.locator('#settings-open').click();
await page.locator('#accent').selectOption('blue');
await page.getByRole('button',{name:'Enregistrer',exact:true}).click();
assert.equal(await page.evaluate(()=>document.body.style.getPropertyValue('--accent')),'#8ac7ff');
await page.reload();
assert.equal(await page.evaluate(()=>document.body.style.getPropertyValue('--accent')),'#8ac7ff');
await page.locator('#favorite-apps [data-view="map"]').click();
await page.locator('.leaflet-container').waitFor();
await page.getByText('Coordonnées manuelles',{exact:true}).click();
await page.locator('#latitude').fill('48.85'); await page.locator('#longitude').fill('2.35');
await page.getByRole('button',{name:'Utiliser ce départ',exact:true}).click();
await page.waitForFunction(()=>document.querySelector('#weather-temperature').textContent==='18');
await page.locator('#place-query').fill('Paris'); await page.getByRole('button',{name:'Rechercher un lieu'}).click();
await page.getByRole('button',{name:'Destination de test',exact:true}).click();
await page.getByText('Aperçu du trajet · activez le GPS pour le guidage',{exact:true}).waitFor();
assert.equal(await page.locator('#route-steps li').count(),3);
await page.locator('[data-waze-destination]').waitFor({state:'visible'});
assert.equal(new URL(await page.locator('[data-waze-destination]').getAttribute('href')).searchParams.get('ll'),'48.86,2.36');
await page.getByRole('button',{name:'⌖ Activer le GPS',exact:true}).click();
await page.waitForFunction(()=>document.querySelector('#position-status').textContent.includes('GPS actif'));
await page.waitForFunction(()=>document.querySelector('#next-instruction').textContent.includes('gauche'));
await page.getByText('Alertes de zones',{exact:true}).click();
const zones = {type:'FeatureCollection',features:[{type:'Feature',geometry:{type:'Point',coordinates:[2.35,48.85]},properties:{id:'test',name:'Zone QA',country:'FR',radiusM:500,source:'TEST AUTOMATISÉ',updatedAt:new Date(Date.now()-100000).toISOString(),expiresAt:new Date(Date.now()+86400000).toISOString()}}]};
await page.locator('#zones-file').setInputFiles({name:'zones.geojson',mimeType:'application/json',buffer:Buffer.from(JSON.stringify(zones))});
await page.waitForFunction(()=>document.querySelector('#zones-status').textContent.includes('1 zones'));
await page.locator('#alert-country').selectOption('FR'); await page.locator('#alerts-enabled').check();
await page.locator('#zone-alert').waitFor({state:'visible'});
await page.locator('#zone-alert-close').click();
await page.locator('#gps-stop').click();
await page.waitForFunction(()=>document.querySelector('#next-instruction').textContent.includes('pause'));
for (const size of [{width:1280,height:800},{width:1024,height:600},{width:800,height:480},{width:390,height:844}]) {
await page.setViewportSize(size);
for (const view of ['home','drive','music','stream','map']) {
await page.evaluate(view=>location.hash=view,view); await page.locator(`#${view}`).waitFor({state:'visible'});
assert.equal(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth),true,`Overflow ${view} ${size.width}`);
}
}
await page.setViewportSize({width:1024,height:600});
await page.locator('#favorite-apps [data-view="map"]').click();
await page.locator('#favorite-apps [data-view="home"]').click();
await page.locator('#settings-open').click(); await page.locator('#theme').selectOption('light'); await page.locator('#accent').selectOption('custom'); await page.locator('#custom-color').fill('#ff0000'); await page.getByRole('button',{name:'Enregistrer',exact:true}).click();
await page.locator('#favorite-apps [data-view="map"]').click();
await page.getByRole('button',{name:'Utiliser ce départ',exact:true}).click();
await page.waitForFunction(()=>document.querySelector('#weather-temperature').textContent==='18');
await page.route('**/api/weather?*',r=>r.fulfill({status:502,json:{error:'Météo hors ligne'}}));
await page.locator('#favorite-apps [data-view="home"]').click();
await page.locator('#weather-refresh').click();
await page.waitForFunction(()=>document.querySelector('#weather-temperature').textContent==='—' && document.querySelector('#weather-status').textContent==='Météo hors ligne');
await page.reload();
assert.equal(await page.locator('#alerts-enabled').isChecked(),false);
assert.deepEqual(errors,[]);
console.log('PASS themes + persistence; manual weather; search/route; GPS guidance; zone import/proximity alert; GPS stop; 5 views × 4 resolutions; no JS errors. Providers mocked; tiles replaced locally.');
await browser.close();