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