|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 var Services = SpecialPowers.Services; |
|
6 |
|
7 /* |
|
8 * $_ |
|
9 * |
|
10 * Returns the element with the specified |name| attribute. |
|
11 */ |
|
12 function $_(formNum, name) { |
|
13 var form = document.getElementById("form" + formNum); |
|
14 if (!form) { |
|
15 ok(false, "$_ couldn't find requested form " + formNum); |
|
16 return null; |
|
17 } |
|
18 |
|
19 var element = form.elements.namedItem(name); |
|
20 if (!element) { |
|
21 ok(false, "$_ couldn't find requested element " + name); |
|
22 return null; |
|
23 } |
|
24 |
|
25 // Note that namedItem is a bit stupid, and will prefer an |
|
26 // |id| attribute over a |name| attribute when looking for |
|
27 // the element. |
|
28 |
|
29 if (element.hasAttribute("name") && element.getAttribute("name") != name) { |
|
30 ok(false, "$_ got confused."); |
|
31 return null; |
|
32 } |
|
33 |
|
34 return element; |
|
35 } |
|
36 |
|
37 // Mochitest gives us a sendKey(), but it's targeted to a specific element. |
|
38 // This basically sends an untargeted key event, to whatever's focused. |
|
39 function doKey(aKey, modifier) { |
|
40 var keyName = "DOM_VK_" + aKey.toUpperCase(); |
|
41 var key = SpecialPowers.Ci.nsIDOMKeyEvent[keyName]; |
|
42 |
|
43 // undefined --> null |
|
44 if (!modifier) |
|
45 modifier = null; |
|
46 |
|
47 // Window utils for sending fake sey events. |
|
48 var wutils = SpecialPowers.getDOMWindowUtils(window); |
|
49 |
|
50 if (wutils.sendKeyEvent("keydown", key, 0, modifier)) { |
|
51 wutils.sendKeyEvent("keypress", key, 0, modifier); |
|
52 } |
|
53 wutils.sendKeyEvent("keyup", key, 0, modifier); |
|
54 } |
|
55 |
|
56 |
|
57 function getAutocompletePopup() { |
|
58 var Ci = SpecialPowers.Ci; |
|
59 chromeWin = SpecialPowers.wrap(window) |
|
60 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
61 .getInterface(Ci.nsIWebNavigation) |
|
62 .QueryInterface(Ci.nsIDocShellTreeItem) |
|
63 .rootTreeItem |
|
64 .QueryInterface(Ci.nsIInterfaceRequestor) |
|
65 .getInterface(Ci.nsIDOMWindow) |
|
66 .QueryInterface(Ci.nsIDOMChromeWindow); |
|
67 autocompleteMenu = chromeWin.document.getElementById("PopupAutoComplete"); |
|
68 ok(autocompleteMenu, "Got autocomplete popup"); |
|
69 |
|
70 return autocompleteMenu; |
|
71 } |
|
72 |
|
73 |
|
74 function cleanUpFormHist() { |
|
75 SpecialPowers.formHistory.update({ op : "remove" }); |
|
76 } |
|
77 cleanUpFormHist(); |
|
78 |
|
79 |
|
80 var checkObserver = { |
|
81 verifyStack: [], |
|
82 callback: null, |
|
83 |
|
84 waitForChecks: function(callback) { |
|
85 if (this.verifyStack.length == 0) |
|
86 callback(); |
|
87 else |
|
88 this.callback = callback; |
|
89 }, |
|
90 |
|
91 observe: function(subject, topic, data) { |
|
92 if (data != "formhistory-add" && data != "formhistory-update") |
|
93 return; |
|
94 ok(this.verifyStack.length > 0, "checking if saved form data was expected"); |
|
95 |
|
96 // Make sure that every piece of data we expect to be saved is saved, and no |
|
97 // more. Here it is assumed that for every entry satchel saves or modifies, a |
|
98 // message is sent. |
|
99 // |
|
100 // We don't actually check the content of the message, but just that the right |
|
101 // quantity of messages is received. |
|
102 // - if there are too few messages, test will time out |
|
103 // - if there are too many messages, test will error out here |
|
104 // |
|
105 var expected = this.verifyStack.shift(); |
|
106 |
|
107 countEntries(expected.name, expected.value, |
|
108 function(num) { |
|
109 ok(num > 0, expected.message); |
|
110 if (checkObserver.verifyStack.length == 0) { |
|
111 var callback = checkObserver.callback; |
|
112 checkObserver.callback = null; |
|
113 callback(); |
|
114 } |
|
115 }); |
|
116 } |
|
117 }; |
|
118 |
|
119 function checkForSave(name, value, message) { |
|
120 checkObserver.verifyStack.push({ name : name, value: value, message: message }); |
|
121 } |
|
122 |
|
123 |
|
124 function getFormSubmitButton(formNum) { |
|
125 var form = $("form" + formNum); // by id, not name |
|
126 ok(form != null, "getting form " + formNum); |
|
127 |
|
128 // we can't just call form.submit(), because that doesn't seem to |
|
129 // invoke the form onsubmit handler. |
|
130 var button = form.firstChild; |
|
131 while (button && button.type != "submit") { button = button.nextSibling; } |
|
132 ok(button != null, "getting form submit button"); |
|
133 |
|
134 return button; |
|
135 } |
|
136 |
|
137 // Count the number of entries with the given name and value, and call then(number) |
|
138 // when done. If name or value is null, then the value of that field does not matter. |
|
139 function countEntries(name, value, then) { |
|
140 var obj = {}; |
|
141 if (name !== null) |
|
142 obj.fieldname = name; |
|
143 if (value !== null) |
|
144 obj.value = value; |
|
145 |
|
146 var count = 0; |
|
147 SpecialPowers.formHistory.count(obj, { handleResult: function (result) { count = result }, |
|
148 handleError: function (error) { |
|
149 do_throw("Error occurred searching form history: " + error); |
|
150 }, |
|
151 handleCompletion: function (reason) { if (!reason) then(count); } |
|
152 }); |
|
153 } |
|
154 |
|
155 // Wrapper around FormHistory.update which handles errors. Calls then() when done. |
|
156 function updateFormHistory(changes, then) { |
|
157 SpecialPowers.formHistory.update(changes, { handleError: function (error) { |
|
158 do_throw("Error occurred updating form history: " + error); |
|
159 }, |
|
160 handleCompletion: function (reason) { if (!reason) then(); }, |
|
161 }); |
|
162 } |