[go: nahoru, domu]

blob: e40e5a5087fbaf96b124c04ed3b16177949bbd6d [file] [log] [blame]
// Copyright 2022 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.content.Intent;
import android.net.Uri;
import android.webkit.WebChromeClient;
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.AwContentsClient.FileChooserParamsImpl;
import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.FileUtils;
import org.chromium.base.PathUtils;
import org.chromium.base.test.util.DoNotBatch;
import org.chromium.net.test.util.TestWebServer;
import java.io.File;
import java.util.concurrent.TimeoutException;
/** Integration tests for the WebChromeClient.onShowFileChooser method. */
@RunWith(Parameterized.class)
@UseParametersRunnerFactory(AwJUnit4ClassRunnerWithParameters.Factory.class)
@DoNotBatch(reason = "Shared dependencies among the tests cause conflicts during batch testing.")
public class AwFileChooserTest extends AwParameterizedTest {
@Rule public AwActivityTestRule mActivityTestRule;
private AwTestContainerView mTestContainerView;
private TestAwContentsClient mContentsClient = new TestAwContentsClient();
private AwContents mAwContents;
private AwSettings mAwSettings;
private TestWebServer mWebServer;
private TestAwContentsClient.ShowFileChooserHelper mShowFileChooserHelper;
private static final String INDEX_HTML_ROUTE = "/index.html";
private static final String FILE_CHOICE_BUTTON_ID = "fileChooserInput";
private File mTestFile1;
private File mTestFile2;
private File mTestDirectory;
private static final String TEST_DIRECTORY_PATH = PathUtils.getDataDirectory() + "/test";
private static final String EMPTY_STRING = "";
private static final String TAG = "AwFileChooserTest";
public AwFileChooserTest(AwSettingsMutation param) {
this.mActivityTestRule = new AwActivityTestRule(param.getMutation());
}
@Before
public void setUp() throws Exception {
mContentsClient = new TestAwContentsClient();
mTestContainerView = mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
mAwContents = mTestContainerView.getAwContents();
mShowFileChooserHelper = mContentsClient.getShowFileChooserHelper();
mAwSettings = mActivityTestRule.getAwSettingsOnUiThread(mAwContents);
mAwSettings.setAllowFileAccess(true);
AwActivityTestRule.enableJavaScriptOnUiThread(mAwContents);
mTestDirectory = new File(TEST_DIRECTORY_PATH);
Assert.assertTrue(mTestDirectory.mkdirs());
mTestFile1 = new File(mTestDirectory.getPath() + "/test1.txt");
Assert.assertTrue(mTestFile1.createNewFile());
mTestFile2 = new File(mTestDirectory.getPath() + "/test2.txt");
Assert.assertTrue(mTestFile2.createNewFile());
Assert.assertTrue(
"Test file 1 is an empty string!",
!EMPTY_STRING.equalsIgnoreCase(mTestFile1.getPath()));
Assert.assertNotNull("Test File 1 is null!", mTestFile1.getPath());
Assert.assertTrue(
"Test file 2 is an empty string!",
!EMPTY_STRING.equalsIgnoreCase(mTestFile2.getPath()));
Assert.assertNotNull("Test File 2 is null!", mTestFile2.getPath());
mWebServer = TestWebServer.start();
}
@After
public void tearDown() {
if (mWebServer != null) mWebServer.shutdown();
Assert.assertTrue(FileUtils.recursivelyDeleteFile(mTestDirectory, FileUtils.DELETE_ALL));
}
@Test
@SmallTest
public void testShowSingleFileChoice() throws Throwable {
final String singleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' /><br><br>");
final String url = mWebServer.setResponse(INDEX_HTML_ROUTE, singleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {Uri.fromFile(mTestFile1).toString()});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("1");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
Assert.assertEquals(WebChromeClient.FileChooserParams.MODE_OPEN, params.getMode());
}
@Test
@SmallTest
public void testShowMultipleFileChoice() throws Throwable {
final String multipleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' multiple/><br><br>");
final String url =
mWebServer.setResponse(INDEX_HTML_ROUTE, multipleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {
Uri.fromFile(mTestFile1).toString(), Uri.fromFile(mTestFile2).toString()
});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("2");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
Assert.assertEquals(WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE, params.getMode());
}
@Test
@SmallTest
public void testShowDirectoryChoice() throws Throwable {
final String multipleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' webkitdirectory ><br><br>");
final String url =
mWebServer.setResponse(INDEX_HTML_ROUTE, multipleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {
Uri.fromFile(mTestFile1).toString(), Uri.fromFile(mTestFile2).toString()
});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("2");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
// Upload folder is not currently supported in webview
// As a workaround, it is treated as OPEN_MULTIPLE_MODE
Assert.assertEquals(WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE, params.getMode());
}
@Test
@SmallTest
public void testAcceptTypes() throws Throwable {
final String[] expectedIntentExtraTypes = {"application/pdf", "text/plain", "image/png"};
final String expectedIntentType = expectedIntentExtraTypes[0];
final String expectedAcceptTypesString = ".pdf,.txt,.png";
final String singleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='"
+ expectedAcceptTypesString
+ "' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' /><br><br>");
final String url = mWebServer.setResponse(INDEX_HTML_ROUTE, singleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {Uri.fromFile(mTestFile1).toString()});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("1");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
Assert.assertEquals(expectedAcceptTypesString, params.getAcceptTypesString());
// Testing FileChooserParamsImpl.createIntent API
// Verifies that the file choice type and the extra types are set properly
Intent i = params.createIntent();
Assert.assertEquals(
i.getStringArrayExtra(Intent.EXTRA_MIME_TYPES), expectedIntentExtraTypes);
Assert.assertEquals(i.getType(), expectedIntentType);
}
@Test
@SmallTest
public void testIsCaptureEnabled() throws Throwable {
final boolean captureEnabled = true;
final String singleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' capture/><br><br>");
final String url = mWebServer.setResponse(INDEX_HTML_ROUTE, singleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {Uri.fromFile(mTestFile1).toString()});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("1");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
Assert.assertEquals(captureEnabled, params.isCaptureEnabled());
}
@Test
@SmallTest
public void testIsCaptureDisabled() throws Throwable {
final boolean captureEnabled = false;
final String singleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' /><br><br>");
final String url = mWebServer.setResponse(INDEX_HTML_ROUTE, singleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {Uri.fromFile(mTestFile1).toString()});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("1");
final FileChooserParamsImpl params = mShowFileChooserHelper.getFileParams();
Assert.assertEquals(captureEnabled, params.isCaptureEnabled());
}
@Test
@SmallTest
public void testInvalidUriIsCanceled() throws Throwable {
final String singleFileUploadPageHtml =
CommonResources.makeHtmlPageFrom(
/* headers= */ "",
/* body= */ "<input type='file' accept='.txt' id='"
+ FILE_CHOICE_BUTTON_ID
+ "' /><br><br>");
final String url = mWebServer.setResponse(INDEX_HTML_ROUTE, singleFileUploadPageHtml, null);
mShowFileChooserHelper.setChosenFilesToUpload(
// Using one real Uri and one invalid Uri because
// ActivityTestRule#executeJavaScriptAndWaitForResult
// waits for a DOM change to occur In order for the DOM to change, we must provide
// at least one real Uri
new String[] {Uri.fromFile(mTestFile1).toString(), "/BadUri/ThatIsnt/Valid"});
mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
clickSelectFileButtonAndWaitForCallback("1");
// Using two real Uris and one invalid Uri
mShowFileChooserHelper.setChosenFilesToUpload(
new String[] {
Uri.fromFile(mTestFile1).toString(),
Uri.fromFile(mTestFile2).toString(),
"/BadUri/ThatIsnt/Valid"
});
clickSelectFileButtonAndWaitForCallback("2");
}
/** Simulates user clicking Choose File button. */
private void clickSelectFileButton() throws Exception {
JSUtils.clickNodeWithUserGesture(mAwContents.getWebContents(), FILE_CHOICE_BUTTON_ID);
}
/**
* Wait until the expected string matches what
* value is in the DOM returned by the JavaScript code
*/
private void pollJavascriptResult(String script, String expectedResult) {
AwActivityTestRule.pollInstrumentationThread(
() -> {
try {
return expectedResult.equals(executeJavaScriptAndWaitForResult(script));
} catch (Throwable t) {
throw new RuntimeException(t);
}
});
}
private String executeJavaScriptAndWaitForResult(String code) throws Throwable {
return mActivityTestRule.executeJavaScriptAndWaitForResult(
mTestContainerView.getAwContents(), mContentsClient, code);
}
private void clickSelectFileButtonAndWaitForCallback(String expectedNumberOfFiles)
throws TimeoutException, Exception, Throwable {
int callCount = mShowFileChooserHelper.getCallCount();
clickSelectFileButton();
mShowFileChooserHelper.waitForCallback(callCount);
final String pollFileObjectOnDom =
"document.getElementById('" + FILE_CHOICE_BUTTON_ID + "').files.length";
pollJavascriptResult(pollFileObjectOnDom, expectedNumberOfFiles);
}
}