Bug 981997 - Fix test for setInputMethodActive and dead object error. r=yxl

This commit is contained in:
Tim Chien 2014-03-12 08:45:27 -04:00
parent e43c49d443
commit a40e20d646
5 changed files with 166 additions and 73 deletions

View File

@ -715,17 +715,24 @@ BrowserElementParent.prototype = {
// Deactivate the old input method if needed.
if (activeInputFrame && isActive) {
let reqOld = XPCNativeWrapper.unwrap(activeInputFrame)
.setInputMethodActive(false);
reqOld.onsuccess = function() {
if (Cu.isDeadWrapper(activeInputFrame)) {
// If the activeInputFrame is already a dead object,
// we should simply set it to null directly.
activeInputFrame = null;
this._sendSetInputMethodActiveDOMRequest(req, isActive);
}.bind(this);
reqOld.onerror = function() {
Services.DOMRequest.fireErrorAsync(req,
'Failed to deactivate the old input method: ' +
reqOld.error + '.');
};
} else {
let reqOld = XPCNativeWrapper.unwrap(activeInputFrame)
.setInputMethodActive(false);
reqOld.onsuccess = function() {
activeInputFrame = null;
this._sendSetInputMethodActiveDOMRequest(req, isActive);
}.bind(this);
reqOld.onerror = function() {
Services.DOMRequest.fireErrorAsync(req,
'Failed to deactivate the old input method: ' +
reqOld.error + '.');
};
}
} else {
this._sendSetInputMethodActiveDOMRequest(req, isActive);
}

View File

@ -10,6 +10,12 @@ browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function setup() {
let appInfo = SpecialPowers.Cc['@mozilla.org/xre/app-info;1']
.getService(SpecialPowers.Ci.nsIXULAppInfo);
if (appInfo.name != 'B2G') {
SpecialPowers.Cu.import("resource://gre/modules/Keyboard.jsm", window);
}
SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", true);
SpecialPowers.setBoolPref("dom.mozInputMethod.testing", true);
SpecialPowers.addPermission('input-manage', true, document);
@ -18,78 +24,154 @@ function setup() {
function tearDown() {
SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", false);
SpecialPowers.setBoolPref("dom.mozInputMethod.testing", false);
SpecialPowers.removePermission("input-manage", document);
SpecialPowers.removePermission('input-manage', document);
SimpleTest.finish();
}
function runTest() {
// Create an input field to receive string from input method iframes.
let input = document.createElement('input');
input.type = 'text';
document.body.appendChild(input);
let path = location.pathname;
let imeUrl = location.protocol + '//' + location.host +
path.substring(0, path.lastIndexOf('/')) +
'/file_inputmethod.html';
SpecialPowers.pushPermissions([{
type: 'input',
allow: true,
context: {
url: imeUrl,
appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
isInBrowserElement: true
}
}], createFrames);
}
var gFrames = [];
var gInputFrame;
function createFrames() {
// Create two input method iframes.
let frames = [];
let loadendCount = 0;
let countLoadend = function() {
ok(this.setInputMethodActive, 'Can access setInputMethodActive.');
if (this === gInputFrame) {
// The frame script running in the frame where the input is hosted.
let appFrameScript = function appFrameScript() {
let input = content.document.body.firstElementChild;
input.oninput = function() {
sendAsyncMessage('test:InputMethod:oninput', this.value);
};
/*
* Bug 957213. Sometimes we need to refocus the input field to avoid
* intermittent test failure.
*/
content.setInterval(function() {
input.focus();
}, 500);
}
// Inject frame script to receive input.
let mm = SpecialPowers.getBrowserFrameMessageManager(gInputFrame);
mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false);
mm.addMessageListener("test:InputMethod:oninput", next);
}
loadendCount++;
if (loadendCount === 3) {
startTest();
}
};
// Create an input field to receive string from input method iframes.
gInputFrame = document.createElement('iframe');
SpecialPowers.wrap(gInputFrame).mozbrowser = true;
gInputFrame.src =
'data:text/html,<input autofocus value="hello" />' +
'<p>This is targetted mozbrowser frame.</p>';
document.body.appendChild(gInputFrame);
gInputFrame.addEventListener('mozbrowserloadend', countLoadend);
for (let i = 0; i < 2; i++) {
frames[i] = document.createElement('iframe');
SpecialPowers.wrap(frames[i]).mozbrowser = true;
let frame = gFrames[i] = document.createElement('iframe');
SpecialPowers.wrap(gFrames[i]).mozbrowser = true;
// When the input method iframe is activated, it will send the URL
// hash to current focused element. We set different hash to each
// iframe so that iframes can be differentiated by their hash.
frames[i].src = 'file_inputmethod.html#' + i;
frames[i].setAttribute('mozapp', location.href.replace(/[^/]+$/, 'file_inputmethod.webapp'));
document.body.appendChild(frames[i]);
frame.src = 'file_inputmethod.html#' + i;
document.body.appendChild(frame);
frame.addEventListener('mozbrowserloadend', countLoadend);
}
}
let count = 0;
function startTest() {
// Set focus to the input field and wait for input methods' inputting.
SpecialPowers.DOMWindowUtils.focus(input);
var timerId = null;
input.oninput = function() {
// The texts sent from the first and the second input method are '#0' and
// '#1' respectively.
switch (count) {
case 1:
is(input.value, '#0', 'Failed to get correct input from the first iframe.');
testNextInputMethod();
break;
case 2:
is(input.value, '#0#1', 'Failed to get correct input from the second iframe.');
// Do nothing and wait for the next input from the second iframe.
count++;
break;
case 3:
is(input.value, '#0#1#1', 'Failed to get correct input from the second iframe.');
// Receive the second input from the second iframe.
count++;
// Deactive the second iframe.
frames[1].setInputMethodActive(false);
// Wait for a short while to ensure the second iframe is not active any
// more.
timerId = setTimeout(function() {
ok(true, 'Successfully deactivate the second iframe.');
tearDown();
}, 1000);
break;
default:
ok(false, 'Failed to deactivate the second iframe.');
clearTimeout(timerId);
SpecialPowers.DOMWindowUtils.focus(gInputFrame);
let req0 = gFrames[0].setInputMethodActive(true);
req0.onsuccess = function() {
ok(true, 'setInputMethodActive succeeded (0).');
};
req0.onerror = function() {
ok(false, 'setInputMethodActive failed (0): ' + this.error.name);
};
}
var gTimerId = null;
var gCount = 0;
function next(msg) {
gCount++;
let wrappedMsg = SpecialPowers.wrap(msg);
let value = wrappedMsg.data;
// The texts sent from the first and the second input method are '#0' and
// '#1' respectively.
switch (gCount) {
case 1:
is(value, '#0hello',
'Failed to get correct input from the first iframe.');
let req1 = gFrames[1].setInputMethodActive(true);
req1.onsuccess = function() {
ok(true, 'setInputMethodActive succeeded (1).');
};
req1.onerror = function() {
ok(false, 'setInputMethodActive failed (1): ' + this.error.name);
};
break;
case 2:
is(value, '#0#1hello',
'Failed to get correct input from the second iframe.');
// Do nothing and wait for the next input from the second iframe.
break;
case 3:
is(value, '#0#1#1hello',
'Failed to get correct input from the second iframe.');
// Receive the second input from the second iframe.
// Deactive the second iframe.
let req3 = gFrames[1].setInputMethodActive(false);
req3.onsuccess = function() {
ok(true, 'setInputMethodActive(false) succeeded (3).');
};
req3.onerror = function() {
ok(false, 'setInputMethodActive(false) failed (3): ' + this.error.name);
};
// Wait for a short while to ensure the second iframe is not active any
// more.
gTimerId = setTimeout(function() {
ok(true, 'Successfully deactivate the second iframe.');
tearDown();
break;
}
}, 1000);
break;
case 4:
ok(false, 'Failed to deactivate the second iframe in time.');
clearTimeout(gTimerId);
tearDown();
break;
}
ok(frames[0].setInputMethodActive, 'Cannot access setInputMethodActive.');
function testNextInputMethod() {
frames[count++].setInputMethodActive(true);
}
// Wait for a short while to let input method get ready.
setTimeout(function() {
testNextInputMethod();
}, 500);
}
setup();

View File

@ -1,3 +1,4 @@
<!DOCTYPE HTML>
<html>
<body>
<script>
@ -8,14 +9,18 @@
im.oninputcontextchange = function() {
var ctx = im.inputcontext;
if (ctx) {
dump('inputcontext is received for input method ' + location.hash + '\n');
intervalId = setInterval(function() {
dump('sending text in input method ' + location.hash + '\n');
ctx.replaceSurroundingText(location.hash);
}, 500);
} else {
dump('inputcontext is removed for input method ' + location.hash + '\n');
clearInterval(intervalId);
}
};
}
</script>
<p>This frame representing the input method frame.</p>
</body>
</html>

View File

@ -52,6 +52,7 @@ skip-if = toolkit=='gonk'
[test_browserElement_oop_SecurityChange.html]
skip-if = toolkit == 'android' #TIMED_OUT, bug 766586
[test_browserElement_oop_SendEvent.html]
[test_browserElement_oop_SetInputMethodActive.html]
[test_browserElement_oop_SetVisible.html]
[test_browserElement_oop_SetVisibleFrames.html]
[test_browserElement_oop_SetVisibleFrames2.html]
@ -75,6 +76,3 @@ disabled = bug 924771
disabled = bug 924771
[test_browserElement_oop_ExposableURI.html]
disabled = bug 924771
# Disabled until we fix bug 906096.
[test_browserElement_oop_SetInputMethodActive.html]
disabled = bug 906096

View File

@ -47,6 +47,7 @@ support-files =
browserElement_ScrollEvent.js
browserElement_SecurityChange.js
browserElement_SendEvent.js
browserElement_SetInputMethodActive.js
browserElement_SetVisible.js
browserElement_SetVisibleFrames.js
browserElement_SetVisibleFrames2.js
@ -97,6 +98,7 @@ support-files =
file_empty_script.js
file_focus.html
file_http_401_response.sjs
file_inputmethod.html
file_post_request.html
file_wyciwyg.html
@ -163,6 +165,9 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_inproc_SecurityChange.html]
skip-if = toolkit == 'android' || (toolkit == 'gonk' && !debug) # android(TIMED_OUT, bug 766586) androidx86(TIMED_OUT, bug 766586)
[test_browserElement_inproc_SendEvent.html]
# The setInputMethodActive() tests will timed out on Android
[test_browserElement_inproc_SetInputMethodActive.html]
skip-if = (os == "android")
[test_browserElement_inproc_SetVisible.html]
[test_browserElement_inproc_SetVisibleFrames.html]
[test_browserElement_inproc_SetVisibleFrames2.html]
@ -178,10 +183,6 @@ skip-if = (toolkit == 'gonk' && !debug)
[test_browserElement_inproc_XFrameOptionsDeny.html]
[test_browserElement_inproc_XFrameOptionsSameOrigin.html]
[test_browserElement_oop_NextPaint.html]
# Disabled until we fix bug 906096.
[test_browserElement_inproc_SetInputMethodActive.html]
disabled = bug 906096
support-files = browserElement_SetInputMethodActive.js file_inputmethod.html
# Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
[test_browserElement_inproc_Reload.html]
disabled = bug 774100