runAsync<T> method

Future<T?> runAsync<T>(
  1. Future<T> callback(), {
  2. Shot? shot,
  3. Settle? settle,
})

tester.runAsync with a watchdog on it: real async work, and a sentence rather than a hang when it turns out not to be work at all.

Everything a scenario waits on for real — a database, a socket, an http call, an asset the app has not read yet — needs a turn of the real event loop, and this is the turn. The catch is that no pump can run while it is open, so awaiting a future that was made outside it, and that only a pump could complete, deadlocks the whole run silently. The watchdog reports that within seconds, and names the cache usually behind it.

var bytes = await s.runAsync(() => report.generatePdf());

A verb like the rest of them: it settles afterwards and captures what landed. Real work arriving is exactly the moment the tree has something new to paint — a query returns and the list fills in — and before this it was the one method on this surface that sat among tap and drag and quietly did neither, so every site that needed the repaint settled by hand.

Work that lands nothing on screen still takes no step: the automatic shot is skipped where the settle drew no frame, so the generatePdf above is followed by its document and by nothing else.

Implementation

Future<T?> runAsync<T>(
  Future<T> Function() callback, {
  Shot? shot,
  Settle? settle,
}) => _step(
  shot,
  settle,
  () => watchRunAsync(() => tester.runAsync(callback)),
  verb: 'runAsync',
  autoShotNeedsChange: true,
);