Bug 1468048 - Add tests for GeckoSession.saveState() and restoreState() r=droeh,jchen draft
authorJames Willcox <snorp@snorp.net>
Fri, 15 Jun 2018 11:42:04 -0700
changeset 814640 956d802e22f04eca979c66f3c5593387ee57902d
parent 814639 99559b0b43994eadb47c574bb559d7d3ac8c74d7
child 814641 10c048eec10d0636653aa7052bb84adf9ba0ec0b
push id115291
push userbmo:snorp@snorp.net
push dateThu, 05 Jul 2018 20:44:33 +0000
reviewersdroeh, jchen
bugs1468048
milestone63.0a1
Bug 1468048 - Add tests for GeckoSession.saveState() and restoreState() r=droeh,jchen MozReview-Commit-ID: 7oIHXAQvGcq
mobile/android/geckoview/src/androidTest/assets/www/saveState.html
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt
new file mode 100644
--- /dev/null
+++ b/mobile/android/geckoview/src/androidTest/assets/www/saveState.html
@@ -0,0 +1,17 @@
+<html>
+    <head>
+        <title>Hello, world!</title>
+        <meta name="viewport" content="width=device-width,initial-scale=1">
+        <style>
+            p {
+                height: 300vh;
+            }
+        </style>
+    </head>
+    <body>
+        <form id="form">
+            <input type="text" id="name">
+        </form>
+        <p>Hello, world!</p>
+    </body>
+</html>
\ No newline at end of file
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -29,16 +29,18 @@ open class BaseSessionTest(noErrorCollec
         const val CONTENT_CRASH_URL = "about:crashcontent"
         const val DOWNLOAD_HTML_PATH = "/assets/www/download.html"
         const val HELLO_HTML_PATH = "/assets/www/hello.html"
         const val HELLO2_HTML_PATH = "/assets/www/hello2.html"
         const val INPUTS_PATH = "/assets/www/inputs.html"
         const val INVALID_URI = "http://www.test.invalid/"
         const val NEW_SESSION_HTML_PATH = "/assets/www/newSession.html"
         const val NEW_SESSION_CHILD_HTML_PATH = "/assets/www/newSession_child.html"
+        const val SAVE_STATE_PATH = "/assets/www/saveState.html"
+        const val SELECTION_ACTION_PATH = "/assets/www/selectionAction.html"
         const val TITLE_CHANGE_HTML_PATH = "/assets/www/titleChange.html"
         const val TRACKERS_PATH = "/assets/www/trackers.html"
     }
 
     @get:Rule val sessionRule = GeckoSessionTestRule()
 
     @get:Rule val errors = ErrorCollector()
 
@@ -59,18 +61,21 @@ open class BaseSessionTest(noErrorCollec
 
     fun getTestBytes(path: String) =
             InstrumentationRegistry.getTargetContext().resources.assets
                     .open(path.removePrefix("/assets/")).readBytes()
 
     val GeckoSession.isRemote
         get() = this.settings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS)
 
+    fun createTestUrl(path: String) =
+            GeckoSessionTestRule.APK_URI_PREFIX + path.removePrefix("/")
+
     fun GeckoSession.loadTestPath(path: String) =
-            this.loadUri(GeckoSessionTestRule.APK_URI_PREFIX + path.removePrefix("/"))
+            this.loadUri(createTestUrl(path))
 
     inline fun GeckoSession.toParcel(lambda: (Parcel) -> Unit) {
         val parcel = Parcel.obtain()
         try {
             this.writeToParcel(parcel, 0)
 
             val pos = parcel.dataPosition()
             parcel.setDataPosition(0)
@@ -79,16 +84,17 @@ open class BaseSessionTest(noErrorCollec
 
             assertThat("Read parcel matches written parcel",
                        parcel.dataPosition(), Matchers.equalTo(pos))
         } finally {
             parcel.recycle()
         }
     }
 
+
     fun GeckoSession.open() =
             sessionRule.openSession(this)
 
     fun GeckoSession.waitForPageStop() =
             sessionRule.waitForPageStop(this)
 
     fun GeckoSession.waitForPageStops(count: Int) =
             sessionRule.waitForPageStops(this, count)
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt
@@ -4,16 +4,18 @@
 
 package org.mozilla.geckoview.test
 
 import org.mozilla.geckoview.GeckoResponse
 import org.mozilla.geckoview.GeckoSession
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.IgnoreCrash
 import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI
+import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
 import org.mozilla.geckoview.test.util.Callbacks
 
 import android.support.test.filters.MediumTest
 import android.support.test.runner.AndroidJUnit4
 import org.hamcrest.Matchers.*
 import org.junit.Assume.assumeThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -114,9 +116,43 @@ class ContentDelegateTest : BaseSessionT
             sessionRule.waitUntilCalled(object : Callbacks.ContentDelegate {
                 @AssertCalled(count = 1)
                 override fun onCrash(session: GeckoSession) {
                     remainingSessions.remove(session)
                 }
             })
         }
     }
+
+    @WithDevToolsAPI
+    @WithDisplay(width = 400, height = 400)
+    @Test fun saveAndRestoreState() {
+        val startUri = createTestUrl(SAVE_STATE_PATH)
+        sessionRule.session.loadUri(startUri)
+        sessionRule.waitForPageStop()
+
+        sessionRule.session.evaluateJS("document.getElementById('name').value = 'the name'; window.scrollBy(0, 100);")
+
+        val state = sessionRule.waitForResult(sessionRule.session.saveState())
+        assertThat("State should not be null", state, notNullValue())
+
+        sessionRule.session.loadUri("about:blank")
+        sessionRule.waitForPageStop()
+
+        sessionRule.session.restoreState(state)
+        sessionRule.waitForPageStop()
+
+        sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate {
+            @AssertCalled
+            override fun onLocationChange(session: GeckoSession, url: String) {
+                assertThat("URI should match", url, equalTo(startUri))
+            }
+        })
+
+        assertThat("'name' field should match",
+                sessionRule.session.evaluateJS("document.getElementById('name').value").toString(),
+                equalTo("the name"))
+
+        assertThat("Scroll position should match",
+                sessionRule.session.evaluateJS("window.scrollY") as Double,
+                closeTo(100.0, .5))
+    }
 }