tor-browser

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

NavigationUtils.js (5369B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 // /////////////////////////////////////////////////////////////////////////
      6 //
      7 // Utilities for navigation tests
      8 //
      9 // /////////////////////////////////////////////////////////////////////////
     10 
     11 var body = "This frame was navigated.";
     12 var target_url = "navigation_target_url.html";
     13 
     14 var popup_body = "This is a popup";
     15 var target_popup_url = "navigation_target_popup_url.html";
     16 
     17 // /////////////////////////////////////////////////////////////////////////
     18 // Functions that navigate frames
     19 // /////////////////////////////////////////////////////////////////////////
     20 
     21 function navigateByLocation(wnd) {
     22  try {
     23    wnd.location = target_url;
     24  } catch (ex) {
     25    // We need to keep our finished frames count consistent.
     26    // Oddly, this ends up simulating the behavior of IE7.
     27    window.open(target_url, "_blank", "width=10,height=10");
     28  }
     29 }
     30 
     31 function navigateByOpen(name) {
     32  window.open(target_url, name, "width=10,height=10");
     33 }
     34 
     35 function navigateByForm(name) {
     36  var form = document.createElement("form");
     37  form.action = target_url;
     38  form.method = "POST";
     39  form.target = name;
     40  document.body.appendChild(form);
     41  form.submit();
     42 }
     43 
     44 var hyperlink_count = 0;
     45 
     46 function navigateByHyperlink(name) {
     47  var link = document.createElement("a");
     48  link.href = target_url;
     49  link.target = name;
     50  link.id = "navigation_hyperlink_" + hyperlink_count++;
     51  document.body.appendChild(link);
     52  sendMouseEvent({ type: "click" }, link.id);
     53 }
     54 
     55 // /////////////////////////////////////////////////////////////////////////
     56 // Functions that call into Mochitest framework
     57 // /////////////////////////////////////////////////////////////////////////
     58 
     59 async function isNavigated(wnd, message) {
     60  var result = null;
     61  try {
     62    result = await SpecialPowers.spawn(wnd, [], () =>
     63      this.content.document.body.innerHTML.trim()
     64    );
     65  } catch (ex) {
     66    result = ex;
     67  }
     68  is(result, body, message);
     69 }
     70 
     71 function isBlank(wnd, message) {
     72  var result = null;
     73  try {
     74    result = wnd.document.body.innerHTML.trim();
     75  } catch (ex) {
     76    result = ex;
     77  }
     78  is(result, "This is a blank document.", message);
     79 }
     80 
     81 function isAccessible(wnd, message) {
     82  try {
     83    wnd.document.body.innerHTML;
     84    ok(true, message);
     85  } catch (ex) {
     86    ok(false, message);
     87  }
     88 }
     89 
     90 function isInaccessible(wnd, message) {
     91  try {
     92    wnd.document.body.innerHTML;
     93    ok(false, message);
     94  } catch (ex) {
     95    ok(true, message);
     96  }
     97 }
     98 
     99 function delay(msec) {
    100  return new Promise(resolve => setTimeout(resolve, msec));
    101 }
    102 
    103 // /////////////////////////////////////////////////////////////////////////
    104 // Functions that uses SpecialPowers.spawn
    105 // /////////////////////////////////////////////////////////////////////////
    106 
    107 async function waitForFinishedFrames(numFrames) {
    108  SimpleTest.requestFlakyTimeout("Polling");
    109 
    110  var finishedWindows = new Set();
    111 
    112  async function searchForFinishedFrames(win) {
    113    try {
    114      let { href, bodyText, readyState } = await SpecialPowers.spawn(
    115        win,
    116        [],
    117        () => {
    118          return {
    119            href: this.content.location.href,
    120            bodyText:
    121              this.content.document.body &&
    122              this.content.document.body.textContent.trim(),
    123            readyState: this.content.document.readyState,
    124          };
    125        }
    126      );
    127 
    128      if (
    129        (href.endsWith(target_url) || href.endsWith(target_popup_url)) &&
    130        (bodyText == body || bodyText == popup_body) &&
    131        readyState == "complete"
    132      ) {
    133        finishedWindows.add(SpecialPowers.getBrowsingContextID(win));
    134      }
    135    } catch (e) {
    136      // This may throw if a frame is not fully initialized, in which
    137      // case we'll handle it in a later iteration.
    138    }
    139 
    140    for (let i = 0; i < win.frames.length; i++) {
    141      await searchForFinishedFrames(win.frames[i]);
    142    }
    143  }
    144 
    145  while (finishedWindows.size < numFrames) {
    146    await delay(500);
    147 
    148    for (let win of SpecialPowers.getGroupTopLevelWindows(window)) {
    149      win = SpecialPowers.unwrap(win);
    150      await searchForFinishedFrames(win);
    151    }
    152  }
    153 
    154  if (finishedWindows.size > numFrames) {
    155    throw new Error("Too many frames loaded.");
    156  }
    157 }
    158 
    159 async function getFramesByName(name) {
    160  let results = [];
    161  for (let win of SpecialPowers.getGroupTopLevelWindows(window)) {
    162    win = SpecialPowers.unwrap(win);
    163    if (
    164      (await SpecialPowers.spawn(win, [], () => this.content.name)) === name
    165    ) {
    166      results.push(win);
    167    }
    168  }
    169 
    170  return results;
    171 }
    172 
    173 async function cleanupWindows() {
    174  for (let win of SpecialPowers.getGroupTopLevelWindows(window)) {
    175    win = SpecialPowers.unwrap(win);
    176    if (win.closed) {
    177      continue;
    178    }
    179 
    180    let href = "";
    181    try {
    182      href = await SpecialPowers.spawn(
    183        win,
    184        [],
    185        () =>
    186          this.content && this.content.location && this.content.location.href
    187      );
    188    } catch (error) {
    189      // SpecialPowers.spawn(win, ...) throws if win is closed. We did
    190      // our best to not call it on a closed window, but races happen.
    191      if (!win.closed) {
    192        throw error;
    193      }
    194    }
    195 
    196    if (
    197      href &&
    198      (href.endsWith(target_url) || href.endsWith(target_popup_url))
    199    ) {
    200      win.close();
    201    }
    202  }
    203 }