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

DEMO-013 Freight: find a shipment and add a note

Edit Load test Duplicate

Staff workflow on the demo site: search and filter the shipments table, sort it, open a shipment, save a note (a JSON request the page makes), and confirm the 'mark delivered' dialog.

demodialogsfreighttables version: 1.0 DEMO-013__freight_shipments_and_notes.py group: Freight regressiongroup: Freight smoke

Runs
18
Pass rate
89%
16 passed / 2 failed
Avg duration
3s
p95 4s
Estimate
3s
avg of last 10 judged runs
Flakiness
0.24
0 stable · 1 alternates
Current streak
12
passed

Last 18 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 18 runs — slowest steps first, one line each

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

fastest 2s · slowest 4s

Why this test failed grouped by message, last 90 days

timesmessagelast
2 AssertionError: saving a note failed: 'The notes service is busy -- t… Sep 24 open

Outcomes by target version

What this test does plain language, derived from the code

  1. site = Freight(page, ctx).sign_in()
  2. ⏱ Timed phase: search shipments
  3. page.goto(site.url("ops/shipments/"))
  4. Type “Lumen” into #shipment-search
  5. Choose “in_transit” in #status-filter
  6. Click #apply-filters
  7. Wait until #result-count appears
  8. count = page.locator("#shipments-table tbody tr").count()
  9. assert count >= 1, "Lumen Optics has a shipment in transit (AF-100001); the search found none"
  10. ctx.log(page.inner_text("#result-count"))
  11. ⏱ Timed phase: sort by ETA
  12. Click #shipments-table th a[data-sort=eta]
  13. Wait until #shipments-table th[aria-sort] a[data-sort=eta] appears
  14. ⏱ Timed phase: open AF-100001
  15. Click #shipments-table a:text-is('AF-100001')
  16. Wait until #ship-status appears
  17. Take a screenshot (“shipment”)
  18. ⏱ Timed phase: save a note
  19. page.fill("#note-text", NOTE)
  20. Click #note-save
  21. page.wait_for_selector(
  22. f"#notes-list .note-text:has-text('promised by Friday'), #note-error:not([hidden])",
  23. timeout=10000)
  24. if page.is_visible("#note-error"):
  25. Take a screenshot (“note-failed”)
  26. raise AssertionError(f"saving a note failed: {page.inner_text('#note-error')!r}")
  27. page.once("dialog", lambda dialog: dialog.accept())
  28. ⏱ Timed phase: mark delivered
  29. Click #deliver-btn
  30. Wait until #ship-status:text-is('Delivered') appears
  31. Take a screenshot (“delivered”)
  32. assert page.is_visible(f"#notes-list .note-text:has-text('promised by Friday')"), \
  33. "the note did not survive the page reload"
Show the code
"""The staff workflow: search, filter, sort, open a shipment, write a note,
confirm a dialog.

The busiest screens of any back-office app are a filterable table and a
detail page with actions -- this drives both. Saving a note is a JSON
request made by the page's own JavaScript; the test waits for its OUTCOME
(the note appears, or an error does) instead of sleeping. "Mark delivered"
asks for confirmation in a browser dialog, which the test accepts.

If a release makes saving fail now and then, this is the test whose pass
rate drops -- flakiness is a signal about the SITE, and the hub's Metrics
and Analytics pages show it that way.
"""
from _lib.freight import Freight

NOTE = "Customer asked for a delivery window -- promised by Friday"


def run(page, ctx):
    site = Freight(page, ctx).sign_in()

    with ctx.timed("search shipments"):
        page.goto(site.url("ops/shipments/"))
        page.fill("#shipment-search", "Lumen")
        page.select_option("#status-filter", "in_transit")
        page.click("#apply-filters")
        page.wait_for_selector("#result-count")
    count = page.locator("#shipments-table tbody tr").count()
    assert count >= 1, "Lumen Optics has a shipment in transit (AF-100001); the search found none"
    ctx.log(page.inner_text("#result-count"))

    with ctx.timed("sort by ETA"):
        page.click("#shipments-table th a[data-sort=eta]")
        page.wait_for_selector("#shipments-table th[aria-sort] a[data-sort=eta]")

    with ctx.timed("open AF-100001"):
        page.click("#shipments-table a:text-is('AF-100001')")
        page.wait_for_selector("#ship-status")
    ctx.screenshot("shipment")

    with ctx.timed("save a note"):
        page.fill("#note-text", NOTE)
        page.click("#note-save")
        page.wait_for_selector(
            f"#notes-list .note-text:has-text('promised by Friday'), #note-error:not([hidden])",
            timeout=10000)
    if page.is_visible("#note-error"):
        ctx.screenshot("note-failed")
        raise AssertionError(f"saving a note failed: {page.inner_text('#note-error')!r}")

    page.once("dialog", lambda dialog: dialog.accept())
    with ctx.timed("mark delivered"):
        page.click("#deliver-btn")
        page.wait_for_selector("#ship-status:text-is('Delivered')")
    ctx.screenshot("delivered")
    assert page.is_visible(f"#notes-list .note-text:has-text('promised by Friday')"), \
        "the note did not survive the page reload"

All runs

RunStatusQueuedDuration VersionTriggerBatch
#488 passed 2026-09-25 07:00:10 3s 3.0.0 schedule schedule: Freight regression …
#395 passed 2026-09-24 23:24:12 3s 3.0.0 group group: Freight smoke
#391 passed 2026-09-24 23:23:58 3s 3.0.0 group group: Freight smoke
#387 passed 2026-09-24 23:22:20 3s 3.0.0 group group: Freight smoke
#383 passed 2026-09-24 23:10:27 2s 3.0.0 group group: Freight smoke
#376 passed 2026-09-24 22:10:14 3s 3.0.0 schedule schedule: Freight smoke 22:10
#368 passed 2026-09-24 22:05:21 4s 3.0.0 group group: Freight regression
#358 passed 2026-09-24 22:04:30 3s 3.0.0 group group: Freight smoke
#354 passed 2026-09-24 22:04:21 3s 2.1.0 group group: Freight smoke
#334 passed 2026-09-24 19:48:13 3s 3.0.0 cli-adopted 4 tests (terminal)
#310 passed 2026-09-24 18:59:58 3s 3.0.0 cli-adopted 8 tests (terminal)
#302 passed 2026-09-24 18:57:59 3s 2.1.0 cli-adopted 8 tests (terminal)
#297 failed 2026-09-24 18:57:49 3s 2.0.0 cli-adopted DEMO-013
#296 passed 2026-09-24 18:57:44 3s 2.0.0 cli-adopted DEMO-013
#295 passed 2026-09-24 18:57:39 3s 2.0.0 cli-adopted DEMO-013
#290 failed 2026-09-24 18:55:40 3s 2.0.0 cli-adopted 8 tests (terminal)
#151 passed 2026-09-24 18:52:00 3s 1.1.0 cli-adopted 8 tests (terminal)
#13 passed 2026-09-24 18:48:19 4s 1.0.0 cli-adopted 8 tests (terminal)