Files
annu-kute-ced/tests/e2e/test_search_pagination.py
T

126 lines
4.6 KiB
Python
Raw Normal View History

2026-07-27 09:15:47 +04:00
"""Tests E2E de la pagination de la recherche (recherche.php).
La pagination est déléguée à l'API PeerTube (paramètre start) et le total
affiché est le total réel renvoyé par l'API — et non le nombre de vidéos
réellement présentes sur la page.
"""
import json
import math
import re
import urllib.parse
import urllib.request
import pytest
VIDEOS_PAR_PAGE = 12 # VIDEOS_PER_PAGE (includes/config.default.php)
TERMES_CANDIDATS = ["a", "e", "video", "les"]
def _total_api(peertube_url, terme):
"""Total d'une recherche plein texte côté API PeerTube."""
params = urllib.parse.urlencode({
"search": terme,
"isLocal": "true",
"count": 1,
})
url = f"{peertube_url}/api/v1/search/videos?{params}"
with urllib.request.urlopen(url, timeout=30) as rep:
return int(json.load(rep).get("total", 0))
def _nombre_resultats(page):
"""Extrait le total affiché dans le bandeau des résultats."""
texte = page.locator(".search-results-count p").inner_text()
m = re.search(r"(\d+)", texte)
assert m, f"Total introuvable dans le bandeau : {texte!r}"
return int(m.group(1))
def _ids_cartes(page):
"""Identifiants des vidéos affichées dans la grille de résultats."""
cartes = page.locator(".video-grid .video-card")
return {
cartes.nth(i).get_attribute("data-video-id")
for i in range(cartes.count())
}
@pytest.fixture(scope="session")
def terme_paginable(peertube_url):
"""Un terme de recherche couvrant au moins deux pages de résultats."""
for terme in TERMES_CANDIDATS:
try:
if _total_api(peertube_url, terme) > VIDEOS_PAR_PAGE:
return terme
except Exception:
continue
pytest.skip("Aucun terme avec plus d'une page de résultats (réseau ?)")
def test_recherche_affiche_total_reel(page, base_url, peertube_url, terme_paginable):
"""Le total affiché est le total réel de l'API, pas le contenu de la page."""
total_api = _total_api(peertube_url, terme_paginable)
page.goto(
f"{base_url}/recherche.php?q={urllib.parse.quote(terme_paginable)}",
wait_until="domcontentloaded",
)
cartes = page.locator(".video-grid .video-card")
if cartes.count() == 0:
pytest.skip("Aucune vidéo reçue de l'API PeerTube (réseau indisponible ?)")
total_affiche = _nombre_resultats(page)
assert total_affiche == total_api
# La première page ne contient qu'une page de résultats, pas le total
assert total_affiche > cartes.count()
assert cartes.count() == min(VIDEOS_PAR_PAGE, total_affiche)
# La barre de pagination reflète le total réel
assert page.locator(".pagination").count() == 1
assert page.locator(".page-number.current").inner_text() == "1"
numeros = [
int(page.locator(".page-number").nth(i).inner_text())
for i in range(page.locator(".page-number").count())
]
assert max(numeros) == math.ceil(total_affiche / VIDEOS_PAR_PAGE)
def test_recherche_navigation_page_2(page, base_url, terme_paginable):
"""Le lien « Suivant » mène à la page 2, avec des vidéos différentes."""
page.goto(
f"{base_url}/recherche.php?q={urllib.parse.quote(terme_paginable)}",
wait_until="domcontentloaded",
)
ids_page1 = _ids_cartes(page)
if not ids_page1:
pytest.skip("Aucune vidéo reçue de l'API PeerTube (réseau indisponible ?)")
page.locator(".page-link.next").click()
page.wait_for_url(re.compile(r"[?&]page=2(&|$)"))
assert page.locator(".page-number.current").inner_text() == "2"
assert page.locator(".page-link.prev").count() == 1
ids_page2 = _ids_cartes(page)
assert ids_page2, "La page 2 ne contient aucune vidéo"
assert ids_page2.isdisjoint(ids_page1), "Les pages 1 et 2 partagent des vidéos"
def test_recherche_page_hors_limites(page, base_url, terme_paginable):
"""Une page au-delà de la dernière retombe sur une page valide."""
page.goto(
f"{base_url}/recherche.php?q={urllib.parse.quote(terme_paginable)}&page=99999999",
wait_until="domcontentloaded",
)
cartes = page.locator(".video-grid .video-card")
if cartes.count() == 0:
pytest.skip("Aucune vidéo reçue de l'API PeerTube (réseau indisponible ?)")
# La page se rabat sur une page valide (jamais de grille vide ni d'erreur)
total_affiche = _nombre_resultats(page)
assert total_affiche > 0
assert page.locator(".page-number.current").count() == 1
page_courante = int(page.locator(".page-number.current").inner_text())
assert 1 <= page_courante <= math.ceil(total_affiche / VIDEOS_PAR_PAGE)