Bug 1191597 part 3 - Convert fullscreen-api-keys to a browser chrome test. draft
authorXidorn Quan <quanxunzhen@gmail.com>
Fri, 08 Jan 2016 12:55:08 +1100
changeset 319974 30ede73c4b964754c93e2e4323fd9d05b01121c9
parent 319973 5c5196bdd8252d52c0504dc1fdbb178e92d50dd0
child 319975 540b9761d59fbd3e937c941f6e0ad155b2ac4b46
push id9116
push userxquan@mozilla.com
push dateFri, 08 Jan 2016 09:53:58 +0000
bugs1191597
milestone46.0a1
Bug 1191597 part 3 - Convert fullscreen-api-keys to a browser chrome test.
dom/html/test/browser.ini
dom/html/test/browser_fullscreen-api-keys.js
dom/html/test/file_fullscreen-api-keys.html
dom/html/test/mochitest.ini
dom/html/test/test_fullscreen-api.html
--- a/dom/html/test/browser.ini
+++ b/dom/html/test/browser.ini
@@ -1,19 +1,21 @@
 [DEFAULT]
 support-files =
   bug592641_img.jpg
   dummy_page.html
   file_bug649778.html
   file_bug649778.html^headers^
+  file_fullscreen-api-keys.html
   head.js
 
 [browser_bug592641.js]
 [browser_bug649778.js]
 skip-if = e10s # Bug ?????? - leaked until shutdown [nsGlobalWindow #16 about:blank]
 [browser_bug1081537.js]
 [browser_bug1108547.js]
 support-files =
   file_bug1108547-1.html
   file_bug1108547-2.html
   file_bug1108547-3.html
 [browser_DOMDocElementInserted.js]
+[browser_fullscreen-api-keys.js]
 [browser_fullscreen-contextmenu-esc.js]
new file mode 100644
--- /dev/null
+++ b/dom/html/test/browser_fullscreen-api-keys.js
@@ -0,0 +1,164 @@
+"use strict";
+
+/** Test for Bug 545812 **/
+
+// List of key codes which should exit full-screen mode.
+const kKeyList = [
+  { code: "VK_ESCAPE", suppressed: true},
+  { code: "VK_F11",    suppressed: false},
+];
+
+function frameScript() {
+  let doc = content.document;
+  addMessageListener("Test:RequestFullscreen", () => {
+    doc.body.mozRequestFullScreen();
+  });
+  addMessageListener("Test:DispatchUntrustedKeyEvents", msg => {
+    var evt = new content.CustomEvent("Test:DispatchKeyEvents", {
+      detail: { code: msg.data }
+    });
+    content.dispatchEvent(evt);
+  });
+
+  doc.addEventListener("mozfullscreenchange", () => {
+    sendAsyncMessage("Test:FullscreenChanged", !!doc.mozFullScreenElement);
+  });
+
+  function keyHandler(evt) {
+    sendAsyncMessage("Test:KeyReceived", {
+      type: evt.type,
+      keyCode: evt.keyCode
+    });
+  }
+  doc.addEventListener("keydown", keyHandler, true);
+  doc.addEventListener("keyup", keyHandler, true);
+  doc.addEventListener("keypress", keyHandler, true);
+
+  function waitUntilActive() {
+    if (doc.docShell.isActive && doc.hasFocus()) {
+      sendAsyncMessage("Test:Activated");
+    } else {
+      setTimeout(waitUntilActive, 10);
+    }
+  }
+  waitUntilActive();
+}
+
+var gMessageManager;
+
+function listenOneMessage(aMsg, aListener) {
+  function listener({ data }) {
+    gMessageManager.removeMessageListener(aMsg, listener);
+    aListener(data);
+  }
+  gMessageManager.addMessageListener(aMsg, listener);
+}
+
+function promiseOneMessage(aMsg) {
+  return new Promise(resolve => listenOneMessage(aMsg, resolve));
+}
+
+function captureUnexpectedFullscreenChange() {
+  ok(false, "Caught an unexpected fullscreen change");
+}
+
+function* temporaryRemoveUnexpectedFullscreenChangeCapture(callback) {
+  gMessageManager.removeMessageListener(
+    "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
+  yield* callback();
+  gMessageManager.addMessageListener(
+    "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
+}
+
+function captureUnexpectedKeyEvent(type) {
+  ok(false, `Caught an unexpected ${type} event`);
+}
+
+function* temporaryRemoveUnexpectedKeyEventCapture(callback) {
+  gMessageManager.removeMessageListener(
+    "Test:KeyReceived", captureUnexpectedKeyEvent);
+  yield* callback();
+  gMessageManager.addMessageListener(
+    "Test:KeyReceived", captureUnexpectedKeyEvent);
+}
+
+function* receiveExpectedKeyEvents(keyCode) {
+  info("Waiting for key events");
+  let events = ["keydown", "keypress", "keyup"];
+  while (events.length > 0) {
+    let evt = yield promiseOneMessage("Test:KeyReceived");
+    let expected = events.shift();
+    is(evt.type, expected, `Should receive a ${expected} event`);
+    is(evt.keyCode, keyCode,
+       `Should receive the event with key code ${keyCode}`);
+  }
+}
+
+const kPage = "http://example.org/browser/" +
+              "dom/html/test/file_fullscreen-api-keys.html";
+
+add_task(function* () {
+  yield pushPrefs(
+    ["full-screen-api.transition-duration.enter", "0 0"],
+    ["full-screen-api.transition-duration.leave", "0 0"]);
+
+  let tab = gBrowser.addTab(kPage);
+  let browser = tab.linkedBrowser;
+  gBrowser.selectedTab = tab;
+  registerCleanupFunction(() => gBrowser.removeTab(tab));
+  yield waitForDocLoadComplete();
+
+  gMessageManager = browser.messageManager;
+  gMessageManager.loadFrameScript(
+    "data:,(" + frameScript.toString() + ")();", false);
+
+  // Wait for the document being actived, so that
+  // fullscreen request won't be denied.
+  yield promiseOneMessage("Test:Activated");
+
+  // Register listener to capture unexpected events
+  gMessageManager.addMessageListener(
+    "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
+  gMessageManager.addMessageListener(
+    "Test:KeyReceived", captureUnexpectedKeyEvent);
+  registerCleanupFunction(() => {
+    gMessageManager.removeMessageListener(
+      "Test:FullscreenChanged", captureUnexpectedFullscreenChange);
+    gMessageManager.removeMessageListener(
+      "Test:KeyReceived", captureUnexpectedKeyEvent);
+  });
+
+  for (let {code, suppressed} of kKeyList) {
+    var keyCode = KeyEvent["DOM_" + code];
+    info(`Test keycode ${code} (${keyCode})`);
+
+    info("Enter fullscreen");
+    yield* temporaryRemoveUnexpectedFullscreenChangeCapture(function* () {
+      gMessageManager.sendAsyncMessage("Test:RequestFullscreen");
+      let state = yield promiseOneMessage("Test:FullscreenChanged");
+      ok(state, "The content should have entered fullscreen");
+      ok(document.mozFullScreenElement,
+         "The chrome should also be in fullscreen");
+    });
+
+    info("Dispatch untrusted key events from content");
+    yield* temporaryRemoveUnexpectedKeyEventCapture(function* () {
+      gMessageManager.sendAsyncMessage("Test:DispatchUntrustedKeyEvents", code);
+      yield* receiveExpectedKeyEvents(keyCode);
+    });
+
+    info("Send trusted key events");
+    yield* temporaryRemoveUnexpectedFullscreenChangeCapture(function* () {
+      yield* temporaryRemoveUnexpectedKeyEventCapture(function* () {
+        EventUtils.synthesizeKey(code, {});
+        if (!suppressed) {
+          yield* receiveExpectedKeyEvents(keyCode);
+        }
+        let state = yield promiseOneMessage("Test:FullscreenChanged");
+        ok(!state, "The content should have exited fullscreen");
+        ok(!document.mozFullScreenElement,
+           "The chrome should also have exited fullscreen");
+      });
+    });
+  }
+});
--- a/dom/html/test/file_fullscreen-api-keys.html
+++ b/dom/html/test/file_fullscreen-api-keys.html
@@ -1,129 +1,32 @@
- <!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=545812
-
-Test that restricted key pressed drop documents out of DOM full-screen mode.
-
--->
+<!DOCTYPE html>
+<html lang="en">
 <head>
-  <title>Test for Bug 545812</title>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="application/javascript" src="file_fullscreen-utils.js"></script>
-  <style>
-  body {
-    background-color: black;
-  }
-  </style>
+  <meta charset="UTF-8">
 </head>
 <body>
-
-<script type="application/javascript">
-
-/** Test for Bug 545812 **/
-
-// List of key codes which should exit full-screen mode.
-var keyList = [
-  { code: "VK_ESCAPE", suppressed: true},
-  { code: "VK_F11",    suppressed: false},
-];
-
-function ok(condition, msg) {
-  opener.ok(condition, "[keys] " + msg);
-}
-
-function is(a, b, msg) {
-  opener.is(a, b, "[keys] " + msg);
-}
-
-var gKeyTestIndex = 0;
-var gKeyName;
-var gKeyCode;
-var gKeySuppressed;
-var gKeyReceived = false;
+<script>
+window.addEventListener("Test:DispatchKeyEvents", aEvent => {
+  var keyCode = KeyEvent["DOM_" + aEvent.detail.code];
 
-function keyHandler(event) {
-  gKeyReceived = true;
-}
-
-function checkKeyEffect() {
-  is(gKeySuppressed, !gKeyReceived, "Should not receive key events for " + gKeyName);
-  is(document.mozFullScreen, false, "Should exit full-screen mode for " + gKeyName + " press");
-  if (gKeyTestIndex < keyList.length) {
-    setTimeout(testNextKey, 0);
-  } else {
-    opener.nextTest();
-  }
-}
-
-function testTrustedKeyEvents() {
   document.body.focus();
-  gKeyReceived = false;
-  addFullscreenChangeContinuation("exit", checkKeyEffect);
-  synthesizeKey(gKeyName, {});
-}
-
-function testScriptInitiatedKeyEvents() {
-  // Script initiated untrusted key events should not cause full-screen exit.
-  document.body.focus();
-  gKeyReceived = false;
   var evt = document.createEvent("KeyEvents");
   evt.initKeyEvent("keydown", true, true, window,
                    false, false, false, false,
-                   gKeyCode, 0);
+                   keyCode, 0);
   document.body.dispatchEvent(evt);
 
   evt = document.createEvent("KeyEvents");
   evt.initKeyEvent("keypress", true, true, window,
                    false, false, false, false,
-                   gKeyCode, 0);
+                   keyCode, 0);
   document.body.dispatchEvent(evt);
 
   evt = document.createEvent("KeyEvents");
   evt.initKeyEvent("keyup", true, true, window,
                    false, false, false, false,
-                   gKeyCode, 0);
+                   keyCode, 0);
   document.body.dispatchEvent(evt);
-  
-  ok(gKeyReceived, "dispatchEvent should dispatch events synchronously");
-  ok(document.mozFullScreen,
-     "Should remain in full-screen mode for script initiated key events for " + gKeyName);
-}
-
-function testNextKey() {
-  if (!document.mozFullScreen) {
-    // Async request fullscreen to avoid the request be accidentally
-    // cancelled due to unfinished clean-up of exiting fullscreen.
-    setTimeout(() => {
-      addFullscreenChangeContinuation("enter", reallyTestNextKey);
-      document.body.mozRequestFullScreen();
-    }, 0);
-  }
-  else {
-    reallyTestNextKey();
-  }
-}
-
-function reallyTestNextKey() {
-  ok(document.mozFullScreen, "Must be in full-screen mode");
-
-  gKeyName = keyList[gKeyTestIndex].code;
-  gKeyCode = KeyEvent["DOM_" + gKeyName];
-  gKeySuppressed = keyList[gKeyTestIndex].suppressed;
-  gKeyTestIndex++;
-
-  testScriptInitiatedKeyEvents();
-  testTrustedKeyEvents();
-}
-
-window.addEventListener("keydown", keyHandler, true);
-window.addEventListener("keyup", keyHandler, true);
-window.addEventListener("keypress", keyHandler, true);
-
-function begin() {
-  testNextKey();
-}
+});
 </script>
-</pre>
 </body>
 </html>
--- a/dom/html/test/mochitest.ini
+++ b/dom/html/test/mochitest.ini
@@ -41,17 +41,16 @@ support-files =
   file_bug209275_1.html
   file_bug209275_2.html
   file_bug209275_3.html
   file_bug297761.html
   file_bug417760.png
   file_bug893537.html
   file_formSubmission_img.jpg
   file_formSubmission_text.txt
-  file_fullscreen-api-keys.html
   file_fullscreen-api.html
   file_fullscreen-denied-inner.html
   file_fullscreen-denied.html
   file_fullscreen-esc-exit-inner.html
   file_fullscreen-esc-exit.html
   file_fullscreen-hidden.html
   file_fullscreen-multiple-inner.html
   file_fullscreen-multiple.html
--- a/dom/html/test/test_fullscreen-api.html
+++ b/dom/html/test/test_fullscreen-api.html
@@ -28,17 +28,16 @@ SimpleTest.requestFlakyTimeout("untriage
 // run in an iframe, which by default will not have the allowfullscreen
 // attribute set, so full-screen won't work.
 var gTestWindows = [
   "file_fullscreen-multiple.html",
   "file_fullscreen-rollback.html",
   "file_fullscreen-esc-exit.html",
   "file_fullscreen-denied.html",
   "file_fullscreen-api.html",
-  "file_fullscreen-api-keys.html",
   "file_fullscreen-plugins.html",
   "file_fullscreen-hidden.html",
   "file_fullscreen-svg-element.html",
   "file_fullscreen-navigation.html",
   "file_fullscreen-scrollbar.html",
   "file_fullscreen-selector.html",
   "file_fullscreen-top-layer.html",
   "file_fullscreen-nested.html",