summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/general/browser_save_video_frame.js
blob: e9b8a0475dd654289c6962268e9d25c1c1261d74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

const VIDEO_URL = "http://mochi.test:8888/browser/browser/base/content/test/general/web_video.html";

/**
 * mockTransfer.js provides a utility that lets us mock out
 * the "Save File" dialog.
 */
Cc["@mozilla.org/moz/jssubscript-loader;1"]
  .getService(Ci.mozIJSSubScriptLoader)
  .loadSubScript("chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js",
                 this);

/**
 * Creates and returns an nsIFile for a new temporary save
 * directory.
 *
 * @return nsIFile
 */
function createTemporarySaveDirectory() {
  let saveDir = Cc["@mozilla.org/file/directory_service;1"]
                  .getService(Ci.nsIProperties)
                  .get("TmpD", Ci.nsIFile);
  saveDir.append("testsavedir");
  if (!saveDir.exists())
    saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
  return saveDir;
}
/**
 * MockTransfer exposes a "mockTransferCallback" global which
 * allows us to define a callback to be called once the mock file
 * selector has selected where to save the file.
 */
function waitForTransferComplete() {
  return new Promise((resolve) => {
    mockTransferCallback = () => {
      ok(true, "Transfer completed");
      resolve();
    }
  });
}

/**
 * Given some browser, loads a framescript that right-clicks
 * on the video1 element to spawn a contextmenu.
 */
function rightClickVideo(browser) {
  let frame_script = () => {
    const Ci = Components.interfaces;
    let utils = content.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIDOMWindowUtils);

    let document = content.document;
    let video = document.getElementById("video1");
    let rect = video.getBoundingClientRect();

    /* Synthesize a click in the center of the video. */
    let left = rect.left + (rect.width / 2);
    let top = rect.top + (rect.height / 2);

    utils.sendMouseEvent("contextmenu", left, top,
                         2, /* aButton */
                         1, /* aClickCount */
                         0  /* aModifiers */);
  };
  let mm = browser.messageManager;
  mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
}

/**
 * Loads a page with a <video> element, right-clicks it and chooses
 * to save a frame screenshot to the disk. Completes once we've
 * verified that the frame has been saved to disk.
 */
add_task(function*() {
  let MockFilePicker = SpecialPowers.MockFilePicker;
  MockFilePicker.init(window);

  // Create the folder the video will be saved into.
  let destDir = createTemporarySaveDirectory();
  let destFile = destDir.clone();

  MockFilePicker.displayDirectory = destDir;
  MockFilePicker.showCallback = function(fp) {
    destFile.append(fp.defaultString);
    MockFilePicker.returnFiles = [destFile];
    MockFilePicker.filterIndex = 1; // kSaveAsType_URL
  };

  mockTransferRegisterer.register();

  // Make sure that we clean these things up when we're done.
  registerCleanupFunction(function () {
    mockTransferRegisterer.unregister();
    MockFilePicker.cleanup();
    destDir.remove(true);
  });

  let tab = gBrowser.addTab();
  gBrowser.selectedTab = tab;
  let browser = tab.linkedBrowser;
  info("Loading video tab");
  yield promiseTabLoadEvent(tab, VIDEO_URL);
  info("Video tab loaded.");

  let context = document.getElementById("contentAreaContextMenu");
  let popupPromise = promisePopupShown(context);

  info("Synthesizing right-click on video element");
  rightClickVideo(browser);
  info("Waiting for popup to fire popupshown.");
  yield popupPromise;
  info("Popup fired popupshown");

  let saveSnapshotCommand = document.getElementById("context-video-saveimage");
  let promiseTransfer = waitForTransferComplete()
  info("Firing save snapshot command");
  saveSnapshotCommand.doCommand();
  context.hidePopup();
  info("Waiting for transfer completion");
  yield promiseTransfer;
  info("Transfer complete");
  gBrowser.removeTab(tab);
});