tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

invoker-utils.js (5225B)


      1 function waitForRender() {
      2  return new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
      3 }
      4 async function clickOn(element) {
      5  await waitForRender();
      6  let rect = element.getBoundingClientRect();
      7  let actions = new test_driver.Actions();
      8  // FIXME: Switch to pointerMove(0, 0, {origin: element}) once
      9  // https://github.com/web-platform-tests/wpt/issues/41257 is fixed.
     10  await actions
     11      .pointerMove(Math.round(rect.x + rect.width / 2), Math.round(rect.y + rect.height / 2), {})
     12      .pointerDown({button: actions.ButtonType.LEFT})
     13      .pointerUp({button: actions.ButtonType.LEFT})
     14      .send();
     15  await waitForRender();
     16 }
     17 async function focusOn(element) {
     18  element.focus();
     19  await waitForRender();
     20  assert_equals(document.activeElement,element,'focus should be on element');
     21 }
     22 async function hoverOver(element) {
     23  await waitForRender();
     24  let rect = element.getBoundingClientRect();
     25  let actions = new test_driver.Actions();
     26  // FIXME: Switch to pointerMove(0, 0, {origin: element}) once
     27  // https://github.com/web-platform-tests/wpt/issues/41257 is fixed.
     28  await actions
     29      .pointerMove(Math.round(rect.x + rect.width / 2), Math.round(rect.y + rect.height / 2), {})
     30      .send();
     31  await waitForRender();
     32 }
     33 async function longPress(element) {
     34  await waitForRender();
     35  let rect = element.getBoundingClientRect();
     36  // FIXME: Switch to pointerMove(0, 0, {origin: element}) once
     37  // https://github.com/web-platform-tests/wpt/issues/41257 is fixed.
     38  const x = Math.round(rect.x + rect.width / 2);
     39  const y = Math.round(rect.y + rect.height / 2);
     40  await new test_driver.Actions()
     41    .addPointer("touchPointer", "touch")
     42    .pointerMove(x, y, {sourceName: "touchPointer"})
     43    .pointerDown({sourceName: "touchPointer"})
     44    // This needs to be long enough to trigger long-press on all platforms:
     45    .pause(1000, "pointer", {sourceName: "touchPointer"})
     46    .pointerUp({sourceName: "touchPointer"})
     47    .send();
     48  await waitForRender();
     49 }
     50 function mouseOverAndRecord(t,element) {
     51  let timingInfo = {element, started: performance.now()};
     52  return (new test_driver.Actions())
     53      .pointerMove(0, 0, {origin: element})
     54      .send()
     55      .then(() => timingInfo);
     56 }
     57 function focusAndRecord(t,element) {
     58  let timingInfo = {element, started: performance.now()};
     59  element.focus();
     60  return timingInfo;
     61 }
     62 async function hoverOrFocus(invokerMethod,element) {
     63  if (invokerMethod === 'hover') {
     64    await hoverOver(element);
     65  } else {
     66    assert_equals(invokerMethod,'focus');
     67    element.focus();
     68    await waitForRender();
     69  }
     70 }
     71 async function mouseOverOrFocusAndRecord(t,invokerMethod,element) {
     72  if (invokerMethod === 'hover') {
     73    return await mouseOverAndRecord(t,element);
     74  } else {
     75    assert_equals(invokerMethod,'focus');
     76    return focusAndRecord(t,element);
     77  }
     78 }
     79 // Note that this may err on the side of being too large (reporting a number
     80 // that is larger than the actual time since the mouseover happened), due to how
     81 // `timingInfo.started` is initialized, on first mouse move. However, this
     82 // function is intended to be used as a detector for the test harness taking too
     83 // long for some tests, so it's ok to be conservative.
     84 function msSinceMouseOver(timingInfo) {
     85  return performance.now() - timingInfo.started;
     86 }
     87 async function waitForHoverTime(hoverWaitTimeMs) {
     88  await new Promise(resolve => step_timeout(resolve,hoverWaitTimeMs));
     89  await waitForRender();
     90 };
     91 
     92 async function createPopoverAndInvokerForHoverTests(test, showdelayMs, hideDelayMs) {
     93  const unrelated = document.createElement('div');
     94  unrelated.tabIndex = 0;
     95  document.body.appendChild(unrelated);
     96  unrelated.textContent = 'Unrelated';
     97  unrelated.setAttribute('style','position:fixed; top:0;');
     98  // Ensure we never hover over or focus on an active interestfor element.
     99  unrelated.focus();
    100  await hoverOver(unrelated);
    101  const popover = document.createElement('div');
    102  popover.popover = 'auto';
    103  popover.setAttribute('style','inset:auto; top: 100px;');
    104  popover.textContent = 'Popover';
    105  document.body.appendChild(popover);
    106  let invoker = document.createElement('button');
    107  invoker.interestForElement = popover;
    108  invoker.setAttribute('style',`
    109    interest-delay-start: ${showdelayMs}ms;
    110    interest-delay-end: ${hideDelayMs}ms;
    111    position:fixed;
    112    top:200px;
    113    width:fit-content;
    114    height:fit-content;
    115    `);
    116  invoker.innerText = 'Invoker';
    117  document.body.appendChild(invoker);
    118  const actualShowDelay = Number(getComputedStyle(invoker).interestDelayStart.slice(0,-1))*1000;
    119  assert_equals(actualShowDelay,showdelayMs,'interest-delay-start is incorrect');
    120  const actualHideDelay = Number(getComputedStyle(invoker).interestDelayEnd.slice(0,-1))*1000;
    121  assert_equals(actualHideDelay,hideDelayMs,'interest-delay-end is incorrect');
    122  test.add_cleanup(() => {
    123    popover.remove();
    124    invoker.remove();
    125    unrelated.remove();
    126  });
    127  assert_false(popover.matches(':popover-open'),'The popover should start out closed');
    128  return {popover, invoker, unrelated};
    129 }
    130 async function sendLoseInterestHotkey() {
    131  const kEscape = '\uE00C';
    132  await new test_driver.Actions()
    133    .keyDown(kEscape)
    134    .keyUp(kEscape)
    135    .send();
    136  await waitForRender();
    137 }