Bug 957213 - Rewrite tests for inputmethod to avoid intermittent errors. r=yxl, a=test-only
authorJan Jongboom <janjongboom@gmail.com>
Wed, 25 Jun 2014 07:58:00 -0400
changeset 208875 dd4a95d01ad80daa091ffb76fa1629de30e95f17
parent 208874 34ef96fed1e12717d0ce0af6d1fdaa4e36ad2d5d
child 208876 8acfd1375a84e2acc63d0c18059a45ca027620c9
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyxl, test-only
bugs957213
milestone32.0a2
Bug 957213 - Rewrite tests for inputmethod to avoid intermittent errors. r=yxl, a=test-only
dom/inputmethod/mochitest/file_inputmethod.html
dom/inputmethod/mochitest/mochitest.ini
dom/inputmethod/mochitest/test_bug944397.html
dom/inputmethod/mochitest/test_bug953044.html
--- a/dom/inputmethod/mochitest/file_inputmethod.html
+++ b/dom/inputmethod/mochitest/file_inputmethod.html
@@ -1,18 +1,25 @@
 <html>
 <body>
 <script>
   var im = navigator.mozInputMethod;
   if (im) {
-    // Automatically append location hash to current input field.
-    im.oninputcontextchange = function() {
-      var ctx = im.inputcontext;
-      if (ctx) {
-        intervalId = setTimeout(function() {
-          ctx.replaceSurroundingText(location.hash);
-        }, 0);
-      }
-    };
+    im.oninputcontextchange = onIcc;
+
+    if (im.inputcontext) {
+      onIcc();
+    }
+  }
+
+  function onIcc() {
+    var ctx = im.inputcontext;
+    if (ctx) {
+      ctx.replaceSurroundingText(location.hash).then(function() {
+        /* Happy flow */
+      }, function(err) {
+        dump('ReplaceSurroundingText failed ' + err + '\n');
+      });
+    }
   }
 </script>
 </body>
 </html>
--- a/dom/inputmethod/mochitest/mochitest.ini
+++ b/dom/inputmethod/mochitest/mochitest.ini
@@ -6,12 +6,13 @@ support-files =
   file_inputmethod.html
   file_test_app.html
   file_test_sendkey_cancel.html
   file_test_sms_app.html
 
 [test_basic.html]
 [test_bug944397.html]
 [test_bug949059.html]
+[test_bug953044.html]
 [test_bug960946.html]
 [test_bug978918.html]
 [test_delete_focused_element.html]
 [test_sendkey_cancel.html]
--- a/dom/inputmethod/mochitest/test_bug944397.html
+++ b/dom/inputmethod/mochitest/test_bug944397.html
@@ -18,94 +18,94 @@ https://bugzilla.mozilla.org/show_bug.cg
 inputmethod_setup(function() {
   runTest();
 });
 
 // The frame script running in file_test_app.html.
 function appFrameScript() {
   let input = content.document.getElementById('test-input');
   input.oninput = function() {
-    dump('oninput was called in file_test_app.html.');
-    sendAsyncMessage('test:InputMethod:oninput', {});
+    sendAsyncMessage('test:InputMethod:oninput', {
+      value: input.value
+    });
   };
-
-  /*
-   * Bug 957213. Sometimes we need to refocus the input field to avoid
-   * intermittent test failure.
-   */
-  content.setInterval(function() {
-    input.focus();
-  }, 500);
 }
 
 function runTest() {
-  let timeoutId = null;
-
-  // Create an app frame to recieve keyboard inputs.
-  let app = document.createElement('iframe');
-  app.src = 'file_test_app.html';
-  app.setAttribute('mozbrowser', true);
-  document.body.appendChild(app);
-  app.addEventListener('mozbrowserloadend', function() {
-    let mm = SpecialPowers.getBrowserFrameMessageManager(app);
-    mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false);
-    mm.addMessageListener("test:InputMethod:oninput", function() {
-      ok(true, 'Keyboard input was received.');
-      clearTimeout(timeoutId);
-      inputmethod_cleanup();
-    });
-  });
+  let app, keyboard;
 
-  // Create a browser frame to load the input method app.
-  let keyboard = document.createElement('iframe');
-  keyboard.setAttribute('mozbrowser', true);
-  document.body.appendChild(keyboard);
-
-  // Bug 953044 setInputMethodActive(false) before input method app loads should
-  // always succeed.
-  let req = keyboard.setInputMethodActive(false);
-  req.onsuccess = function() {
-    ok(true, 'setInputMethodActive before loading succeeded.');
-  };
-
-  req.onerror = function() {
-   ok(false, 'setInputMethodActive before loading failed: ' + this.error.name);
-   clearTimeout(timeoutId);
-   inputmethod_cleanup();
-  };
+  /**
+   * So this test does the following:
+   * 1. Create a mozbrowser iframe with a text field in it, and focus the text field
+   * 2. 100ms. after loading we create new keyboard iframe, that will try to execute
+   *    replaceSurroundingText on the current active inputcontext
+   * 3. That should trigger 'input' event on the said text field
+   * 4. And if that happens we know everything is OK
+   */
 
   let path = location.pathname;
-  let imeUrl = location.protocol + '//' + location.host +
-               path.substring(0, path.lastIndexOf('/')) +
-               '/file_inputmethod.html#data';
-  SpecialPowers.pushPermissions([{
-    type: 'input',
-    allow: true,
-    context: imeUrl
-  }], function() {
-     let req = keyboard.setInputMethodActive(true);
+  let basePath = location.protocol + '//' + location.host +
+               path.substring(0, path.lastIndexOf('/'));
 
-     req.onsuccess = function() {
-       ok(true, 'setInputMethodActive succeeded.');
-     };
+  // STEP 1: Create an app frame to recieve keyboard inputs.
+  function step1() {
+    app = document.createElement('iframe');
+    app.src = basePath + '/file_test_app.html';
+    app.setAttribute('mozbrowser', true);
+    document.body.appendChild(app);
+    app.addEventListener('mozbrowserloadend', function() {
+      let mm = SpecialPowers.getBrowserFrameMessageManager(app);
+      mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false);
+      mm.addMessageListener("test:InputMethod:oninput", function(ev) {
+        step4(SpecialPowers.wrap(ev).json.value);
+      });
+
+      step2();
+    });
+  }
+
+  function step2() {
+    // STEP 2a: Create a browser frame to load the input method app.
+    keyboard = document.createElement('iframe');
+    keyboard.setAttribute('mozbrowser', true);
+    document.body.appendChild(keyboard);
+
+    // STEP 2b: Grant input privileges to the keyboard iframe
+    let imeUrl = basePath + '/file_inputmethod.html#data';
 
-     req.onerror = function() {
-       ok(false, 'setInputMethodActive failed: ' + this.error.name);
-       inputmethod_cleanup();
-     };
+    SpecialPowers.pushPermissions([{
+      type: 'input',
+      allow: true,
+      context: imeUrl
+    }], function() {
+      // STEP 2c: Tell Gecko to use this iframe as its keyboard app
+      let req = keyboard.setInputMethodActive(true);
+
+      req.onsuccess = function() {
+        ok(true, 'setInputMethodActive succeeded.');
+      };
 
-     // Loads the input method app to the browser frame after a delay.
-     SpecialPowers.DOMWindowUtils.focus(app);
-     setTimeout(function() {
-       keyboard.src = imeUrl;
-       timeoutId = setTimeout(function() {
-         inputmethod_cleanup();
-         ok(false, 'Failed to generate keyboard input.');
-       }, 20000);
-     }, 100);
-  });
+      req.onerror = function() {
+        ok(false, 'setInputMethodActive failed: ' + this.error.name);
+        inputmethod_cleanup();
+      };
+
+      // STEP 3: Loads the input method app to the browser frame after a delay.
+      setTimeout(function() {
+        keyboard.src = imeUrl;
+      }, 100);
+    });
+  }
+
+  function step4(val) {
+    ok(true, 'Keyboard input was received.');
+    is(val, '#dataYuan', 'Input value');
+    inputmethod_cleanup();
+  }
+
+  step1();
 }
 
 </script>
 </pre>
 </body>
 </html>
 
new file mode 100644
--- /dev/null
+++ b/dom/inputmethod/mochitest/test_bug953044.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=953044
+-->
+<head>
+  <title>Basic test for InputMethod API.</title>
+  <script type="application/javascript;version=1.7" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript;version=1.7" src="inputmethod_common.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=953044">Mozilla Bug 953044</a>
+<p id="display"></p>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.7">
+
+inputmethod_setup(function() {
+  runTest();
+});
+
+function runTest() {
+  // Create an app frame to recieve keyboard inputs.
+  let app = document.createElement('iframe');
+  app.src = 'file_test_app.html';
+  app.setAttribute('mozbrowser', true);
+  document.body.appendChild(app);
+
+  // Create a browser frame to load the input method app.
+  let keyboard = document.createElement('iframe');
+  keyboard.setAttribute('mozbrowser', true);
+  document.body.appendChild(keyboard);
+
+  // Bug 953044 setInputMethodActive(false) before input method app loads should
+  // always succeed.
+  let req = keyboard.setInputMethodActive(false);
+  req.onsuccess = function() {
+    ok(true, 'setInputMethodActive before loading succeeded.');
+    inputmethod_cleanup();
+  };
+
+  req.onerror = function() {
+    ok(false, 'setInputMethodActive before loading failed: ' + this.error.name);
+    inputmethod_cleanup();
+  };
+}
+
+</script>
+</pre>
+</body>
+</html>
+