addon-sdk/source/test/test-selection.js

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:50a7cc62feca
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 'use strict';
6
7 module.metadata = {
8 'engines': {
9 'Firefox': '*'
10 }
11 };
12
13 const HTML = "<html>\
14 <body>\
15 <div>foo</div>\
16 <div>and</div>\
17 <textarea>noodles</textarea>\
18 </body>\
19 </html>";
20
21 const URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML);
22
23 const FRAME_HTML = "<iframe src='" + URL + "'><iframe>";
24 const FRAME_URL = "data:text/html;charset=utf-8," + encodeURIComponent(FRAME_HTML);
25
26 const { defer } = require("sdk/core/promise");
27 const tabs = require("sdk/tabs");
28 const { setTabURL } = require("sdk/tabs/utils");
29 const { getActiveTab, getTabContentWindow, closeTab } = require("sdk/tabs/utils")
30 const { getMostRecentBrowserWindow } = require("sdk/window/utils");
31 const { open: openNewWindow } = require("sdk/window/helpers");
32 const { Loader } = require("sdk/test/loader");
33 const { setTimeout } = require("sdk/timers");
34 const { Cu } = require("chrome");
35 const { merge } = require("sdk/util/object");
36 const { isPrivate } = require("sdk/private-browsing");
37 const events = require("sdk/system/events");
38 // General purpose utility functions
39
40 /**
41 * Opens the url given and return a promise, that will be resolved with the
42 * content window when the document is ready.
43 *
44 * I believe this approach could be useful in most of our unit test, that
45 * requires to open a tab and need to access to its content.
46 */
47 function open(url, options) {
48 let { promise, resolve } = defer();
49
50 if (options && typeof(options) === "object") {
51 openNewWindow("", {
52 features: merge({ toolbar: true }, options)
53 }).then(function(chromeWindow) {
54 if (isPrivate(chromeWindow) !== !!options.private)
55 throw new Error("Window should have Private set to " + !!options.private);
56
57 let tab = getActiveTab(chromeWindow);
58
59 tab.linkedBrowser.addEventListener("load", function ready(event) {
60 let { document } = getTabContentWindow(tab);
61
62 if (document.readyState === "complete" && document.URL === url) {
63 this.removeEventListener(event.type, ready);
64
65 resolve(document.defaultView);
66 }
67 }, true);
68
69 setTabURL(tab, url);
70 });
71
72 return promise;
73 };
74
75 tabs.open({
76 url: url,
77 onReady: function(tab) {
78 // Unfortunately there is no way to get a XUL Tab from SDK Tab on Firefox,
79 // only on Fennec. We should implement `tabNS` also on Firefox in order
80 // to have that.
81
82 // Here we assuming that the most recent browser window is the one we're
83 // doing the test, and the active tab is the one we just opened.
84 let window = getTabContentWindow(getActiveTab(getMostRecentBrowserWindow()));
85
86 resolve(window);
87 }
88 });
89
90 return promise;
91 };
92
93 /**
94 * Close the Active Tab
95 */
96 function close(window) {
97 if (window && window.top && typeof(window.top).close === "function") {
98 window.top.close();
99 } else {
100 // Here we assuming that the most recent browser window is the one we're
101 // doing the test, and the active tab is the one we just opened.
102 let tab = getActiveTab(getMostRecentBrowserWindow());
103
104 closeTab(tab);
105 }
106 }
107
108 /**
109 * Reload the window given and return a promise, that will be resolved with the
110 * content window after a small delay.
111 */
112 function reload(window) {
113 let { promise, resolve } = defer();
114
115 // Here we assuming that the most recent browser window is the one we're
116 // doing the test, and the active tab is the one we just opened.
117 let tab = tabs.activeTab;
118
119 tab.once("ready", function () {
120 resolve(window);
121 });
122
123 window.location.reload(true);
124
125 return promise;
126 }
127
128 // Selection's unit test utility function
129
130 /**
131 * Returns the frame's window once the document is loaded
132 */
133 function getFrameWindow(window) {
134 let { promise, resolve } = defer();
135
136 let frame = window.frames[0];
137 let { document } = frame;
138
139 frame.focus();
140
141 if (document.readyState === "complete")
142 return frame;
143
144 document.addEventListener("readystatechange", function readystate() {
145 if (this.readyState === "complete") {
146 this.removeEventListener("readystatechange", readystate);
147 frame.focus();
148 resolve(frame);
149 }
150 });
151
152 return promise;
153 }
154
155 /**
156 * Hide the frame in order to destroy the selection object, and show it again
157 * after ~500 msec, to give time to attach the code on `document-shown`
158 * notification.
159 * In the process, call `Cu.forgeGC` to ensure that the `document-shown` code
160 * is not garbaged.
161 */
162 function hideAndShowFrame(window) {
163 let { promise, resolve } = defer();
164 let iframe = window.document.querySelector("iframe");
165
166 iframe.style.display = "none";
167
168 Cu.schedulePreciseGC(function() {
169 events.on("document-shown", function shown(event) {
170 if (iframe.contentWindow !== event.subject.defaultView)
171 return;
172
173 events.off("document-shown", shown);
174 setTimeout(resolve, 0, window);
175 }, true);
176
177 iframe.style.display = "";
178 });
179
180 return promise;
181 }
182
183 /**
184 * Select the first div in the page, adding the range to the selection.
185 */
186 function selectFirstDiv(window) {
187 let div = window.document.querySelector("div");
188 let selection = window.getSelection();
189 let range = window.document.createRange();
190
191 if (selection.rangeCount > 0)
192 selection.removeAllRanges();
193
194 range.selectNode(div);
195 selection.addRange(range);
196
197 return window;
198 }
199
200 /**
201 * Select all divs in the page, adding the ranges to the selection.
202 */
203 function selectAllDivs(window) {
204 let divs = window.document.getElementsByTagName("div");
205 let selection = window.getSelection();
206
207 if (selection.rangeCount > 0)
208 selection.removeAllRanges();
209
210 for (let i = 0; i < divs.length; i++) {
211 let range = window.document.createRange();
212
213 range.selectNode(divs[i]);
214 selection.addRange(range);
215 }
216
217 return window;
218 }
219
220 /**
221 * Select the textarea content
222 */
223 function selectTextarea(window) {
224 let selection = window.getSelection();
225 let textarea = window.document.querySelector("textarea");
226
227 if (selection.rangeCount > 0)
228 selection.removeAllRanges();
229
230 textarea.setSelectionRange(0, textarea.value.length);
231 textarea.focus();
232
233 return window;
234 }
235
236 /**
237 * Select the content of the first div
238 */
239 function selectContentFirstDiv(window) {
240 let div = window.document.querySelector("div");
241 let selection = window.getSelection();
242 let range = window.document.createRange();
243
244 if (selection.rangeCount > 0)
245 selection.removeAllRanges();
246
247 range.selectNodeContents(div);
248 selection.addRange(range);
249
250 return window;
251 }
252
253 /**
254 * Dispatch the selection event for the selection listener added by
255 * `nsISelectionPrivate.addSelectionListener`
256 */
257 function dispatchSelectionEvent(window) {
258 // We modify the selection in order to dispatch the selection's event, by
259 // contract the selection by one character. So if the text selected is "foo"
260 // will be "fo".
261 window.getSelection().modify("extend", "backward", "character");
262
263 return window;
264 }
265
266 /**
267 * Dispatch the selection event for the selection listener added by
268 * `window.onselect` / `window.addEventListener`
269 */
270 function dispatchOnSelectEvent(window) {
271 let { document } = window;
272 let textarea = document.querySelector("textarea");
273 let event = document.createEvent("UIEvents");
274
275 event.initUIEvent("select", true, true, window, 1);
276
277 textarea.dispatchEvent(event);
278
279 return window;
280 }
281
282 /**
283 * Creates empty ranges and add them to selections
284 */
285 function createEmptySelections(window) {
286 selectAllDivs(window);
287
288 let selection = window.getSelection();
289
290 for (let i = 0; i < selection.rangeCount; i++)
291 selection.getRangeAt(i).collapse(true);
292 }
293
294 // Test cases
295
296 exports["test No Selection"] = function(assert, done) {
297 let loader = Loader(module);
298 let selection = loader.require("sdk/selection");
299
300 open(URL).then(function() {
301
302 assert.equal(selection.isContiguous, false,
303 "selection.isContiguous without selection works.");
304
305 assert.strictEqual(selection.text, null,
306 "selection.text without selection works.");
307
308 assert.strictEqual(selection.html, null,
309 "selection.html without selection works.");
310
311 let selectionCount = 0;
312 for each (let sel in selection)
313 selectionCount++;
314
315 assert.equal(selectionCount, 0,
316 "No iterable selections");
317
318 }).then(close).then(loader.unload).then(done, assert.fail);
319 };
320
321 exports["test Single DOM Selection"] = function(assert, done) {
322 let loader = Loader(module);
323 let selection = loader.require("sdk/selection");
324
325 open(URL).then(selectFirstDiv).then(function() {
326
327 assert.equal(selection.isContiguous, true,
328 "selection.isContiguous with single DOM Selection works.");
329
330 assert.equal(selection.text, "foo",
331 "selection.text with single DOM Selection works.");
332
333 assert.equal(selection.html, "<div>foo</div>",
334 "selection.html with single DOM Selection works.");
335
336 let selectionCount = 0;
337 for each (let sel in selection) {
338 selectionCount++;
339
340 assert.equal(sel.text, "foo",
341 "iterable selection.text with single DOM Selection works.");
342
343 assert.equal(sel.html, "<div>foo</div>",
344 "iterable selection.html with single DOM Selection works.");
345 }
346
347 assert.equal(selectionCount, 1,
348 "One iterable selection");
349
350 }).then(close).then(loader.unload).then(done, assert.fail);
351 };
352
353 exports["test Multiple DOM Selection"] = function(assert, done) {
354 let loader = Loader(module);
355 let selection = loader.require("sdk/selection");
356
357 open(URL).then(selectAllDivs).then(function() {
358 let expectedText = ["foo", "and"];
359 let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
360
361 assert.equal(selection.isContiguous, false,
362 "selection.isContiguous with multiple DOM Selection works.");
363
364 assert.equal(selection.text, expectedText[0],
365 "selection.text with multiple DOM Selection works.");
366
367 assert.equal(selection.html, expectedHTML[0],
368 "selection.html with multiple DOM Selection works.");
369
370 let selectionCount = 0;
371 for each (let sel in selection) {
372 assert.equal(sel.text, expectedText[selectionCount],
373 "iterable selection.text with multiple DOM Selection works.");
374
375 assert.equal(sel.html, expectedHTML[selectionCount],
376 "iterable selection.text with multiple DOM Selection works.");
377
378 selectionCount++;
379 }
380
381 assert.equal(selectionCount, 2,
382 "Two iterable selections");
383
384 }).then(close).then(loader.unload).then(done, assert.fail);
385 };
386
387 exports["test Textarea Selection"] = function(assert, done) {
388 let loader = Loader(module);
389 let selection = loader.require("sdk/selection");
390
391 open(URL).then(selectTextarea).then(function() {
392
393 assert.equal(selection.isContiguous, true,
394 "selection.isContiguous with Textarea Selection works.");
395
396 assert.equal(selection.text, "noodles",
397 "selection.text with Textarea Selection works.");
398
399 assert.strictEqual(selection.html, null,
400 "selection.html with Textarea Selection works.");
401
402 let selectionCount = 0;
403 for each (let sel in selection) {
404 selectionCount++;
405
406 assert.equal(sel.text, "noodles",
407 "iterable selection.text with Textarea Selection works.");
408
409 assert.strictEqual(sel.html, null,
410 "iterable selection.html with Textarea Selection works.");
411 }
412
413 assert.equal(selectionCount, 1,
414 "One iterable selection");
415
416 }).then(close).then(loader.unload).then(done, assert.fail);
417 };
418
419 exports["test Set Text in Multiple DOM Selection"] = function(assert, done) {
420 let loader = Loader(module);
421 let selection = loader.require("sdk/selection");
422
423 open(URL).then(selectAllDivs).then(function() {
424 let expectedText = ["bar", "and"];
425 let expectedHTML = ["bar", "<div>and</div>"];
426
427 selection.text = "bar";
428
429 assert.equal(selection.text, expectedText[0],
430 "set selection.text with single DOM Selection works.");
431
432 assert.equal(selection.html, expectedHTML[0],
433 "selection.html with single DOM Selection works.");
434
435 let selectionCount = 0;
436 for each (let sel in selection) {
437
438 assert.equal(sel.text, expectedText[selectionCount],
439 "iterable selection.text with multiple DOM Selection works.");
440
441 assert.equal(sel.html, expectedHTML[selectionCount],
442 "iterable selection.html with multiple DOM Selection works.");
443
444 selectionCount++;
445 }
446
447 assert.equal(selectionCount, 2,
448 "Two iterable selections");
449
450 }).then(close).then(loader.unload).then(done, assert.fail);
451 };
452
453 exports["test Set HTML in Multiple DOM Selection"] = function(assert, done) {
454 let loader = Loader(module);
455 let selection = loader.require("sdk/selection");
456
457 open(URL).then(selectAllDivs).then(function() {
458 let html = "<span>b<b>a</b>r</span>";
459
460 let expectedText = ["bar", "and"];
461 let expectedHTML = [html, "<div>and</div>"];
462
463 selection.html = html;
464
465 assert.equal(selection.text, expectedText[0],
466 "set selection.text with DOM Selection works.");
467
468 assert.equal(selection.html, expectedHTML[0],
469 "selection.html with DOM Selection works.");
470
471 let selectionCount = 0;
472 for each (let sel in selection) {
473
474 assert.equal(sel.text, expectedText[selectionCount],
475 "iterable selection.text with multiple DOM Selection works.");
476
477 assert.equal(sel.html, expectedHTML[selectionCount],
478 "iterable selection.html with multiple DOM Selection works.");
479
480 selectionCount++;
481 }
482
483 assert.equal(selectionCount, 2,
484 "Two iterable selections");
485
486 }).then(close).then(loader.unload).then(done, assert.fail);
487 };
488
489 exports["test Set HTML as text in Multiple DOM Selection"] = function(assert, done) {
490 let loader = Loader(module);
491 let selection = loader.require("sdk/selection");
492
493 open(URL).then(selectAllDivs).then(function() {
494 let text = "<span>b<b>a</b>r</span>";
495 let html = "&lt;span&gt;b&lt;b&gt;a&lt;/b&gt;r&lt;/span&gt;";
496
497 let expectedText = [text, "and"];
498 let expectedHTML = [html, "<div>and</div>"];
499
500 selection.text = text;
501
502 assert.equal(selection.text, expectedText[0],
503 "set selection.text with DOM Selection works.");
504
505 assert.equal(selection.html, expectedHTML[0],
506 "selection.html with DOM Selection works.");
507
508 let selectionCount = 0;
509 for each (let sel in selection) {
510
511 assert.equal(sel.text, expectedText[selectionCount],
512 "iterable selection.text with multiple DOM Selection works.");
513
514 assert.equal(sel.html, expectedHTML[selectionCount],
515 "iterable selection.html with multiple DOM Selection works.");
516
517 selectionCount++;
518 }
519
520 assert.equal(selectionCount, 2,
521 "Two iterable selections");
522
523 }).then(close).then(loader.unload).then(done, assert.fail);
524 };
525
526 exports["test Set Text in Textarea Selection"] = function(assert, done) {
527 let loader = Loader(module);
528 let selection = loader.require("sdk/selection");
529
530 open(URL).then(selectTextarea).then(function() {
531
532 let text = "bar";
533
534 selection.text = text;
535
536 assert.equal(selection.text, text,
537 "set selection.text with Textarea Selection works.");
538
539 assert.strictEqual(selection.html, null,
540 "selection.html with Textarea Selection works.");
541
542 let selectionCount = 0;
543 for each (let sel in selection) {
544 selectionCount++;
545
546 assert.equal(sel.text, text,
547 "iterable selection.text with Textarea Selection works.");
548
549 assert.strictEqual(sel.html, null,
550 "iterable selection.html with Textarea Selection works.");
551 }
552
553 assert.equal(selectionCount, 1,
554 "One iterable selection");
555
556 }).then(close).then(loader.unload).then(done, assert.fail);
557 };
558
559 exports["test Set HTML in Textarea Selection"] = function(assert, done) {
560 let loader = Loader(module);
561 let selection = loader.require("sdk/selection");
562
563 open(URL).then(selectTextarea).then(function() {
564
565 let html = "<span>b<b>a</b>r</span>";
566
567 // Textarea can't have HTML so set `html` property is equals to set `text`
568 // property
569 selection.html = html;
570
571 assert.equal(selection.text, html,
572 "set selection.text with Textarea Selection works.");
573
574 assert.strictEqual(selection.html, null,
575 "selection.html with Textarea Selection works.");
576
577 let selectionCount = 0;
578 for each (let sel in selection) {
579 selectionCount++;
580
581 assert.equal(sel.text, html,
582 "iterable selection.text with Textarea Selection works.");
583
584 assert.strictEqual(sel.html, null,
585 "iterable selection.html with Textarea Selection works.");
586 }
587
588 assert.equal(selectionCount, 1,
589 "One iterable selection");
590
591 }).then(close).then(loader.unload).then(done, assert.fail);
592 };
593
594 exports["test Empty Selections"] = function(assert, done) {
595 let loader = Loader(module);
596 let selection = loader.require("sdk/selection");
597
598 open(URL).then(createEmptySelections).then(function(){
599 assert.equal(selection.isContiguous, false,
600 "selection.isContiguous with empty selections works.");
601
602 assert.strictEqual(selection.text, null,
603 "selection.text with empty selections works.");
604
605 assert.strictEqual(selection.html, null,
606 "selection.html with empty selections works.");
607
608 let selectionCount = 0;
609 for each (let sel in selection)
610 selectionCount++;
611
612 assert.equal(selectionCount, 0,
613 "No iterable selections");
614
615 }).then(close).then(loader.unload).then(done, assert.fail);
616 }
617
618
619 exports["test No Selection Exception"] = function(assert, done) {
620 const NO_SELECTION = /It isn't possible to change the selection/;
621
622 let loader = Loader(module);
623 let selection = loader.require("sdk/selection");
624
625 open(URL).then(function() {
626
627 // We're trying to change a selection when there is no selection
628 assert.throws(function() {
629 selection.text = "bar";
630 }, NO_SELECTION);
631
632 assert.throws(function() {
633 selection.html = "bar";
634 }, NO_SELECTION);
635
636 }).then(close).then(loader.unload).then(done, assert.fail);
637 };
638
639 exports["test for...of without selections"] = function(assert, done) {
640 let loader = Loader(module);
641 let selection = loader.require("sdk/selection");
642
643 open(URL).then(function() {
644 let selectionCount = 0;
645
646 for (let sel of selection)
647 selectionCount++;
648
649 assert.equal(selectionCount, 0,
650 "No iterable selections");
651
652 }).then(close).then(loader.unload).then(null, function(error) {
653 // iterable are not supported yet in Firefox 16, for example, but
654 // they are in Firefox 17.
655 if (error.message.indexOf("is not iterable") > -1)
656 assert.pass("`iterable` method not supported in this application");
657 else
658 assert.fail(error);
659 }).then(done, assert.fail);
660 }
661
662 exports["test for...of with selections"] = function(assert, done) {
663 let loader = Loader(module);
664 let selection = loader.require("sdk/selection");
665
666 open(URL).then(selectAllDivs).then(function(){
667 let expectedText = ["foo", "and"];
668 let expectedHTML = ["<div>foo</div>", "<div>and</div>"];
669
670 let selectionCount = 0;
671
672 for (let sel of selection) {
673 assert.equal(sel.text, expectedText[selectionCount],
674 "iterable selection.text with for...of works.");
675
676 assert.equal(sel.html, expectedHTML[selectionCount],
677 "iterable selection.text with for...of works.");
678
679 selectionCount++;
680 }
681
682 assert.equal(selectionCount, 2,
683 "Two iterable selections");
684
685 }).then(close).then(loader.unload).then(null, function(error) {
686 // iterable are not supported yet in Firefox 16, for example, but
687 // they are in Firefox 17.
688 if (error.message.indexOf("is not iterable") > -1)
689 assert.pass("`iterable` method not supported in this application");
690 else
691 assert.fail(error);
692 }).then(done, assert.fail)
693 }
694
695 exports["test Selection Listener"] = function(assert, done) {
696 let loader = Loader(module);
697 let selection = loader.require("sdk/selection");
698
699 selection.once("select", function() {
700 assert.equal(selection.text, "fo");
701 done();
702 });
703
704 open(URL).then(selectContentFirstDiv).
705 then(dispatchSelectionEvent).
706 then(close).
707 then(loader.unload, assert.fail);
708 };
709
710 exports["test Textarea OnSelect Listener"] = function(assert, done) {
711 let loader = Loader(module);
712 let selection = loader.require("sdk/selection");
713
714 selection.once("select", function() {
715 assert.equal(selection.text, "noodles");
716 done();
717 });
718
719 open(URL).then(selectTextarea).
720 then(dispatchOnSelectEvent).
721 then(close).
722 then(loader.unload, assert.fail);
723 };
724
725 exports["test Selection listener removed on unload"] = function(assert, done) {
726 let loader = Loader(module);
727 let selection = loader.require("sdk/selection");
728
729 selection.once("select", function() {
730 assert.fail("Shouldn't be never called");
731 });
732
733 loader.unload();
734
735 assert.pass();
736
737 open(URL).
738 then(selectContentFirstDiv).
739 then(dispatchSelectionEvent).
740 then(close).
741 then(done, assert.fail);
742 };
743
744 exports["test Textarea onSelect Listener removed on unload"] = function(assert, done) {
745 let loader = Loader(module);
746 let selection = loader.require("sdk/selection");
747
748 selection.once("select", function() {
749 assert.fail("Shouldn't be never called");
750 });
751
752 loader.unload();
753
754 assert.pass();
755
756 open(URL).
757 then(selectTextarea).
758 then(dispatchOnSelectEvent).
759 then(close).
760 then(done, assert.fail);
761 };
762
763
764 exports["test Selection Listener on existing document"] = function(assert, done) {
765 let loader = Loader(module);
766
767 open(URL).then(function(window){
768 let selection = loader.require("sdk/selection");
769
770 selection.once("select", function() {
771 assert.equal(selection.text, "fo");
772 done();
773 });
774
775 return window;
776 }).then(selectContentFirstDiv).
777 then(dispatchSelectionEvent).
778 then(close).
779 then(loader.unload, assert.fail);
780 };
781
782
783 exports["test Textarea OnSelect Listener on existing document"] = function(assert, done) {
784 let loader = Loader(module);
785
786 open(URL).then(function(window){
787 let selection = loader.require("sdk/selection");
788
789 selection.once("select", function() {
790 assert.equal(selection.text, "noodles");
791 done();
792 });
793
794 return window;
795 }).then(selectTextarea).
796 then(dispatchOnSelectEvent).
797 then(close).
798 then(loader.unload, assert.fail);
799 };
800
801 exports["test Selection Listener on document reload"] = function(assert, done) {
802 let loader = Loader(module);
803 let selection = loader.require("sdk/selection");
804
805 selection.once("select", function() {
806 assert.equal(selection.text, "fo");
807 done();
808 });
809
810 open(URL).
811 then(reload).
812 then(selectContentFirstDiv).
813 then(dispatchSelectionEvent).
814 then(close).
815 then(loader.unload, assert.fail);
816 };
817
818 exports["test Textarea OnSelect Listener on document reload"] = function(assert, done) {
819 let loader = Loader(module);
820 let selection = loader.require("sdk/selection");
821
822 selection.once("select", function() {
823 assert.equal(selection.text, "noodles");
824 done();
825 });
826
827 open(URL).
828 then(reload).
829 then(selectTextarea).
830 then(dispatchOnSelectEvent).
831 then(close).
832 then(loader.unload, assert.fail);
833 };
834
835 exports["test Selection Listener on frame"] = function(assert, done) {
836 let loader = Loader(module);
837 let selection = loader.require("sdk/selection");
838
839 selection.once("select", function() {
840 assert.equal(selection.text, "fo");
841 close();
842 loader.unload();
843 done();
844 });
845
846 open(FRAME_URL).
847 then(hideAndShowFrame).
848 then(getFrameWindow).
849 then(selectContentFirstDiv).
850 then(dispatchSelectionEvent).
851 then(null, assert.fail);
852 };
853
854 exports["test Textarea onSelect Listener on frame"] = function(assert, done) {
855 let loader = Loader(module);
856 let selection = loader.require("sdk/selection");
857
858 selection.once("select", function() {
859 assert.equal(selection.text, "noodles");
860 close();
861 loader.unload();
862 done();
863 });
864
865 open(FRAME_URL).
866 then(hideAndShowFrame).
867 then(getFrameWindow).
868 then(selectTextarea).
869 then(dispatchOnSelectEvent).
870 then(null, assert.fail);
871 };
872
873
874 exports["test PBPW Selection Listener"] = function(assert, done) {
875 let loader = Loader(module);
876 let selection = loader.require("sdk/selection");
877
878 selection.once("select", function() {
879 assert.fail("Shouldn't be never called");
880 });
881
882 assert.pass();
883
884 open(URL, {private: true}).
885 then(selectContentFirstDiv).
886 then(dispatchSelectionEvent).
887 then(close).
888 then(loader.unload).
889 then(done, assert.fail);
890 };
891
892 exports["test PBPW Textarea OnSelect Listener"] = function(assert, done) {
893 let loader = Loader(module);
894 let selection = loader.require("sdk/selection");
895
896 selection.once("select", function() {
897 assert.fail("Shouldn't be never called");
898 });
899
900 assert.pass();
901
902 open(URL, {private: true}).
903 then(selectTextarea).
904 then(dispatchOnSelectEvent).
905 then(close).
906 then(loader.unload).
907 then(done, assert.fail);
908 };
909
910
911 exports["test PBPW Single DOM Selection"] = function(assert, done) {
912 let loader = Loader(module);
913 let selection = loader.require("sdk/selection");
914
915 open(URL, {private: true}).then(selectFirstDiv).then(function(window) {
916
917 assert.equal(selection.isContiguous, false,
918 "selection.isContiguous with single DOM Selection in PBPW works.");
919
920 assert.equal(selection.text, null,
921 "selection.text with single DOM Selection in PBPW works.");
922
923 assert.equal(selection.html, null,
924 "selection.html with single DOM Selection in PBPW works.");
925
926 let selectionCount = 0;
927 for each (let sel in selection)
928 selectionCount++;
929
930 assert.equal(selectionCount, 0,
931 "No iterable selection in PBPW");
932
933 return window;
934 }).then(close).then(loader.unload).then(done, assert.fail);
935 };
936
937 exports["test PBPW Textarea Selection"] = function(assert, done) {
938 let loader = Loader(module);
939 let selection = loader.require("sdk/selection");
940
941 open(URL, {private: true}).then(selectTextarea).then(function(window) {
942
943 assert.equal(selection.isContiguous, false,
944 "selection.isContiguous with Textarea Selection in PBPW works.");
945
946 assert.equal(selection.text, null,
947 "selection.text with Textarea Selection in PBPW works.");
948
949 assert.strictEqual(selection.html, null,
950 "selection.html with Textarea Selection in PBPW works.");
951
952 let selectionCount = 0;
953 for each (let sel in selection) {
954 selectionCount++;
955
956 assert.equal(sel.text, null,
957 "iterable selection.text with Textarea Selection in PBPW works.");
958
959 assert.strictEqual(sel.html, null,
960 "iterable selection.html with Textarea Selection in PBPW works.");
961 }
962
963 assert.equal(selectionCount, 0,
964 "No iterable selection in PBPW");
965
966 return window;
967 }).then(close).then(loader.unload).then(done, assert.fail);
968 };
969
970 // TODO: test Selection Listener on long-held connection (Bug 661884)
971 //
972 // I didn't find a way to do so with httpd, using `processAsync` I'm able to
973 // Keep the connection but not to flush the buffer to the client in two steps,
974 // that is what I need for this test (e.g. flush "Hello" to the client, makes
975 // selection when the connection is still hold, and check that the listener
976 // is executed before the server send "World" and close the connection).
977 //
978 // Because this test is needed to the refactoring of context-menu as well, I
979 // believe we will find a proper solution quickly.
980 /*
981 exports["test Selection Listener on long-held connection"] = function(assert, done) {
982
983 };
984 */
985
986 // If the platform doesn't support the PBPW, we're replacing PBPW tests
987 if (!require("sdk/private-browsing/utils").isWindowPBSupported) {
988 Object.keys(module.exports).forEach(function(key) {
989 if (key.indexOf("test PBPW") === 0) {
990 module.exports[key] = function Unsupported (assert) {
991 assert.pass("Private Window Per Browsing is not supported on this platform.");
992 }
993 }
994 });
995 }
996
997 require("test").run(exports)

mercurial