function waitFor({
  predicate = noOp,
  onSuccess = noOp,
  onFailure = noOp,
  timeout = 10e3, // 10 sec
  interval = 50,
  elapsed = 0,
}) {
  setTimeout(async () => {
    try {
      const done = await predicate()
      if (done) return onSuccess(done, elapsed)
    } catch (err) {
      return onFailure(err)
    }
    if (elapsed >= timeout) return onFailure('timeout')
    waitFor({ predicate, onSuccess, onFailure, timeout, elapsed: elapsed + interval })
  }, interval)
}
waitFor predicate to resolve to true
@param {*} param0