<lambda>null1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
2 * Any copyright is dedicated to the Public Domain.
3 http://creativecommons.org/publicdomain/zero/1.0/ */
4
5 package org.mozilla.geckoview.test
6
7 import android.os.Handler
8 import android.os.Looper
9 import org.mozilla.geckoview.GeckoResult
10 import org.mozilla.geckoview.GeckoSession
11 import org.mozilla.geckoview.GeckoSession.SessionState
12 import org.mozilla.geckoview.GeckoSession.ContentDelegate
13 import org.mozilla.geckoview.GeckoSession.NavigationDelegate
14 import org.mozilla.geckoview.GeckoSession.ScrollDelegate
15 import org.mozilla.geckoview.GeckoSession.PromptDelegate
16 import org.mozilla.geckoview.GeckoSession.ProgressDelegate
17 import org.mozilla.geckoview.GeckoSession.HistoryDelegate
18 import org.mozilla.geckoview.GeckoSessionSettings
19 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.*
20 import org.mozilla.geckoview.test.util.UiThreadUtils
21
22 import androidx.test.filters.MediumTest
23 import androidx.test.ext.junit.runners.AndroidJUnit4
24
25 import org.hamcrest.Matchers.*
26 import org.json.JSONArray
27 import org.json.JSONObject
28 import org.junit.Assume.assumeThat
29 import org.junit.Test
30 import org.junit.runner.RunWith
31
32 /**
33 * Test for the GeckoSessionTestRule class, to ensure it properly sets up a session for
34 * each test, and to ensure it can properly wait for and assert delegate
35 * callbacks.
36 */
37 @RunWith(AndroidJUnit4::class)
38 @MediumTest
39 class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
40
41 @Test fun getSession() {
42 assertThat("Can get session", mainSession, notNullValue())
43 assertThat("Session is open",
44 mainSession.isOpen, equalTo(true))
45 }
46
47 @ClosedSessionAtStart
48 @Test fun getSession_closedSession() {
49 assertThat("Session is closed", mainSession.isOpen, equalTo(false))
50 }
51
52 @Setting.List(Setting(key = Setting.Key.USE_PRIVATE_MODE, value = "true"),
53 Setting(key = Setting.Key.DISPLAY_MODE, value = "DISPLAY_MODE_MINIMAL_UI"),
54 Setting(key = Setting.Key.ALLOW_JAVASCRIPT, value = "false"))
55 @Setting(key = Setting.Key.USE_TRACKING_PROTECTION, value = "true")
56 @Test fun settingsApplied() {
57 assertThat("USE_PRIVATE_MODE should be set",
58 mainSession.settings.usePrivateMode,
59 equalTo(true))
60 assertThat("DISPLAY_MODE should be set",
61 mainSession.settings.displayMode,
62 equalTo(GeckoSessionSettings.DISPLAY_MODE_MINIMAL_UI))
63 assertThat("USE_TRACKING_PROTECTION should be set",
64 mainSession.settings.useTrackingProtection,
65 equalTo(true))
66 assertThat("ALLOW_JAVASCRIPT should be set",
67 mainSession.settings.allowJavascript,
68 equalTo(false))
69 }
70
71 @Test(expected = UiThreadUtils.TimeoutException::class)
72 @TimeoutMillis(2000)
73 fun noPendingCallbacks() {
74 // Make sure we don't have unexpected pending callbacks at the start of a test.
75 sessionRule.waitUntilCalled(object : ProgressDelegate, HistoryDelegate {
76 // There may be extraneous onSessionStateChange and onHistoryStateChange calls
77 // after a test, so ignore the first received.
78 @AssertCalled(count = 2)
79 override fun onSessionStateChange(session: GeckoSession, state: SessionState) {
80 }
81
82 @AssertCalled(count = 2)
83 override fun onHistoryStateChange(session: GeckoSession, historyList: HistoryDelegate.HistoryList) {
84 }
85 })
86 }
87
88 @NullDelegate.List(NullDelegate(ContentDelegate::class),
89 NullDelegate(NavigationDelegate::class))
90 @NullDelegate(ScrollDelegate::class)
91 @Test fun nullDelegate() {
92 assertThat("Content delegate should be null",
93 mainSession.contentDelegate, nullValue())
94 assertThat("Navigation delegate should be null",
95 mainSession.navigationDelegate, nullValue())
96 assertThat("Scroll delegate should be null",
97 mainSession.scrollDelegate, nullValue())
98
99 assertThat("Progress delegate should not be null",
100 mainSession.progressDelegate, notNullValue())
101 }
102
103 @NullDelegate(ProgressDelegate::class)
104 @ClosedSessionAtStart
105 @Test fun nullDelegate_closed() {
106 assertThat("Progress delegate should be null",
107 mainSession.progressDelegate, nullValue())
108 }
109
110 @Test(expected = AssertionError::class)
111 @NullDelegate(ProgressDelegate::class)
112 @ClosedSessionAtStart
113 fun nullDelegate_requireProgressOnOpen() {
114 assertThat("Progress delegate should be null",
115 mainSession.progressDelegate, nullValue())
116
117 mainSession.open()
118 }
119
120 @Test fun waitForPageStop() {
121 mainSession.loadTestPath(HELLO_HTML_PATH)
122 sessionRule.waitForPageStop()
123
124 var counter = 0
125
126 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
127 override fun onPageStop(session: GeckoSession, success: Boolean) {
128 counter++
129 }
130 })
131
132 assertThat("Callback count should be correct", counter, equalTo(1))
133 }
134
135 @Test fun waitForPageStops() {
136 mainSession.loadTestPath(HELLO_HTML_PATH)
137 mainSession.reload()
138 sessionRule.waitForPageStops(2)
139
140 var counter = 0
141
142 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
143 override fun onPageStop(session: GeckoSession, success: Boolean) {
144 counter++
145 }
146 })
147
148 assertThat("Callback count should be correct", counter, equalTo(2))
149 }
150
151 @Test(expected = AssertionError::class)
152 @NullDelegate(ProgressDelegate::class)
153 @ClosedSessionAtStart
154 fun waitForPageStops_throwOnNullDelegate() {
155 mainSession.loadTestPath(HELLO_HTML_PATH)
156 sessionRule.waitForPageStop()
157
158 mainSession.open(sessionRule.runtime) // Avoid waiting for initial load
159 mainSession.reload()
160 mainSession.waitForPageStops(2)
161 }
162
163 @Test fun waitUntilCalled_anyInterfaceMethod() {
164 // TODO: Bug 1673953
165 assumeThat(sessionRule.env.isFission, equalTo(false))
166 mainSession.loadTestPath(HELLO_HTML_PATH)
167 sessionRule.waitUntilCalled(ProgressDelegate::class)
168
169 var counter = 0
170
171 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
172 override fun onPageStart(session: GeckoSession, url: String) {
173 counter++
174 }
175
176 override fun onPageStop(session: GeckoSession, success: Boolean) {
177 counter++
178 }
179
180 override fun onSecurityChange(session: GeckoSession,
181 securityInfo: ProgressDelegate.SecurityInformation) {
182 counter++
183 }
184
185 override fun onProgressChange(session: GeckoSession, progress: Int) {
186 counter++
187 }
188
189 override fun onSessionStateChange(session: GeckoSession, state: SessionState) {
190 counter++
191 }
192 })
193
194 assertThat("Callback count should be correct", counter, equalTo(1))
195 }
196
197 @Test fun waitUntilCalled_specificInterfaceMethod() {
198 mainSession.loadTestPath(HELLO_HTML_PATH)
199 sessionRule.waitUntilCalled(ProgressDelegate::class,
200 "onPageStart", "onPageStop")
201
202 var counter = 0
203
204 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
205 override fun onPageStart(session: GeckoSession, url: String) {
206 counter++
207 }
208
209 override fun onPageStop(session: GeckoSession, success: Boolean) {
210 counter++
211 }
212 })
213
214 assertThat("Callback count should be correct", counter, equalTo(2))
215 }
216
217 @Test(expected = AssertionError::class)
218 fun waitUntilCalled_throwOnNotGeckoSessionInterface() {
219 mainSession.loadTestPath(HELLO_HTML_PATH)
220 sessionRule.waitUntilCalled(CharSequence::class)
221 }
222
223 fun waitUntilCalled_notThrowOnCallbackInterface() {
224 mainSession.loadTestPath(HELLO_HTML_PATH)
225 sessionRule.waitUntilCalled(ProgressDelegate::class)
226 }
227
228 @NullDelegate(ScrollDelegate::class)
229 @Test fun waitUntilCalled_notThrowOnNonNullDelegateMethod() {
230 mainSession.loadTestPath(HELLO_HTML_PATH)
231 sessionRule.waitForPageStop()
232
233 mainSession.reload()
234 mainSession.waitUntilCalled(ProgressDelegate::class, "onPageStop")
235 }
236
237 @Test fun waitUntilCalled_anyObjectMethod() {
238 // TODO: Bug 1673953
239 assumeThat(sessionRule.env.isFission, equalTo(false))
240 mainSession.loadTestPath(HELLO_HTML_PATH)
241
242 var counter = 0
243
244 sessionRule.waitUntilCalled(object : ProgressDelegate {
245 override fun onPageStart(session: GeckoSession, url: String) {
246 counter++
247 }
248
249 override fun onPageStop(session: GeckoSession, success: Boolean) {
250 counter++
251 }
252
253 override fun onSecurityChange(session: GeckoSession,
254 securityInfo: ProgressDelegate.SecurityInformation) {
255 counter++
256 }
257
258 override fun onProgressChange(session: GeckoSession, progress: Int) {
259 counter++
260 }
261
262 override fun onSessionStateChange(session: GeckoSession, state: SessionState) {
263 counter++
264 }
265 })
266
267 assertThat("Callback count should be correct", counter, equalTo(1))
268 }
269
270 @Test fun waitUntilCalled_specificObjectMethod() {
271 mainSession.loadTestPath(HELLO_HTML_PATH)
272
273 var counter = 0
274
275 sessionRule.waitUntilCalled(object : ProgressDelegate {
276 @AssertCalled
277 override fun onPageStart(session: GeckoSession, url: String) {
278 counter++
279 }
280
281 @AssertCalled
282 override fun onPageStop(session: GeckoSession, success: Boolean) {
283 counter++
284 }
285 })
286
287 assertThat("Callback count should be correct", counter, equalTo(2))
288 }
289
290 @Test(expected = AssertionError::class)
291 @NullDelegate(ScrollDelegate::class)
292 fun waitUntilCalled_throwOnNullDelegateObject() {
293 mainSession.loadTestPath(HELLO_HTML_PATH)
294 sessionRule.waitForPageStop()
295
296 mainSession.reload()
297 mainSession.waitUntilCalled(object : ScrollDelegate {
298 @AssertCalled
299 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
300 }
301 })
302 }
303
304 @NullDelegate(ScrollDelegate::class)
305 @Test fun waitUntilCalled_notThrowOnNonNullDelegateObject() {
306 mainSession.loadTestPath(HELLO_HTML_PATH)
307 sessionRule.waitForPageStop()
308
309 mainSession.reload()
310 mainSession.waitUntilCalled(object : ProgressDelegate {
311 @AssertCalled
312 override fun onPageStop(session: GeckoSession, success: Boolean) {
313 }
314 })
315 }
316
317 @Test fun waitUntilCalled_multipleCount() {
318 mainSession.loadTestPath(HELLO_HTML_PATH)
319 mainSession.reload()
320
321 var counter = 0
322
323 sessionRule.waitUntilCalled(object : ProgressDelegate {
324 @AssertCalled(count = 2)
325 override fun onPageStart(session: GeckoSession, url: String) {
326 counter++
327 }
328
329 @AssertCalled(count = 2)
330 override fun onPageStop(session: GeckoSession, success: Boolean) {
331 counter++
332 }
333 })
334
335 assertThat("Callback count should be correct", counter, equalTo(4))
336 }
337
338 @Test fun waitUntilCalled_currentCall() {
339 mainSession.loadTestPath(HELLO_HTML_PATH)
340 mainSession.reload()
341
342 var counter = 0
343
344 sessionRule.waitUntilCalled(object : ProgressDelegate {
345 @AssertCalled(count = 2, order = [1, 2])
346 override fun onPageStop(session: GeckoSession, success: Boolean) {
347 val info = sessionRule.currentCall
348 assertThat("Method info should be valid", info, notNullValue())
349 assertThat("Counter should be correct",
350 info.counter, equalTo(forEachCall(1, 2)))
351 assertThat("Order should equal counter",
352 info.order, equalTo(info.counter))
353 counter++
354 }
355 })
356
357 assertThat("Callback count should be correct", counter, equalTo(2))
358 }
359
360 @Test(expected = IllegalStateException::class)
361 fun waitUntilCalled_passThroughExceptions() {
362 mainSession.loadTestPath(HELLO_HTML_PATH)
363 sessionRule.waitUntilCalled(object : ProgressDelegate {
364 @AssertCalled
365 override fun onPageStop(session: GeckoSession, success: Boolean) {
366 throw IllegalStateException()
367 }
368 })
369 }
370
371 @Test fun waitUntilCalled_zeroCount() {
372 // Support having @AssertCalled(count = 0) annotations for waitUntilCalled calls.
373 mainSession.loadTestPath(HELLO_HTML_PATH)
374 sessionRule.waitUntilCalled(object : ProgressDelegate, ScrollDelegate {
375 @AssertCalled(count = 1)
376 override fun onPageStop(session: GeckoSession, success: Boolean) {
377 }
378
379 @AssertCalled(count = 0)
380 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
381 }
382 })
383 }
384
385 @Test fun forCallbacksDuringWait_anyMethod() {
386 // TODO: Bug 1673953
387 assumeThat(sessionRule.env.isFission, equalTo(false))
388 mainSession.loadTestPath(HELLO_HTML_PATH)
389 sessionRule.waitForPageStop()
390
391 var counter = 0
392
393 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
394 override fun onPageStop(session: GeckoSession, success: Boolean) {
395 counter++
396 }
397 })
398
399 assertThat("Callback count should be correct", counter, equalTo(1))
400 }
401
402 @Test(expected = AssertionError::class)
403 fun forCallbacksDuringWait_throwOnAnyMethodNotCalled() {
404 mainSession.loadTestPath(HELLO_HTML_PATH)
405 sessionRule.waitForPageStop()
406
407 sessionRule.forCallbacksDuringWait(object : ScrollDelegate {})
408 }
409
410 @Test fun forCallbacksDuringWait_specificMethod() {
411 mainSession.loadTestPath(HELLO_HTML_PATH)
412 sessionRule.waitForPageStop()
413
414 var counter = 0
415
416 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
417 @AssertCalled
418 override fun onPageStart(session: GeckoSession, url: String) {
419 counter++
420 }
421
422 @AssertCalled
423 override fun onPageStop(session: GeckoSession, success: Boolean) {
424 counter++
425 }
426 })
427
428 assertThat("Callback count should be correct", counter, equalTo(2))
429 }
430
431 @Test fun forCallbacksDuringWait_specificMethodMultipleTimes() {
432 mainSession.loadTestPath(HELLO_HTML_PATH)
433 mainSession.reload()
434 sessionRule.waitForPageStops(2)
435
436 var counter = 0
437
438 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
439 @AssertCalled
440 override fun onPageStart(session: GeckoSession, url: String) {
441 counter++
442 }
443
444 @AssertCalled
445 override fun onPageStop(session: GeckoSession, success: Boolean) {
446 counter++
447 }
448 })
449
450 assertThat("Callback count should be correct", counter, equalTo(4))
451 }
452
453 @Test(expected = AssertionError::class)
454 fun forCallbacksDuringWait_throwOnSpecificMethodNotCalled() {
455 mainSession.loadTestPath(HELLO_HTML_PATH)
456 sessionRule.waitForPageStop()
457
458 sessionRule.forCallbacksDuringWait(object : ScrollDelegate {
459 @AssertCalled
460 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
461 }
462 })
463 }
464
465 @Test fun forCallbacksDuringWait_specificCount() {
466 mainSession.loadTestPath(HELLO_HTML_PATH)
467 mainSession.reload()
468 sessionRule.waitForPageStops(2)
469
470 var counter = 0
471
472 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
473 @AssertCalled(count = 2)
474 override fun onPageStart(session: GeckoSession, url: String) {
475 counter++
476 }
477
478 @AssertCalled(count = 2)
479 override fun onPageStop(session: GeckoSession, success: Boolean) {
480 counter++
481 }
482 })
483
484 assertThat("Callback count should be correct", counter, equalTo(4))
485 }
486
487 @Test(expected = AssertionError::class)
488 fun forCallbacksDuringWait_throwOnWrongCount() {
489 mainSession.loadTestPath(HELLO_HTML_PATH)
490 mainSession.reload()
491 sessionRule.waitForPageStops(2)
492
493 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
494 @AssertCalled(count = 1)
495 override fun onPageStart(session: GeckoSession, url: String) {
496 }
497
498 @AssertCalled(count = 1)
499 override fun onPageStop(session: GeckoSession, success: Boolean) {
500 }
501 })
502 }
503
504 @Test fun forCallbacksDuringWait_specificOrder() {
505 mainSession.loadTestPath(HELLO_HTML_PATH)
506 sessionRule.waitForPageStop()
507
508 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
509 @AssertCalled(order = [1])
510 override fun onPageStart(session: GeckoSession, url: String) {
511 }
512
513 @AssertCalled(order = [2])
514 override fun onPageStop(session: GeckoSession, success: Boolean) {
515 }
516 })
517 }
518
519 @Test(expected = AssertionError::class)
520 fun forCallbacksDuringWait_throwOnWrongOrder() {
521 mainSession.loadTestPath(HELLO_HTML_PATH)
522 sessionRule.waitForPageStop()
523
524 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
525 @AssertCalled(order = [2])
526 override fun onPageStart(session: GeckoSession, url: String) {
527 }
528
529 @AssertCalled(order = [1])
530 override fun onPageStop(session: GeckoSession, success: Boolean) {
531 }
532 })
533 }
534
535 @Test fun forCallbacksDuringWait_multipleOrder() {
536 mainSession.loadTestPath(HELLO_HTML_PATH)
537 mainSession.reload()
538 sessionRule.waitForPageStops(2)
539
540 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
541 @AssertCalled(order = [1, 3, 1])
542 override fun onPageStart(session: GeckoSession, url: String) {
543 }
544
545 @AssertCalled(order = [2, 4, 1])
546 override fun onPageStop(session: GeckoSession, success: Boolean) {
547 }
548 })
549 }
550
551 @Test(expected = AssertionError::class)
552 fun forCallbacksDuringWait_throwOnWrongMultipleOrder() {
553 mainSession.loadTestPath(HELLO_HTML_PATH)
554 mainSession.reload()
555 sessionRule.waitForPageStops(2)
556
557 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
558 @AssertCalled(order = [1, 2, 1])
559 override fun onPageStart(session: GeckoSession, url: String) {
560 }
561
562 @AssertCalled(order = [3, 4, 1])
563 override fun onPageStop(session: GeckoSession, success: Boolean) {
564 }
565 })
566 }
567
568 @Test fun forCallbacksDuringWait_notCalled() {
569 mainSession.loadTestPath(HELLO_HTML_PATH)
570 sessionRule.waitForPageStop()
571
572 sessionRule.forCallbacksDuringWait(object : ScrollDelegate {
573 @AssertCalled(false)
574 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
575 }
576 })
577 }
578
579 @Test(expected = AssertionError::class)
580 fun forCallbacksDuringWait_throwOnCallingNoCall() {
581 mainSession.loadTestPath(HELLO_HTML_PATH)
582 sessionRule.waitForPageStop()
583
584 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
585 @AssertCalled(false)
586 override fun onPageStop(session: GeckoSession, success: Boolean) {
587 }
588 })
589 }
590
591 @Test fun forCallbacksDuringWait_zeroCountEqualsNotCalled() {
592 mainSession.loadTestPath(HELLO_HTML_PATH)
593 sessionRule.waitForPageStop()
594
595 sessionRule.forCallbacksDuringWait(object : ScrollDelegate {
596 @AssertCalled(count = 0)
597 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
598 }
599 })
600 }
601
602 @Test(expected = AssertionError::class)
603 fun forCallbacksDuringWait_throwOnCallingZeroCount() {
604 mainSession.loadTestPath(HELLO_HTML_PATH)
605 sessionRule.waitForPageStop()
606
607 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
608 @AssertCalled(count = 0)
609 override fun onPageStop(session: GeckoSession, success: Boolean) {
610 }
611 })
612 }
613
614 @Test fun forCallbacksDuringWait_limitedToLastWait() {
615 mainSession.loadTestPath(HELLO_HTML_PATH)
616 mainSession.reload()
617 mainSession.reload()
618 mainSession.reload()
619
620 // Wait for Gecko to finish all loads.
621 Thread.sleep(100)
622
623 sessionRule.waitForPageStop() // Wait for loadUri.
624 sessionRule.waitForPageStop() // Wait for first reload.
625
626 var counter = 0
627
628 // assert should only apply to callbacks within range (loadUri, first reload].
629 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
630 @AssertCalled(count = 1)
631 override fun onPageStart(session: GeckoSession, url: String) {
632 counter++
633 }
634
635 @AssertCalled(count = 1)
636 override fun onPageStop(session: GeckoSession, success: Boolean) {
637 counter++
638 }
639 })
640
641 assertThat("Callback count should be correct", counter, equalTo(2))
642 }
643
644 @Test fun forCallbacksDuringWait_currentCall() {
645 mainSession.loadTestPath(HELLO_HTML_PATH)
646 sessionRule.waitForPageStop()
647
648 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
649 @AssertCalled(count = 1)
650 override fun onPageStop(session: GeckoSession, success: Boolean) {
651 val info = sessionRule.currentCall
652 assertThat("Method info should be valid", info, notNullValue())
653 assertThat("Counter should be correct",
654 info.counter, equalTo(1))
655 assertThat("Order should equal counter",
656 info.order, equalTo(0))
657 }
658 })
659 }
660
661 @Test(expected = IllegalStateException::class)
662 fun forCallbacksDuringWait_passThroughExceptions() {
663 mainSession.loadTestPath(HELLO_HTML_PATH)
664 sessionRule.waitForPageStop()
665
666 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
667 @AssertCalled
668 override fun onPageStop(session: GeckoSession, success: Boolean) {
669 throw IllegalStateException()
670 }
671 })
672 }
673
674 @Test(expected = AssertionError::class)
675 @NullDelegate(ScrollDelegate::class)
676 fun forCallbacksDuringWait_throwOnAnyNullDelegate() {
677 mainSession.loadTestPath(HELLO_HTML_PATH)
678 sessionRule.waitForPageStop()
679 mainSession.reload()
680 mainSession.waitForPageStop()
681
682 mainSession.forCallbacksDuringWait(object : NavigationDelegate, ScrollDelegate {})
683 }
684
685 @Test(expected = AssertionError::class)
686 @NullDelegate(ScrollDelegate::class)
687 fun forCallbacksDuringWait_throwOnSpecificNullDelegate() {
688 mainSession.loadTestPath(HELLO_HTML_PATH)
689 sessionRule.waitForPageStop()
690 mainSession.reload()
691 mainSession.waitForPageStop()
692
693 mainSession.forCallbacksDuringWait(object : ScrollDelegate {
694 @AssertCalled
695 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
696 }
697 })
698 }
699
700 @NullDelegate(ScrollDelegate::class)
701 @Test fun forCallbacksDuringWait_notThrowOnNonNullDelegate() {
702 mainSession.loadTestPath(HELLO_HTML_PATH)
703 sessionRule.waitForPageStop()
704 mainSession.reload()
705 mainSession.waitForPageStop()
706
707 mainSession.forCallbacksDuringWait(object : ProgressDelegate {
708 @AssertCalled
709 override fun onPageStop(session: GeckoSession, success: Boolean) {
710 }
711 })
712 }
713
714 @Test(expected = AssertionError::class)
715 fun getCurrentCall_throwOnNoCurrentCall() {
716 sessionRule.currentCall
717 }
718
719 @Test fun delegateUntilTestEnd() {
720 var counter = 0
721
722 sessionRule.delegateUntilTestEnd(object : ProgressDelegate {
723 @AssertCalled(count = 1, order = [1])
724 override fun onPageStart(session: GeckoSession, url: String) {
725 counter++
726 }
727
728 @AssertCalled(count = 1, order = [2])
729 override fun onPageStop(session: GeckoSession, success: Boolean) {
730 counter++
731 }
732 })
733
734 mainSession.loadTestPath(HELLO_HTML_PATH)
735 sessionRule.waitForPageStop()
736
737 assertThat("Callback count should be correct", counter, equalTo(2))
738 }
739
740 @Test fun delegateUntilTestEnd_notCalled() {
741 sessionRule.delegateUntilTestEnd(object : ScrollDelegate {
742 @AssertCalled(false)
743 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
744 }
745 })
746 }
747
748 @Test(expected = AssertionError::class)
749 fun delegateUntilTestEnd_throwOnNotCalled() {
750 sessionRule.delegateUntilTestEnd(object : ScrollDelegate {
751 @AssertCalled(count = 1)
752 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
753 }
754 })
755 sessionRule.performTestEndCheck()
756 }
757
758 @Test(expected = AssertionError::class)
759 fun delegateUntilTestEnd_throwOnCallingNoCall() {
760 sessionRule.delegateUntilTestEnd(object : ProgressDelegate {
761 @AssertCalled(false)
762 override fun onPageStop(session: GeckoSession, success: Boolean) {
763 }
764 })
765
766 mainSession.loadTestPath(HELLO_HTML_PATH)
767 sessionRule.waitForPageStop()
768 }
769
770 @Test(expected = AssertionError::class)
771 fun delegateUntilTestEnd_throwOnWrongOrder() {
772 sessionRule.delegateUntilTestEnd(object : ProgressDelegate {
773 @AssertCalled(count = 1, order = [2])
774 override fun onPageStart(session: GeckoSession, url: String) {
775 }
776
777 @AssertCalled(count = 1, order = [1])
778 override fun onPageStop(session: GeckoSession, success: Boolean) {
779 }
780 })
781
782 mainSession.loadTestPath(HELLO_HTML_PATH)
783 sessionRule.waitForPageStop()
784 }
785
786 @Test fun delegateUntilTestEnd_currentCall() {
787 sessionRule.delegateUntilTestEnd(object : ProgressDelegate {
788 @AssertCalled(count = 1)
789 override fun onPageStop(session: GeckoSession, success: Boolean) {
790 val info = sessionRule.currentCall
791 assertThat("Method info should be valid", info, notNullValue())
792 assertThat("Counter should be correct",
793 info.counter, equalTo(1))
794 assertThat("Order should equal counter",
795 info.order, equalTo(0))
796 }
797 })
798
799 mainSession.loadTestPath(HELLO_HTML_PATH)
800 sessionRule.waitForPageStop()
801 }
802
803 @Test fun delegateDuringNextWait() {
804 mainSession.loadTestPath(HELLO_HTML_PATH)
805 sessionRule.waitForPageStop()
806 var counter = 0
807
808 sessionRule.delegateDuringNextWait(object : ProgressDelegate {
809 @AssertCalled(count = 1, order = [1])
810 override fun onPageStart(session: GeckoSession, url: String) {
811 counter++
812 }
813
814 @AssertCalled(count = 1, order = [2])
815 override fun onPageStop(session: GeckoSession, success: Boolean) {
816 counter++
817 }
818 })
819
820 mainSession.loadTestPath(HELLO_HTML_PATH)
821 sessionRule.waitForPageStop()
822
823 assertThat("Should have delegated", counter, equalTo(2))
824
825 mainSession.reload()
826 sessionRule.waitForPageStop()
827
828 assertThat("Delegate should be cleared", counter, equalTo(2))
829 }
830
831 @Test(expected = AssertionError::class)
832 fun delegateDuringNextWait_throwOnNotCalled() {
833 sessionRule.delegateDuringNextWait(object : ScrollDelegate {
834 @AssertCalled(count = 1)
835 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
836 }
837 })
838 mainSession.loadTestPath(HELLO_HTML_PATH)
839 sessionRule.waitForPageStop()
840 }
841
842 @Test(expected = AssertionError::class)
843 fun delegateDuringNextWait_throwOnNotCalledAtTestEnd() {
844 sessionRule.delegateDuringNextWait(object : ScrollDelegate {
845 @AssertCalled(count = 1)
846 override fun onScrollChanged(session: GeckoSession, scrollX: Int, scrollY: Int) {
847 }
848 })
849 sessionRule.performTestEndCheck()
850 }
851
852 @Test fun delegateDuringNextWait_hasPrecedence() {
853 var testCounter = 0
854 var waitCounter = 0
855
856 sessionRule.delegateUntilTestEnd(object : ProgressDelegate,
857 NavigationDelegate {
858 @AssertCalled(count = 1, order = [2])
859 override fun onPageStart(session: GeckoSession, url: String) {
860 testCounter++
861 }
862
863 @AssertCalled(count = 1, order = [4])
864 override fun onPageStop(session: GeckoSession, success: Boolean) {
865 testCounter++
866 }
867
868 @AssertCalled(count = 2, order = [1, 3])
869 override fun onCanGoBack(session: GeckoSession, canGoBack: Boolean) {
870 testCounter++
871 }
872
873 @AssertCalled(count = 2, order = [1, 3])
874 override fun onCanGoForward(session: GeckoSession, canGoForward: Boolean) {
875 testCounter++
876 }
877 })
878
879 sessionRule.delegateDuringNextWait(object : ProgressDelegate {
880 @AssertCalled(count = 1, order = [1])
881 override fun onPageStart(session: GeckoSession, url: String) {
882 waitCounter++
883 }
884
885 @AssertCalled(count = 1, order = [2])
886 override fun onPageStop(session: GeckoSession, success: Boolean) {
887 waitCounter++
888 }
889 })
890
891 mainSession.loadTestPath(HELLO_HTML_PATH)
892 sessionRule.waitForPageStop()
893
894 assertThat("Text delegate should be overridden",
895 testCounter, equalTo(2))
896 assertThat("Wait delegate should be used", waitCounter, equalTo(2))
897
898 mainSession.reload()
899 sessionRule.waitForPageStop()
900
901 assertThat("Test delegate should be used", testCounter, equalTo(6))
902 assertThat("Wait delegate should be cleared", waitCounter, equalTo(2))
903 }
904
905 @Test(expected = IllegalStateException::class)
906 fun delegateDuringNextWait_passThroughExceptions() {
907 sessionRule.delegateDuringNextWait(object : ProgressDelegate {
908 @AssertCalled
909 override fun onPageStop(session: GeckoSession, success: Boolean) {
910 throw IllegalStateException()
911 }
912 })
913
914 mainSession.loadTestPath(HELLO_HTML_PATH)
915 sessionRule.waitForPageStop()
916 }
917
918 @Test(expected = AssertionError::class)
919 @NullDelegate(NavigationDelegate::class)
920 fun delegateDuringNextWait_throwOnNullDelegate() {
921 mainSession.delegateDuringNextWait(object : NavigationDelegate {
922 override fun onLocationChange(session: GeckoSession, url: String?) {
923 }
924 })
925 }
926
927 @Test fun wrapSession() {
928 val session = sessionRule.wrapSession(
929 GeckoSession(mainSession.settings))
930 sessionRule.openSession(session)
931 session.reload()
932 session.waitForPageStop()
933 }
934
935 @Test fun createOpenSession() {
936 val newSession = sessionRule.createOpenSession()
937 assertThat("Can create session", newSession, notNullValue())
938 assertThat("New session is open", newSession.isOpen, equalTo(true))
939 assertThat("New session has same settings",
940 newSession.settings, equalTo(mainSession.settings))
941 }
942
943 @Test fun createOpenSession_withSettings() {
944 val settings = GeckoSessionSettings.Builder(mainSession.settings)
945 .usePrivateMode(true)
946 .build()
947
948 val newSession = sessionRule.createOpenSession(settings)
949 assertThat("New session has same settings", newSession.settings, equalTo(settings))
950 }
951
952 @Test fun createOpenSession_canInterleaveOtherCalls() {
953 // TODO: Bug 1673953
954 assumeThat(sessionRule.env.isFission, equalTo(false))
955
956 mainSession.loadTestPath(HELLO_HTML_PATH)
957
958 val newSession = sessionRule.createOpenSession()
959 mainSession.loadTestPath(HELLO_HTML_PATH)
960 sessionRule.waitForPageStops(2)
961
962 newSession.forCallbacksDuringWait(object : ProgressDelegate {
963 @AssertCalled(false)
964 override fun onPageStop(session: GeckoSession, success: Boolean) {
965 }
966 })
967
968 mainSession.forCallbacksDuringWait(object : ProgressDelegate {
969 @AssertCalled(count = 2)
970 override fun onPageStop(session: GeckoSession, success: Boolean) {
971 }
972 })
973 }
974
975 @Test fun createClosedSession() {
976 val newSession = sessionRule.createClosedSession()
977 assertThat("Can create session", newSession, notNullValue())
978 assertThat("New session is open", newSession.isOpen, equalTo(false))
979 assertThat("New session has same settings",
980 newSession.settings, equalTo(mainSession.settings))
981 }
982
983 @Test fun createClosedSession_withSettings() {
984 val settings = GeckoSessionSettings.Builder(mainSession.settings).usePrivateMode(true).build()
985
986 val newSession = sessionRule.createClosedSession(settings)
987 assertThat("New session has same settings", newSession.settings, equalTo(settings))
988 }
989
990 @Test(expected = UiThreadUtils.TimeoutException::class)
991 @TimeoutMillis(2000)
992 @ClosedSessionAtStart
993 fun noPendingCallbacks_withSpecificSession() {
994 sessionRule.createOpenSession()
995 // Make sure we don't have unexpected pending callbacks after opening a session.
996 sessionRule.waitUntilCalled(object : HistoryDelegate, ProgressDelegate {
997 // There may be extraneous onSessionStateChange and onHistoryStateChange calls
998 // after a test, so ignore the first received.
999 @AssertCalled(count = 2)
1000 override fun onSessionStateChange(session: GeckoSession, state: SessionState) {
1001 }
1002
1003 @AssertCalled(count = 2)
1004 override fun onHistoryStateChange(session: GeckoSession, historyList: HistoryDelegate.HistoryList) {
1005 }
1006 })
1007 }
1008
1009 @Test fun waitForPageStop_withSpecificSession() {
1010 val newSession = sessionRule.createOpenSession()
1011 newSession.loadTestPath(HELLO_HTML_PATH)
1012 newSession.waitForPageStop()
1013 }
1014
1015 @Test fun waitForPageStop_withAllSessions() {
1016 val newSession = sessionRule.createOpenSession()
1017 newSession.loadTestPath(HELLO_HTML_PATH)
1018 sessionRule.waitForPageStop()
1019 }
1020
1021 @Test(expected = AssertionError::class)
1022 fun waitForPageStop_throwOnNotWrapped() {
1023 GeckoSession(mainSession.settings).waitForPageStop()
1024 }
1025
1026 @Test fun waitForPageStops_withSpecificSessions() {
1027 val newSession = sessionRule.createOpenSession()
1028 newSession.loadTestPath(HELLO_HTML_PATH)
1029 newSession.reload()
1030 newSession.waitForPageStops(2)
1031 }
1032
1033 @Test fun waitForPageStops_withAllSessions() {
1034 val newSession = sessionRule.createOpenSession()
1035 newSession.loadTestPath(HELLO_HTML_PATH)
1036 mainSession.loadTestPath(HELLO_HTML_PATH)
1037 sessionRule.waitForPageStops(2)
1038 }
1039
1040 @Test fun waitForPageStops_acrossSessionCreation() {
1041 // TODO: Bug 1673953
1042 assumeThat(sessionRule.env.isFission, equalTo(false))
1043
1044 mainSession.loadTestPath(HELLO_HTML_PATH)
1045 val session = sessionRule.createOpenSession()
1046 mainSession.reload()
1047 session.loadTestPath(HELLO_HTML_PATH)
1048 sessionRule.waitForPageStops(3)
1049 }
1050
1051 @Test fun waitUntilCalled_interfaceWithSpecificSession() {
1052 val newSession = sessionRule.createOpenSession()
1053 newSession.loadTestPath(HELLO_HTML_PATH)
1054 newSession.waitUntilCalled(ProgressDelegate::class, "onPageStop")
1055 }
1056
1057 @Test fun waitUntilCalled_interfaceWithAllSessions() {
1058 val newSession = sessionRule.createOpenSession()
1059 newSession.loadTestPath(HELLO_HTML_PATH)
1060 sessionRule.waitUntilCalled(ProgressDelegate::class, "onPageStop")
1061 }
1062
1063 @Test fun waitUntilCalled_callbackWithSpecificSession() {
1064 val newSession = sessionRule.createOpenSession()
1065 newSession.loadTestPath(HELLO_HTML_PATH)
1066 newSession.waitUntilCalled(object : ProgressDelegate {
1067 @AssertCalled(count = 1)
1068 override fun onPageStop(session: GeckoSession, success: Boolean) {
1069 }
1070 })
1071 }
1072
1073 @Test fun waitUntilCalled_callbackWithAllSessions() {
1074 val newSession = sessionRule.createOpenSession()
1075 newSession.loadTestPath(HELLO_HTML_PATH)
1076 mainSession.loadTestPath(HELLO_HTML_PATH)
1077 sessionRule.waitUntilCalled(object : ProgressDelegate {
1078 @AssertCalled(count = 2)
1079 override fun onPageStop(session: GeckoSession, success: Boolean) {
1080 }
1081 })
1082 }
1083
1084 @Test fun forCallbacksDuringWait_withSpecificSession() {
1085 val newSession = sessionRule.createOpenSession()
1086 newSession.loadTestPath(HELLO_HTML_PATH)
1087 newSession.waitForPageStop()
1088
1089 var counter = 0
1090
1091 newSession.forCallbacksDuringWait(object : ProgressDelegate {
1092 @AssertCalled(count = 1)
1093 override fun onPageStop(session: GeckoSession, success: Boolean) {
1094 counter++
1095 }
1096 })
1097
1098 mainSession.forCallbacksDuringWait(object : ProgressDelegate {
1099 @AssertCalled(false)
1100 override fun onPageStop(session: GeckoSession, success: Boolean) {
1101 counter++
1102 }
1103 })
1104
1105 assertThat("Callback count should be correct", counter, equalTo(1))
1106 }
1107
1108 @Test fun forCallbacksDuringWait_withAllSessions() {
1109 val newSession = sessionRule.createOpenSession()
1110 newSession.loadTestPath(HELLO_HTML_PATH)
1111 mainSession.loadTestPath(HELLO_HTML_PATH)
1112 sessionRule.waitForPageStops(2)
1113
1114 var counter = 0
1115
1116 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
1117 @AssertCalled(count = 2)
1118 override fun onPageStop(session: GeckoSession, success: Boolean) {
1119 counter++
1120 }
1121 })
1122
1123 assertThat("Callback count should be correct", counter, equalTo(2))
1124 }
1125
1126 @Test fun forCallbacksDuringWait_limitedToLastSessionWait() {
1127 val newSession = sessionRule.createOpenSession()
1128
1129 mainSession.loadTestPath(HELLO_HTML_PATH)
1130 mainSession.waitForPageStop()
1131
1132 newSession.loadTestPath(HELLO_HTML_PATH)
1133 newSession.waitForPageStop()
1134
1135 // forCallbacksDuringWait calls strictly apply to the last wait, session-specific or not.
1136 var counter = 0
1137
1138 mainSession.forCallbacksDuringWait(object : ProgressDelegate {
1139 @AssertCalled(false)
1140 override fun onPageStop(session: GeckoSession, success: Boolean) {
1141 counter++
1142 }
1143 })
1144
1145 newSession.forCallbacksDuringWait(object : ProgressDelegate {
1146 @AssertCalled(count = 1)
1147 override fun onPageStop(session: GeckoSession, success: Boolean) {
1148 counter++
1149 }
1150 })
1151
1152 sessionRule.forCallbacksDuringWait(object : ProgressDelegate {
1153 @AssertCalled(count = 1)
1154 override fun onPageStop(session: GeckoSession, success: Boolean) {
1155 counter++
1156 }
1157 })
1158
1159 assertThat("Callback count should be correct", counter, equalTo(2))
1160 }
1161
1162 @Test fun delegateUntilTestEnd_withSpecificSession() {
1163 val newSession = sessionRule.createOpenSession()
1164
1165 var counter = 0
1166
1167 newSession.delegateUntilTestEnd(object : ProgressDelegate {
1168 @AssertCalled(count = 1)
1169 override fun onPageStop(session: GeckoSession, success: Boolean) {
1170 counter++
1171 }
1172 })
1173
1174 mainSession.delegateUntilTestEnd(object : ProgressDelegate {
1175 @AssertCalled(false)
1176 override fun onPageStop(session: GeckoSession, success: Boolean) {
1177 counter++
1178 }
1179 })
1180
1181 newSession.loadTestPath(HELLO_HTML_PATH)
1182 newSession.waitForPageStop()
1183
1184 assertThat("Callback count should be correct", counter, equalTo(1))
1185 }
1186
1187 @Test fun delegateUntilTestEnd_withAllSessions() {
1188 var counter = 0
1189
1190 sessionRule.delegateUntilTestEnd(object : ProgressDelegate {
1191 @AssertCalled(count = 1)
1192 override fun onPageStop(session: GeckoSession, success: Boolean) {
1193 counter++
1194 }
1195 })
1196
1197 val newSession = sessionRule.createOpenSession()
1198 newSession.loadTestPath(HELLO_HTML_PATH)
1199 newSession.waitForPageStop()
1200
1201 assertThat("Callback count should be correct", counter, equalTo(1))
1202 }
1203
1204 @Test fun delegateDuringNextWait_hasPrecedenceWithSpecificSession() {
1205 val newSession = sessionRule.createOpenSession()
1206 var counter = 0
1207
1208 newSession.delegateDuringNextWait(object : ProgressDelegate {
1209 @AssertCalled(count = 1)
1210 override fun onPageStop(session: GeckoSession, success: Boolean) {
1211 counter++
1212 }
1213 })
1214
1215 newSession.delegateUntilTestEnd(object : ProgressDelegate {
1216 @AssertCalled(false)
1217 override fun onPageStop(session: GeckoSession, success: Boolean) {
1218 counter++
1219 }
1220 })
1221
1222 newSession.loadTestPath(HELLO_HTML_PATH)
1223 mainSession.loadTestPath(HELLO_HTML_PATH)
1224 sessionRule.waitForPageStops(2)
1225
1226 assertThat("Callback count should be correct", counter, equalTo(1))
1227 }
1228
1229 @Test fun delegateDuringNextWait_specificSessionOverridesAll() {
1230 val newSession = sessionRule.createOpenSession()
1231 var counter = 0
1232
1233 newSession.delegateDuringNextWait(object : ProgressDelegate {
1234 @AssertCalled(count = 1)
1235 override fun onPageStop(session: GeckoSession, success: Boolean) {
1236 counter++
1237 }
1238 })
1239
1240 sessionRule.delegateDuringNextWait(object : ProgressDelegate {
1241 @AssertCalled(count = 1)
1242 override fun onPageStop(session: GeckoSession, success: Boolean) {
1243 counter++
1244 }
1245 })
1246
1247 newSession.loadTestPath(HELLO_HTML_PATH)
1248 mainSession.loadTestPath(HELLO_HTML_PATH)
1249 sessionRule.waitForPageStops(2)
1250
1251 assertThat("Callback count should be correct", counter, equalTo(2))
1252 }
1253
1254 @WithDisplay(width = 100, height = 100)
1255 @Test fun synthesizeTap() {
1256 mainSession.loadTestPath(CLICK_TO_RELOAD_HTML_PATH)
1257 mainSession.waitForPageStop()
1258
1259 mainSession.synthesizeTap(50, 50)
1260 mainSession.waitForPageStop()
1261 }
1262
1263 @WithDisplay(width = 100, height = 100)
1264 @Test fun synthesizeMouseMove() {
1265 mainSession.loadTestPath(MOUSE_TO_RELOAD_HTML_PATH)
1266 mainSession.waitForPageStop()
1267
1268 mainSession.synthesizeMouseMove(50, 50)
1269 mainSession.waitForPageStop()
1270 }
1271
1272 @Test fun evaluateExtensionJS() {
1273 assertThat("JS string result should be correct",
1274 sessionRule.evaluateExtensionJS("return 'foo';") as String, equalTo("foo"))
1275
1276 assertThat("JS number result should be correct",
1277 sessionRule.evaluateExtensionJS("return 1+1;") as Double, equalTo(2.0))
1278
1279 assertThat("JS boolean result should be correct",
1280 sessionRule.evaluateExtensionJS("return !0;") as Boolean, equalTo(true))
1281
1282 val expected = JSONObject("{bar:42,baz:true,foo:'bar'}")
1283 val actual = sessionRule.evaluateExtensionJS("return {foo:'bar',bar:42,baz:true};") as JSONObject
1284 for (key in expected.keys()) {
1285 assertThat("JS object result should be correct",
1286 actual.get(key), equalTo(expected.get(key)))
1287 }
1288
1289 assertThat("JS array result should be correct",
1290 sessionRule.evaluateExtensionJS("return [1,2,3];") as JSONArray,
1291 equalTo(JSONArray("[1,2,3]")))
1292
1293 assertThat("Can access extension APIS",
1294 sessionRule.evaluateExtensionJS("return !!browser.runtime;") as Boolean,
1295 equalTo(true))
1296
1297 assertThat("Can access extension APIS",
1298 sessionRule.evaluateExtensionJS("""
1299 return true;
1300 // Comments at the end are allowed""".trimIndent()) as Boolean,
1301 equalTo(true))
1302
1303 try {
1304 sessionRule.evaluateExtensionJS("test({ what")
1305 assertThat("Should fail", true, equalTo(false))
1306 } catch (e: RejectedPromiseException) {
1307 assertThat("Syntax errors are reported",
1308 e.message, containsString("SyntaxError"))
1309 }
1310 }
1311
1312 @Test fun evaluateJS() {
1313 mainSession.loadTestPath(HELLO_HTML_PATH);
1314 mainSession.waitForPageStop();
1315
1316 assertThat("JS string result should be correct",
1317 mainSession.evaluateJS("'foo'") as String, equalTo("foo"))
1318
1319 assertThat("JS number result should be correct",
1320 mainSession.evaluateJS("1+1") as Double, equalTo(2.0))
1321
1322 assertThat("JS boolean result should be correct",
1323 mainSession.evaluateJS("!0") as Boolean, equalTo(true))
1324
1325 val expected = JSONObject("{bar:42,baz:true,foo:'bar'}")
1326 val actual = mainSession.evaluateJS("({foo:'bar',bar:42,baz:true})") as JSONObject
1327 for (key in expected.keys()) {
1328 assertThat("JS object result should be correct",
1329 actual.get(key), equalTo(expected.get(key)))
1330 }
1331
1332 assertThat("JS array result should be correct",
1333 mainSession.evaluateJS("[1,2,3]") as JSONArray,
1334 equalTo(JSONArray("[1,2,3]")))
1335
1336 assertThat("JS DOM object result should be correct",
1337 mainSession.evaluateJS("document.body.tagName") as String,
1338 equalTo("BODY"))
1339 }
1340
1341 @Test fun evaluateJS_windowObject() {
1342 mainSession.loadTestPath(HELLO_HTML_PATH)
1343 mainSession.waitForPageStop()
1344
1345 assertThat("JS DOM window result should be correct",
1346 (mainSession.evaluateJS("window.location.pathname")) as String,
1347 equalTo(HELLO_HTML_PATH))
1348 }
1349
1350 @Test fun evaluateJS_multipleSessions() {
1351 mainSession.loadTestPath(HELLO_HTML_PATH)
1352 mainSession.waitForPageStop()
1353
1354 mainSession.evaluateJS("this.foo = 42")
1355 assertThat("Variable should be set",
1356 mainSession.evaluateJS("this.foo") as Double, equalTo(42.0))
1357
1358 val newSession = sessionRule.createOpenSession()
1359 newSession.loadTestPath(HELLO_HTML_PATH)
1360 newSession.waitForPageStop()
1361
1362 val result = newSession.evaluateJS("this.foo")
1363 assertThat("New session should have separate JS context",
1364 result, nullValue())
1365 }
1366
1367 @Test fun evaluateJS_supportPromises() {
1368 mainSession.loadTestPath(HELLO_HTML_PATH)
1369 mainSession.waitForPageStop()
1370
1371 assertThat("Can get resolved promise",
1372 mainSession.evaluatePromiseJS(
1373 "new Promise(resolve => resolve('foo'))").value as String,
1374 equalTo("foo"));
1375
1376 val promise = mainSession.evaluatePromiseJS(
1377 "new Promise(r => window.resolve = r)")
1378
1379 mainSession.evaluateJS("window.resolve('bar')")
1380
1381 assertThat("Can wait for promise to resolve",
1382 promise.value as String, equalTo("bar"))
1383 }
1384
1385 @Test(expected = RejectedPromiseException::class)
1386 fun evaluateJS_throwOnRejectedPromise() {
1387 mainSession.loadTestPath(HELLO_HTML_PATH)
1388 mainSession.waitForPageStop()
1389 mainSession.evaluatePromiseJS("Promise.reject('foo')").value
1390 }
1391
1392 @Test fun evaluateJS_notBlockMainThread() {
1393 mainSession.loadTestPath(HELLO_HTML_PATH)
1394 mainSession.waitForPageStop()
1395 // Test that we can still receive delegate callbacks during evaluateJS,
1396 // by calling alert(), which blocks until prompt delegate is called.
1397 assertThat("JS blocking result should be correct",
1398 mainSession.evaluateJS("alert(); 'foo'") as String,
1399 equalTo("foo"))
1400 }
1401
1402 @TimeoutMillis(1000)
1403 @Test(expected = UiThreadUtils.TimeoutException::class)
1404 fun evaluateJS_canTimeout() {
1405 mainSession.loadTestPath(HELLO_HTML_PATH)
1406 mainSession.waitForPageStop()
1407 mainSession.delegateUntilTestEnd(object : PromptDelegate {
1408 override fun onAlertPrompt(session: GeckoSession, prompt: PromptDelegate.AlertPrompt): GeckoResult<PromptDelegate.PromptResponse> {
1409 // Return a GeckoResult that we will never complete, so it hangs.
1410 val res = GeckoResult<PromptDelegate.PromptResponse>()
1411 return res
1412 }
1413 })
1414 mainSession.evaluateJS("alert()")
1415 }
1416
1417 @Test(expected = RuntimeException::class)
1418 fun evaluateJS_throwOnJSException() {
1419 mainSession.loadTestPath(HELLO_HTML_PATH)
1420 mainSession.waitForPageStop()
1421 mainSession.evaluateJS("throw Error()")
1422 }
1423
1424 @Test(expected = RuntimeException::class)
1425 fun evaluateJS_throwOnSyntaxError() {
1426 mainSession.loadTestPath(HELLO_HTML_PATH)
1427 mainSession.waitForPageStop()
1428 mainSession.evaluateJS("<{[")
1429 }
1430
1431 @Test(expected = RuntimeException::class)
1432 fun evaluateJS_throwOnChromeAccess() {
1433 mainSession.loadTestPath(HELLO_HTML_PATH)
1434 mainSession.waitForPageStop()
1435 mainSession.evaluateJS("ChromeUtils")
1436 }
1437
1438 @Test fun getPrefs_undefinedPrefReturnsNull() {
1439 assertThat("Undefined pref should have null value",
1440 sessionRule.getPrefs("invalid.pref")[0], equalTo(JSONObject.NULL))
1441 }
1442
1443 @Test fun setPrefsUntilTestEnd() {
1444 sessionRule.setPrefsUntilTestEnd(mapOf(
1445 "test.pref.bool" to true,
1446 "test.pref.int" to 1,
1447 "test.pref.foo" to "foo"))
1448
1449 var prefs = sessionRule.getPrefs(
1450 "test.pref.bool",
1451 "test.pref.int",
1452 "test.pref.foo",
1453 "test.pref.bar")
1454
1455 assertThat("Prefs should be set", prefs[0] as Boolean, equalTo(true))
1456 assertThat("Prefs should be set", prefs[1] as Int, equalTo(1))
1457 assertThat("Prefs should be set", prefs[2] as String, equalTo("foo"))
1458 assertThat("Prefs should be set", prefs[3], equalTo(JSONObject.NULL))
1459
1460 sessionRule.setPrefsUntilTestEnd(mapOf(
1461 "test.pref.foo" to "bar",
1462 "test.pref.bar" to "baz"))
1463
1464 prefs = sessionRule.getPrefs(
1465 "test.pref.bool",
1466 "test.pref.int",
1467 "test.pref.foo",
1468 "test.pref.bar")
1469
1470 assertThat("New prefs should be set", prefs[0] as Boolean, equalTo(true))
1471 assertThat("New prefs should be set", prefs[1] as Int, equalTo(1))
1472 assertThat("New prefs should be set", prefs[2] as String, equalTo("bar"))
1473 assertThat("New prefs should be set", prefs[3] as String, equalTo("baz"))
1474 }
1475
1476 @Test fun setPrefsDuringNextWait() {
1477 mainSession.loadTestPath(HELLO_HTML_PATH)
1478 sessionRule.waitForPageStop()
1479
1480 sessionRule.setPrefsDuringNextWait(mapOf(
1481 "test.pref.bool" to true,
1482 "test.pref.int" to 1,
1483 "test.pref.foo" to "foo"))
1484
1485 var prefs = sessionRule.getPrefs(
1486 "test.pref.bool",
1487 "test.pref.int",
1488 "test.pref.foo")
1489
1490 assertThat("Prefs should be set before wait", prefs[0] as Boolean, equalTo(true))
1491 assertThat("Prefs should be set before wait", prefs[1] as Int, equalTo(1))
1492 assertThat("Prefs should be set before wait", prefs[2] as String, equalTo("foo"))
1493
1494 mainSession.reload()
1495 mainSession.waitForPageStop()
1496
1497 prefs = sessionRule.getPrefs(
1498 "test.pref.bool",
1499 "test.pref.int",
1500 "test.pref.foo")
1501
1502 assertThat("Prefs should be cleared after wait", prefs[0], equalTo(JSONObject.NULL))
1503 assertThat("Prefs should be cleared after wait", prefs[1], equalTo(JSONObject.NULL))
1504 assertThat("Prefs should be cleared after wait", prefs[2], equalTo(JSONObject.NULL))
1505 }
1506
1507 @Test fun setPrefsDuringNextWait_hasPrecedence() {
1508 mainSession.loadTestPath(HELLO_HTML_PATH)
1509 sessionRule.waitForPageStop()
1510
1511 sessionRule.setPrefsUntilTestEnd(mapOf(
1512 "test.pref.int" to 1,
1513 "test.pref.foo" to "foo"))
1514
1515 sessionRule.setPrefsDuringNextWait(mapOf(
1516 "test.pref.foo" to "bar",
1517 "test.pref.bar" to "baz"))
1518
1519 var prefs = sessionRule.getPrefs(
1520 "test.pref.int",
1521 "test.pref.foo",
1522 "test.pref.bar")
1523
1524 assertThat("Prefs should be overridden", prefs[0] as Int, equalTo(1))
1525 assertThat("Prefs should be overridden", prefs[1] as String, equalTo("bar"))
1526 assertThat("Prefs should be overridden", prefs[2] as String, equalTo("baz"))
1527
1528 mainSession.reload()
1529 mainSession.waitForPageStop()
1530
1531 prefs = sessionRule.getPrefs(
1532 "test.pref.int",
1533 "test.pref.foo",
1534 "test.pref.bar")
1535
1536 assertThat("Overriden prefs should be restored", prefs[0] as Int, equalTo(1))
1537 assertThat("Overriden prefs should be restored", prefs[1] as String, equalTo("foo"))
1538 assertThat("Overriden prefs should be restored", prefs[2], equalTo(JSONObject.NULL))
1539 }
1540
1541 @Test fun waitForJS() {
1542 mainSession.loadTestPath(HELLO_HTML_PATH)
1543 sessionRule.waitForPageStop()
1544
1545 assertThat("waitForJS should return correct result",
1546 mainSession.waitForJS("alert(), 'foo'") as String,
1547 equalTo("foo"))
1548
1549 mainSession.forCallbacksDuringWait(object : PromptDelegate {
1550 @AssertCalled(count = 1)
1551 override fun onAlertPrompt(session: GeckoSession, prompt: PromptDelegate.AlertPrompt): GeckoResult<PromptDelegate.PromptResponse>? {
1552 return null;
1553 }
1554 })
1555 }
1556
1557 @Test fun waitForJS_resolvePromise() {
1558 mainSession.loadTestPath(HELLO_HTML_PATH)
1559 sessionRule.waitForPageStop()
1560 assertThat("waitForJS should wait for promises",
1561 mainSession.waitForJS("Promise.resolve('foo')") as String,
1562 equalTo("foo"))
1563 }
1564
1565 @Test fun waitForJS_delegateDuringWait() {
1566 mainSession.loadTestPath(HELLO_HTML_PATH)
1567 sessionRule.waitForPageStop()
1568
1569 var count = 0
1570 mainSession.delegateDuringNextWait(object : PromptDelegate {
1571 override fun onAlertPrompt(session: GeckoSession, prompt: PromptDelegate.AlertPrompt): GeckoResult<PromptDelegate.PromptResponse> {
1572 count++
1573 return GeckoResult.fromValue(prompt.dismiss())
1574 }
1575 })
1576
1577 mainSession.waitForJS("alert()")
1578 mainSession.waitForJS("alert()")
1579
1580 // The delegate set through delegateDuringNextWait
1581 // should have been cleared after the first wait.
1582 assertThat("Delegate should only run once", count, equalTo(1))
1583 }
1584
1585 @Test(expected = RejectedPromiseException::class)
1586 fun waitForJS_whileNavigating() {
1587 mainSession.loadTestPath(HELLO_HTML_PATH)
1588 mainSession.waitForPageStop()
1589
1590 // Trigger navigation and try again
1591 mainSession.loadTestPath(HELLO2_HTML_PATH)
1592 mainSession.waitForPageStop()
1593
1594 // Navigate away and trigger a waitForJS that never completes, this will
1595 // fail because the page navigates away (disconnecting the port) before
1596 // the page can respond.
1597 mainSession.goBack()
1598 mainSession.waitForJS("new Promise(resolve => {})")
1599 }
1600
1601 private interface TestDelegate {
1602 fun onDelegate(foo: String, bar: String): Int
1603 }
1604
1605 @Test fun addExternalDelegateUntilTestEnd() {
1606 lateinit var delegate: TestDelegate
1607
1608 sessionRule.addExternalDelegateUntilTestEnd(
1609 TestDelegate::class, { newDelegate -> delegate = newDelegate }, { },
1610 object : TestDelegate {
1611 @AssertCalled(count = 1)
1612 override fun onDelegate(foo: String, bar: String): Int {
1613 assertThat("First argument should be correct", foo, equalTo("foo"))
1614 assertThat("Second argument should be correct", bar, equalTo("bar"))
1615 return 42
1616 }
1617 })
1618
1619 assertThat("Delegate should be registered", delegate, notNullValue())
1620 assertThat("Delegate return value should be correct",
1621 delegate.onDelegate("foo", "bar"), equalTo(42))
1622 sessionRule.performTestEndCheck()
1623 }
1624
1625 @Test(expected = AssertionError::class)
1626 fun addExternalDelegateUntilTestEnd_throwOnNotCalled() {
1627 sessionRule.addExternalDelegateUntilTestEnd(TestDelegate::class, { }, { },
1628 object : TestDelegate {
1629 @AssertCalled(count = 1)
1630 override fun onDelegate(foo: String, bar: String): Int {
1631 return 42
1632 }
1633 })
1634 sessionRule.performTestEndCheck()
1635 }
1636
1637 @Test fun addExternalDelegateDuringNextWait() {
1638 mainSession.loadTestPath(HELLO_HTML_PATH)
1639 sessionRule.waitForPageStop()
1640
1641 var delegate: Runnable? = null
1642
1643 sessionRule.addExternalDelegateDuringNextWait(Runnable::class,
1644 { newDelegate -> delegate = newDelegate },
1645 { delegate = null }, Runnable { })
1646
1647 assertThat("Delegate should be registered", delegate, notNullValue())
1648 delegate?.run()
1649
1650 mainSession.reload()
1651 mainSession.waitForPageStop()
1652 mainSession.forCallbacksDuringWait(Runnable @AssertCalled(count = 1) {})
1653
1654 assertThat("Delegate should be unregistered after wait", delegate, nullValue())
1655 }
1656
1657 @Test fun addExternalDelegateDuringNextWait_hasPrecedence() {
1658 mainSession.loadTestPath(HELLO_HTML_PATH)
1659 sessionRule.waitForPageStop()
1660
1661 var delegate: TestDelegate? = null
1662 val register = { newDelegate: TestDelegate -> delegate = newDelegate }
1663 val unregister = { _: TestDelegate -> delegate = null }
1664
1665 sessionRule.addExternalDelegateDuringNextWait(TestDelegate::class, register, unregister,
1666 object : TestDelegate {
1667 @AssertCalled(count = 1)
1668 override fun onDelegate(foo: String, bar: String): Int {
1669 return 24
1670 }
1671 })
1672
1673 sessionRule.addExternalDelegateUntilTestEnd(TestDelegate::class, register, unregister,
1674 object : TestDelegate {
1675 @AssertCalled(count = 1)
1676 override fun onDelegate(foo: String, bar: String): Int {
1677 return 42
1678 }
1679 })
1680
1681 assertThat("Wait delegate should be registered", delegate, notNullValue())
1682 assertThat("Wait delegate return value should be correct",
1683 delegate?.onDelegate("", ""), equalTo(24))
1684
1685 mainSession.reload()
1686 mainSession.waitForPageStop()
1687
1688 assertThat("Test delegate should still be registered", delegate, notNullValue())
1689 assertThat("Test delegate return value should be correct",
1690 delegate?.onDelegate("", ""), equalTo(42))
1691 sessionRule.performTestEndCheck()
1692 }
1693
1694 @IgnoreCrash
1695 @Test fun contentCrashIgnored() {
1696 // TODO: Bug 1673953
1697 assumeThat(sessionRule.env.isFission, equalTo(false))
1698
1699 // TODO: bug 1710940
1700 assumeThat(sessionRule.env.isIsolatedProcess, equalTo(false))
1701
1702 mainSession.loadUri(CONTENT_CRASH_URL)
1703 mainSession.waitUntilCalled(object : ContentDelegate {
1704 @AssertCalled(count = 1)
1705 override fun onCrash(session: GeckoSession) = Unit
1706 })
1707 }
1708
1709 @Test(expected = ChildCrashedException::class)
1710 fun contentCrashFails() {
1711 assumeThat(sessionRule.env.shouldShutdownOnCrash(), equalTo(false))
1712
1713 mainSession.loadUri(CONTENT_CRASH_URL)
1714 sessionRule.waitForPageStop()
1715 }
1716
1717 @Test fun waitForResult() {
1718 val handler = Handler(Looper.getMainLooper())
1719 val result = object : GeckoResult<Int>() {
1720 init {
1721 handler.postDelayed({
1722 complete(42)
1723 }, 100)
1724 }
1725 }
1726
1727 val value = sessionRule.waitForResult(result)
1728 assertThat("Value should match", value, equalTo(42))
1729 }
1730
1731 @Test(expected = IllegalStateException::class)
1732 fun waitForResultExceptionally() {
1733 val handler = Handler(Looper.getMainLooper())
1734 val result = object : GeckoResult<Int>() {
1735 init {
1736 handler.postDelayed({
1737 completeExceptionally(IllegalStateException("boom"))
1738 }, 100)
1739 }
1740 }
1741
1742 sessionRule.waitForResult(result)
1743 }
1744 }
1745