[go: nahoru, domu]

blob: 9ce9293c4244a126337480ecb8c1a051f458df56 [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview.test;
import android.util.Pair;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.test.TestAwContentsClient.OnReceivedErrorHelper;
import org.chromium.base.task.PostTask;
import org.chromium.base.task.TaskTraits;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.Feature;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content_public.common.ContentUrlConstants;
import org.chromium.net.test.util.TestWebServer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
/** Tests for the ContentViewClient.onPageStarted() method. */
@RunWith(Parameterized.class)
@UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
public class ClientOnPageStartedTest extends AwParameterizedTest {
@Rule public AwActivityTestRule mActivityTestRule;
private TestAwContentsClient mContentsClient;
private AwContents mAwContents;
private TestWebServer mWebServer;
private CallbackHelper mHangingRequestCallbackHelper;
private Semaphore mHangingRequestSemaphore;
private String mHangingUrl;
private String mRedirectToHangingUrl;
public ClientOnPageStartedTest(AwSettingsMutation param) {
this.mActivityTestRule = new AwActivityTestRule(param.getMutation());
}
@Before
public void setupTestServer() throws Exception {
mWebServer = TestWebServer.start();
mHangingRequestCallbackHelper = new CallbackHelper();
mHangingRequestSemaphore = new Semaphore(0);
Runnable hangingResponseRunnable =
() -> {
mHangingRequestCallbackHelper.notifyCalled();
try {
mHangingRequestSemaphore.acquire();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
};
mHangingUrl =
mWebServer.setResponseWithRunnableAction(
"/hanging_page.html",
"<body>hanging page</body>",
null,
hangingResponseRunnable);
mRedirectToHangingUrl = mWebServer.setRedirect("/redirect_to_hanging.html", mHangingUrl);
}
@After
public void tearDownTestServer() {
if (mHangingRequestSemaphore != null) {
mHangingRequestSemaphore.release(9999);
}
if (mWebServer != null) {
mWebServer.shutdown();
}
mWebServer = null;
mHangingRequestCallbackHelper = null;
mHangingRequestSemaphore = null;
mHangingUrl = null;
mRedirectToHangingUrl = null;
}
@Before
public void setUp() {
setTestAwContentsClient(new TestAwContentsClient());
AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
}
private void setTestAwContentsClient(TestAwContentsClient contentsClient) {
mContentsClient = contentsClient;
final AwTestContainerView testContainerView =
mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
mAwContents = testContainerView.getAwContents();
}
@Test
@MediumTest
@Feature({"AndroidWebView"})
public void testOnPageStartedPassesCorrectUrl() throws Throwable {
TestCallbackHelperContainer.OnPageStartedHelper onPageStartedHelper =
mContentsClient.getOnPageStartedHelper();
String html = "<html><body>Simple page.</body></html>";
int currentCallCount = onPageStartedHelper.getCallCount();
mActivityTestRule.loadDataAsync(mAwContents, html, "text/html", false);
onPageStartedHelper.waitForCallback(currentCallCount);
Assert.assertEquals("data:text/html," + html, onPageStartedHelper.getUrl());
}
@Test
@MediumTest
@Feature({"AndroidWebView"})
public void testOnPageStartedCalledOnceOnError() throws Throwable {
class LocalTestClient extends TestAwContentsClient {
private boolean mIsOnReceivedErrorCalled;
private boolean mIsOnPageStartedCalled;
private boolean mAllowAboutBlank;
@Override
public void onReceivedError(AwWebResourceRequest request, AwWebResourceError error) {
Assert.assertEquals(
"onReceivedError called twice for " + request.url,
false,
mIsOnReceivedErrorCalled);
mIsOnReceivedErrorCalled = true;
Assert.assertEquals(
"onPageStarted not called before onReceivedError for " + request.url,
true,
mIsOnPageStartedCalled);
super.onReceivedError(request, error);
}
@Override
public void onPageStarted(String url) {
if (mAllowAboutBlank && ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL.equals(url)) {
super.onPageStarted(url);
return;
}
Assert.assertEquals(
"onPageStarted called twice for " + url, false, mIsOnPageStartedCalled);
mIsOnPageStartedCalled = true;
Assert.assertEquals(
"onReceivedError called before onPageStarted for " + url,
false,
mIsOnReceivedErrorCalled);
super.onPageStarted(url);
}
void setAllowAboutBlank() {
mAllowAboutBlank = true;
}
}
LocalTestClient testContentsClient = new LocalTestClient();
setTestAwContentsClient(testContentsClient);
OnReceivedErrorHelper onReceivedErrorHelper = mContentsClient.getOnReceivedErrorHelper();
TestCallbackHelperContainer.OnPageStartedHelper onPageStartedHelper =
mContentsClient.getOnPageStartedHelper();
TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
mContentsClient.getOnPageFinishedHelper();
String invalidUrl = "http://localhost:7/non_existent";
mActivityTestRule.loadUrlSync(mAwContents, onPageFinishedHelper, invalidUrl);
Assert.assertEquals(invalidUrl, onReceivedErrorHelper.getRequest().url);
Assert.assertEquals(invalidUrl, onPageStartedHelper.getUrl());
// Rather than wait a fixed time to see that another onPageStarted callback isn't issued
// we load a valid page. Since callbacks arrive sequentially, this will ensure that
// any extra calls of onPageStarted / onReceivedError will arrive to our client.
testContentsClient.setAllowAboutBlank();
mActivityTestRule.loadUrlSync(
mAwContents, onPageFinishedHelper, ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL);
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testNotCalledForDownloadContentDisposition() throws Throwable {
String data = "download data";
String contentDisposition = "attachment;filename=\"download.txt\"";
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())));
String downloadUrl = mWebServer.setResponse("/download.txt", data, downloadHeaders);
doDownloadTest(downloadUrl);
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testNotCalledForDownloadPdf() throws Throwable {
String data = "";
String mimeType = " application/pdf";
List<Pair<String, String>> downloadHeaders = new ArrayList<Pair<String, String>>();
downloadHeaders.add(Pair.create("Content-Type", mimeType));
downloadHeaders.add(Pair.create("Content-Length", Integer.toString(data.length())));
String downloadUrl = mWebServer.setResponse("/download.pdf", data, downloadHeaders);
doDownloadTest(downloadUrl);
}
private void doDownloadTest(String downloadUrl) throws Throwable {
mActivityTestRule.loadUrlSync(
mAwContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
// Navigate to download from js.
int downloadCount = mContentsClient.getOnDownloadStartHelper().getCallCount();
int pageStartedCount = mContentsClient.getOnPageStartedHelper().getCallCount();
int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
int shouldOverrideUrlLoadingCount =
mContentsClient.getShouldOverrideUrlLoadingHelper().getCallCount();
int onLoadResourceCount = mContentsClient.getOnLoadResourceHelper().getCallCount();
PostTask.runOrPostTask(
TaskTraits.UI_DEFAULT,
() -> {
mAwContents.evaluateJavaScript(
"window.location.assign(\"" + downloadUrl + "\");", null);
});
// onPageStarted and onPageFinished should not be called.
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.waitForCallback(shouldOverrideUrlLoadingCount);
mContentsClient.getOnDownloadStartHelper().waitForCallback(downloadCount);
mContentsClient.getOnLoadResourceHelper().waitForCallback(onLoadResourceCount);
Assert.assertEquals(
downloadUrl,
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.getShouldOverrideUrlLoadingUrl());
Assert.assertEquals(downloadUrl, mContentsClient.getOnDownloadStartHelper().getUrl());
Assert.assertEquals(
downloadUrl, mContentsClient.getOnLoadResourceHelper().getLastLoadedResource());
Assert.assertEquals(
pageStartedCount, mContentsClient.getOnPageStartedHelper().getCallCount());
Assert.assertEquals(
pageFinishedCount, mContentsClient.getOnPageFinishedHelper().getCallCount());
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testRendererInitiatedHangingNavigation() throws Throwable {
mActivityTestRule.loadUrlSync(
mAwContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
// Load page that hangs (before semaphore is released).
int pageStartedCount = mContentsClient.getOnPageStartedHelper().getCallCount();
int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
int shouldOverrideUrlLoadingCount =
mContentsClient.getShouldOverrideUrlLoadingHelper().getCallCount();
int onLoadResourceCount = mContentsClient.getOnLoadResourceHelper().getCallCount();
int hangingRequestCount = mHangingRequestCallbackHelper.getCallCount();
PostTask.runOrPostTask(
TaskTraits.UI_DEFAULT,
() -> {
mAwContents.evaluateJavaScript(
"window.location.assign(\"" + mHangingUrl + "\");", null);
});
// onPageStarted and onPageFinished should not be called yet.
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.waitForCallback(shouldOverrideUrlLoadingCount);
mContentsClient.getOnLoadResourceHelper().waitForCallback(onLoadResourceCount);
mHangingRequestCallbackHelper.waitForCallback(hangingRequestCount);
Assert.assertEquals(
mHangingUrl,
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.getShouldOverrideUrlLoadingUrl());
Assert.assertEquals(
mHangingUrl, mContentsClient.getOnLoadResourceHelper().getLastLoadedResource());
Assert.assertEquals(
pageStartedCount, mContentsClient.getOnPageStartedHelper().getCallCount());
Assert.assertEquals(
pageFinishedCount, mContentsClient.getOnPageFinishedHelper().getCallCount());
// Release request on server. Should get onPageStarted/Finished after.
mHangingRequestSemaphore.release();
mContentsClient.getOnPageStartedHelper().waitForCallback(pageStartedCount);
mContentsClient.getOnPageFinishedHelper().waitForCallback(pageFinishedCount);
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageStartedHelper().getUrl());
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageFinishedHelper().getUrl());
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testBrowserInitiatedHangingNavigation() throws Throwable {
// Load page that hangs (before semaphore is released).
int pageStartedCount = mContentsClient.getOnPageStartedHelper().getCallCount();
int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
int onLoadResourceCount = mContentsClient.getOnLoadResourceHelper().getCallCount();
int hangingRequestCount = mHangingRequestCallbackHelper.getCallCount();
mActivityTestRule.loadUrlAsync(mAwContents, mHangingUrl);
// onPageStarted and onPageFinished should not be called yet.
mContentsClient.getOnLoadResourceHelper().waitForCallback(onLoadResourceCount);
mHangingRequestCallbackHelper.waitForCallback(hangingRequestCount);
Assert.assertEquals(
mHangingUrl, mContentsClient.getOnLoadResourceHelper().getLastLoadedResource());
Assert.assertEquals(
pageStartedCount, mContentsClient.getOnPageStartedHelper().getCallCount());
Assert.assertEquals(
pageFinishedCount, mContentsClient.getOnPageFinishedHelper().getCallCount());
// Release request on server. Should get onPageStarted/Finished after.
mHangingRequestSemaphore.release();
mContentsClient.getOnPageStartedHelper().waitForCallback(pageStartedCount);
mContentsClient.getOnPageFinishedHelper().waitForCallback(pageFinishedCount);
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageStartedHelper().getUrl());
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageFinishedHelper().getUrl());
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testRendererInitiatedRedirectHangingNavigation() throws Throwable {
mActivityTestRule.loadUrlSync(
mAwContents, mContentsClient.getOnPageFinishedHelper(), "about:blank");
// Load page that hangs (before semaphore is released).
int pageStartedCount = mContentsClient.getOnPageStartedHelper().getCallCount();
int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
int shouldOverrideUrlLoadingCount =
mContentsClient.getShouldOverrideUrlLoadingHelper().getCallCount();
int onLoadResourceCount = mContentsClient.getOnLoadResourceHelper().getCallCount();
int hangingRequestCount = mHangingRequestCallbackHelper.getCallCount();
PostTask.runOrPostTask(
TaskTraits.UI_DEFAULT,
() -> {
mAwContents.evaluateJavaScript(
"window.location.assign(\"" + mRedirectToHangingUrl + "\");", null);
});
// onPageStarted and onPageFinished should not be called yet.
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.waitForCallback(shouldOverrideUrlLoadingCount, 2);
mContentsClient.getOnLoadResourceHelper().waitForCallback(onLoadResourceCount);
mHangingRequestCallbackHelper.waitForCallback(hangingRequestCount);
Assert.assertEquals(
mHangingUrl,
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.getShouldOverrideUrlLoadingUrl());
Assert.assertEquals(
mRedirectToHangingUrl,
mContentsClient.getOnLoadResourceHelper().getLastLoadedResource());
Assert.assertEquals(
pageStartedCount, mContentsClient.getOnPageStartedHelper().getCallCount());
Assert.assertEquals(
pageFinishedCount, mContentsClient.getOnPageFinishedHelper().getCallCount());
// Release request on server. Should get onPageStarted/Finished after.
mHangingRequestSemaphore.release();
mContentsClient.getOnPageStartedHelper().waitForCallback(pageStartedCount);
mContentsClient.getOnPageFinishedHelper().waitForCallback(pageFinishedCount);
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageStartedHelper().getUrl());
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageFinishedHelper().getUrl());
}
@Test
@SmallTest
@Feature({"AndroidWebView"})
public void testBrowserInitiatedRedirectHangingNavigation() throws Throwable {
// Load page that hangs (before semaphore is released).
int pageStartedCount = mContentsClient.getOnPageStartedHelper().getCallCount();
int pageFinishedCount = mContentsClient.getOnPageFinishedHelper().getCallCount();
int shouldOverrideUrlLoadingCount =
mContentsClient.getShouldOverrideUrlLoadingHelper().getCallCount();
int onLoadResourceCount = mContentsClient.getOnLoadResourceHelper().getCallCount();
int hangingRequestCount = mHangingRequestCallbackHelper.getCallCount();
mActivityTestRule.loadUrlAsync(mAwContents, mRedirectToHangingUrl);
// onPageStarted and onPageFinished should not be called yet.
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.waitForCallback(shouldOverrideUrlLoadingCount);
mContentsClient.getOnLoadResourceHelper().waitForCallback(onLoadResourceCount);
mHangingRequestCallbackHelper.waitForCallback(hangingRequestCount);
Assert.assertEquals(
mHangingUrl,
mContentsClient
.getShouldOverrideUrlLoadingHelper()
.getShouldOverrideUrlLoadingUrl());
Assert.assertEquals(
mRedirectToHangingUrl,
mContentsClient.getOnLoadResourceHelper().getLastLoadedResource());
Assert.assertEquals(
pageStartedCount, mContentsClient.getOnPageStartedHelper().getCallCount());
Assert.assertEquals(
pageFinishedCount, mContentsClient.getOnPageFinishedHelper().getCallCount());
// Release request on server. Should get onPageStarted/Finished after.
mHangingRequestSemaphore.release();
mContentsClient.getOnPageStartedHelper().waitForCallback(pageStartedCount);
mContentsClient.getOnPageFinishedHelper().waitForCallback(pageFinishedCount);
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageStartedHelper().getUrl());
Assert.assertEquals(mHangingUrl, mContentsClient.getOnPageFinishedHelper().getUrl());
}
}