Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  head.js   Sprache: JAVA

 
/* eslint no-unused-vars: ["error", {vars: "local", args: "none"}] */

const { PermissionTestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/PermissionTestUtils.sys.mjs"
);
const { PromptTestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/PromptTestUtils.sys.mjs"
);

const RELATIVE_DIR = "toolkit/mozapps/extensions/test/xpinstall/";

const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
const TESTROOT2 = "http://example.org/browser/" + RELATIVE_DIR;
const PROMPT_URL = "chrome://global/content/commonDialog.xhtml";
const ADDONS_URL = "chrome://mozapps/content/extensions/aboutaddons.html";
const PREF_LOGGING_ENABLED = "extensions.logging.enabled";
const PREF_INSTALL_REQUIREBUILTINCERTS =
  "extensions.install.requireBuiltInCerts";
const PREF_INSTALL_REQUIRESECUREORIGIN =
  "extensions.install.requireSecureOrigin";
const CHROME_NAME = "mochikit";

function getChromeRoot(path) {
  if (path === undefined) {
    return "chrome://" + CHROME_NAME + "/content/browser/" + RELATIVE_DIR;
  }
  return getRootDirectory(path);
}

function extractChromeRoot(path) {
  var chromeRootPath = getChromeRoot(path);
  var jar = getJar(chromeRootPath);
  if (jar) {
    var tmpdir = extractJarToTmp(jar);
    return "file://" + tmpdir.path + "/";
  }
  return chromeRootPath;
}

function setInstallTriggerPrefs() {
  Services.prefs.setBoolPref("extensions.InstallTrigger.enabled"true);
  Services.prefs.setBoolPref("extensions.InstallTriggerImpl.enabled"true);
  // Relax the user input requirements while running tests that call this test helper.
  Services.prefs.setBoolPref("xpinstall.userActivation.required"false);
  registerCleanupFunction(clearInstallTriggerPrefs);
}

function clearInstallTriggerPrefs() {
  Services.prefs.clearUserPref("extensions.InstallTrigger.enabled");
  Services.prefs.clearUserPref("extensions.InstallTriggerImpl.enabled");
  Services.prefs.clearUserPref("xpinstall.userActivation.required");
}

/**
 * This is a test harness designed to handle responding to UI during the process
 * of installing an XPI. A test can set callbacks to hear about specific parts
 * of the sequence.
 * Before use setup must be called and finish must be called afterwards.
 */

var Harness = {
  // If set then the callback is called when an install is attempted and
  // software installation is disabled.
  installDisabledCallback: null,
  // If set then the callback is called when an install is attempted and
  // then canceled.
  installCancelledCallback: null,
  // If set then the callback will be called when an install's origin is blocked.
  installOriginBlockedCallback: null,
  // If set then the callback will be called when an install is blocked by the
  // whitelist. The callback should return true to continue with the install
  // anyway.
  installBlockedCallback: null,
  // If set will be called in the event of authentication being needed to get
  // the xpi. Should return a 2 element array of username and password, or
  // null to not authenticate.
  authenticationCallback: null,
  // If set this will be called to allow checking the contents of the xpinstall
  // confirmation dialog. The callback should return true to continue the install.
  installConfirmCallback: null,
  // If set will be called when downloading of an item has begun.
  downloadStartedCallback: null,
  // If set will be called during the download of an item.
  downloadProgressCallback: null,
  // If set will be called when an xpi fails to download.
  downloadFailedCallback: null,
  // If set will be called when an xpi download is cancelled.
  downloadCancelledCallback: null,
  // If set will be called when downloading of an item has ended.
  downloadEndedCallback: null,
  // If set will be called when installation by the extension manager of an xpi
  // item starts
  installStartedCallback: null,
  // If set will be called when an xpi fails to install.
  installFailedCallback: null,
  // If set will be called when each xpi item to be installed completes
  // installation.
  installEndedCallback: null,
  // If set will be called when all triggered items are installed or the install
  // is canceled.
  installsCompletedCallback: null,
  // If set the harness will wait for this DOM event before calling
  // installsCompletedCallback
  finalContentEvent: null,

  waitingForEvent: false,
  pendingCount: null,
  installCount: null,
  runningInstalls: null,

  waitingForFinish: false,

  // A unique value to return from the installConfirmCallback to indicate that
  // the install UI shouldn't be closed automatically
  leaveOpen: {},

  // Setup and tear down functions
  setup(win = window) {
    if (!this.waitingForFinish) {
      waitForExplicitFinish();
      this.waitingForFinish = true;

      Services.prefs.setBoolPref(PREF_INSTALL_REQUIRESECUREORIGIN, false);
      Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
      Services.prefs.setBoolPref(
        "network.cookieJarSettings.unblocked_for_testing",
        true
      );

      Services.obs.addObserver(this"addon-install-started");
      Services.obs.addObserver(this"addon-install-disabled");
      Services.obs.addObserver(this"addon-install-origin-blocked");
      Services.obs.addObserver(this"addon-install-blocked");
      Services.obs.addObserver(this"addon-install-failed");

      // For browser_auth tests which trigger auth dialogs.
      Services.obs.addObserver(this"common-dialog-loaded");

      this._boundWin = Cu.getWeakReference(win); // need this so our addon manager listener knows which window to use.
      AddonManager.addInstallListener(this);
      AddonManager.addAddonListener(this);

      win.addEventListener("popupshown"this);
      win.PanelUI.notificationPanel.addEventListener("popupshown"this);

      var self = this;
      registerCleanupFunction(async function () {
        Services.prefs.clearUserPref(PREF_LOGGING_ENABLED);
        Services.prefs.clearUserPref(PREF_INSTALL_REQUIRESECUREORIGIN);
        Services.prefs.clearUserPref(
          "network.cookieJarSettings.unblocked_for_testing"
        );

        Services.obs.removeObserver(self, "addon-install-started");
        Services.obs.removeObserver(self, "addon-install-disabled");
        Services.obs.removeObserver(self, "addon-install-origin-blocked");
        Services.obs.removeObserver(self, "addon-install-blocked");
        Services.obs.removeObserver(self, "addon-install-failed");

        Services.obs.removeObserver(self, "common-dialog-loaded");

        AddonManager.removeInstallListener(self);
        AddonManager.removeAddonListener(self);

        win.removeEventListener("popupshown", self);
        win.PanelUI.notificationPanel.removeEventListener("popupshown", self);
        win = null;

        let aInstalls = await AddonManager.getAllInstalls();
        is(
          aInstalls.length,
          0,
          "Should be no active installs at the end of the test"
        );
        await Promise.all(
          aInstalls.map(async function (aInstall) {
            info(
              "Install for " +
                aInstall.sourceURI +
                " is in state " +
                aInstall.state
            );
            if (aInstall.state == AddonManager.STATE_INSTALLED) {
              await aInstall.addon.uninstall();
            } else {
              aInstall.cancel();
            }
          })
        );
      });
    }

    this.installCount = 0;
    this.pendingCount = 0;
    this.runningInstalls = [];
  },

  finish(win = window) {
    // Some tests using this harness somehow finish leaving
    // the addon-installed panel open.  hiding here addresses
    // that which fixes the rest of the tests.  Since no test
    // here cares about this panel, we just need it to close.
    win.PanelUI.notificationPanel.hidePopup();
    win.AppMenuNotifications.removeNotification("addon-installed");
    delete this._boundWin;
    finish();
  },

  endTest() {
    let callback = this.installsCompletedCallback;
    let count = this.installCount;

    is(this.runningInstalls.length, 0, "Should be no running installs left");
    this.runningInstalls.forEach(function (aInstall) {
      info(
        "Install for " + aInstall.sourceURI + " is in state " + aInstall.state
      );
    });

    this.installOriginBlockedCallback = null;
    this.installBlockedCallback = null;
    this.authenticationCallback = null;
    this.installConfirmCallback = null;
    this.downloadStartedCallback = null;
    this.downloadProgressCallback = null;
    this.downloadCancelledCallback = null;
    this.downloadFailedCallback = null;
    this.downloadEndedCallback = null;
    this.installStartedCallback = null;
    this.installFailedCallback = null;
    this.installEndedCallback = null;
    this.installsCompletedCallback = null;
    this.runningInstalls = null;

    if (callback) {
      executeSoon(() => callback(count));
    }
  },

  promptReady(dialog) {
    let promptType = dialog.args.promptType;

    switch (promptType) {
      case "alert":
      case "alertCheck":
      case "confirmCheck":
      case "confirm":
      case "confirmEx":
        PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 });
        break;
      case "promptUserAndPass":
        // This is a login dialog, hopefully an authentication prompt
        // for the xpi.
        if (this.authenticationCallback) {
          var auth = this.authenticationCallback();
          if (auth && auth.length == 2) {
            PromptTestUtils.handlePrompt(dialog, {
              loginInput: auth[0],
              passwordInput: auth[1],
              buttonNumClick: 0,
            });
          } else {
            PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 1 });
          }
        } else {
          PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 1 });
        }
        break;
      default:
        ok(false"prompt type " + promptType + " not handled in test.");
        break;
    }
  },

  popupReady(panel) {
    if (this.installBlockedCallback) {
      ok(false"Should have been blocked by the whitelist");
    }
    this.pendingCount++;

    // If there is a confirm callback then its return status determines whether
    // to install the items or not. If not the test is over.
    let result = true;
    if (this.installConfirmCallback) {
      result = this.installConfirmCallback(panel);
      if (result === this.leaveOpen) {
        return;
      }
    }

    const panelEl = panel.closest("panel");
    const panelState = panelEl.state;

    const clickButton = () => {
      info(`Clicking ${result ? "primary" : "secondary"} panel button`);
      Assert.equal(
        panelEl.state,
        "open",
        "Expect panel state to be open when clicking panel buttons"
      );
      if (!result) {
        panel.secondaryButton.click();
      } else {
        panel.button.click();
      }
    };

    if (panelState === "showing") {
      info(
        "panel is still showing, wait for 'popup-shown' topic to be notified"
      );
      BrowserUtils.promiseObserved(
        "popup-shown",
        shownPanel => shownPanel === panelEl
      ).then(clickButton);
    } else {
      clickButton();
    }
  },

  handleEvent(event) {
    if (event.type === "popupshown") {
      if (event.target == event.view.PanelUI.notificationPanel) {
        event.view.PanelUI.notificationPanel.hidePopup();
      } else if (event.target.firstElementChild) {
        let popupId = event.target.firstElementChild.getAttribute("popupid");
        if (popupId === "addon-webext-permissions") {
          this.popupReady(event.target.firstElementChild);
        } else if (popupId === "addon-install-failed") {
          event.target.firstElementChild.button.click();
        }
      }
    }
  },

  // Install blocked handling

  installDisabled(installInfo) {
    ok(
      !!this.installDisabledCallback,
      "Installation shouldn't have been disabled"
    );
    if (this.installDisabledCallback) {
      this.installDisabledCallback(installInfo);
    }
    this.expectingCancelled = true;
    this.expectingCancelled = false;
    this.endTest();
  },

  installCancelled(installInfo) {
    if (this.expectingCancelled) {
      return;
    }

    ok(
      !!this.installCancelledCallback,
      "Installation shouldn't have been cancelled"
    );
    if (this.installCancelledCallback) {
      this.installCancelledCallback(installInfo);
    }
    this.endTest();
  },

  installOriginBlocked(installInfo) {
    ok(!!this.installOriginBlockedCallback, "Shouldn't have been blocked");
    if (this.installOriginBlockedCallback) {
      this.installOriginBlockedCallback(installInfo);
    }
    this.endTest();
  },

  installBlocked(installInfo) {
    ok(
      !!this.installBlockedCallback,
      "Shouldn't have been blocked by the whitelist"
    );
    if (
      this.installBlockedCallback &&
      this.installBlockedCallback(installInfo)
    ) {
      this.installBlockedCallback = null;
      installInfo.install();
    } else {
      this.expectingCancelled = true;
      installInfo.installs.forEach(function (install) {
        install.cancel();
      });
      this.expectingCancelled = false;
      this.endTest();
    }
  },

  // Addon Install Listener

  onNewInstall(install) {
    this.runningInstalls.push(install);

    if (this.finalContentEvent && !this.waitingForEvent) {
      this.waitingForEvent = true;
      info("Waiting for " + this.finalContentEvent);
      BrowserTestUtils.waitForContentEvent(
        this._boundWin.get().gBrowser.selectedBrowser,
        this.finalContentEvent,
        true,
        null,
        true
      ).then(() => {
        info("Saw " + this.finalContentEvent + "," + this.waitingForEvent);
        this.waitingForEvent = false;
        if (this.pendingCount == 0) {
          this.endTest();
        }
      });
    }
  },

  onDownloadStarted(install) {
    this.pendingCount++;
    if (this.downloadStartedCallback) {
      this.downloadStartedCallback(install);
    }
  },

  onDownloadProgress(install) {
    if (this.downloadProgressCallback) {
      this.downloadProgressCallback(install);
    }
  },

  onDownloadEnded(install) {
    if (this.downloadEndedCallback) {
      this.downloadEndedCallback(install);
    }
  },

  onDownloadCancelled(install) {
    isnot(
      this.runningInstalls.indexOf(install),
      -1,
      "Should only see cancelations for started installs"
    );
    this.runningInstalls.splice(this.runningInstalls.indexOf(install), 1);

    if (
      this.downloadCancelledCallback &&
      this.downloadCancelledCallback(install) === false
    ) {
      return;
    }
    this.checkTestEnded();
  },

  onDownloadFailed(install) {
    if (this.downloadFailedCallback) {
      this.downloadFailedCallback(install);
    }
    this.checkTestEnded();
  },

  onInstallStarted(install) {
    if (this.installStartedCallback) {
      this.installStartedCallback(install);
    }
  },

  async onInstallEnded(install, addon) {
    this.installCount++;
    if (this.installEndedCallback) {
      await this.installEndedCallback(install, addon);
    }
    this.checkTestEnded();
  },

  onInstallFailed(install) {
    if (this.installFailedCallback) {
      this.installFailedCallback(install);
    }
    this.checkTestEnded();
  },

  onUninstalled(addon) {
    let idx = this.runningInstalls.findIndex(install => install.addon == addon);
    if (idx != -1) {
      this.runningInstalls.splice(idx, 1);
      this.checkTestEnded();
    }
  },

  onInstallCancelled(install) {
    // This is ugly.  We have a bunch of tests that cancel installs
    // but don't expect this event to be raised.
    // For at least one test (browser_whitelist3.js), we used to generate
    // onDownloadCancelled when the user cancelled the installation at the
    // confirmation prompt.  We're now generating onInstallCancelled instead
    // of onDownloadCancelled but making this code unconditional breaks a
    // bunch of other tests.  Ugh.
    let idx = this.runningInstalls.indexOf(install);
    if (idx != -1) {
      this.runningInstalls.splice(this.runningInstalls.indexOf(install), 1);
      this.checkTestEnded();
    }
  },

  checkTestEnded() {
    if (--this.pendingCount == 0 && !this.waitingForEvent) {
      this.endTest();
    }
  },

  // nsIObserver

  observe(subject, topic) {
    var installInfo = subject.wrappedJSObject;
    switch (topic) {
      case "addon-install-started":
        is(
          this.runningInstalls.length,
          installInfo.installs.length,
          "Should have seen the expected number of installs started"
        );
        break;
      case "addon-install-disabled":
        this.installDisabled(installInfo);
        break;
      case "addon-install-cancelled":
        this.installCancelled(installInfo);
        break;
      case "addon-install-origin-blocked":
        this.installOriginBlocked(installInfo);
        break;
      case "addon-install-blocked":
        this.installBlocked(installInfo);
        break;
      case "addon-install-failed":
        installInfo.installs.forEach(function (aInstall) {
          isnot(
            this.runningInstalls.indexOf(aInstall),
            -1,
            "Should only see failures for started installs"
          );

          ok(
            aInstall.error != 0 || aInstall.addon.appDisabled,
            "Failed installs should have an error or be appDisabled"
          );

          this.runningInstalls.splice(
            this.runningInstalls.indexOf(aInstall),
            1
          );
        }, this);
        break;
      case "common-dialog-loaded":
        this.promptReady(subject.Dialog);
        break;
    }
  },

  QueryInterface: ChromeUtils.generateQI(["nsIObserver"]),
};

Messung V0.5
C=93 H=98 G=95

¤ Dauer der Verarbeitung: 0.32 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge