chromium/third_party/blink/web_tests/fast/forms/resources/picker-common.js

function requestAnimationFramePromise(w) {
  return new Promise((resolve) => (w || window).requestAnimationFrame(resolve));
}

function waitUntilOpen(popupWindow) {
  return new Promise((resolve, reject) => {
    if (!popupWindow)
      reject('popupWindow is null');
    function tick() {
      // didOpenPicker gets set by pickerCommon.js: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/forms/resources/pickerCommon.js;l=213;drc=f2f1e770d7def6c722b0092d77b2d3395c46a477
      if (popupWindow.didOpenPicker)
        resolve();
      else
        requestAnimationFrame(tick.bind(this));
    }
    tick();
  });
}

// Returns a promise that resolves when a picker is opened.
function openPicker(element) {
  return test_driver.bless("show picker")
  .then(() => requestAnimationFramePromise())
  .then(() => {
    if (element instanceof HTMLSelectElement) {
      // Select is the only control with a picker that (currently)
      // doesn't support showPicker().
      element.focus();
      const isMac = navigator.platform.toUpperCase().indexOf('MAC')>=0;
      let activation_key;
      if (isMac) {
        activation_key = '\uE00A' + '\uE015'; // Alt-Arrow-Down
      } else {
        activation_key = ' '; // Spacebar
      }
      return test_driver.send_keys(element, activation_key);
    } else {
      return element.showPicker(); // Should work for file, color, and date/time
    }
  })
  .then(() => {
      if (!window.internals)
        throw 'Internals not available';
      return waitUntilOpen(window.internals.pagePopupWindow);
    })
  .then(() => requestAnimationFramePromise(window.internals.pagePopupWindow))
  .then(() => requestAnimationFramePromise())
  .then(() => requestAnimationFramePromise(window.internals.pagePopupWindow))
  .then(() => requestAnimationFramePromise());
}

function attemptToClosePicker(element) {
  element.blur(); // Sometimes works to close the picker
  internals.endColorChooser(element); // Works for color only
  return eventSender.keyDown('Escape'); // Hitting esc could close file picker
}

// Opens the picker on the given element, waits for it to be
// displayed, and ends the test. This function also enables
// pixel result output, and will add any errors to the visible
// output. If runAfterOpening is provided, it will be called
// after the picker is opened, and before several rAF() calls.
function openPickerAppearanceOnly(element, runAfterOpening) {
  function showError(e) {
    attemptToClosePicker(element);
    const errorMessage = document.createElement('pre');
    errorMessage.innerText = 'FAIL: \n' + e + '\n\n';
    element.parentNode.insertBefore(errorMessage,element);
  }
  if (!window.testRunner) {
    return showError('testRunner is required');
  }
  testRunner.waitUntilDone();
  testRunner.setShouldGeneratePixelResults(true);

  openPicker(element)
    .then(() => {
      if (runAfterOpening !== undefined) {
        return runAfterOpening();
      }
    })
    .then(() => requestAnimationFramePromise())
    .then(() => requestAnimationFramePromise())
    .then(() => testRunner.notifyDone())
    .catch((e) => {
      showError(e);
      testRunner.notifyDone();
    });
}

// Do NOT use openPickerDeprecatedJsTest for any new tests. See crbug.com/1299212.
// This is here to support old tests only.
let waitedForLoad=false;
function openPickerDeprecatedJsTest(element, successCallback, failureCallback) {
  if (!waitedForLoad) {
    waitedForLoad = true;
    window.jsTestIsAsync = true;
    window.onload = () => {
      openPickerDeprecatedJsTest(element, successCallback, failureCallback);
    };
    return;
  }
  openPicker(element)
  .then(() => requestAnimationFramePromise())
  .then(() => requestAnimationFramePromise())
  .then(() => {
    successCallback();
  })
  .catch((e) => {
    if (failureCallback !== undefined) {
      failureCallback(e);
    } else {
      testFailed('Error: ' + e);
      finishJSTest();
    }
  });
}
function waitUntilClosingDeprecatedJsTest(callback) {
  setTimeout(callback, 1);
}

// Enable lang attribute aware UI for all controls.
if (window.internals)
  internals.runtimeFlags.langAttributeAwareFormControlUIEnabled = true;