Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ PYTHONPATH=. .venv/bin/pytest -m "not browser" --cov --cov-report=term-missing -
git diff --check
```

Also run `pytest -m browser` with CI's WebKit setup when available. On this
Rocky host, the bundled WebKit cannot launch because of its system-library
requirements. Use a rootless `podman` (or Docker) installation and network
access to the Microsoft Playwright image to run WebKit in a matching container:
Also run `pytest -m browser` with CI's WebKit setup. On this Rocky host, the
bundled WebKit cannot launch because of its system-library requirements, but a
rootless `podman` installation and network access to the Microsoft Playwright
image are available. When working on this machine, presume that the
containerized WebKit procedure below can be run and attempt it before using any
fallback. A bundled-WebKit launch failure is not evidence that WebKit is
unavailable.

```sh
WEBKIT_VERSION="$(.venv/bin/python -c 'from importlib.metadata import version; print(version("playwright"))')"
Expand All @@ -34,8 +37,11 @@ podman stop driving-record-webkit

The image and installed Python Playwright version must match because the
run-server protocol is version-specific. `--network host` lets containerized
WebKit reach the temporary `127.0.0.1` server created by the tests. If this
setup is unavailable, state that limitation explicitly and run the project's
configured Chromium fallback only when the test documents it.
WebKit reach the temporary `127.0.0.1` server created by the tests. If sandbox
permissions prevent loopback binding or Podman execution, request escalation
and retry the same procedure. Use the project's configured Chromium fallback
only after the containerized WebKit procedure has been attempted and failed;
report the exact failing command and reason before doing so. If the procedure
cannot be run after that retry, state the limitation explicitly.
Inspect each PR's GitHub check results after pushing; distinguish a pre-existing
or unrelated failure from one introduced by the branch with log evidence.
27 changes: 27 additions & 0 deletions driving_log/static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,33 @@
});
});

const driveGroups = document.querySelectorAll("details[data-drive-group-key]");
if (driveGroups.length) {
const storageKey = `driving-log:expanded-drive-groups:${location.pathname}${location.search}`;
let expanded = new Set();
try {
expanded = new Set(JSON.parse(sessionStorage.getItem(storageKey) || "[]"));
} catch (_) {
// Storage may be unavailable in private browsing or under a strict policy.
}
const saveExpanded = () => {
try {
sessionStorage.setItem(storageKey, JSON.stringify([...expanded]));
} catch (_) {
// The disclosure still works for this page when persistence is unavailable.
}
};
driveGroups.forEach(group => {
const key = group.dataset.driveGroupKey;
if (expanded.has(key)) group.open = true;
group.addEventListener("toggle", () => {
if (group.open) expanded.add(key);
else expanded.delete(key);
saveExpanded();
});
});
}

document.querySelectorAll("[data-cancel-form]").forEach(link => {
const form = document.getElementById(link.dataset.cancelForm);
if (!form) return;
Expand Down
2 changes: 1 addition & 1 deletion driving_log/templates/drives.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ <h1>Drive history</h1>
{% if groups %}
<div class="drive-groups">
{% for group in groups %}
<details class="drive-group">
<details class="drive-group" data-drive-group-key="{{ group.key }}">
<summary><span class="group-label">{{ group.label }}</span><small>{{ group.drives | length }} drive{{ "" if group.drives|length == 1 else "s" }} · {{ format_minutes(group.minutes) }} · {{ group.percentage }}% of total<br>{% if group.day_minutes and group.night_minutes %}{{ format_minutes(group.day_minutes) }} day · {{ format_minutes(group.night_minutes) }} night{% elif group.day_minutes %}{{ format_minutes(group.day_minutes) }} day{% else %}{{ format_minutes(group.night_minutes) }} night{% endif %}</small></summary>
<div class="drive-list">{% for item in group.drives %}{{ drive_row(item) }}{% endfor %}</div>
</details>
Expand Down
23 changes: 23 additions & 0 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,29 @@ def test_mobile_webkit_live_drive_recovery() -> None:
assert recovered.locator('input[name="acknowledge_warnings"]').count() == 0
assert recovered.locator('input[name="supervisor_dl_number"]').count() == 0
assert recovered.locator('input[name="supervisor_dl_state"]').count() == 0
recovered.get_by_role("button", name="Save completed drive").click()
recovered.get_by_role("heading", name="Student progress").wait_for()
for grouping in (
"date",
"supervisor",
"day_night",
"part_of_day",
"road_type",
"weather",
"duration",
):
recovered.goto(f"{url}/drives?group_by={grouping}")
group = recovered.locator("details[data-drive-group-key]").first
group.locator("summary").click()
assert group.get_attribute("open") == ""
recovered.reload()
recovered.get_by_role("heading", name="Drive history").wait_for()
assert group.get_attribute("open") == ""
group.locator(".drive-row").click()
recovered.get_by_role("heading", name="Drive details").wait_for()
recovered.go_back()
Comment thread
ahernsean marked this conversation as resolved.
recovered.get_by_role("heading", name="Drive history").wait_for()
assert group.get_attribute("open") == ""
recovered.goto(f"{url}/dmv")
recovered.locator('select[name="display_name"]').select_option("Sean Ahern")
recovered.locator('input[name="dl_number"]').fill("SYNTHETIC-1234")
Expand Down
Loading