91 lines
3.7 KiB
Python
91 lines
3.7 KiB
Python
"""Tests E2E de la page vidéo (video.php)."""
|
|||
|
|
import json
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
|
||
|
|
def _premier_video_id(page, base_url):
|
||
|
|
"""Récupère l'identifiant de la première carte vidéo de l'accueil."""
|
||
|
|
page.goto(base_url + "/index.php", wait_until="domcontentloaded")
|
||
|
|
ids = page.locator(".video-card").evaluate_all(
|
||
|
|
"(els) => els.map(e => e.dataset.videoId).filter(Boolean)"
|
||
|
|
)
|
||
|
|
# Déduplique en conservant l'ordre (la même vidéo peut être en short et en grille)
|
||
|
|
uniques = list(dict.fromkeys(ids))
|
||
|
|
if not uniques:
|
||
|
|
pytest.skip("Aucune vidéo reçue de l'API PeerTube (réseau indisponible ?)")
|
||
|
|
return uniques[0]
|
||
|
|
|
||
|
|
|
||
|
|
def _jsonld_blocks(page):
|
||
|
|
"""Parse tous les blocs <script type='application/ld+json'> de la page."""
|
||
|
|
blocs = []
|
||
|
|
for brut in page.locator('script[type="application/ld+json"]').all_text_contents():
|
||
|
|
blocs.append(json.loads(brut))
|
||
|
|
return blocs
|
||
|
|
|
||
|
|
|
||
|
|
def test_video_page_jsonld_videoobject(page, base_url):
|
||
|
|
"""La page vidéo expose des données structurées VideoObject valides."""
|
||
|
|
video_id = _premier_video_id(page, base_url)
|
||
|
|
page.goto(base_url + f"/video.php?id={video_id}", wait_until="domcontentloaded")
|
||
|
|
|
||
|
|
blocs = _jsonld_blocks(page)
|
||
|
|
types = [b.get("@type") for b in blocs]
|
||
|
|
assert "VideoObject" in types, f"Pas de VideoObject dans les JSON-LD : {types}"
|
||
|
|
|
||
|
|
video_ld = blocs[types.index("VideoObject")]
|
||
|
|
assert video_ld.get("@context") == "https://schema.org"
|
||
|
|
assert video_ld.get("name"), "Le nom du VideoObject est vide"
|
||
|
|
assert video_ld.get("embedUrl", "").endswith(f"/videos/embed/{video_id}")
|
||
|
|
assert video_ld.get("thumbnailUrl"), "thumbnailUrl manquant"
|
||
|
|
assert video_ld.get("uploadDate"), "uploadDate manquant"
|
||
|
|
assert video_ld.get("duration"), "duration manquante"
|
||
|
|
|
||
|
|
# Le fil d'Ariane est également publié
|
||
|
|
assert "BreadcrumbList" in types
|
||
|
|
|
||
|
|
|
||
|
|
def test_video_page_peertube_embed(page, base_url, peertube_url):
|
||
|
|
"""Le lecteur embarque l'iframe PeerTube de la vidéo demandée."""
|
||
|
|
video_id = _premier_video_id(page, base_url)
|
||
|
|
page.goto(base_url + f"/video.php?id={video_id}", wait_until="domcontentloaded")
|
||
|
|
|
||
|
|
iframe = page.locator(".video-player iframe")
|
||
|
|
assert iframe.count() == 1, "L'iframe du lecteur est absente"
|
||
|
|
src = iframe.get_attribute("src")
|
||
|
|
assert src.startswith(f"{peertube_url}/videos/embed/{video_id}"), (
|
||
|
|
f"Source d'iframe inattendue : {src}"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def test_video_page_suggestions(page, base_url):
|
||
|
|
"""La colonne de suggestions propose d'autres vidéos du site."""
|
||
|
|
video_id = _premier_video_id(page, base_url)
|
||
|
|
page.goto(base_url + f"/video.php?id={video_id}", wait_until="domcontentloaded")
|
||
|
|
|
||
|
|
suggestions = page.locator(".video-suggestions")
|
||
|
|
assert suggestions.count() == 1, "La section de suggestions est absente"
|
||
|
|
assert suggestions.locator("h2").inner_text() == "Vidéos suggérées"
|
||
|
|
|
||
|
|
cartes = suggestions.locator(".suggested-video")
|
||
|
|
if cartes.count() == 0:
|
||
|
|
pytest.skip("Aucune vidéo suggérée (API PeerTube indisponible ?)")
|
||
|
|
|
||
|
|
hrefs = cartes.locator("a.suggested-video-link").evaluate_all(
|
||
|
|
"(els) => els.map(e => e.getAttribute('href'))"
|
||
|
|
)
|
||
|
|
for href in hrefs:
|
||
|
|
assert href and href.startswith("video.php?id="), (
|
||
|
|
f"Lien de suggestion inattendu : {href}"
|
||
|
|
)
|
||
|
|
# La vidéo courante ne doit pas se suggérer elle-même
|
||
|
|
assert f"video.php?id={video_id}" not in hrefs
|
||
|
|
|
||
|
|
|
||
|
|
def test_video_page_invalid_id_redirects(page, base_url):
|
||
|
|
"""Un identifiant vidéo invalide redirige vers l'accueil (sans appel réseau)."""
|
||
|
|
page.goto(base_url + "/video.php?id=pas-un-uuid-valide",
|
||
|
|
wait_until="domcontentloaded")
|
||
|
|
assert page.url.endswith("/index.php"), f"URL après redirection : {page.url}"
|