tor-browser

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

browser_orientationchange_event.js (11747B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test that the "orientationchange" event is fired when the "rotate button" is clicked.
      7 
      8 const TEST_DOCUMENT = `doc_with_remote_iframe_and_isolated_cross_origin_capabilities.sjs`;
      9 const TEST_COM_URL = URL_ROOT_COM_SSL + TEST_DOCUMENT;
     10 
     11 const testDevice = {
     12  name: "Fake Phone RDM Test",
     13  width: 320,
     14  height: 570,
     15  pixelRatio: 5.5,
     16  userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
     17  touch: true,
     18  firefoxOS: true,
     19  os: "custom",
     20  featured: true,
     21 };
     22 
     23 // Add the new device to the list
     24 addDeviceForTest(testDevice);
     25 
     26 addRDMTask(TEST_COM_URL, async function ({ ui }) {
     27  await pushPref("devtools.responsive.viewport.angle", 0);
     28 
     29  info("Check the original orientation values before the orientationchange");
     30  is(
     31    await getScreenOrientationType(ui.getViewportBrowser()),
     32    "portrait-primary",
     33    "Primary orientation type is portrait-primary"
     34  );
     35 
     36  is(
     37    await getScreenOrientationAngle(ui.getViewportBrowser()),
     38    0,
     39    "Original angle is set at 0 degrees"
     40  );
     41 
     42  info(
     43    "Check that rotating the viewport does trigger an orientationchange event"
     44  );
     45  let iframeBrowsingContext =
     46    ui.getViewportBrowser().browsingContext.children[0];
     47 
     48  let waitForOrientationChangeEvent = isOrientationChangeEventEmitted(
     49    ui.getViewportBrowser()
     50  );
     51  let waitForScreenOrientationChangeEvent =
     52    isWindowScreenOrientationChangeEventEmitted(ui.getViewportBrowser());
     53 
     54  let waitForOrientationChangeEventInIframe = isOrientationChangeEventEmitted(
     55    iframeBrowsingContext
     56  );
     57  let waitForScreenOrientationChangeEventInIframe =
     58    isWindowScreenOrientationChangeEventEmitted(iframeBrowsingContext);
     59  rotateViewport(ui);
     60  is(
     61    await waitForOrientationChangeEvent,
     62    true,
     63    "'orientationchange' event fired"
     64  );
     65  is(
     66    await waitForScreenOrientationChangeEvent,
     67    true,
     68    "'change' event fired on window.screen.orientation"
     69  );
     70 
     71  is(
     72    await waitForOrientationChangeEventInIframe,
     73    true,
     74    "'orientationchange' event fired in iframe"
     75  );
     76  is(
     77    await waitForScreenOrientationChangeEventInIframe,
     78    true,
     79    "'change' event fired on window.screen.orientation in iframe"
     80  );
     81 
     82  is(
     83    await getScreenOrientationType(ui.getViewportBrowser()),
     84    "landscape-primary",
     85    "Orientation state was updated to landscape-primary"
     86  );
     87 
     88  is(
     89    await getScreenOrientationAngle(ui.getViewportBrowser()),
     90    90,
     91    "Orientation angle was updated to 90 degrees"
     92  );
     93 
     94  is(
     95    await getScreenOrientationType(iframeBrowsingContext),
     96    "landscape-primary",
     97    "Orientation state in iframe was updated to landscape-primary"
     98  );
     99 
    100  is(
    101    await getScreenOrientationAngle(iframeBrowsingContext),
    102    90,
    103    "Orientation angle in iframe was updated to 90 degrees"
    104  );
    105 
    106  info("Check that the viewport orientation values persist after reload");
    107  await reloadBrowser();
    108  iframeBrowsingContext = ui.getViewportBrowser().browsingContext.children[0];
    109 
    110  is(
    111    await getScreenOrientationType(ui.getViewportBrowser()),
    112    "landscape-primary",
    113    "Orientation is still landscape-primary"
    114  );
    115  is(
    116    await getInitialScreenOrientationType(ui.getViewportBrowser()),
    117    "landscape-primary",
    118    "orientation type was set on the page very early in its lifecycle"
    119  );
    120  is(
    121    await getScreenOrientationAngle(ui.getViewportBrowser()),
    122    90,
    123    "Orientation angle is still 90"
    124  );
    125  is(
    126    await getInitialScreenOrientationAngle(ui.getViewportBrowser()),
    127    90,
    128    "orientation angle was set on the page early in its lifecycle"
    129  );
    130 
    131  is(
    132    await getScreenOrientationType(iframeBrowsingContext),
    133    "landscape-primary",
    134    "Orientation is still landscape-primary in iframe"
    135  );
    136  is(
    137    await getScreenOrientationAngle(iframeBrowsingContext),
    138    90,
    139    "Orientation angle is still 90 in iframe"
    140  );
    141 
    142  info(
    143    "Check that the viewport orientation values persist after navigating to a page that forces the creation of a new browsing context"
    144  );
    145  const browser = ui.getViewportBrowser();
    146  const previousBrowsingContextId = browser.browsingContext.id;
    147  const waitForReload = await watchForDevToolsReload(browser);
    148 
    149  BrowserTestUtils.startLoadingURIString(
    150    browser,
    151    URL_ROOT_ORG_SSL + TEST_DOCUMENT + "?crossOriginIsolated=true"
    152  );
    153  await waitForReload();
    154  iframeBrowsingContext = ui.getViewportBrowser().browsingContext.children[0];
    155 
    156  isnot(
    157    browser.browsingContext.id,
    158    previousBrowsingContextId,
    159    "A new browsing context was created"
    160  );
    161 
    162  is(
    163    await getScreenOrientationType(ui.getViewportBrowser()),
    164    "landscape-primary",
    165    "Orientation is still landscape-primary after navigating to a new browsing context"
    166  );
    167  is(
    168    await getInitialScreenOrientationType(ui.getViewportBrowser()),
    169    "landscape-primary",
    170    "orientation type was set on the page very early in its lifecycle"
    171  );
    172  is(
    173    await getScreenOrientationAngle(ui.getViewportBrowser()),
    174    90,
    175    "Orientation angle is still 90 after navigating to a new browsing context"
    176  );
    177  is(
    178    await getInitialScreenOrientationAngle(ui.getViewportBrowser()),
    179    90,
    180    "orientation angle was set on the page early in its lifecycle"
    181  );
    182 
    183  is(
    184    await getScreenOrientationType(iframeBrowsingContext),
    185    "landscape-primary",
    186    "Orientation in iframe is still landscape-primary after navigating to a new browsing context"
    187  );
    188  is(
    189    await getScreenOrientationAngle(iframeBrowsingContext),
    190    90,
    191    "Orientation angle in iframe is still 90 after navigating to a new browsing context"
    192  );
    193 
    194  waitForOrientationChangeEvent = isOrientationChangeEventEmitted(
    195    ui.getViewportBrowser()
    196  );
    197  rotateViewport(ui);
    198  await waitForOrientationChangeEvent;
    199 
    200  info(
    201    "Check the orientationchange event is not dispatched when changing devices."
    202  );
    203  waitForOrientationChangeEvent = isOrientationChangeEventEmitted(
    204    ui.getViewportBrowser()
    205  );
    206  waitForScreenOrientationChangeEvent =
    207    isWindowScreenOrientationChangeEventEmitted(ui.getViewportBrowser());
    208 
    209  waitForOrientationChangeEventInIframe = isOrientationChangeEventEmitted(
    210    iframeBrowsingContext
    211  );
    212  waitForScreenOrientationChangeEventInIframe =
    213    isWindowScreenOrientationChangeEventEmitted(iframeBrowsingContext);
    214 
    215  await selectDevice(ui, testDevice.name);
    216  is(
    217    await waitForOrientationChangeEvent,
    218    false,
    219    "orientationchange event was not dispatched when changing devices"
    220  );
    221  is(
    222    await waitForScreenOrientationChangeEvent,
    223    false,
    224    "on window.screen.orientation, change event was not dispatched when changing devices"
    225  );
    226 
    227  is(
    228    await waitForOrientationChangeEventInIframe,
    229    false,
    230    "orientationchange event was not dispatched in iframe when changing devices"
    231  );
    232  is(
    233    await waitForScreenOrientationChangeEventInIframe,
    234    false,
    235    "on window.screen.orientation, change event was not dispatched in iframe when changing devices"
    236  );
    237 
    238  info("Check the new orientation values after selecting device.");
    239  is(
    240    await getScreenOrientationType(ui.getViewportBrowser()),
    241    "portrait-primary",
    242    "New orientation type is portrait-primary"
    243  );
    244 
    245  is(
    246    await getScreenOrientationAngle(ui.getViewportBrowser()),
    247    0,
    248    "Orientation angle is 0"
    249  );
    250 
    251  is(
    252    await getScreenOrientationType(iframeBrowsingContext),
    253    "portrait-primary",
    254    "New orientation type in iframe is portrait-primary"
    255  );
    256 
    257  is(
    258    await getScreenOrientationAngle(iframeBrowsingContext),
    259    0,
    260    "Orientation angle in iframe is 0"
    261  );
    262 
    263  info(
    264    "Check the orientationchange event is not dispatched when calling the command with the same orientation."
    265  );
    266  waitForOrientationChangeEvent = isOrientationChangeEventEmitted(
    267    ui.getViewportBrowser()
    268  );
    269  waitForScreenOrientationChangeEvent =
    270    isWindowScreenOrientationChangeEventEmitted(ui.getViewportBrowser());
    271 
    272  waitForOrientationChangeEventInIframe = isOrientationChangeEventEmitted(
    273    iframeBrowsingContext
    274  );
    275  waitForScreenOrientationChangeEventInIframe =
    276    isWindowScreenOrientationChangeEventEmitted(iframeBrowsingContext);
    277 
    278  // We're directly calling the command here as there's no way to do such action from the UI.
    279  await ui.commands.targetConfigurationCommand.updateConfiguration({
    280    rdmPaneOrientation: {
    281      type: "portrait-primary",
    282      angle: 0,
    283    },
    284  });
    285  is(
    286    await waitForOrientationChangeEvent,
    287    false,
    288    "orientationchange event was not dispatched after trying to set the same orientation again"
    289  );
    290  is(
    291    await waitForScreenOrientationChangeEvent,
    292    false,
    293    "on window.screen.orientation, change event was not dispatched after trying to set the same orientation again"
    294  );
    295 
    296  is(
    297    await waitForOrientationChangeEventInIframe,
    298    false,
    299    "orientationchange event was not dispatched in iframe after trying to set the same orientation again"
    300  );
    301  is(
    302    await waitForScreenOrientationChangeEventInIframe,
    303    false,
    304    "on window.screen.orientation, change event was not dispatched in iframe after trying to set the same orientation again"
    305  );
    306 });
    307 
    308 function getScreenOrientationType(browserOrBrowsingContext) {
    309  return SpecialPowers.spawn(browserOrBrowsingContext, [], () => {
    310    return content.screen.orientation.type;
    311  });
    312 }
    313 
    314 function getScreenOrientationAngle(browserOrBrowsingContext) {
    315  return SpecialPowers.spawn(
    316    browserOrBrowsingContext,
    317    [],
    318    () => content.screen.orientation.angle
    319  );
    320 }
    321 
    322 function getInitialScreenOrientationType(browserOrBrowsingContext) {
    323  return SpecialPowers.spawn(
    324    browserOrBrowsingContext,
    325    [],
    326    () => content.wrappedJSObject.initialOrientationType
    327  );
    328 }
    329 
    330 function getInitialScreenOrientationAngle(browserOrBrowsingContext) {
    331  return SpecialPowers.spawn(
    332    browserOrBrowsingContext,
    333    [],
    334    () => content.wrappedJSObject.initialOrientationAngle
    335  );
    336 }
    337 
    338 async function isOrientationChangeEventEmitted(browserOrBrowsingContext) {
    339  const onTimeout = wait(1000).then(() => "TIMEOUT");
    340  const onOrientationChangeEvent = SpecialPowers.spawn(
    341    browserOrBrowsingContext,
    342    [],
    343    () => {
    344      content.eventController = new content.AbortController();
    345      return new Promise(resolve => {
    346        content.window.addEventListener(
    347          "orientationchange",
    348          () => {
    349            resolve();
    350          },
    351          {
    352            signal: content.eventController.signal,
    353            once: true,
    354          }
    355        );
    356      });
    357    }
    358  );
    359 
    360  const result = await Promise.race([onTimeout, onOrientationChangeEvent]);
    361 
    362  // Remove the event listener
    363  await SpecialPowers.spawn(browserOrBrowsingContext, [], () => {
    364    content.eventController.abort();
    365    delete content.eventController;
    366  });
    367 
    368  return result !== "TIMEOUT";
    369 }
    370 
    371 async function isWindowScreenOrientationChangeEventEmitted(
    372  browserOrBrowsingContext
    373 ) {
    374  const onTimeout = wait(1000).then(() => "TIMEOUT");
    375 
    376  const onScreenOrientationChangeEvent = SpecialPowers.spawn(
    377    browserOrBrowsingContext,
    378    [],
    379    () => {
    380      content.eventController4ScreenOrientationChange =
    381        new content.AbortController();
    382      return new Promise(resolve => {
    383        content.window.screen.orientation.addEventListener(
    384          "change",
    385          () => resolve(),
    386          {
    387            signal: content.eventController4ScreenOrientationChange.signal,
    388            once: true,
    389          }
    390        );
    391      });
    392    }
    393  );
    394 
    395  const result = await Promise.race([
    396    onTimeout,
    397    onScreenOrientationChangeEvent,
    398  ]);
    399 
    400  await SpecialPowers.spawn(browserOrBrowsingContext, [], () => {
    401    content.eventController4ScreenOrientationChange.abort();
    402    delete content.eventController4ScreenOrientationChange;
    403  });
    404 
    405  return result !== "TIMEOUT";
    406 }