Skip to report
Chief / Bettter feedback widget 1.2.0 (OperationalLayer · lab · ops)13 Nov 2026, 00:10 UTC; ops added 01:55 UTC

Taking the screenshot can no longer block feedback

The feedback widget's screenshot now has Cancel, Escape and an 8-second limit, and pages that froze or lost their screenshot get one in under 4 seconds; live on the lab and on ops, both checked in a real browser.

Lab and ops: live and checked

Seconds until the feedback card opens, widget 1.2.0 (labels: what 1.1.0 did on the same page)

Some pictures hang (1.1.0: never ended)0.53 s
Another site's pictures, some hang (1.1.0: never ended)3.3 s
120 mixed cards, scrolled (1.1.0: no screenshot)0.88 s
A picture answers with a web page (1.1.0: no screenshot)0.32 s
2,000 cards, scrolled down (1.1.0: 8.1 s, 4.3 s frozen)1.3 s
Pictures still loading on the page (1.1.0: 4.3 s)3.4 s
Browser never finishes drawing: the 8 s limit, sent without one8 s
Source: demo.html with demo_server.py, local Chrome via browser-use, 12 Nov 23:5x UTC; 1.1.0 and 1.2.0 on the same pages

What people see

Before (1.1.0)

  • "Taking a screenshot…" can stay forever (Vlada, 12 Nov)
  • No Cancel; Escape does nothing
  • The page's sticky header stays shifted while it waits
  • One bad picture: the item goes without a screenshot

Now (1.2.0)

  • Cancel or Escape at any moment: write without a screenshot
  • After 8 s the card opens anyway; everything else is sent
  • The page is always put back as it was
  • A picture that does not arrive is grey; "Try again" keeps the text

Before: still taking a screenshot after 30 seconds

Demo page dimmed behind a 'Taking a screenshot…' box with no button, 30 seconds after the click, widget 1.1.0
Widget 1.1.0 on demo.html (40 design cards; the screenshot's copies of some pictures never answer), 30 s after the click. Local Chrome, 12 Nov.

Now: Cancel and Esc are on the veil

Demo page dimmed behind a 'Taking a screenshot…' box with a Cancel button and the line 'Esc or Cancel: write it without a screenshot'
Widget 1.2.0, same page, 1 s after the click (decoding forced to hang to keep the veil up). Cancel opened the card 0.4 s after the click.

Live on the lab: the card with its screenshot

The feedback card on the Mayer brand page of tech-builder.bettter.us with 'Attach the screenshot' ticked and a thumbnail
https://tech-builder.bettter.us/mayer/ scrolled down (56 pictures, 11,424 px long): screenshot in 2.5 s on a busy machine. The check item it sent (tb-0104) was deleted at 00:07:57 UTC.

Without a screenshot: the reason, and Try again

The feedback card saying 'No screenshot: you skipped it. The page and what you pointed at are still sent. Try again', with the comment kept
After Esc: the card says why, and Try again keeps the kind and the comment (checked in local Chrome).

The 2,000-card page scrolled to 20,000 px (seconds)

1.1.0 until the card opens (quiet)8.1 s
1.1.0 longest freeze (quiet)4.3 s
1.2.0 until the card opens (quiet)1.3 s
1.2.0 longest freeze (quiet)0.8 s
1.1.0 until the card opens (busy, slower run)12.7 s
1.2.0 until the card opens (busy, slower run)2 s
Source: demo.html?grid=2000&kinds=ok, local Chrome; quiet machine 12 Nov 23:5x UTC; busy machine (load 7-13) 13 Nov 00:02 UTC, two runs each

The screenshot still matches the page

Side by side: the 2,000-card demo page as Chrome draws it, and the widget's screenshot of it, with the same cards in the same places
Left: the page. Right: 1.2.0's screenshot. Boxes entirely off-screen are copied without their contents; on a stress page (collapsing margins, floats, escaping elements) the screenshots were pixel-identical to 1.1.0's.

Where it is

  1. Widget 1.2.0

    OperationalLayer PR #45: the fix, tests, demo, contract field; merged 13 Nov 01:44 UTC

  2. Lab merged

    Lab PRs #35 and #36 merged into the lab's main

  3. Lab live

    Deployed 13 Nov 00:06 UTC from main a9497db; checked in a real browser

  4. Ops live

    Deployed 13 Nov 01:51 UTC from main 19bb872 by ops's own refresh; checked in a real browser

Not done yet
  • On ops, the three design pictures that the lab's site shows on the Activity page come out grey in the screenshot: the lab's site does not let other sites read its pictures (no CORS header), so no browser can copy them. The inbox labels them "did not load in time", which is not the real reason.
  • On the ops Activity page (about 2,400 elements) the page pauses for about 1.5 to 1.7 s while the screenshot copy is made; the card still opens in 2.7 s.
  • The platform (Upcycle-Studio) has its own copy of the widget; its session (9f1ff34421) is fixing it with the same behaviour, not released yet.
  • On the lab, a browser that loaded the page in the last hours may keep 1.1.0 for up to about 1.5 h (the lab sends no cache header for the widget file); ops sends no-cache.
Why it froze
  • The screenshot is drawn from the page itself by html-to-image. It fetched every picture again, full size, off-screen ones too, with no time limit: one picture that never answered kept "Taking a screenshot…" up for good, and its open requests used up the site's six connections.
  • One picture that was not a picture (an error page, a broken file) cost the whole screenshot.
  • On long pages it copied every element with about 470 styles each, in one go: the page froze for seconds.
  • Nothing could stop it: no Cancel, no Escape, no limit; the sticky header stayed shifted until it ended.
  • The 1×1 grey placeholder both widgets carried was itself a broken PNG (found by the platform session).
What the widget does now
  • An 8-second limit (screenshotTimeout), Cancel and Escape; the page is put back however it ends; picture requests stop with it.
  • Pictures the page shows are drawn from the page at the size shown; another site's are fetched with 3 s each (at most 12 MB, six at a time) and shrunk; off-screen ones are never fetched; anything that fails is grey.
  • Boxes entirely off-screen are copied without their contents (same size, nothing moves).
  • Each item says what happened to its screenshot (context.screenshot: attached, left out, timeout, cancelled or failed, the time, pictures missing); the inbox shows it. Additive v1 contract field.
Checks run
  • node --test shared/feedback-widget/test/capture.test.js: 9 passed (time limit, Cancel, failure, picture paths, 12 MB cap, valid placeholder, cut-off copy). Breaking the restore, the timer or the abort makes them fail.
  • python3 -m unittest discover -s opsdash/tests: 65 passed; docs/contracts/check.py: 0 problems.
  • Lab: 18-23 widget tests passed; the full lab suite fails the same 3 tests and 2 errors on main with and without the change (missing local data and pins).
  • Browser (local Chrome, browser-use): eight demo pages before and after; timeout, Cancel, Escape, Send and Try again; a stress page compared with 1.1.0 pixel by pixel.
  • Lab rebuild compared with the live site before deploying: of 1,567 files only the build stamp, the build time and the two widget files differed.
  • Ops live (13 Nov 01:52 UTC, local Chrome): it serves exactly the 1.2.0 files on main (the same hashes as the lab) behind its login; the screenshot was attached in 2.7 s, Escape opened the card with "No screenshot: you skipped it", and Send stored the item with its screenshot. The check item was deleted at 01:53 UTC (store backed up first); the ops inbox is empty again.
  • The ops deploy first waited on another project's status page: since 01:10 UTC an apostrophe in its header stopped every ops refresh. Its session fixed it at 01:46 UTC, and the 01:50 refresh deployed this release.
New feedback from people (checked 13 Nov 00:07 UTC)
  • Ops inbox: none.
  • Adapter: Elena Hordiienko left 32 items on 12 Nov (23 blazers on v1.6.21, 9 trousers), still new; the Adapter session (1505d1af9f) was told.
  • Platform: one new question (12 Nov 13:11 UTC) about the test preselection spreadsheet.
  • Lab: Catarina's notes tb-0073 to tb-0103 are being integrated by the lab session (416b42ca30).