function waitForFunction(fn, arg, options = {}) {
  const settings = {
    ...defaults,
    ...options,
  };

  return new Promise((resolve, reject) => {
    let timeElapsed = 0;
    let lastError;

    const int = setInterval(() => {
      let result;

      try {
        result = fn(arg);
      } catch (err) {
        lastError = err;
      }

      if (result) {
        clearInterval(int);
        resolve(result);
      }

      timeElapsed += settings.delay;

      if (timeElapsed >= settings.timeout) {
        console.error(
          `\nwaitForFunction did not return a truthy value within ${settings.timeout} ms.\n`,
        );
        reject(lastError || result);
      }
    }, settings.delay);
  });
}
Waits for specified function to resolve to a truthy value.

@param {Function} fn function to be evaluated until truthy
@param {*} arg optional argument to pass to `fn`
@param {Object} options optional parameters
@param {number} options.delay delay between fn invocations
@param {number} options.timeout timeout in milliseconds
@returns {Promise} promise which resolves to the truthy fn return value or
rejects to an error object or last non-truthy fn return value