Allow same-day return journeys in the date selector

Select the outbound date again to complete a day trip, with a clear hint and summary and no misleading range highlight. Cover desktop and mobile selection, submission, and reselection with Playwright.

Closes #9
This commit is contained in:
Edward Betts 2026-09-18 20:22:32 +01:00
parent c9aad7ad4c
commit 8be2e29d76
2 changed files with 83 additions and 19 deletions

View file

@ -1,4 +1,5 @@
import threading
from datetime import date, timedelta
from typing import Any, Generator
import pytest
@ -647,29 +648,91 @@ def test_return_advance_first_standard_premier_totals(local_server: str) -> None
browser.close()
def test_return_calendar_selects_outbound_before_return(local_server: str) -> None:
@pytest.mark.parametrize("return_days", [0, 7], ids=["day-trip", "longer-trip"])
@pytest.mark.parametrize("mobile", [False, True], ids=["desktop", "mobile"])
def test_return_calendar_selects_outbound_before_return(
local_server: str, return_days: int, mobile: bool
) -> None:
with sync_playwright() as p:
browser = _launch_browser(p)
page = browser.new_page()
page = browser.new_page(
viewport={"width": 390 if mobile else 1280, "height": 844},
has_touch=mobile,
)
page.goto(f"{local_server}/", wait_until="domcontentloaded")
today = date.fromisoformat(page.locator("#travel_date").input_value())
outbound = (today + timedelta(days=1)).isoformat()
returning = (today + timedelta(days=1 + return_days)).isoformat()
page.locator("#journey-return").check(force=True)
def select_day(value: str) -> None:
button = page.locator(f'.cal-cell[data-date="{value}"] button')
if mobile:
button.tap()
else:
button.click()
page.locator("#journey-return").check()
assert page.locator("#cal-hint").inner_text() == "Select outbound date"
assert page.locator("#travel_date").input_value() == ""
assert page.locator("#return_date").input_value() == ""
page.get_by_role("button", name="10 June 2026").click()
assert page.locator("#travel_date").input_value() == "2026-06-10"
select_day(outbound)
assert page.locator("#travel_date").input_value() == outbound
assert page.locator("#return_date").input_value() == ""
assert "Now select return date" in page.locator("#cal-hint").inner_text()
assert "same date for a day trip" in page.locator("#cal-hint").inner_text()
page.get_by_role("button", name="17 June 2026").click()
assert page.locator("#travel_date").input_value() == "2026-06-10"
assert page.locator("#return_date").input_value() == "2026-06-17"
assert "Return: Wed 17 Jun" in page.locator("#cal-hint").inner_text()
select_day(returning)
assert page.locator("#travel_date").input_value() == outbound
assert page.locator("#return_date").input_value() == returning
assert page.locator("#return_date").get_attribute("name") == "return_date"
hint = page.locator("#cal-hint").inner_text()
assert ("Day trip:" if return_days == 0 else "Return:") in hint
if return_days == 0:
assert page.locator(".cal-selected").count() == 1
# A day trip must not show a range extending into the next day,
# including after the pointer leaves the calendar.
page.locator("h2").hover()
assert page.locator(".cal-in-range").count() == 0
assert page.locator(f'.cal-cell[data-date="{outbound}"]').evaluate(
"el => el.style.background"
) == ""
assert page.evaluate(
"document.documentElement.scrollWidth <= window.innerWidth"
)
page.locator('button[type="submit"]').click()
page.wait_for_url("**/results/BRI/paris/return/2026-06-10/2026-06-17", timeout=10000)
page.wait_for_url(
f"**/results/BRI/paris/return/{outbound}/{returning}", timeout=10000
)
browser.close()
def test_return_calendar_can_restart_and_move_outbound_earlier(local_server: str) -> None:
with sync_playwright() as p:
browser = _launch_browser(p)
page = browser.new_page()
page.goto(f"{local_server}/", wait_until="domcontentloaded")
today = date.fromisoformat(page.locator("#travel_date").input_value())
tomorrow = (today + timedelta(days=1)).isoformat()
page.locator("#journey-return").check()
day = page.locator(f'.cal-cell[data-date="{tomorrow}"] button')
day.click()
day.click()
assert page.locator("#return_date").input_value() == tomorrow
# The next click starts a fresh selection, even on the selected date.
day.click()
assert page.locator("#return_date").input_value() == ""
page.locator(f'.cal-cell[data-date="{today}"] button').click()
assert page.locator("#travel_date").input_value() == today.isoformat()
assert page.locator("#return_date").input_value() == ""
day.click()
assert page.locator("#return_date").input_value() == tomorrow
page.locator("#journey-outbound").check()
assert page.locator("#travel_date").input_value() == today.isoformat()
assert page.locator("#return_date").get_attribute("name") == ""
browser.close()