Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/browser/components/downloads/test/browser/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Quelle  head.js   Sprache: JAVA

 
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */


/**
 * Provides infrastructure for automated download components tests.
 */


// Globals

ChromeUtils.defineESModuleGetters(this, {
  Downloads: "resource://gre/modules/Downloads.sys.mjs",
  DownloadsCommon: "resource:///modules/DownloadsCommon.sys.mjs",
  FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
  HttpServer: "resource://testing-common/httpd.sys.mjs",
  PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
});

let gTestTargetFile = new FileUtils.File(
  PathUtils.join(
    Services.dirsvc.get("TmpD", Ci.nsIFile).path,
    "dm-ui-test.file"
  )
);

gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
Services.prefs.setIntPref("security.dialog_enable_delay", 0);

// The file may have been already deleted when removing a paused download.
// Also clear security.dialog_enable_delay pref.
registerCleanupFunction(async () => {
  Services.prefs.clearUserPref("security.dialog_enable_delay");

  if (await IOUtils.exists(gTestTargetFile.path)) {
    info("removing " + gTestTargetFile.path);
    if (Services.appinfo.OS === "WINNT") {
      // We need to make the file writable to delete it on Windows.
      await IOUtils.setPermissions(gTestTargetFile.path, 0o600);
    }
    await IOUtils.remove(gTestTargetFile.path);
  }
});

const DATA_PDF = atob(
  "JVBERi0xLjANCjEgMCBvYmo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iaiAyIDAgb2JqPDwvVHlwZS9QYWdlcy9LaWRzWzMgMCBSXS9Db3VudCAxPj5lbmRvYmogMyAwIG9iajw8L1R5cGUvUGFnZS9NZWRpYUJveFswIDAgMyAzXT4+ZW5kb2JqDQp4cmVmDQowIDQNCjAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDAwMDAxMCAwMDAwMCBuDQowMDAwMDAwMDUzIDAwMDAwIG4NCjAwMDAwMDAxMDIgMDAwMDAgbg0KdHJhaWxlcjw8L1NpemUgNC9Sb290IDEgMCBSPj4NCnN0YXJ0eHJlZg0KMTQ5DQolRU9G"
);

const TEST_DATA_SHORT = "This test string is downloaded.";

/**
 * This is an internal reference that should not be used directly by tests.
 */

var _gDeferResponses = Promise.withResolvers();

/**
 * Ensures that all the interruptible requests started after this function is
 * called won't complete until the continueResponses function is called.
 *
 * Normally, the internal HTTP server returns all the available data as soon as
 * a request is received.  In order for some requests to be served one part at a
 * time, special interruptible handlers are registered on the HTTP server.  This
 * allows testing events or actions that need to happen in the middle of a
 * download.
 *
 * For example, the handler accessible at the httpUri("interruptible.txt")
 * address returns the TEST_DATA_SHORT text, then it may block until the
 * continueResponses method is called.  At this point, the handler sends the
 * TEST_DATA_SHORT text again to complete the response.
 *
 * If an interruptible request is started before the function is called, it may
 * or may not be blocked depending on the actual sequence of events.
 */

function mustInterruptResponses() {
  // If there are pending blocked requests, allow them to complete.  This is
  // done to prevent requests from being blocked forever, but should not affect
  // the test logic, since previously started requests should not be monitored
  // on the client side anymore.
  _gDeferResponses.resolve();

  info("Interruptible responses will be blocked midway.");
  _gDeferResponses = Promise.withResolvers();
}

/**
 * Allows all the current and future interruptible requests to complete.
 */

function continueResponses() {
  info("Interruptible responses are now allowed to continue.");
  _gDeferResponses.resolve();
}

/**
 * Fails this response and allows the future interruptible requests to complete.
 */

function failResponses() {
  info("Interruptible response is failed and next ones allowed to continue.");
  _gDeferResponses.reject();
}

/**
 * Creates a download, which could be interrupted in the middle of it's progress.
 */

function promiseInterruptibleDownload(extension = ".txt") {
  let interruptibleFile = new FileUtils.File(
    PathUtils.join(PathUtils.tempDir, `interruptible${extension}`)
  );
  interruptibleFile.createUnique(
    Ci.nsIFile.NORMAL_FILE_TYPE,
    FileUtils.PERMS_FILE
  );

  registerCleanupFunction(async () => {
    if (await IOUtils.exists(interruptibleFile.path)) {
      if (Services.appinfo.OS === "WINNT") {
        // We need to make the file writable to delete it on Windows.
        await IOUtils.setPermissions(interruptibleFile.path, 0o600);
      }
      await IOUtils.remove(interruptibleFile.path);
    }
  });

  return Downloads.createDownload({
    source: httpUrl("interruptible.txt"),
    target: { path: interruptibleFile.path },
  });
}

// Asynchronous support subroutines

async function createDownloadedFile(pathname, contents) {
  let file = new FileUtils.File(pathname);
  if (file.exists()) {
    info(`File at ${pathname} already exists`);
  }
  // No post-test cleanup necessary; tmp downloads directory is already removed after each test
  await IOUtils.writeUTF8(pathname, contents);
  ok(file.exists(), `Created ${pathname}`);
  return file;
}

async function openContextMenu(itemElement, win = window) {
  let popupShownPromise = BrowserTestUtils.waitForEvent(
    itemElement.ownerDocument,
    "popupshown"
  );
  EventUtils.synthesizeMouseAtCenter(
    itemElement,
    {
      type: "contextmenu",
      button: 2,
    },
    win
  );
  let { target } = await popupShownPromise;
  return target;
}

function promiseFocus() {
  return new Promise(resolve => {
    waitForFocus(resolve);
  });
}

function promisePanelOpened() {
  if (DownloadsPanel.panel && DownloadsPanel.panel.state == "open") {
    return Promise.resolve();
  }

  return new Promise(resolve => {
    // Hook to wait until the panel is shown.
    let originalOnPopupShown = DownloadsPanel._onPopupShown;
    DownloadsPanel._onPopupShown = function () {
      DownloadsPanel._onPopupShown = originalOnPopupShown;
      originalOnPopupShown.apply(this, arguments);

      // Defer to the next tick of the event loop so that we don't continue
      // processing during the DOM event handler itself.
      setTimeout(resolve, 0);
    };
  });
}

function promiseDownloadFinished(list) {
  return new Promise(resolve => {
    list.addView({
      onDownloadChanged(download) {
        download.launchWhenSucceeded = false;
        if (download.succeeded || download.error) {
          list.removeView(this);
          resolve(download);
        }
      },
    });
  });
}

async function task_resetState() {
  // Remove all downloads.
  let publicList = await Downloads.getList(Downloads.PUBLIC);
  let downloads = await publicList.getAll();
  for (let download of downloads) {
    await publicList.remove(download);
    if (await IOUtils.exists(download.target.path)) {
      await download.finalize(true);
      info("removing " + download.target.path);
      if (Services.appinfo.OS === "WINNT") {
        // We need to make the file writable to delete it on Windows.
        await IOUtils.setPermissions(download.target.path, 0o600);
      }
      await IOUtils.remove(download.target.path);
    }
  }

  DownloadsPanel.hidePanel();

  await promiseFocus();
}

async function task_addDownloads(aItems) {
  let startTimeMs = Date.now();

  let publicList = await Downloads.getList(Downloads.PUBLIC);
  for (let item of aItems) {
    let source = {
      url: "http://www.example.com/test-download.txt",
      ...item.source,
    };
    let target =
      item.target instanceof Ci.nsIFile
        ? item.target
        : {
            path: gTestTargetFile.path,
            ...item.target,
          };

    let download = {
      source,
      target,
      succeeded: item.state == DownloadsCommon.DOWNLOAD_FINISHED,
      canceled:
        item.state == DownloadsCommon.DOWNLOAD_CANCELED ||
        item.state == DownloadsCommon.DOWNLOAD_PAUSED,
      deleted: item.deleted ?? false,
      error:
        item.state == DownloadsCommon.DOWNLOAD_FAILED
          ? new Error("Failed.")
          : null,
      hasPartialData: item.state == DownloadsCommon.DOWNLOAD_PAUSED,
      hasBlockedData: item.hasBlockedData || false,
      openDownloadsListOnStart: item.openDownloadsListOnStart ?? true,
      contentType: item.contentType,
      startTime: new Date(startTimeMs++),
    };
    // `"errorObj" in download` must be false when there's no error.
    if (item.errorObj) {
      download.errorObj = item.errorObj;
    }
    download = await Downloads.createDownload(download);
    await publicList.add(download);
    await download.refresh();
  }
}

async function task_openPanel() {
  await promiseFocus();

  let promise = promisePanelOpened();
  DownloadsPanel.showPanel();
  await promise;

  await BrowserTestUtils.waitForMutationCondition(
    DownloadsView.richListBox,
    { attributeFilter: ["disabled"] },
    () => !DownloadsView.richListBox.hasAttribute("disabled")
  );
}

async function setDownloadDir() {
  let tmpDir = PathUtils.join(
    PathUtils.tempDir,
    "testsavedir" + Math.floor(Math.random() * 2 ** 32)
  );
  // Create this dir if it doesn't exist (ignores existing dirs)
  await IOUtils.makeDirectory(tmpDir);
  registerCleanupFunction(async function () {
    try {
      await IOUtils.remove(tmpDir, { recursive: true });
    } catch (e) {
      console.error(e);
    }
  });
  Services.prefs.setIntPref("browser.download.folderList", 2);
  Services.prefs.setCharPref("browser.download.dir", tmpDir);
  return tmpDir;
}

let gHttpServer = null;
let gShouldServeInterruptibleFileAsDownload = false;
function startServer() {
  gHttpServer = new HttpServer();
  gHttpServer.start(-1);
  registerCleanupFunction(() => {
    return new Promise(resolve => {
      // Ensure all the pending HTTP requests have a chance to finish.
      continueResponses();
      // Stop the HTTP server, calling resolve when it's done.
      gHttpServer.stop(resolve);
    });
  });

  gHttpServer.identity.setPrimary(
    "http",
    "www.example.com",
    gHttpServer.identity.primaryPort
  );

  gHttpServer.registerPathHandler("/file1.txt", (request, response) => {
    response.setStatusLine(null, 200, "OK");
    response.write("file1");
    response.processAsync();
    response.finish();
  });
  gHttpServer.registerPathHandler("/file2.txt", (request, response) => {
    response.setStatusLine(null, 200, "OK");
    response.write("file2");
    response.processAsync();
    response.finish();
  });
  gHttpServer.registerPathHandler("/file3.txt", (request, response) => {
    response.setStatusLine(null, 200, "OK");
    response.write("file3");
    response.processAsync();
    response.finish();
  });

  gHttpServer.registerPathHandler(
    "/interruptible.txt",
    function (aRequest, aResponse) {
      info("Interruptible request started.");

      // Process the first part of the response.
      aResponse.processAsync();
      aResponse.setHeader("Content-Type""text/plain"false);
      if (gShouldServeInterruptibleFileAsDownload) {
        aResponse.setHeader("Content-Disposition""attachment");
      }
      aResponse.setHeader(
        "Content-Length",
        "" + TEST_DATA_SHORT.length * 2,
        false
      );
      aResponse.write(TEST_DATA_SHORT);

      // Wait on the current deferred object, then finish the request.
      _gDeferResponses.promise
        .then(
          () => {
            aResponse.write(TEST_DATA_SHORT);
            aResponse.finish();
            info("Interruptible request finished.");
          },
          () => {
            // Don't send data, so that it looks truncated.
            aResponse.finish();
            info("Interruptible request failed.");
          }
        )
        .catch(console.error);
    }
  );
}

function serveInterruptibleAsDownload() {
  gShouldServeInterruptibleFileAsDownload = true;
  registerCleanupFunction(
    () => (gShouldServeInterruptibleFileAsDownload = false)
  );
}

function httpUrl(aFileName) {
  return (
    "http://localhost:" + gHttpServer.identity.primaryPort + "/" + aFileName
  );
}

function openLibrary(aLeftPaneRoot) {
  let library = window.openDialog(
    "chrome://browser/content/places/places.xhtml",
    "",
    "chrome,toolbar=yes,dialog=no,resizable",
    aLeftPaneRoot
  );

  return new Promise(resolve => {
    waitForFocus(resolve, library);
  });
}

/**
 * Waits for a download to reach its progress, in case it has not
 * reached the expected progress already.
 *
 * @param aDownload
 *        The Download object to wait upon.
 *
 * @return {Promise}
 * @resolves When the download has reached its progress.
 * @rejects Never.
 */

function promiseDownloadHasProgress(aDownload, progress) {
  return new Promise(resolve => {
    // Wait for the download to reach its progress.
    let onchange = function () {
      let downloadInProgress =
        !aDownload.stopped && aDownload.progress == progress;
      let downloadFinished =
        progress == 100 &&
        aDownload.progress == progress &&
        aDownload.succeeded;
      if (downloadInProgress || downloadFinished) {
        info(`Download reached ${progress}%`);
        aDownload.onchange = null;
        resolve();
      }
    };

    // Register for the notification, but also call the function directly in
    // case the download already reached the expected progress.
    aDownload.onchange = onchange;
    onchange();
  });
}

/**
 * Waits for a given button to become visible.
 */

function promiseButtonShown(id) {
  let dwu = window.windowUtils;
  return BrowserTestUtils.waitForCondition(() => {
    let target = document.getElementById(id);
    let bounds = dwu.getBoundsWithoutFlushing(target);
    return bounds.width > 0 && bounds.height > 0;
  }, `Waiting for button ${id} to have non-0 size`);
}

async function simulateDropAndCheck(win, dropTarget, urls) {
  let dragData = [[{ type: "text/plain", data: urls.join("\n") }]];
  let list = await Downloads.getList(Downloads.ALL);

  let added = new Set();
  let succeeded = new Set();
  await new Promise(resolve => {
    let view = {
      onDownloadAdded(download) {
        added.add(download.source.url);
      },
      onDownloadChanged(download) {
        if (!added.has(download.source.url)) {
          return;
        }
        if (!download.succeeded) {
          return;
        }
        succeeded.add(download.source.url);
        if (succeeded.size == urls.length) {
          list.removeView(view).then(resolve);
        }
      },
    };
    list.addView(view).then(function () {
      EventUtils.synthesizeDrop(dropTarget, dropTarget, dragData, "link", win);
    });
  });

  for (let url of urls) {
    ok(added.has(url), url + " is added to download");
  }
}

/**
 * This is a temporary workaround for frequent intermittents.
 * For some reason the download target size is not updated, even if the code
 * is "apparently" already executing and awaiting for refresh().
 * TODO(Bug 1814364): Figure out a proper fix for this.
 */

async function expectNonZeroDownloadTargetSize(downloadTarget) {
  if (!downloadTarget.size) {
    await downloadTarget.refresh();
  }
  return downloadTarget.size;
}

Messung V0.5
C=99 H=100 G=99

¤ Dauer der Verarbeitung: 0.26 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.