Commit e897b800 authored by Wei-Yin Chen (陳威尹)'s avatar Wei-Yin Chen (陳威尹) Committed by Commit Bot

Add end-to-end Reader mode preference tests

Bug: 1070293
Change-Id: Ib70026f3e74e50b81642866f098c1834eab1588b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2146226
Commit-Queue: Wei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760348}
parent a890dc4e
...@@ -4,12 +4,33 @@ ...@@ -4,12 +4,33 @@
package org.chromium.chrome.browser.dom_distiller; package org.chromium.chrome.browser.dom_distiller;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.actionWithAssertions;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.chromium.chrome.browser.dom_distiller.ReaderModeManager.DOM_DISTILLER_SCHEME;
import android.app.Activity; import android.app.Activity;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.action.GeneralClickAction;
import android.support.test.espresso.action.GeneralLocation;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Tap;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
...@@ -20,21 +41,31 @@ import org.junit.Before; ...@@ -20,21 +41,31 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.infobar.InfoBar; import org.chromium.chrome.browser.infobar.InfoBar;
import org.chromium.chrome.browser.infobar.ReaderModeInfoBar; import org.chromium.chrome.browser.infobar.ReaderModeInfoBar;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.ChromeTabUtils;
import org.chromium.chrome.test.util.MenuUtils;
import org.chromium.chrome.test.util.ViewUtils;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.dom_distiller.core.DistilledPagePrefs;
import org.chromium.components.dom_distiller.core.DomDistillerService;
import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer; import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
...@@ -65,11 +96,14 @@ public class ReaderModeTest { ...@@ -65,11 +96,14 @@ public class ReaderModeTest {
private EmbeddedTestServer mTestServer; private EmbeddedTestServer mTestServer;
private String mURL; private String mURL;
@Mock
DistilledPagePrefs.Observer mTestObserver;
@Before @Before
public void setUp() throws InterruptedException, TimeoutException { public void setUp() throws InterruptedException, TimeoutException {
MockitoAnnotations.initMocks(this);
mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
mURL = mTestServer.getURL(TEST_PAGE); mURL = mTestServer.getURL(TEST_PAGE);
mActivityTestRule.startMainActivityWithURL(mURL);
} }
@After @After
...@@ -80,6 +114,7 @@ public class ReaderModeTest { ...@@ -80,6 +114,7 @@ public class ReaderModeTest {
@Test @Test
@MediumTest @MediumTest
public void testReaderModeInfobarShown() { public void testReaderModeInfobarShown() {
mActivityTestRule.startMainActivityWithURL(mURL);
waitForReaderModeInfobar(); waitForReaderModeInfobar();
} }
...@@ -87,6 +122,7 @@ public class ReaderModeTest { ...@@ -87,6 +122,7 @@ public class ReaderModeTest {
@MediumTest @MediumTest
@Features.EnableFeatures(ChromeFeatureList.READER_MODE_IN_CCT) @Features.EnableFeatures(ChromeFeatureList.READER_MODE_IN_CCT)
public void testReaderModeInCCT() throws TimeoutException { public void testReaderModeInCCT() throws TimeoutException {
mActivityTestRule.startMainActivityWithURL(mURL);
Tab originalTab = mActivityTestRule.getActivity().getActivityTab(); Tab originalTab = mActivityTestRule.getActivity().getActivityTab();
String innerHtml = getInnerHtml(originalTab); String innerHtml = getInnerHtml(originalTab);
assertThat(innerHtml).doesNotContain("article-header"); assertThat(innerHtml).doesNotContain("article-header");
...@@ -110,13 +146,14 @@ public class ReaderModeTest { ...@@ -110,13 +146,14 @@ public class ReaderModeTest {
@Test @Test
@MediumTest @MediumTest
@Features.EnableFeatures(ChromeFeatureList.READER_MODE_IN_CCT) @Features.EnableFeatures({ChromeFeatureList.READER_MODE_IN_CCT})
public void testReaderModeInCCT_Incognito() throws TimeoutException { public void testReaderModeInCCT_Incognito() throws TimeoutException {
mActivityTestRule.startMainActivityWithURL(mURL);
ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(), ChromeTabUtils.fullyLoadUrlInNewTab(InstrumentationRegistry.getInstrumentation(),
mActivityTestRule.getActivity(), mURL, true); mActivityTestRule.getActivity(), mURL, true);
Tab originalTab = mActivityTestRule.getActivity().getActivityTab(); Tab originalTab = mActivityTestRule.getActivity().getActivityTab();
assertThat(originalTab.isIncognito()).isEqualTo(true); assertTrue(originalTab.isIncognito());
String innerHtml = getInnerHtml(originalTab); String innerHtml = getInnerHtml(originalTab);
assertThat(innerHtml).doesNotContain("article-header"); assertThat(innerHtml).doesNotContain("article-header");
...@@ -141,6 +178,7 @@ public class ReaderModeTest { ...@@ -141,6 +178,7 @@ public class ReaderModeTest {
@MediumTest @MediumTest
@Features.DisableFeatures(ChromeFeatureList.READER_MODE_IN_CCT) @Features.DisableFeatures(ChromeFeatureList.READER_MODE_IN_CCT)
public void testReaderModeInTab() throws TimeoutException { public void testReaderModeInTab() throws TimeoutException {
mActivityTestRule.startMainActivityWithURL(mURL);
Tab tab = mActivityTestRule.getActivity().getActivityTab(); Tab tab = mActivityTestRule.getActivity().getActivityTab();
String innerHtml = getInnerHtml(tab); String innerHtml = getInnerHtml(tab);
assertThat(innerHtml).doesNotContain("article-header"); assertThat(innerHtml).doesNotContain("article-header");
...@@ -157,6 +195,42 @@ public class ReaderModeTest { ...@@ -157,6 +195,42 @@ public class ReaderModeTest {
assertThat(innerHtml).contains(CONTENT); assertThat(innerHtml).contains(CONTENT);
} }
@Test
@MediumTest
@Features.EnableFeatures(ChromeFeatureList.READER_MODE_IN_CCT)
public void testPreferenceInCCT() {
mActivityTestRule.startMainActivityWithURL(mURL);
Tab originalTab = mActivityTestRule.getActivity().getActivityTab();
TestThreadUtils.runOnUiThreadBlocking(() -> {
originalTab.getUserDataHost()
.getUserData(ReaderModeManager.USER_DATA_KEY)
.activateReaderMode(originalTab);
});
CustomTabActivity customTabActivity = waitForCustomTabActivity();
CriteriaHelper.pollUiThread(() -> customTabActivity.getActivityTab() != null);
@NonNull
Tab distillerViewerTab = Objects.requireNonNull(customTabActivity.getActivityTab());
waitForDistillation(TITLE, distillerViewerTab);
testPreference(customTabActivity, distillerViewerTab);
}
@Test
@MediumTest
@Features.DisableFeatures(ChromeFeatureList.READER_MODE_IN_CCT)
public void testPreferenceInTab() {
// getDistillerViewUrlFromUrl() requires native, so start on blank page first.
mActivityTestRule.startMainActivityOnBlankPage();
mActivityTestRule.startMainActivityWithURL(
DomDistillerUrlUtils.getDistillerViewUrlFromUrl(DOM_DISTILLER_SCHEME, mURL, TITLE));
Tab tab = mActivityTestRule.getActivity().getActivityTab();
waitForDistillation(TITLE, tab);
testPreference(mActivityTestRule.getActivity(), tab);
}
/** /**
* Wait until a {@link CustomTabActivity} shows up, and return it. * Wait until a {@link CustomTabActivity} shows up, and return it.
* @return a {@link CustomTabActivity} * @return a {@link CustomTabActivity}
...@@ -175,19 +249,122 @@ public class ReaderModeTest { ...@@ -175,19 +249,122 @@ public class ReaderModeTest {
return activity.get(); return activity.get();
} }
private DistilledPagePrefs getDistilledPagePrefs() {
AtomicReference<DistilledPagePrefs> prefs = new AtomicReference<>();
TestThreadUtils.runOnUiThreadBlocking(() -> {
DomDistillerService domDistillerService =
DomDistillerServiceFactory.getForProfile(Profile.getLastUsedRegularProfile());
prefs.set(domDistillerService.getDistilledPagePrefs());
});
return prefs.get();
}
private void testThemeColor(ChromeActivity activity, Tab tab) {
waitForBackgroundColor(tab, "\"rgb(255, 255, 255)\"");
MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), activity,
org.chromium.chrome.R.id.reader_mode_prefs_id);
onView(isRoot()).check(ViewUtils.waitForView(allOf(withText("Dark"), isDisplayed())));
onView(withText("Dark")).perform(click());
Espresso.pressBack();
waitForBackgroundColor(tab, "\"rgb(32, 33, 36)\"");
MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), activity,
org.chromium.chrome.R.id.reader_mode_prefs_id);
onView(isRoot()).check(ViewUtils.waitForView(allOf(withText("Sepia"), isDisplayed())));
onView(withText("Sepia")).perform(click());
Espresso.pressBack();
waitForBackgroundColor(tab, "\"rgb(254, 247, 224)\"");
MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), activity,
org.chromium.chrome.R.id.reader_mode_prefs_id);
onView(isRoot()).check(ViewUtils.waitForView(allOf(withText("Light"), isDisplayed())));
onView(withText("Light")).perform(click());
Espresso.pressBack();
waitForBackgroundColor(tab, "\"rgb(255, 255, 255)\"");
verify(mTestObserver, times(3)).onChangeTheme(anyInt());
}
private void testFontSize(ChromeActivity activity, Tab tab) {
waitForFontSize(tab, "\"14px\"");
MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), activity,
org.chromium.chrome.R.id.reader_mode_prefs_id);
onView(isRoot()).check(ViewUtils.waitForView(allOf(withId(R.id.font_size), isDisplayed())));
// Max is 200% font size.
onView(withId(R.id.font_size))
.perform(actionWithAssertions(new GeneralClickAction(
Tap.SINGLE, GeneralLocation.CENTER_RIGHT, Press.FINGER)));
Espresso.pressBack();
waitForFontSize(tab, "\"28px\"");
MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), activity,
org.chromium.chrome.R.id.reader_mode_prefs_id);
onView(isRoot()).check(ViewUtils.waitForView(allOf(withId(R.id.font_size), isDisplayed())));
// Min is 50% font size.
onView(withId(R.id.font_size))
.perform(actionWithAssertions(new GeneralClickAction(
Tap.SINGLE, GeneralLocation.CENTER_LEFT, Press.FINGER)));
Espresso.pressBack();
waitForFontSize(tab, "\"7px\"");
verify(mTestObserver, times(2)).onChangeFontScaling(anyFloat());
}
private void testPreference(ChromeActivity activity, Tab tab) {
DistilledPagePrefs prefs = getDistilledPagePrefs();
prefs.addObserver(mTestObserver);
testThemeColor(activity, tab);
testFontSize(activity, tab);
// TODO(crbug/1069520): change font family as well.
}
/** /**
* @param tab The tab to be inspected. * Run JavaScript on a certain {@link Tab}.
* @return The inner HTML of a certain {@link Tab}. * @param tab The tab to be injected to.
* @param javaScript The JavaScript code to be injected.
* @return The result of the code.
*/ */
private String getInnerHtml(Tab tab) throws TimeoutException { private String runJavaScript(Tab tab, String javaScript) throws TimeoutException {
TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
javascriptHelper.evaluateJavaScriptForTests( javascriptHelper.evaluateJavaScriptForTests(tab.getWebContents(), javaScript);
tab.getWebContents(), "document.body.innerHTML");
javascriptHelper.waitUntilHasValue(); javascriptHelper.waitUntilHasValue();
return javascriptHelper.getJsonResultAndClear(); return javascriptHelper.getJsonResultAndClear();
} }
/**
* @param tab The tab to be inspected.
* @return The inner HTML of a certain {@link Tab}.
*/
private String getInnerHtml(Tab tab) throws TimeoutException {
return runJavaScript(tab, "document.body.innerHTML");
}
/**
* Wait until the background color of a certain {@link Tab} to be a given value.
* @param tab The tab to be inspected.
* @param expectedColor The expected background color
*/
private void waitForBackgroundColor(Tab tab, String expectedColor) {
String query = "window.getComputedStyle(document.body)['backgroundColor']";
CriteriaHelper.pollInstrumentationThread(
Criteria.equals(expectedColor, () -> runJavaScript(tab, query)));
}
/**
* Wait until the font size of a certain {@link Tab} to be a given value.
* @param tab The tab to be inspected.
* @param expectedSize The expected font size
*/
private void waitForFontSize(Tab tab, String expectedSize) {
String query = "window.getComputedStyle(document.body)['fontSize']";
CriteriaHelper.pollInstrumentationThread(
Criteria.equals(expectedSize, () -> runJavaScript(tab, query)));
}
/** /**
* Wait until a {@link ReaderModeInfoBar} shows up. * Wait until a {@link ReaderModeInfoBar} shows up.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment