1 package org.robolectric.shadows; 2 3 import static com.google.common.truth.Truth.assertThat; 4 import static org.robolectric.Shadows.shadowOf; 5 6 import android.content.pm.PackageInfo; 7 import android.os.Bundle; 8 import android.view.ViewGroup.LayoutParams; 9 import android.webkit.WebBackForwardList; 10 import android.webkit.WebChromeClient; 11 import android.webkit.WebSettings; 12 import android.webkit.WebView; 13 import android.webkit.WebViewClient; 14 import androidx.test.core.app.ApplicationProvider; 15 import androidx.test.ext.junit.runners.AndroidJUnit4; 16 import java.util.HashMap; 17 import java.util.Map; 18 import org.junit.Before; 19 import org.junit.Test; 20 import org.junit.runner.RunWith; 21 import org.robolectric.annotation.Config; 22 23 @RunWith(AndroidJUnit4.class) 24 public class ShadowWebViewTest { 25 26 private WebView webView; 27 28 @Before setUp()29 public void setUp() throws Exception { 30 webView = new WebView(ApplicationProvider.getApplicationContext()); 31 } 32 33 @Test shouldRecordLastLoadedUrl()34 public void shouldRecordLastLoadedUrl() { 35 webView.loadUrl("http://example.com"); 36 assertThat(shadowOf(webView).getLastLoadedUrl()).isEqualTo("http://example.com"); 37 } 38 39 @Test shouldRecordLastLoadedUrlForRequestWithAdditionalHeaders()40 public void shouldRecordLastLoadedUrlForRequestWithAdditionalHeaders() { 41 webView.loadUrl("http://example.com", null); 42 assertThat(shadowOf(webView).getLastLoadedUrl()).isEqualTo("http://example.com"); 43 assertThat(shadowOf(webView).getLastAdditionalHttpHeaders()).isNull(); 44 45 Map<String, String> additionalHttpHeaders = new HashMap<>(1); 46 additionalHttpHeaders.put("key1", "value1"); 47 webView.loadUrl("http://example.com", additionalHttpHeaders); 48 assertThat(shadowOf(webView).getLastLoadedUrl()).isEqualTo("http://example.com"); 49 assertThat(shadowOf(webView).getLastAdditionalHttpHeaders()).isNotNull(); 50 assertThat(shadowOf(webView).getLastAdditionalHttpHeaders()).containsKey("key1"); 51 assertThat(shadowOf(webView).getLastAdditionalHttpHeaders().get("key1")).isEqualTo("value1"); 52 } 53 54 @Test shouldRecordLastLoadedData()55 public void shouldRecordLastLoadedData() { 56 webView.loadData("<html><body><h1>Hi</h1></body></html>", "text/html", "utf-8"); 57 ShadowWebView.LoadData lastLoadData = shadowOf(webView).getLastLoadData(); 58 assertThat(lastLoadData.data).isEqualTo("<html><body><h1>Hi</h1></body></html>"); 59 assertThat(lastLoadData.mimeType).isEqualTo("text/html"); 60 assertThat(lastLoadData.encoding).isEqualTo("utf-8"); 61 } 62 63 @Test shouldRecordLastLoadDataWithBaseURL()64 public void shouldRecordLastLoadDataWithBaseURL() throws Exception { 65 webView.loadDataWithBaseURL("base/url", "<html><body><h1>Hi</h1></body></html>", "text/html", "utf-8", "history/url"); 66 ShadowWebView.LoadDataWithBaseURL lastLoadData = shadowOf(webView).getLastLoadDataWithBaseURL(); 67 assertThat(lastLoadData.baseUrl).isEqualTo("base/url"); 68 assertThat(lastLoadData.data).isEqualTo("<html><body><h1>Hi</h1></body></html>"); 69 assertThat(lastLoadData.mimeType).isEqualTo("text/html"); 70 assertThat(lastLoadData.encoding).isEqualTo("utf-8"); 71 assertThat(lastLoadData.historyUrl).isEqualTo("history/url"); 72 } 73 74 @Test shouldReturnSettings()75 public void shouldReturnSettings() { 76 WebSettings webSettings = webView.getSettings(); 77 78 assertThat(webSettings).isNotNull(); 79 } 80 81 @Test shouldRecordWebViewClient()82 public void shouldRecordWebViewClient() { 83 WebViewClient webViewClient = new WebViewClient(); 84 85 assertThat(shadowOf(webView).getWebViewClient()).isNull(); 86 webView.setWebViewClient(webViewClient); 87 assertThat(shadowOf(webView).getWebViewClient()).isSameInstanceAs(webViewClient); 88 } 89 90 @Test shouldRecordWebChromeClient()91 public void shouldRecordWebChromeClient() { 92 WebChromeClient webChromeClient = new WebChromeClient(); 93 assertThat(shadowOf(webView).getWebChromeClient()).isNull(); 94 webView.setWebChromeClient(webChromeClient); 95 assertThat(shadowOf(webView).getWebChromeClient()).isSameInstanceAs(webChromeClient); 96 } 97 98 @Test shouldRecordJavascriptInteraces()99 public void shouldRecordJavascriptInteraces() { 100 String[] names = {"name1", "name2"}; 101 for (String name : names) { 102 Object obj = new Object(); 103 assertThat(shadowOf(webView).getJavascriptInterface(name)).isNull(); 104 webView.addJavascriptInterface(obj, name); 105 assertThat(shadowOf(webView).getJavascriptInterface(name)).isSameInstanceAs(obj); 106 } 107 } 108 109 @Test canGoBack()110 public void canGoBack() throws Exception { 111 webView.clearHistory(); 112 assertThat(webView.canGoBack()).isFalse(); 113 webView.loadUrl("fake.url", null); 114 webView.loadUrl("fake.url", null); 115 assertThat(webView.canGoBack()).isTrue(); 116 webView.goBack(); 117 assertThat(webView.canGoBack()).isFalse(); 118 } 119 120 @Test shouldStoreTheNumberOfTimesGoBackWasCalled()121 public void shouldStoreTheNumberOfTimesGoBackWasCalled() throws Exception { 122 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(0); 123 webView.goBack(); 124 webView.loadUrl("foo.bar", null); 125 // If there is no history (only one page), we shouldn't invoke go back. 126 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(0); 127 webView.loadUrl("foo.bar", null); 128 webView.loadUrl("foo.bar", null); 129 webView.loadUrl("foo.bar", null); 130 webView.loadUrl("foo.bar", null); 131 webView.loadUrl("foo.bar", null); 132 webView.goBack(); 133 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(1); 134 webView.goBack(); 135 webView.goBack(); 136 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(3); 137 webView.goBack(); 138 webView.goBack(); 139 webView.goBack(); 140 // We've gone back one too many times for the history, so we should only have 5 invocations. 141 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(5); 142 } 143 144 @Test shouldStoreTheNumberOfTimesGoBackWasCalled_SetCanGoBack()145 public void shouldStoreTheNumberOfTimesGoBackWasCalled_SetCanGoBack() { 146 shadowOf(webView).setCanGoBack(true); 147 webView.goBack(); 148 webView.goBack(); 149 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(2); 150 shadowOf(webView).setCanGoBack(false); 151 webView.goBack(); 152 webView.goBack(); 153 assertThat(shadowOf(webView).getGoBackInvocations()).isEqualTo(2); 154 } 155 156 @Test shouldRecordClearCacheWithoutDiskFiles()157 public void shouldRecordClearCacheWithoutDiskFiles() { 158 assertThat(shadowOf(webView).wasClearCacheCalled()).isFalse(); 159 160 webView.clearCache(false); 161 assertThat(shadowOf(webView).wasClearCacheCalled()).isTrue(); 162 assertThat(shadowOf(webView).didClearCacheIncludeDiskFiles()).isFalse(); 163 } 164 165 @Test shouldRecordClearCacheWithDiskFiles()166 public void shouldRecordClearCacheWithDiskFiles() { 167 assertThat(shadowOf(webView).wasClearCacheCalled()).isFalse(); 168 169 webView.clearCache(true); 170 assertThat(shadowOf(webView).wasClearCacheCalled()).isTrue(); 171 assertThat(shadowOf(webView).didClearCacheIncludeDiskFiles()).isTrue(); 172 } 173 174 @Test shouldRecordClearFormData()175 public void shouldRecordClearFormData() { 176 assertThat(shadowOf(webView).wasClearFormDataCalled()).isFalse(); 177 webView.clearFormData(); 178 assertThat(shadowOf(webView).wasClearFormDataCalled()).isTrue(); 179 } 180 181 @Test shouldRecordClearHistory()182 public void shouldRecordClearHistory() { 183 assertThat(shadowOf(webView).wasClearHistoryCalled()).isFalse(); 184 webView.clearHistory(); 185 assertThat(shadowOf(webView).wasClearHistoryCalled()).isTrue(); 186 } 187 188 @Test shouldRecordClearView()189 public void shouldRecordClearView() { 190 assertThat(shadowOf(webView).wasClearViewCalled()).isFalse(); 191 webView.clearView(); 192 assertThat(shadowOf(webView).wasClearViewCalled()).isTrue(); 193 } 194 195 @Test getOriginalUrl()196 public void getOriginalUrl() throws Exception { 197 webView.clearHistory(); 198 assertThat(webView.getOriginalUrl()).isNull(); 199 webView.loadUrl("fake.url", null); 200 assertThat(webView.getOriginalUrl()).isEqualTo("fake.url"); 201 } 202 203 @Test getUrl()204 public void getUrl() throws Exception { 205 webView.clearHistory(); 206 assertThat(webView.getUrl()).isNull(); 207 webView.loadUrl("fake.url", null); 208 assertThat(webView.getUrl()).isEqualTo("fake.url"); 209 } 210 211 @Test 212 @Config(minSdk = 19) evaluateJavascript()213 public void evaluateJavascript() { 214 assertThat(shadowOf(webView).getLastEvaluatedJavascript()).isNull(); 215 webView.evaluateJavascript("myScript", null); 216 assertThat(shadowOf(webView).getLastEvaluatedJavascript()).isEqualTo("myScript"); 217 } 218 219 @Test shouldRecordDestroy()220 public void shouldRecordDestroy() { 221 assertThat(shadowOf(webView).wasDestroyCalled()).isFalse(); 222 webView.destroy(); 223 assertThat(shadowOf(webView).wasDestroyCalled()).isTrue(); 224 } 225 226 @Test shouldRecordOnPause()227 public void shouldRecordOnPause() { 228 assertThat(shadowOf(webView).wasOnPauseCalled()).isFalse(); 229 webView.onPause(); 230 assertThat(shadowOf(webView).wasOnPauseCalled()).isTrue(); 231 } 232 233 @Test shouldRecordOnResume()234 public void shouldRecordOnResume() { 235 assertThat(shadowOf(webView).wasOnResumeCalled()).isFalse(); 236 webView.onResume(); 237 assertThat(shadowOf(webView).wasOnResumeCalled()).isTrue(); 238 } 239 240 @Test shouldReturnPreviouslySetLayoutParams()241 public void shouldReturnPreviouslySetLayoutParams() { 242 assertThat(webView.getLayoutParams()).isNull(); 243 LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 244 webView.setLayoutParams(params); 245 assertThat(webView.getLayoutParams()).isSameInstanceAs(params); 246 } 247 248 @Test shouldSaveAndRestoreHistoryList()249 public void shouldSaveAndRestoreHistoryList() { 250 webView.loadUrl("foo1.bar"); 251 webView.loadUrl("foo2.bar"); 252 253 Bundle outState = new Bundle(); 254 webView.saveState(outState); 255 256 WebView newWebView = new WebView(ApplicationProvider.getApplicationContext()); 257 WebBackForwardList historyList = newWebView.restoreState(outState); 258 259 assertThat(newWebView.canGoBack()).isTrue(); 260 assertThat(newWebView.getUrl()).isEqualTo("foo2.bar"); 261 262 assertThat(historyList.getSize()).isEqualTo(2); 263 assertThat(historyList.getCurrentItem().getUrl()).isEqualTo("foo2.bar"); 264 } 265 266 @Test shouldReturnHistoryFromSaveState()267 public void shouldReturnHistoryFromSaveState() { 268 webView.loadUrl("foo1.bar"); 269 webView.loadUrl("foo2.bar"); 270 271 Bundle outState = new Bundle(); 272 WebBackForwardList historyList = webView.saveState(outState); 273 274 assertThat(historyList.getSize()).isEqualTo(2); 275 assertThat(historyList.getCurrentItem().getUrl()).isEqualTo("foo2.bar"); 276 } 277 278 @Test shouldReturnNullFromRestoreStateIfNoHistoryAvailable()279 public void shouldReturnNullFromRestoreStateIfNoHistoryAvailable() { 280 Bundle inState = new Bundle(); 281 WebBackForwardList historyList = webView.restoreState(inState); 282 283 assertThat(historyList).isNull(); 284 } 285 286 @Test shouldCopyBackForwardListWhenEmpty()287 public void shouldCopyBackForwardListWhenEmpty() { 288 WebBackForwardList historyList = webView.copyBackForwardList(); 289 290 assertThat(historyList.getSize()).isEqualTo(0); 291 assertThat(historyList.getCurrentIndex()).isEqualTo(-1); 292 assertThat(historyList.getCurrentItem()).isNull(); 293 } 294 295 @Test shouldCopyBackForwardListWhenPopulated()296 public void shouldCopyBackForwardListWhenPopulated() { 297 webView.loadUrl("foo1.bar"); 298 webView.loadUrl("foo2.bar"); 299 300 WebBackForwardList historyList = webView.copyBackForwardList(); 301 302 assertThat(historyList.getSize()).isEqualTo(2); 303 assertThat(historyList.getCurrentItem().getUrl()).isEqualTo("foo2.bar"); 304 } 305 306 @Test shouldReturnCopyFromCopyBackForwardList()307 public void shouldReturnCopyFromCopyBackForwardList() { 308 WebBackForwardList historyList = webView.copyBackForwardList(); 309 310 // Adding history after copying should not affect the copy. 311 webView.loadUrl("foo1.bar"); 312 webView.loadUrl("foo2.bar"); 313 314 assertThat(historyList.getSize()).isEqualTo(0); 315 assertThat(historyList.getCurrentIndex()).isEqualTo(-1); 316 assertThat(historyList.getCurrentItem()).isNull(); 317 } 318 319 @Test 320 @Config(minSdk = 26) shouldReturnNullForGetCurrentWebViewPackageIfNotSet()321 public void shouldReturnNullForGetCurrentWebViewPackageIfNotSet() { 322 assertThat(WebView.getCurrentWebViewPackage()).isNull(); 323 } 324 325 @Test 326 @Config(minSdk = 26) shouldReturnStoredPackageInfoForGetCurrentWebViewPackageIfSet()327 public void shouldReturnStoredPackageInfoForGetCurrentWebViewPackageIfSet() { 328 PackageInfo packageInfo = new PackageInfo(); 329 packageInfo.packageName = "org.robolectric.shadows.shadowebviewtest"; 330 ShadowWebView.setCurrentWebViewPackage(packageInfo); 331 assertThat(WebView.getCurrentWebViewPackage()).isEqualTo(packageInfo); 332 } 333 } 334