Import initial : code en production sur Hetzner
This commit is contained in:
commit
cf6ee64e31
43 changed files with 14404 additions and 0 deletions
138
tests/app.spec.ts
Normal file
138
tests/app.spec.ts
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
import { expect, test } from '@nuxt/test-utils/playwright'
|
||||
import type { Page } from '@playwright/test'
|
||||
|
||||
test.describe('API de geocodage', () => {
|
||||
test('resout une ville en coordonnees', async ({ request }) => {
|
||||
const res = await request.get('/api/geocode?q=lille')
|
||||
expect(res.ok()).toBeTruthy()
|
||||
|
||||
const places = await res.json()
|
||||
expect(places.length).toBeGreaterThan(0)
|
||||
expect(places[0].lat).toBeCloseTo(50.63, 1)
|
||||
expect(places[0].lon).toBeCloseTo(3.05, 1)
|
||||
})
|
||||
|
||||
test('trouve une ville hors de France', async ({ request }) => {
|
||||
const res = await request.get('/api/geocode?q=Bruxelles')
|
||||
const places = await res.json()
|
||||
// La BAN ignore la Belgique : sans Photon, on retomberait sur un hameau du Loiret.
|
||||
const belge = places.find((p: { label: string }) => p.label.includes('Belgique'))
|
||||
expect(belge).toBeDefined()
|
||||
expect(belge.lat).toBeCloseTo(50.85, 1)
|
||||
})
|
||||
|
||||
test('renvoie un tableau vide sur une saisie trop courte', async ({ request }) => {
|
||||
const res = await request.get('/api/geocode?q=li')
|
||||
expect(await res.json()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Comparateur', () => {
|
||||
const bouton = (page: Page) => page.getByRole('button', { name: 'Comparer', exact: true })
|
||||
|
||||
/** Remplit un champ puis choisit une proposition dans SA propre liste. */
|
||||
async function choisir(page: Page, id: string, champ: string, saisie: string, index = 0) {
|
||||
await page.getByLabel(champ).fill(saisie)
|
||||
await page.locator(`#${id}-list [role="option"]`).nth(index).click()
|
||||
}
|
||||
|
||||
async function comparer(page: Page) {
|
||||
await choisir(page, 'from', 'Départ', 'Lille', 0)
|
||||
await choisir(page, 'to', 'Arrivée', 'Bruxelles', 1)
|
||||
await bouton(page).click()
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// On simule les appels sortants : un test e2e ne doit dependre
|
||||
// ni du quota OpenRouteService ni de la disponibilite de Transitous.
|
||||
await page.route('**/api/geocode**', route => route.fulfill({
|
||||
json: [
|
||||
{ label: 'Lille, France', lat: 50.6292, lon: 3.0573 },
|
||||
{ label: 'Bruxelles, Belgique', lat: 50.8503, lon: 4.3517 },
|
||||
],
|
||||
}))
|
||||
|
||||
await page.route('**/api/compare', route => route.fulfill({
|
||||
json: [
|
||||
{ mode: 'bike', distanceKm: 116, durationMin: 402, co2Grams: 0 },
|
||||
{ mode: 'train', distanceKm: 97, durationMin: 136, co2Grams: 2339, transfers: 2 },
|
||||
{ mode: 'bus', distanceKm: 97, durationMin: 137, co2Grams: 3321, transfers: 2 },
|
||||
{ mode: 'electric_car', distanceKm: 118, durationMin: 86, co2Grams: 12176 },
|
||||
],
|
||||
}))
|
||||
|
||||
await page.goto('/')
|
||||
})
|
||||
|
||||
test('interdit le calcul tant qu aucun lieu n est choisi', async ({ page }) => {
|
||||
await expect(bouton(page)).toBeDisabled()
|
||||
})
|
||||
|
||||
test('ferme la liste apres selection sans la rouvrir', async ({ page }) => {
|
||||
await choisir(page, 'from', 'Départ', 'Lille', 0)
|
||||
// Le watch se redeclenchait sur la valeur ecrite par select() et rouvrait
|
||||
// la liste : le champ suivant devenait inatteignable a la souris.
|
||||
await page.waitForTimeout(600)
|
||||
await expect(page.locator('#from-list')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('reflete le modele quand il change de l exterieur', async ({ page }) => {
|
||||
await choisir(page, 'from', 'Départ', 'Lille', 0)
|
||||
await choisir(page, 'to', 'Arrivée', 'Bruxelles', 1)
|
||||
|
||||
// Sans watch sur le modele, l'inversion laissait les champs inchanges
|
||||
// et l'affichage mentait sur ce qui allait etre calcule.
|
||||
await page.getByRole('button', { name: 'Inverser' }).click()
|
||||
await expect(page.getByLabel('Départ')).toHaveValue('Bruxelles, Belgique')
|
||||
await expect(page.getByLabel('Arrivée')).toHaveValue('Lille, France')
|
||||
})
|
||||
|
||||
test('interdit le calcul si la saisie ne correspond plus au lieu choisi', async ({ page }) => {
|
||||
await choisir(page, 'from', 'Départ', 'Lille', 0)
|
||||
await choisir(page, 'to', 'Arrivée', 'Bruxelles', 1)
|
||||
await expect(bouton(page)).toBeEnabled()
|
||||
|
||||
await page.getByLabel('Arrivée').fill('Bruxel')
|
||||
await expect(bouton(page)).toBeDisabled()
|
||||
})
|
||||
|
||||
test('lance un calcul depuis un trajet d exemple', async ({ page }) => {
|
||||
await page.getByRole('button', { name: 'Lille → Paris' }).click()
|
||||
await expect(page.getByRole('heading', { level: 3 })).toHaveCount(4)
|
||||
})
|
||||
|
||||
test('affiche les quatre modes du plus sobre au plus emetteur', async ({ page }) => {
|
||||
await comparer(page)
|
||||
|
||||
// Le titre porte aussi le chevron et la duree : on cherche le libelle
|
||||
// dans son contenu plutot qu'une egalite stricte.
|
||||
const titles = page.getByRole('heading', { level: 3 })
|
||||
await expect(titles).toHaveCount(4)
|
||||
await expect(titles.nth(0)).toContainText('Vélo')
|
||||
await expect(titles.nth(3)).toContainText('Voiture électrique')
|
||||
})
|
||||
|
||||
test('rappelle les lieux reellement compares', async ({ page }) => {
|
||||
await comparer(page)
|
||||
const rappel = page.getByRole('heading', { level: 2 })
|
||||
await expect(rappel).toContainText('Lille, France')
|
||||
await expect(rappel).toContainText('Bruxelles, Belgique')
|
||||
})
|
||||
|
||||
test('affiche les correspondances des transports en commun', async ({ page }) => {
|
||||
await comparer(page)
|
||||
await expect(page.getByText('2 corresp.').first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('convertit les emissions en kilogrammes au-dela de mille grammes', async ({ page }) => {
|
||||
await comparer(page)
|
||||
await expect(page.getByText('12.2 kg CO₂e')).toBeVisible()
|
||||
await expect(page.getByText('0 g CO₂e')).toBeVisible()
|
||||
})
|
||||
|
||||
test('previent l utilisateur quand le calcul echoue', async ({ page }) => {
|
||||
await page.route('**/api/compare', route => route.fulfill({ status: 500, json: {} }))
|
||||
await comparer(page)
|
||||
await expect(page.getByRole('alert')).toBeVisible()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue