private void useAppCache() throws Exception { final String cachedFilePath = "/foo.js"; final String cachedFileContents = "1 + 1;"; mWebServer.setResponse(cachedFilePath, cachedFileContents, null); final String manifestPath = "/foo.manifest"; final String manifestContents = "CACHE MANIFEST\nCACHE:\n" + cachedFilePath; List<Pair<String, String>> manifestHeaders = new ArrayList<Pair<String, String>>(); manifestHeaders.add(Pair.create("Content-Disposition", "text/cache-manifest")); mWebServer.setResponse(manifestPath, manifestContents, manifestHeaders); final String pagePath = "/appcache.html"; final String pageContents = "<html manifest=\"" + manifestPath + "\">" + "<head><script src=\"" + cachedFilePath + "\"></script></head></html>"; String url = mWebServer.setResponse(pagePath, pageContents, null); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); executeJavaScriptAndWaitForResult( mAwContents, mContentsClient, "window.applicationCache.update();"); }
protected void doReload() throws Throwable { String url = mServer.setResponse("/form", LOAD_RESPONSE, null); String postData = "content=blabla"; byte[] data = EncodingUtils.getBytes(postData, "BASE64"); postUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url, data); assertEquals(0, mContentsClient.getResubmissions()); assertEquals("Load", getTitleOnUiThread(mAwContents)); // Verify reload works as expected. mServer.setResponse("/form", RELOAD_RESPONSE, null); TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = mContentsClient.getOnPageFinishedHelper(); int callCount = onPageFinishedHelper.getCallCount(); // Run reload on UI thread. getInstrumentation() .runOnMainSync( new Runnable() { @Override public void run() { mAwContents.getContentViewCore().reload(true); } }); try { // Wait for page finished callback, or a timeout. A timeout is necessary // to detect a dontResend response. onPageFinishedHelper.waitForCallback(callCount, 1, TIMEOUT, TimeUnit.SECONDS); } catch (TimeoutException e) { } }
@SmallTest @Feature({"AndroidWebView"}) public void testNullContentsClientWithServerRedirect() throws Throwable { try { // The test will fire real intents through the test activity. // Need to temporarily suppress startActivity otherwise there will be a // handler selection window and the test can't dismiss that. getActivity().setIgnoreStartActivity(true); final String testUrl = mWebServer.setResponse( "/" + CommonResources.ABOUT_FILENAME, CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true)); setupWithProvidedContentsClient( new NullContentsClient() { @Override public boolean hasWebViewClient() { return false; } }); loadUrlAsync(mAwContents, testUrl); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return mAwContents.getTitle().equals(CommonResources.ABOUT_TITLE); } }); assertNull(getActivity().getLastSentIntent()); // Now the server will redirect path1 to path2. Path2 will load ABOUT_HTML. // AwContents should create an intent for the server initiated redirection. final String path1 = "/from.html"; final String path2 = "/to.html"; final String fromUrl = mWebServer.setRedirect(path1, path2); final String toUrl = mWebServer.setResponse( path2, CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true)); loadUrlAsync(mAwContents, fromUrl); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return getActivity().getLastSentIntent() != null; } }); assertEquals(toUrl, getActivity().getLastSentIntent().getData().toString()); } finally { getActivity().setIgnoreStartActivity(false); } }
@SmallTest public void testReceiveBasicFavicon() throws Throwable { int callCount = mContentsClient.getFaviconHelper().getCallCount(); final String faviconUrl = mWebServer.setResponseBase64( FAVICON1_URL, CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(true)); final String pageUrl = mWebServer.setResponse( FAVICON1_PAGE_URL, FAVICON1_PAGE_HTML, CommonResources.getTextHtmlHeaders(true)); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); mContentsClient.getFaviconHelper().waitForCallback(callCount); assertEquals(1, mWebServer.getRequestCount(FAVICON1_URL)); Object originalFaviconSource = (new URL(faviconUrl)).getContent(); Bitmap originalFavicon = BitmapFactory.decodeStream((InputStream) originalFaviconSource); assertNotNull(originalFavicon); assertNotNull(mContentsClient.getFaviconHelper().getIcon()); assertTrue(mContentsClient.getFaviconHelper().getIcon().sameAs(originalFavicon)); // Make sure the request counter for favicon is incremented when the page is loaded again // successfully. loadUrlAsync(mAwContents, pageUrl); mContentsClient.getFaviconHelper().waitForCallback(callCount); assertEquals(2, mWebServer.getRequestCount(FAVICON1_URL)); }
@Feature({"AndroidWebView", "Downloads"}) @SmallTest public void testDownload() throws Throwable { AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient); AwContents awContents = testView.getAwContents(); final String data = "download data"; final String contentDisposition = "attachment;filename=\"download.txt\""; final String mimeType = "text/plain"; List<Pair<String, String>> downloadHeaders = new ArrayList<Pair<String, String>>(); downloadHeaders.add(Pair.create("Content-Disposition", contentDisposition)); downloadHeaders.add(Pair.create("Content-Type", mimeType)); downloadHeaders.add(Pair.create("Content-Length", Integer.toString(data.length()))); TestWebServer webServer = null; try { webServer = new TestWebServer(false); final String pageUrl = webServer.setResponse("/download.txt", data, downloadHeaders); final OnDownloadStartHelper downloadStartHelper = mContentsClient.getOnDownloadStartHelper(); final int callCount = downloadStartHelper.getCallCount(); loadUrlAsync(awContents, pageUrl); downloadStartHelper.waitForCallback(callCount); assertEquals(pageUrl, downloadStartHelper.getUrl()); assertEquals(contentDisposition, downloadStartHelper.getContentDisposition()); assertEquals(mimeType, downloadStartHelper.getMimeType()); assertEquals(data.length(), downloadStartHelper.getContentLength()); } finally { if (webServer != null) webServer.shutdown(); } }
/** * Creates a response on the TestWebServer which attempts to set a cookie when fetched. * * @param webServer the webServer on which to create the response * @param path the path component of the url (e.g "/my_thing_with_iframe.html") * @param url the url which which should appear as the src of the iframe. * @return the url which gets the response */ private String makeIframeUrl(TestWebServer webServer, String path, String url) { String responseStr = "<html><head><title>Content!</title></head>" + "<body><iframe src=" + url + "></iframe></body></html>"; return webServer.setResponse(path, responseStr, null); }
@MediumTest @Feature({"AndroidWebView", "Privacy"}) public void testAcceptCookie() throws Throwable { TestWebServer webServer = null; try { webServer = new TestWebServer(false); String path = "/cookie_test.html"; String responseStr = "<html><head><title>TEST!</title></head><body>HELLO!</body></html>"; String url = webServer.setResponse(path, responseStr, null); mCookieManager.setAcceptCookie(false); assertFalse(mCookieManager.acceptCookie()); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); setCookieWithJavaScript("test1", "value1"); assertNull(mCookieManager.getCookie(url)); List<Pair<String, String>> responseHeaders = new ArrayList<Pair<String, String>>(); responseHeaders.add(Pair.create("Set-Cookie", "header-test1=header-value1; path=" + path)); url = webServer.setResponse(path, responseStr, responseHeaders); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); assertNull(mCookieManager.getCookie(url)); mCookieManager.setAcceptCookie(true); assertTrue(mCookieManager.acceptCookie()); url = webServer.setResponse(path, responseStr, null); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); setCookieWithJavaScript("test2", "value2"); waitForCookie(url); String cookie = mCookieManager.getCookie(url); assertNotNull(cookie); validateCookies(cookie, "test2"); responseHeaders = new ArrayList<Pair<String, String>>(); responseHeaders.add(Pair.create("Set-Cookie", "header-test2=header-value2 path=" + path)); url = webServer.setResponse(path, responseStr, responseHeaders); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); waitForCookie(url); cookie = mCookieManager.getCookie(url); assertNotNull(cookie); validateCookies(cookie, "test2", "header-test2"); } finally { if (webServer != null) webServer.shutdown(); } }
@SmallTest @Feature({"AndroidWebView"}) public void testNullContentsClientClickableContent() throws Throwable { try { // The test will fire real intents through the test activity. // Need to temporarily suppress startActivity otherwise there will be a // handler selection window and the test can't dismiss that. getActivity().setIgnoreStartActivity(true); setupWithProvidedContentsClient( new NullContentsClient() { @Override public boolean hasWebViewClient() { return false; } }); final String pageTitle = "Click Title"; final String testEmail = "*****@*****.**"; final String testUrl = mWebServer.setResponse( "/email_test.html", "<html><head><title>" + pageTitle + "</title></head>" + "<body><span id='email'>" + testEmail + "</span></body>", null); // JS is required for the click simulator. mAwContents.getSettings().setJavaScriptEnabled(true); loadUrlAsync(mAwContents, testUrl); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return mAwContents.getTitle().equals(pageTitle); } }); // Clicking on an email should create an intent. DOMUtils.clickNode(this, mAwContents.getContentViewCore(), "email"); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return getActivity().getLastSentIntent() != null; } }); assertEquals( "mailto:" + testEmail.replace("@", "%40"), getActivity().getLastSentIntent().getData().toString()); } finally { getActivity().setIgnoreStartActivity(false); } }
/** * Creates a response on the TestWebServer with a script that attempts to set a cookie. * * @param webServer the webServer on which to create the response * @param path the path component of the url (e.g "/cookie_test.html") * @param key the key of the cookie * @param value the value of the cookie * @return the url which gets the response */ private String makeCookieScriptUrl( TestWebServer webServer, String path, String key, String value) { String response = "<html><head></head><body>" + "<script>document.cookie = \"" + key + "=" + value + "\";</script></body></html>"; return webServer.setResponse(path, response, null); }
/** Loads the main html then triggers the popup window. */ public void triggerPopup( final AwContents parentAwContents, TestAwContentsClient parentAwContentsClient, TestWebServer testWebServer, String mainHtml, String popupHtml, String popupPath, String triggerScript) throws Exception { enableJavaScriptOnUiThread(parentAwContents); getInstrumentation() .runOnMainSync( new Runnable() { @Override public void run() { parentAwContents.getSettings().setSupportMultipleWindows(true); parentAwContents.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); } }); final String parentUrl = testWebServer.setResponse("/popupParent.html", mainHtml, null); if (popupHtml != null) { testWebServer.setResponse(popupPath, popupHtml, null); } else { testWebServer.setResponseWithNoContentStatus(popupPath); } parentAwContentsClient.getOnCreateWindowHelper().setReturnValue(true); loadUrlSync(parentAwContents, parentAwContentsClient.getOnPageFinishedHelper(), parentUrl); TestAwContentsClient.OnCreateWindowHelper onCreateWindowHelper = parentAwContentsClient.getOnCreateWindowHelper(); int currentCallCount = onCreateWindowHelper.getCallCount(); parentAwContents.evaluateJavaScriptForTests(triggerScript, null); onCreateWindowHelper.waitForCallback( currentCallCount, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS); }
@SmallTest @Feature({"AndroidWebView"}) public void testClickableContentInIframe() throws Throwable { standardSetup(); final String pageTitle = "Click Title"; final String testEmail = "*****@*****.**"; final String testUrl = mWebServer.setResponse( "/email_test.html", "<html><head><title>" + pageTitle + "</title></head>" + "<body style='margin:0;'>" + " <iframe style='border:none;' srcdoc=\"" + " <body style='margin:0;'><span id='email'>" + testEmail + "</span></body>" + "\" src='iframe.html'></iframe>" + "</body>", null); // JS is required for the click simulator. mAwContents.getSettings().setJavaScriptEnabled(true); loadUrlAsync(mAwContents, testUrl); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return mAwContents.getTitle().equals(pageTitle); } }); int callCount = mShouldOverrideUrlLoadingHelper.getCallCount(); DOMUtils.clickNodeByJs( this, mAwContents.getContentViewCore(), "window.frames[0].document.getElementById('email')"); mShouldOverrideUrlLoadingHelper.waitForCallback(callCount); assertEquals( "mailto:" + testEmail.replace("@", "%40"), mShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl()); assertFalse(mShouldOverrideUrlLoadingHelper.isRedirect()); assertTrue(mShouldOverrideUrlLoadingHelper.hasUserGesture()); assertFalse(mShouldOverrideUrlLoadingHelper.isMainFrame()); }
@SmallTest @Feature({"AndroidWebView"}) public void testGetFavicon() throws Throwable { final AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient); final AwContents awContents = testView.getAwContents(); TestWebServer webServer = null; try { webServer = new TestWebServer(false); final String faviconUrl = webServer.setResponseBase64( "/" + CommonResources.FAVICON_FILENAME, CommonResources.FAVICON_DATA_BASE64, CommonResources.getImagePngHeaders(false)); final String pageUrl = webServer.setResponse("/favicon.html", CommonResources.FAVICON_STATIC_HTML, null); // The getFavicon will return the right icon a certain time after // the page load completes which makes it slightly hard to test. final Bitmap defaultFavicon = awContents.getFavicon(); getAwSettingsOnUiThread(awContents).setImagesEnabled(true); loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return awContents.getFavicon() != null && !awContents.getFavicon().sameAs(defaultFavicon); } }); final Object originalFaviconSource = (new URL(faviconUrl)).getContent(); final Bitmap originalFavicon = BitmapFactory.decodeStream((InputStream) originalFaviconSource); assertNotNull(originalFavicon); assertTrue(awContents.getFavicon().sameAs(originalFavicon)); } finally { if (webServer != null) webServer.shutdown(); } }
@SmallTest @Feature({"AndroidWebView"}) public void testClearCacheMemoryAndDisk() throws Throwable { final AwTestContainerView testContainer = createAwTestContainerViewOnMainSync(mContentsClient); final AwContents awContents = testContainer.getAwContents(); TestWebServer webServer = null; try { webServer = new TestWebServer(false); final String pagePath = "/clear_cache_test.html"; List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>(); // Set Cache-Control headers to cache this request. One century should be long enough. headers.add(Pair.create("Cache-Control", "max-age=3153600000")); headers.add(Pair.create("Last-Modified", "Wed, 3 Oct 2012 00:00:00 GMT")); final String pageUrl = webServer.setResponse(pagePath, "<html><body>foo</body></html>", headers); // First load to populate cache. clearCacheOnUiThread(awContents, true); loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); assertEquals(1, webServer.getRequestCount(pagePath)); // Load about:blank so next load is not treated as reload by webkit and force // revalidate with the server. loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); // No clearCache call, so should be loaded from cache. loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); assertEquals(1, webServer.getRequestCount(pagePath)); // Same as above. loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), "about:blank"); // Clear cache, so should hit server again. clearCacheOnUiThread(awContents, true); loadUrlSync(awContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); assertEquals(2, webServer.getRequestCount(pagePath)); } finally { if (webServer != null) webServer.shutdown(); } }
@SmallTest public void testReceiveBasicTouchIconLinkRel() throws Throwable { int callCount = mContentsClient.getFaviconHelper().getCallCount(); final String pageUrl = mWebServer.setResponse( TOUCHICON_REL_URL, TOUCHICON_REL_PAGE_HTML, CommonResources.getTextHtmlHeaders(true)); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); mContentsClient.getTouchIconHelper().waitForCallback(callCount, 2); assertEquals(2, mContentsClient.getTouchIconHelper().getTouchIconsCount()); assertFalse( mContentsClient .getTouchIconHelper() .hasTouchIcon(mWebServer.getBaseUrl() + TOUCHICON_REL_LINK)); assertFalse( mContentsClient .getTouchIconHelper() .hasTouchIcon(mWebServer.getBaseUrl() + TOUCHICON_REL_LINK_72)); }
@SmallTest public void testDoNotMakeRequestForFaviconAfter404() throws Throwable { mWebServer.setResponseWithNotFoundStatus(FAVICON1_URL); final String pageUrl = mWebServer.setResponse( FAVICON1_PAGE_URL, FAVICON1_PAGE_HTML, CommonResources.getTextHtmlHeaders(true)); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); poll( new Callable<Boolean>() { @Override public Boolean call() throws Exception { return mWebServer.getRequestCount(FAVICON1_URL) == 1; } }); // Make sure the request counter for favicon is not incremented, since we already got 404. loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), pageUrl); // If a request hasn't been done within this time period, we assume it won't be done. Thread.sleep(MAX_REQUEST_WAITING_LIMIT_MS); assertEquals(1, mWebServer.getRequestCount(FAVICON1_URL)); }
private String addPageToTestServer(TestWebServer webServer, String httpPath, String html) { List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>(); headers.add(Pair.create("Content-Type", "text/html")); headers.add(Pair.create("Cache-Control", "no-store")); return webServer.setResponse(httpPath, html, headers); }
@SmallTest @Feature({"AndroidWebView"}) public void testNullContentsClientOpenLink() throws Throwable { try { // The test will fire real intents through the test activity. // Need to temporarily suppress startActivity otherwise there will be a // handler selection window and the test can't dismiss that. getActivity().setIgnoreStartActivity(true); final String testUrl = mWebServer.setResponse( "/" + CommonResources.ABOUT_FILENAME, CommonResources.ABOUT_HTML, CommonResources.getTextHtmlHeaders(true)); setupWithProvidedContentsClient( new NullContentsClient() { @Override public boolean hasWebViewClient() { return false; } }); mAwContents.getSettings().setJavaScriptEnabled(true); final String pageTitle = "Click Title"; final String htmlWithLink = "<html><title>" + pageTitle + "</title>" + "<body><a id='link' href='" + testUrl + "'>Click this!</a></body></html>"; final String urlWithLink = mWebServer.setResponse( "/html_with_link.html", htmlWithLink, CommonResources.getTextHtmlHeaders(true)); loadUrlAsync(mAwContents, urlWithLink); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return mAwContents.getTitle().equals(pageTitle); } }); // Executing JS code that tries to navigate somewhere should not create an intent. assertEquals( "\"" + testUrl + "\"", JSUtils.executeJavaScriptAndWaitForResult( this, mAwContents, new OnEvaluateJavaScriptResultHelper(), "document.location.href='" + testUrl + "'")); assertNull(getActivity().getLastSentIntent()); // Clicking on a link should create an intent. DOMUtils.clickNode(this, mAwContents.getContentViewCore(), "link"); pollOnUiThread( new Callable<Boolean>() { @Override public Boolean call() { return getActivity().getLastSentIntent() != null; } }); assertEquals(testUrl, getActivity().getLastSentIntent().getData().toString()); } finally { getActivity().setIgnoreStartActivity(false); } }
private void setServerResponseAndLoad(String response) throws Throwable { String url = mWebServer.setResponse("/hittest.html", response, null); loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url); }
/** * Creates a response on the TestWebServer which attempts to set a cookie when fetched. * * @param webServer the webServer on which to create the response * @param path the path component of the url (e.g "/cookie_test.html") * @param key the key of the cookie * @param value the value of the cookie * @return the url which gets the response */ private String makeCookieUrl(TestWebServer webServer, String path, String key, String value) { String response = ""; List<Pair<String, String>> responseHeaders = new ArrayList<Pair<String, String>>(); responseHeaders.add(Pair.create("Set-Cookie", key + "=" + value + "; path=" + path)); return webServer.setResponse(path, response, responseHeaders); }