diff -r 000000000000 -r 6474c204b198 toolkit/content/tests/chrome/file_autocomplete_with_composition.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/content/tests/chrome/file_autocomplete_with_composition.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,633 @@ +// nsDoTestsForAutoCompleteWithComposition tests autocomplete with composition. +// Users must include SimpleTest.js and EventUtils.js. + +function nsDoTestsForAutoCompleteWithComposition(aDescription, + aWindow, + aTarget, + aAutoCompleteController, + aIsFunc, + aGetTargetValueFunc, + aOnFinishFunc) +{ + this._description = aDescription; + this._window = aWindow; + this._target = aTarget; + this._controller = aAutoCompleteController; + + this._is = aIsFunc; + this._getTargetValue = aGetTargetValueFunc; + this._onFinish = aOnFinishFunc; + + this._target.focus(); + + this._DefaultCompleteDefaultIndex = + this._controller.input.completeDefaultIndex; + + this._doTests(); +} + +nsDoTestsForAutoCompleteWithComposition.prototype = { + _window: null, + _target: null, + _controller: null, + _DefaultCompleteDefaultIndex: false, + _description: "", + + _is: null, + _getTargetValue: function () { return "not initialized"; }, + _onFinish: null, + + _doTests: function () + { + if (++this._testingIndex == this._tests.length) { + this._controller.input.completeDefaultIndex = + this._DefaultCompleteDefaultIndex; + this._onFinish(); + return; + } + + var test = this._tests[this._testingIndex]; + if (this._controller.input.completeDefaultIndex != test.completeDefaultIndex) { + this._controller.input.completeDefaultIndex = test.completeDefaultIndex; + } + test.execute(this._window); + + var timeout = this._controller.input.timeout + 10; + this._waitResult(timeout); + }, + + _waitResult: function (aTimes) + { + var obj = this; + if (aTimes-- > 0) { + setTimeout(function () { obj._waitResult(aTimes); }, 0); + } else { + setTimeout(function () { obj._checkResult(); }, 0); + } + }, + + _checkResult: function () + { + var test = this._tests[this._testingIndex]; + this._is(this._getTargetValue(), test.value, + this._description + ", " + test.description + ": value"); + this._is(this._controller.searchString, test.searchString, + this._description + ", " + test.description +": searchString"); + this._is(this._controller.input.popupOpen, test.popup, + this._description + ", " + test.description + ": popupOpen"); + this._doTests(); + }, + + _testingIndex: -1, + _tests: [ + // Simple composition when popup hasn't been shown. + // The autocomplete popup should not be shown during composition, but + // after compositionend, the popup should be shown. + { description: "compositionstart shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow); + synthesizeText( + { "composition": + { "string": "M", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "M", searchString: "" + }, + { description: "compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow); + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "" + }, + { description: "compositionend should open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "Mo" }, aWindow); + synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow); + }, popup: true, value: "Mo", searchString: "Mo" + }, + // If composition starts when popup is shown, the compositionstart event + // should cause closing the popup. + { description: "compositionstart should close the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("z", { type: "keydown" }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow); + synthesizeText( + { "composition": + { "string": "z", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "Moz", searchString: "Mo" + }, + { description: "compositionupdate shouldn't reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow); + synthesizeText( + { "composition": + { "string": "zi", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozi", searchString: "Mo" + }, + { description: "compositionend should research the result and open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "zi", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 2, "length": 0 } + }); + synthesizeComposition({ type: "compositionend", data: "zi" }, aWindow); + synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow); + }, popup: true, value: "Mozi", searchString: "Mozi" + }, + // If composition is cancelled, the value shouldn't be changed. + { description: "compositionstart should reclose the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("l", { type: "keydown" }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "l" }, aWindow); + synthesizeText( + { "composition": + { "string": "l", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozil", searchString: "Mozi" + }, + { description: "compositionupdate shouldn't reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "ll" }, aWindow); + synthesizeText( + { "composition": + { "string": "ll", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozill", searchString: "Mozi" + }, + { description: "empty compositionupdate shouldn't reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow); + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozi", searchString: "Mozi" + }, + { description: "cancled compositionend should reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "" }, aWindow); + synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow); + }, popup: true, value: "Mozi", searchString: "Mozi" + }, + // But if composition replaces some characters and canceled, the search + // string should be the latest value. + { description: "compositionstart with selected string should close the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow); + synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow); + synthesizeKey("z", { type: "keydown" }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow); + synthesizeText( + { "composition": + { "string": "z", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "Moz", searchString: "Mozi" + }, + { description: "compositionupdate shouldn't reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow); + synthesizeText( + { "composition": + { "string": "zi", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozi", searchString: "Mozi" + }, + { description: "empty compositionupdate shouldn't reopen the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow); + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "Mozi" + }, + { description: "canceled compositionend should seach the result with the latest value", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "" }, aWindow); + synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow); + }, popup: true, value: "Mo", searchString: "Mo" + }, + //If all characters are removed, the popup should be closed. + { description: "the value becomes empty by backspace, the popup should be closed", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + }, popup: false, value: "", searchString: "" + }, + // composition which is canceled shouldn't cause opening the popup. + { description: "compositionstart shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow); + synthesizeText( + { "composition": + { "string": "M", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "M", searchString: "" + }, + { description: "compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow); + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "" + }, + { description: "empty compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow); + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + }, popup: false, value: "", searchString: "" + }, + { description: "canceled compositionend shouldn't open the popup if it was closed", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "" }, aWindow); + synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow); + }, popup: false, value: "", searchString: "" + }, + // Down key should open the popup even if the editor is empty. + { description: "DOWN key should open the popup even if the value is empty", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("VK_DOWN", {}, aWindow); + }, popup: true, value: "", searchString: "" + }, + // If popup is open at starting composition, the popup should be reopened + // after composition anyway. + { description: "compositionstart shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow); + synthesizeText( + { "composition": + { "string": "M", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "M", searchString: "" + }, + { description: "compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow); + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "" + }, + { description: "empty compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow); + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + }, popup: false, value: "", searchString: "" + }, + { description: "canceled compositionend should open the popup if it was opened", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "" }, aWindow); + synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow); + }, popup: true, value: "", searchString: "" + }, + // Type normally, and hit escape, the popup should be closed. + { description: "ESCAPE should close the popup after typing something", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("M", { shiftKey: true }, aWindow); + synthesizeKey("o", { shiftKey: true }, aWindow); + synthesizeKey("VK_ESCAPE", {}, aWindow); + }, popup: false, value: "Mo", searchString: "Mo" + }, + // Even if the popup is closed, composition which is canceled should open + // the popup if the value isn't empty. + // XXX This might not be good behavior, but anyway, this is minor issue... + { description: "compositionstart shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("z", { type: "keydown", shiftKey: true }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "z" }, aWindow); + synthesizeText( + { "composition": + { "string": "z", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "Moz", searchString: "Mo" + }, + { description: "compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "zi" }, aWindow); + synthesizeText( + { "composition": + { "string": "zi", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mozi", searchString: "Mo" + }, + { description: "empty compositionupdate shouldn't open the popup", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "" }, aWindow); + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "Mo" + }, + { description: "canceled compositionend shouldn't open the popup if the popup was closed", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 0, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "" }, aWindow); + synthesizeKey("VK_ESCAPE", { type: "keyup" }, aWindow); + }, popup: true, value: "Mo", searchString: "Mo" + }, + // House keeping... + { description: "house keeping for next tests", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + }, popup: false, value: "", searchString: "" + }, + // Testing for nsIAutoCompleteInput.completeDefaultIndex being true. + { description: "compositionstart shouldn't open the popup (completeDefaultIndex is true)", + completeDefaultIndex: true, + execute: function (aWindow) { + synthesizeKey("m", { type: "keydown", shiftKey: true }, aWindow); + synthesizeComposition({ type: "compositionstart" }, aWindow); + synthesizeComposition({ type: "compositionupdate", data: "M" }, aWindow); + synthesizeText( + { "composition": + { "string": "M", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 1, "length": 0 } + }, aWindow); + }, popup: false, value: "M", searchString: "" + }, + { description: "compositionupdate shouldn't open the popup (completeDefaultIndex is true)", + completeDefaultIndex: true, + execute: function (aWindow) { + synthesizeComposition({ type: "compositionupdate", data: "Mo" }, aWindow); + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + }, popup: false, value: "Mo", searchString: "" + }, + { description: "compositionend should open the popup (completeDefaultIndex is true)", + completeDefaultIndex: true, + execute: function (aWindow) { + synthesizeText( + { "composition": + { "string": "Mo", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 2, "length": 0 } + }, aWindow); + synthesizeComposition({ type: "compositionend", data: "Mo" }, aWindow); + synthesizeKey("VK_RETURN", { type: "keyup" }, aWindow); + }, popup: true, value: "Mozilla", searchString: "Mo" + }, + // House keeping... + { description: "house keeping for next tests", + completeDefaultIndex: false, + execute: function (aWindow) { + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + synthesizeKey("VK_BACK_SPACE", {}, aWindow); + }, popup: false, value: "", searchString: "" + } + ] +};