138 lines
No EOL
5.6 KiB
TypeScript
138 lines
No EOL
5.6 KiB
TypeScript
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()
|
|
})
|
|
}) |