import datetime import re import time from pathlib import Path from playwright.sync_api import Page, expect from testutils import extract_and_upload from fietsboek import models from fietsboek.log import HANDLER def wait_for_log( message: str, timeout: datetime.timedelta = datetime.timedelta(seconds=10), ): """Waits for the given log message to appear in the logs.""" pattern = re.compile(message) start = datetime.datetime.now(datetime.UTC) while True: if any(pattern.search(m.message) is not None for m in HANDLER.buffer): return time.sleep(0.5) if datetime.datetime.now(datetime.UTC) - start > timeout: raise RuntimeError(f"Timeout waiting for log {message!r}") def upload_and_wait(playwright_helper, filename: str, tmp_path: Path) -> int: """Upload the track (via the web UI) and wait for the background tasks to finish. Returns the track's ID. """ page: Page = playwright_helper.page playwright_helper.login() page.goto("/") page.get_by_text("Upload").click() extract_and_upload(page, filename, tmp_path) page.locator(".btn", has_text="Upload").click() new_track_id = int(page.url.rsplit("/", 1)[1]) expect(page.locator(".favourite-star")).to_be_visible() wait_for_log(f"Climb extraction done for track {new_track_id}$") return new_track_id def test_no_climbs(playwright_helper, tmp_path, dbaccess): track_id = upload_and_wait(playwright_helper, "no_climbs.gpx.gz", tmp_path) track = dbaccess.get(models.Track, track_id) assert len(track.climbs) == 0 def test_two_climbs(page: Page, playwright_helper, tmp_path, dbaccess): track_id = upload_and_wait(playwright_helper, "two_climbs.gpx.gz", tmp_path) track = dbaccess.get(models.Track, track_id) assert len(track.climbs) == 2 page.goto(f"/track/{track_id}") expect(page.locator(".climb-preview").nth(0)).to_be_visible() expect(page.locator(".climb-details").nth(0)).to_contain_text("2.84 km") expect(page.locator(".climb-details").nth(0)).to_contain_text("5.36 %") expect(page.locator(".climb-preview").nth(1)).to_be_visible() expect(page.locator(".climb-details").nth(1)).to_contain_text("1.29 km") expect(page.locator(".climb-details").nth(1)).to_contain_text("5.58 %")