Commit 3389e04a authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Added initial UI tests for details.

Also, a small refactoring to allow code reuse between infobox-tests and details-tests.

Bug: b/133725664
Change-Id: Ia241cb3bfdae69533a12f1c88fe466deefabef61
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1658021
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarJordan Demeulenaere <jdemeulenaere@chromium.org>
Cr-Commit-Position: refs/heads/master@{#670030}
parent dcf9662d
...@@ -155,9 +155,11 @@ android_library("test_java") { ...@@ -155,9 +155,11 @@ android_library("test_java") {
java_files = [ java_files = [
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantActionsCarouselUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestTestHelper.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestTestHelper.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentRequestUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/EditDistanceTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/EditDistanceTest.java",
] ]
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/autofill_assistant_shadow_bg" android:background="@drawable/autofill_assistant_shadow_bg"
......
...@@ -5,13 +5,20 @@ ...@@ -5,13 +5,20 @@
package org.chromium.chrome.browser.autofill_assistant.details; package org.chromium.chrome.browser.autofill_assistant.details;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsViewBinder.ViewHolder; import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsViewBinder.ViewHolder;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor; import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import java.util.Locale;
/** /**
* Coordinator responsible for showing details. * Coordinator responsible for showing details.
*/ */
...@@ -20,11 +27,22 @@ public class AssistantDetailsCoordinator { ...@@ -20,11 +27,22 @@ public class AssistantDetailsCoordinator {
private final AssistantDetailsModel mModel; private final AssistantDetailsModel mModel;
public AssistantDetailsCoordinator(Context context, AssistantDetailsModel model) { public AssistantDetailsCoordinator(Context context, AssistantDetailsModel model) {
this(context,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? context.getResources().getConfiguration().getLocales().get(0)
: context.getResources().getConfiguration().locale,
model, ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY));
}
@VisibleForTesting
public AssistantDetailsCoordinator(Context context, Locale locale, AssistantDetailsModel model,
ImageFetcher imageFetcher) {
mView = LayoutInflater.from(context).inflate( mView = LayoutInflater.from(context).inflate(
R.layout.autofill_assistant_details, /* root= */ null); R.layout.autofill_assistant_details, /* root= */ null);
mModel = model; mModel = model;
ViewHolder viewHolder = new ViewHolder(context, mView); ViewHolder viewHolder = new ViewHolder(context, mView);
AssistantDetailsViewBinder viewBinder = new AssistantDetailsViewBinder(context); AssistantDetailsViewBinder viewBinder =
new AssistantDetailsViewBinder(context, locale, imageFetcher);
PropertyModelChangeProcessor.create(model, viewHolder, viewBinder); PropertyModelChangeProcessor.create(model, viewHolder, viewBinder);
// Details view is initially hidden. // Details view is initially hidden.
......
...@@ -16,7 +16,6 @@ import android.graphics.Typeface; ...@@ -16,7 +16,6 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable;
import android.media.ThumbnailUtils; import android.media.ThumbnailUtils;
import android.os.Build;
import android.support.annotation.StyleRes; import android.support.annotation.StyleRes;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
...@@ -31,8 +30,6 @@ import org.chromium.chrome.autofill_assistant.R; ...@@ -31,8 +30,6 @@ import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.compositor.animation.CompositorAnimator; import org.chromium.chrome.browser.compositor.animation.CompositorAnimator;
import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher; import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory;
import org.chromium.chrome.browser.modaldialog.AppModalPresenter; import org.chromium.chrome.browser.modaldialog.AppModalPresenter;
import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.DialogDismissalCause;
import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager;
...@@ -77,7 +74,7 @@ class AssistantDetailsViewBinder ...@@ -77,7 +74,7 @@ class AssistantDetailsViewBinder
final TextView mTotalPriceLabelView; final TextView mTotalPriceLabelView;
final TextView mTotalPriceView; final TextView mTotalPriceView;
public ViewHolder(Context context, View detailsView) { ViewHolder(Context context, View detailsView) {
mDefaultImage = (GradientDrawable) context.getResources().getDrawable( mDefaultImage = (GradientDrawable) context.getResources().getDrawable(
R.drawable.autofill_assistant_default_details); R.drawable.autofill_assistant_default_details);
mImageView = detailsView.findViewById(R.id.details_image); mImageView = detailsView.findViewById(R.id.details_image);
...@@ -93,6 +90,7 @@ class AssistantDetailsViewBinder ...@@ -93,6 +90,7 @@ class AssistantDetailsViewBinder
} }
private final Context mContext; private final Context mContext;
private final Locale mLocale;
private final int mImageWidth; private final int mImageWidth;
private final int mImageHeight; private final int mImageHeight;
...@@ -102,15 +100,16 @@ class AssistantDetailsViewBinder ...@@ -102,15 +100,16 @@ class AssistantDetailsViewBinder
private ValueAnimator mPulseAnimation; private ValueAnimator mPulseAnimation;
private ImageFetcher mImageFetcher; private ImageFetcher mImageFetcher;
AssistantDetailsViewBinder(Context context) { AssistantDetailsViewBinder(Context context, Locale locale, ImageFetcher imageFetcher) {
mContext = context; mContext = context;
mLocale = locale;
mImageWidth = context.getResources().getDimensionPixelSize( mImageWidth = context.getResources().getDimensionPixelSize(
R.dimen.autofill_assistant_details_image_size); R.dimen.autofill_assistant_details_image_size);
mImageHeight = context.getResources().getDimensionPixelSize( mImageHeight = context.getResources().getDimensionPixelSize(
R.dimen.autofill_assistant_details_image_size); R.dimen.autofill_assistant_details_image_size);
mPulseAnimationStartColor = context.getResources().getColor(R.color.modern_grey_300); mPulseAnimationStartColor = context.getResources().getColor(R.color.modern_grey_300);
mPulseAnimationEndColor = context.getResources().getColor(R.color.modern_grey_200); mPulseAnimationEndColor = context.getResources().getColor(R.color.modern_grey_200);
mImageFetcher = ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY); mImageFetcher = imageFetcher;
} }
/** /**
...@@ -224,22 +223,16 @@ class AssistantDetailsViewBinder ...@@ -224,22 +223,16 @@ class AssistantDetailsViewBinder
return TextUtils.join(" • ", parts); return TextUtils.join(" • ", parts);
} }
private Locale getLocale() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? mContext.getResources().getConfiguration().getLocales().get(0)
: mContext.getResources().getConfiguration().locale;
}
private String formatDetailsTime(Date date) { private String formatDetailsTime(Date date) {
DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()); DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT, mLocale);
String timeFormatPattern = (df instanceof SimpleDateFormat) String timeFormatPattern = (df instanceof SimpleDateFormat)
? ((SimpleDateFormat) df).toPattern() ? ((SimpleDateFormat) df).toPattern()
: DETAILS_TIME_FORMAT; : DETAILS_TIME_FORMAT;
return new SimpleDateFormat(timeFormatPattern, getLocale()).format(date); return new SimpleDateFormat(timeFormatPattern, mLocale).format(date);
} }
private String formatDetailsDate(Date date) { private String formatDetailsDate(Date date) {
return new SimpleDateFormat(DETAILS_DATE_FORMAT, getLocale()).format(date); return new SimpleDateFormat(DETAILS_DATE_FORMAT, mLocale).format(date);
} }
private void hideIfEmpty(TextView view) { private void hideIfEmpty(TextView view) {
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.autofill_assistant;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.isTextMaxLines;
import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.design.widget.CoordinatorLayout;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.LocaleUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetails;
import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsCoordinator;
import org.chromium.chrome.browser.autofill_assistant.details.AssistantDetailsModel;
import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import java.util.Calendar;
import java.util.Locale;
/** Tests for the Autofill Assistant details. */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class AutofillAssistantDetailsUiTest {
private static class ViewHolder {
final ImageView mImageView;
final TextView mTitleView;
final TextView mDescriptionLine1View;
final TextView mDescriptionLine2View;
final TextView mDescriptionLine3View;
final TextView mPriceAttributionView;
final View mPriceView;
final TextView mTotalPriceLabelView;
final TextView mTotalPriceView;
ViewHolder(View detailsView) {
mImageView = detailsView.findViewById(R.id.details_image);
mTitleView = detailsView.findViewById(R.id.details_title);
mDescriptionLine1View = detailsView.findViewById(R.id.details_line1);
mDescriptionLine2View = detailsView.findViewById(R.id.details_line2);
mDescriptionLine3View = detailsView.findViewById(R.id.details_line3);
mPriceAttributionView = detailsView.findViewById(R.id.details_price_attribution);
mPriceView = detailsView.findViewById(R.id.details_price);
mTotalPriceView = detailsView.findViewById(R.id.details_total_price);
mTotalPriceLabelView = detailsView.findViewById(R.id.details_total_price_label);
}
}
@Rule
public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
@Before
public void setUp() throws Exception {
mCustomTabActivityTestRule.startCustomTabActivityWithIntent(
CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(), "about:blank"));
}
private CustomTabActivity getActivity() {
return mCustomTabActivityTestRule.getActivity();
}
private AssistantDetailsCoordinator createCoordinator(AssistantDetailsModel model)
throws Exception {
return createCoordinator(model, Locale.getDefault());
}
/** Creates a coordinator for use in UI tests, and adds it to the global view hierarchy. */
private AssistantDetailsCoordinator createCoordinator(
AssistantDetailsModel model, Locale locale) throws Exception {
AssistantDetailsCoordinator coordinator = runOnUiThreadBlocking(() -> {
Bitmap testImage = BitmapFactory.decodeResource(
getActivity().getResources(), R.drawable.btn_close);
return new AssistantDetailsCoordinator(InstrumentationRegistry.getTargetContext(),
locale, model,
new AutofillAssistantUiTestUtil.MockImageFetcher(testImage, null));
});
runOnUiThreadBlocking(() -> {
CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
ViewGroup chromeCoordinatorView = getActivity().findViewById(R.id.coordinator);
chromeCoordinatorView.addView(coordinator.getView(), lp);
});
return coordinator;
}
/** Tests assumptions about the initial state of the details. */
@Test
@SmallTest
public void testInitialState() throws Exception {
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model);
assertThat(model.get(AssistantDetailsModel.DETAILS), nullValue());
onView(is(coordinator.getView())).check(matches(not(isDisplayed())));
}
/** Tests visibility of views. */
@Test
@SmallTest
public void testVisibility() throws Exception {
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
runOnUiThreadBlocking(() -> {
model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1", "line 2",
"line 3", false, false, false, false, false, false));
});
onView(is(viewHolder.mImageView)).check(matches(isDisplayed()));
onView(is(viewHolder.mTitleView)).check(matches(isDisplayed()));
onView(is(viewHolder.mDescriptionLine1View)).check(matches(isDisplayed()));
onView(is(viewHolder.mDescriptionLine2View)).check(matches(isDisplayed()));
onView(is(viewHolder.mPriceView)).check(matches(isDisplayed()));
onView(is(viewHolder.mTotalPriceLabelView)).check(matches(isDisplayed()));
onView(is(viewHolder.mTotalPriceView)).check(matches(isDisplayed()));
// When total price is set, descriptionLine3 is shown in mPriceAttributionView instead.
onView(is(viewHolder.mPriceAttributionView)).check(matches(isDisplayed()));
onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed())));
}
@Test
@SmallTest
public void testTitle() throws Exception {
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
/* All description lines are set, title must be in single line. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
null, "line 1", "line 2", "line 3", false, false, false,
false, false, false)));
onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(1)));
/* Description line 2 not set, title may wrap once. */
runOnUiThreadBlocking(()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false,
"Total", "$12", null, "line 1", "", "line 3",
false, false, false, false, false, false)));
onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2)));
/* Description line 1 not set, title may wrap once.*/
runOnUiThreadBlocking(()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false,
"Total", "$12", null, "", "line 2", "line 3",
false, false, false, false, false, false)));
onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(2)));
/* Description lines 1 and 2 not set, title may wrap twice.*/
runOnUiThreadBlocking(()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false,
"Total", "$12", null, "", "", "line 3", false,
false, false, false, false, false)));
onView(is(viewHolder.mTitleView)).check(matches(isTextMaxLines(3)));
/* Check title text and visibility. */
onView(is(viewHolder.mTitleView)).check(matches(allOf(withText("title"), isDisplayed())));
}
@Test
@SmallTest
public void testDescriptionLine1() throws Exception {
Locale locale = LocaleUtils.forLanguageTag("en-US");
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model, locale);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
/* Both line 1 and date are set: description line 1 should show line 1. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1",
"line 2", "line 3", false, false, false, false, false,
false)));
onView(is(viewHolder.mDescriptionLine1View))
.check(matches(allOf(withText("line 1"), isDisplayed())));
/*
* Line 1 is empty, but date is set: description line 1 should show the date & time.
* Note: locale was set to en-US, so we know the output format for date and time.
*/
Calendar calendar = java.util.Calendar.getInstance(locale);
calendar.set(2050, 6, 25, 10, 05, 00);
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
calendar.getTime(), "", "line 2", "line 3", false, false,
false, false, false, false)));
onView(is(viewHolder.mDescriptionLine1View))
.check(matches(withText(containsString("Mon, Jul 25"))));
onView(is(viewHolder.mDescriptionLine1View))
.check(matches(withText(containsString("10:05 AM"))));
/* Line 1 is empty, date is not set: description line 1 should be invisible. */
runOnUiThreadBlocking(()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false,
"Total", "$12", null, "", "line 2", "line 3",
false, false, false, false, false, false)));
onView(is(viewHolder.mDescriptionLine1View)).check(matches(not(isDisplayed())));
}
@Test
@SmallTest
public void testDescriptionLine1NonUSLocale() throws Exception {
Locale locale = LocaleUtils.forLanguageTag("de-DE");
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model, locale);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
Calendar calendar = java.util.Calendar.getInstance(locale);
calendar.set(2050, 6, 25, 10, 05, 00);
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
calendar.getTime(), "", "line 2", "line 3", false, false,
false, false, false, false)));
onView(is(viewHolder.mDescriptionLine1View))
.check(matches(withText(containsString("Mo., Juli 25"))));
onView(is(viewHolder.mDescriptionLine1View))
.check(matches(withText(containsString("10:05"))));
}
@Test
@SmallTest
public void testDescriptionLine2() throws Exception {
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
/* Description line 2 is set and should be visible. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1",
"line 2", "line 3", false, false, false, false, false,
false)));
onView(is(viewHolder.mDescriptionLine2View))
.check(matches(allOf(withText("line 2"), isDisplayed())));
/* Description line 2 is not set and should be invisible. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1", "",
"line 3", false, false, false, false, false, false)));
onView(is(viewHolder.mDescriptionLine2View)).check(matches(not(isDisplayed())));
}
@Test
@SmallTest
public void testDescriptionLine3() throws Exception {
AssistantDetailsModel model = new AssistantDetailsModel();
AssistantDetailsCoordinator coordinator = createCoordinator(model);
ViewHolder viewHolder = runOnUiThreadBlocking(() -> new ViewHolder(coordinator.getView()));
/* No total price set, line 3 should be displayed in the normal spot. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "", "",
java.util.Calendar.getInstance().getTime(), "line 1",
"line 2", "line 3", false, false, false, false, false,
false)));
onView(is(viewHolder.mDescriptionLine3View))
.check(matches(allOf(withText("line 3"), isDisplayed())));
onView(is(viewHolder.mPriceAttributionView)).check(matches(not(isDisplayed())));
/* Total price and line 3 set, line 3 should be displayed in a different view. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1", "",
"line 3", false, false, false, false, false, false)));
onView(is(viewHolder.mPriceAttributionView))
.check(matches(allOf(withText("line 3"), isDisplayed())));
onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed())));
/* Line 3 not set, both views should be invisible. */
runOnUiThreadBlocking(
()
-> model.set(AssistantDetailsModel.DETAILS,
new AssistantDetails("title", "image", null, false, "Total", "$12",
java.util.Calendar.getInstance().getTime(), "line 1", "",
"", false, false, false, false, false, false)));
onView(is(viewHolder.mDescriptionLine3View)).check(matches(not(isDisplayed())));
onView(is(viewHolder.mPriceAttributionView)).check(matches(not(isDisplayed())));
}
}
...@@ -4,6 +4,12 @@ ...@@ -4,6 +4,12 @@
package org.chromium.chrome.browser.autofill_assistant; package org.chromium.chrome.browser.autofill_assistant;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.CoordinatorLayout;
...@@ -13,13 +19,11 @@ import android.view.Gravity; ...@@ -13,13 +19,11 @@ import android.view.Gravity;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.junit.Assert;
import org.junit.Before; 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.chromium.base.Callback;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.autofill_assistant.R;
...@@ -30,42 +34,15 @@ import org.chromium.chrome.browser.autofill_assistant.infobox.AssistantInfoBoxMo ...@@ -30,42 +34,15 @@ import org.chromium.chrome.browser.autofill_assistant.infobox.AssistantInfoBoxMo
import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
import jp.tomorrowkey.android.gifplayer.BaseGifImage;
/** /**
* Tests for the Autofill Assistant infobox. * Tests for the Autofill Assistant infobox.
*/ */
@RunWith(ChromeJUnit4ClassRunner.class) @RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class AutofillAssistantInfoBoxUiTest { public class AutofillAssistantInfoBoxUiTest {
private class MockImageFetcher extends ImageFetcher {
@Override
public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {}
@Override
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {
callback.onResult(BitmapFactory.decodeResource(
getActivity().getResources(), R.drawable.btn_close));
}
@Override
public void clear() {}
@Override
public @ImageFetcherConfig int getConfig() {
return ImageFetcherConfig.IN_MEMORY_ONLY;
}
@Override
public void destroy() {}
}
@Rule @Rule
public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
...@@ -87,8 +64,13 @@ public class AutofillAssistantInfoBoxUiTest { ...@@ -87,8 +64,13 @@ public class AutofillAssistantInfoBoxUiTest {
/** Creates a coordinator for use in UI tests, and adds it to the global view hierarchy. */ /** Creates a coordinator for use in UI tests, and adds it to the global view hierarchy. */
private AssistantInfoBoxCoordinator createCoordinator(AssistantInfoBoxModel model) { private AssistantInfoBoxCoordinator createCoordinator(AssistantInfoBoxModel model) {
ThreadUtils.assertOnUiThread(); ThreadUtils.assertOnUiThread();
AssistantInfoBoxCoordinator coordinator = new AssistantInfoBoxCoordinator(
InstrumentationRegistry.getTargetContext(), model, new MockImageFetcher()); Bitmap testImage =
BitmapFactory.decodeResource(getActivity().getResources(), R.drawable.btn_close);
AssistantInfoBoxCoordinator coordinator =
new AssistantInfoBoxCoordinator(InstrumentationRegistry.getTargetContext(), model,
new AutofillAssistantUiTestUtil.MockImageFetcher(testImage, null));
CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams( CoordinatorLayout.LayoutParams lp = new CoordinatorLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
...@@ -108,8 +90,8 @@ public class AutofillAssistantInfoBoxUiTest { ...@@ -108,8 +90,8 @@ public class AutofillAssistantInfoBoxUiTest {
AssistantInfoBoxModel model = new AssistantInfoBoxModel(); AssistantInfoBoxModel model = new AssistantInfoBoxModel();
AssistantInfoBoxCoordinator coordinator = createCoordinator(model); AssistantInfoBoxCoordinator coordinator = createCoordinator(model);
Assert.assertNull(model.get(AssistantInfoBoxModel.INFO_BOX)); assertNull(model.get(AssistantInfoBoxModel.INFO_BOX));
Assert.assertFalse(coordinator.getView().isShown()); assertFalse(coordinator.getView().isShown());
}); });
} }
...@@ -124,11 +106,10 @@ public class AutofillAssistantInfoBoxUiTest { ...@@ -124,11 +106,10 @@ public class AutofillAssistantInfoBoxUiTest {
AssistantInfoBox infoBox = new AssistantInfoBox("", "Message"); AssistantInfoBox infoBox = new AssistantInfoBox("", "Message");
model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox);
Assert.assertTrue(getExplanationView(coordinator).isShown()); assertTrue(getExplanationView(coordinator).isShown());
Assert.assertNull("Image should not be set", assertNull("Image should not be set",
getExplanationView(coordinator).getCompoundDrawables()[1]); getExplanationView(coordinator).getCompoundDrawables()[1]);
Assert.assertEquals( assertEquals(infoBox.getExplanation(), getExplanationView(coordinator).getText());
infoBox.getExplanation(), getExplanationView(coordinator).getText());
}); });
} }
...@@ -143,11 +124,10 @@ public class AutofillAssistantInfoBoxUiTest { ...@@ -143,11 +124,10 @@ public class AutofillAssistantInfoBoxUiTest {
AssistantInfoBox infoBox = new AssistantInfoBox("x", "Message"); AssistantInfoBox infoBox = new AssistantInfoBox("x", "Message");
model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox);
Assert.assertTrue(getExplanationView(coordinator).isShown()); assertTrue(getExplanationView(coordinator).isShown());
Assert.assertNotNull("Image should be set", assertNotNull("Image should be set",
getExplanationView(coordinator).getCompoundDrawables()[1]); getExplanationView(coordinator).getCompoundDrawables()[1]);
Assert.assertEquals( assertEquals(infoBox.getExplanation(), getExplanationView(coordinator).getText());
infoBox.getExplanation(), getExplanationView(coordinator).getText());
}); });
} }
...@@ -160,10 +140,10 @@ public class AutofillAssistantInfoBoxUiTest { ...@@ -160,10 +140,10 @@ public class AutofillAssistantInfoBoxUiTest {
AssistantInfoBox infoBox = new AssistantInfoBox("", ""); AssistantInfoBox infoBox = new AssistantInfoBox("", "");
model.set(AssistantInfoBoxModel.INFO_BOX, infoBox); model.set(AssistantInfoBoxModel.INFO_BOX, infoBox);
Assert.assertTrue(coordinator.getView().isShown()); assertTrue(coordinator.getView().isShown());
model.set(AssistantInfoBoxModel.INFO_BOX, null); model.set(AssistantInfoBoxModel.INFO_BOX, null);
Assert.assertFalse(coordinator.getView().isShown()); assertFalse(coordinator.getView().isShown());
}); });
} }
} }
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.autofill_assistant;
import android.graphics.Bitmap;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.TextView;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig;
import jp.tomorrowkey.android.gifplayer.BaseGifImage;
/**
* Contains utilities for testing Autofill Assistant.
*/
class AutofillAssistantUiTestUtil {
/** Image fetcher which synchronously returns a preset image. */
static class MockImageFetcher extends ImageFetcher {
private final Bitmap mBitmapToFetch;
private final BaseGifImage mGifToFetch;
MockImageFetcher(@Nullable Bitmap bitmapToFetch, @Nullable BaseGifImage gifToFetch) {
mBitmapToFetch = bitmapToFetch;
mGifToFetch = gifToFetch;
}
@Override
public void fetchGif(String url, String clientName, Callback<BaseGifImage> callback) {
callback.onResult(mGifToFetch);
}
@Override
public void fetchImage(
String url, String clientName, int width, int height, Callback<Bitmap> callback) {
callback.onResult(mBitmapToFetch);
}
@Override
public void clear() {}
@Override
public @ImageFetcherConfig int getConfig() {
return ImageFetcherConfig.IN_MEMORY_ONLY;
}
@Override
public void destroy() {}
}
/** Checks that a text view has a specific maximum number of lines to display. */
public static TypeSafeMatcher<View> isTextMaxLines(int maxLines) {
return new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View item) {
return ((TextView) item).getMaxLines() == maxLines;
}
@Override
public void describeTo(Description description) {
description.appendText("isTextMaxLines");
}
};
}
}
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