111 lines
4.7 KiB
Python
111 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Exercise Web Sessions through embedded production assets in real Firefox."""
|
|
|
|
import os
|
|
import signal
|
|
import socket
|
|
import sqlite3
|
|
import subprocess
|
|
import tempfile
|
|
import time
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
BUILD = ROOT / os.environ.get("TRAINLOG_WEB_E2E_BUILD", "build") / "tui"
|
|
GECKO = Path(
|
|
os.environ.get(
|
|
"TRAINLOG_GECKODRIVER", "/home/fy59/.cache/trainlog/web-e2e-tools/geckodriver"
|
|
)
|
|
)
|
|
EVIDENCE = ROOT / "docs" / "reviews" / "evidence"
|
|
|
|
|
|
class BrowserSessionsTest(unittest.TestCase):
|
|
def test_create_reload_detail_and_mobile_editor(self):
|
|
if not GECKO.is_file():
|
|
self.skipTest("pinned geckodriver unavailable")
|
|
|
|
from selenium import webdriver
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.firefox.service import Service
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
|
|
with tempfile.TemporaryDirectory(prefix="trainlog-web-sessions-") as directory:
|
|
root = Path(directory)
|
|
xdg = root / "data"
|
|
xdg.mkdir()
|
|
with socket.socket() as reserved:
|
|
reserved.bind(("127.0.0.1", 0))
|
|
port = reserved.getsockname()[1]
|
|
environment = os.environ.copy()
|
|
environment.update(
|
|
{
|
|
"XDG_DATA_HOME": str(xdg),
|
|
"XDG_CONFIG_HOME": str(root / "config"),
|
|
"XDG_CACHE_HOME": str(root / "cache"),
|
|
}
|
|
)
|
|
server = subprocess.Popen(
|
|
[str(BUILD / "trainlog"), "--web", "--port", str(port)],
|
|
env=environment,
|
|
stdout=subprocess.DEVNULL,
|
|
stderr=subprocess.DEVNULL,
|
|
start_new_session=True,
|
|
)
|
|
driver = None
|
|
try:
|
|
for _ in range(200):
|
|
with socket.socket() as probe:
|
|
if probe.connect_ex(("127.0.0.1", port)) == 0:
|
|
break
|
|
time.sleep(0.025)
|
|
|
|
options = webdriver.FirefoxOptions()
|
|
options.add_argument("-headless")
|
|
driver = webdriver.Firefox(options=options, service=Service(str(GECKO)))
|
|
wait = WebDriverWait(driver, 15)
|
|
driver.set_window_size(1440, 1000)
|
|
driver.get(f"http://127.0.0.1:{port}/seances")
|
|
wait.until(lambda current: "Aucun résultat" in current.page_source)
|
|
EVIDENCE.mkdir(parents=True, exist_ok=True)
|
|
driver.save_screenshot(str(EVIDENCE / "web-sessions-list-desktop.png"))
|
|
|
|
driver.find_element(By.XPATH, "//button[normalize-space()='Nouvelle séance']").click()
|
|
wait.until(lambda current: "Nouvelle séance" in current.page_source)
|
|
title = driver.find_element(By.XPATH, "//label[normalize-space()='Titre']/input")
|
|
title.send_keys("Séance navigateur éphémère")
|
|
driver.set_window_size(390, 844)
|
|
driver.save_screenshot(str(EVIDENCE / "web-sessions-editor-mobile.png"))
|
|
save = driver.find_element(By.XPATH, "//button[normalize-space()='Enregistrer']")
|
|
driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", save)
|
|
save.click()
|
|
wait.until(lambda current: "PRÉPARATION MANUELLE" in current.page_source)
|
|
driver.refresh()
|
|
wait.until(lambda current: "Séance navigateur éphémère" in current.page_source)
|
|
driver.set_window_size(1440, 1000)
|
|
driver.save_screenshot(str(EVIDENCE / "web-sessions-detail-desktop.png"))
|
|
|
|
database_path = xdg / "trainlog" / "trainlog.db"
|
|
with sqlite3.connect(database_path) as database:
|
|
row = database.execute(
|
|
"SELECT r.title, p.editing_state "
|
|
"FROM session_preparations p "
|
|
"JOIN session_preparation_revisions r "
|
|
"ON r.revision_id = p.current_revision_id"
|
|
).fetchone()
|
|
entry_count = database.execute(
|
|
"SELECT COUNT(*) FROM session_preparation_entries"
|
|
).fetchone()[0]
|
|
self.assertEqual(row, ("Séance navigateur éphémère", "draft"))
|
|
self.assertEqual(entry_count, 0)
|
|
finally:
|
|
if driver is not None:
|
|
driver.quit()
|
|
os.killpg(server.pid, signal.SIGTERM)
|
|
server.wait(timeout=10)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|