🧪 Test Hub
testing: Demo target v3.0.0 · built-in demo site

DEMO-021 Freight: dock schedule by drag-and-drop

Edit Load test Duplicate

Drags arriving trucks onto dock doors with page.drag_and_drop: allowed drops land, a hazardous load at a normal door is refused with the reason, and the schedule survives a reload.

demodrag-and-dropfreightrules version: 1.0 DEMO-021__freight_dock_drag_and_drop.py group: Freight platformgroup: Python and TypeScript, side by side

Runs
8
Pass rate
100%
8 passed / 0 failed
Avg duration
4s
p95 5s
Estimate
4s
avg of last 10 judged runs
Flakiness
0.00
0 stable · 1 alternates
Current streak
8
passed

Last 8 results newest on the right — click a square to open that run

Duration per run point color = outcome; dashed = 7-run average; click a point to open the run

Step timing trends the same step compared across the last 8 runs — slowest steps first, one line each

How long it takes distribution of 8 runs — two humps mean two different behaviours hiding behind one average

fastest 3s · slowest 5s

Why this test failed grouped by message, last 90 days

No failures recorded. 👍

Outcomes by target version

What this test does plain language, derived from the code

  1. site = Freight(page, ctx).sign_in()
  2. site.open("ops/docks/")
  3. card = lambda arrival: f".dock-card[data-arrival='{arrival}']" # noqa: E731
  4. first = lambda sel: page.get_attribute(sel, "data-arrival") # noqa: E731
  5. hazmat = first("#arrivals .dock-card[data-hazardous='1']")
  6. heavy = first("#arrivals .dock-card[data-heavy='1'][data-hazardous='0']")
  7. normal = first("#arrivals .dock-card[data-heavy='0'][data-hazardous='0']")
  8. ctx.log(f"hazmat {hazmat}, heavy {heavy}, normal {normal}")
  9. ⏱ Timed phase: drag a normal load to Door 3, 09:00
  10. page.drag_and_drop(card(normal), "td[data-cell='D3|09:00']")
  11. page.wait_for_selector(f"td[data-cell='D3|09:00'] {card(normal)}")
  12. ⏱ Timed phase: try hazardous goods at Door 1
  13. page.drag_and_drop(card(hazmat), "td[data-cell='D1|10:00']")
  14. Wait until #dock-error:not([hidden]) appears
  15. refusal = page.inner_text("#dock-error")
  16. Take a screenshot (“refused”)
  17. assert "hazardous" in refusal.lower(), f"the refusal should explain why: {refusal!r}"
  18. assert page.locator(f"td[data-cell='D1|10:00'] {card(hazmat)}").count() == 0, \
  19. "a hazardous load was accepted at a non-hazmat door"
  20. ⏱ Timed phase: drag hazardous goods to Door 4 (hazmat)
  21. page.drag_and_drop(card(hazmat), "td[data-cell='D4|10:00']")
  22. page.wait_for_selector(f"td[data-cell='D4|10:00'] {card(hazmat)}")
  23. ⏱ Timed phase: drag a heavy load to a forklift door
  24. page.drag_and_drop(card(heavy), "td[data-cell='D1|11:00']")
  25. page.wait_for_selector(f"td[data-cell='D1|11:00'] {card(heavy)}")
  26. page.reload()
  27. for arrival, cell in ((normal, "D3|09:00"), (hazmat, "D4|10:00"), (heavy, "D1|11:00")):
  28. assert page.locator(f"td[data-cell='{cell}'] {card(arrival)}").count() == 1, \
  29. f"{arrival} is not at {cell} after a reload -- the board was not saved"
  30. Take a screenshot (“scheduled”)
Show the code
"""Drag-and-drop, with rules: schedule arriving trucks onto dock doors.

Drag-and-drop is where record-and-replay tools usually give up. Playwright
does it with one call -- page.drag_and_drop(card, cell) -- through real
browser drag events. The yard has rules the SERVER enforces, so the test
checks both directions: allowed drops land, a forbidden one is refused with
the reason, and the board survives a reload (it is stored, not just drawn).
"""
from _lib.freight import Freight


def run(page, ctx):
    site = Freight(page, ctx).sign_in()
    site.open("ops/docks/")
    card = lambda arrival: f".dock-card[data-arrival='{arrival}']"   # noqa: E731
    first = lambda sel: page.get_attribute(sel, "data-arrival")      # noqa: E731
    hazmat = first("#arrivals .dock-card[data-hazardous='1']")
    heavy = first("#arrivals .dock-card[data-heavy='1'][data-hazardous='0']")
    normal = first("#arrivals .dock-card[data-heavy='0'][data-hazardous='0']")
    ctx.log(f"hazmat {hazmat}, heavy {heavy}, normal {normal}")

    with ctx.timed("drag a normal load to Door 3, 09:00"):
        page.drag_and_drop(card(normal), "td[data-cell='D3|09:00']")
        page.wait_for_selector(f"td[data-cell='D3|09:00'] {card(normal)}")

    with ctx.timed("try hazardous goods at Door 1"):
        page.drag_and_drop(card(hazmat), "td[data-cell='D1|10:00']")
        page.wait_for_selector("#dock-error:not([hidden])")
    refusal = page.inner_text("#dock-error")
    ctx.screenshot("refused")
    assert "hazardous" in refusal.lower(), f"the refusal should explain why: {refusal!r}"
    assert page.locator(f"td[data-cell='D1|10:00'] {card(hazmat)}").count() == 0, \
        "a hazardous load was accepted at a non-hazmat door"

    with ctx.timed("drag hazardous goods to Door 4 (hazmat)"):
        page.drag_and_drop(card(hazmat), "td[data-cell='D4|10:00']")
        page.wait_for_selector(f"td[data-cell='D4|10:00'] {card(hazmat)}")

    with ctx.timed("drag a heavy load to a forklift door"):
        page.drag_and_drop(card(heavy), "td[data-cell='D1|11:00']")
        page.wait_for_selector(f"td[data-cell='D1|11:00'] {card(heavy)}")

    page.reload()
    for arrival, cell in ((normal, "D3|09:00"), (hazmat, "D4|10:00"), (heavy, "D1|11:00")):
        assert page.locator(f"td[data-cell='{cell}'] {card(arrival)}").count() == 1, \
            f"{arrival} is not at {cell} after a reload -- the board was not saved"
    ctx.screenshot("scheduled")

All runs

RunStatusQueuedDuration VersionTriggerBatch
#472 passed 2026-09-25 00:30:11 3s 3.0.0 group group: Python and TypeScript,…
#398 passed 2026-09-24 23:34:49 4s 3.0.0 group group: Freight platform
#361 passed 2026-09-24 22:04:44 5s 3.0.0 group group: Freight platform
#330 passed 2026-09-24 19:47:27 4s 3.0.0 cli-adopted 3 tests (terminal)
#327 passed 2026-09-24 19:46:19 4s 2.1.0 cli-adopted 3 tests (terminal)
#324 passed 2026-09-24 19:45:49 4s 2.0.0 cli-adopted 3 tests (terminal)
#321 passed 2026-09-24 19:45:20 4s 1.1.0 cli-adopted 3 tests (terminal)
#318 passed 2026-09-24 19:44:24 4s 1.0.0 cli-adopted 3 tests (terminal)