Commit 8203409e authored by Hao Zhang's avatar Hao Zhang Committed by Commit Bot

[Autofill] Browser tests for missing expiration date flow.

Bug: 899057
Change-Id: I9a79e9a280ec0a937b44afd319f0dc3e516aef0f
Reviewed-on: https://chromium-review.googlesource.com/c/1321471
Commit-Queue: Hao Zhang <hozhng@google.com>
Reviewed-by: default avatarJared Saul <jsaul@google.com>
Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarFabio Tirelo <ftirelo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607700}
parent b3bf64e2
......@@ -68,8 +68,10 @@ class SaveCardBubbleControllerImplTest : public DialogBrowserTest {
controller_ = SaveCardBubbleControllerImpl::FromWebContents(web_contents);
DCHECK(controller_);
bool should_request_name_from_user =
const bool should_request_name_from_user =
name.find("WithCardholderNameTextfield") != std::string::npos;
const bool should_request_expiration_date_from_user =
name.find("WithCardExpirationDateDropDownBox") != std::string::npos;
BubbleType bubble_type = BubbleType::INACTIVE;
if (name.find("Local") != std::string::npos)
......@@ -87,11 +89,11 @@ class SaveCardBubbleControllerImplTest : public DialogBrowserTest {
base::DoNothing());
break;
case BubbleType::UPLOAD_SAVE:
controller_->OfferUploadSave(
test::GetMaskedServerCard(), GetTestLegalMessage(),
should_request_name_from_user,
/*should_request_expiration_date_from_user=*/false,
/*show_bubble=*/true, base::DoNothing());
controller_->OfferUploadSave(test::GetMaskedServerCard(),
GetTestLegalMessage(),
should_request_name_from_user,
should_request_expiration_date_from_user,
/*show_bubble=*/true, base::DoNothing());
break;
case BubbleType::SIGN_IN_PROMO:
controller_->ShowBubbleForSignInPromo();
......@@ -131,6 +133,13 @@ IN_PROC_BROWSER_TEST_F(SaveCardBubbleControllerImplTest,
ShowAndVerifyUi();
}
// Invokes a bubble asking the user if they want to save a credit card to the
// server, with a pair of dropdowns for entering expiration date.
IN_PROC_BROWSER_TEST_F(SaveCardBubbleControllerImplTest,
InvokeUi_Server_WithCardExpirationDateDropDownBox) {
ShowAndVerifyUi();
}
// Invokes a sign-in promo bubble.
// TODO(crbug.com/855186): This browsertest isn't emulating the environment
// quite correctly; disabling test for now until cause is found.
......
......@@ -21,6 +21,7 @@ enum DialogViewId : int {
FOOTNOTE_VIEW, // Contains the legal messages for upload save
SIGN_IN_PROMO_VIEW, // Contains the sign-in promo view
MANAGE_CARDS_VIEW, // The manage cards view
EXPIRATION_DATE_VIEW, // Contains the dropdowns for expiration date
// The sub-view that contains the sign-in button in the promo.
SIGN_IN_VIEW,
......@@ -40,6 +41,10 @@ enum DialogViewId : int {
// The following are views::TooltipIcon objects.
CARDHOLDER_NAME_TOOLTIP, // Appears during cardholder name entry/confirmation
// The following are views::Combobox objects.
EXPIRATION_DATE_DROPBOX_MONTH,
EXPIRATION_DATE_DROPBOX_YEAR,
};
} // namespace autofill
......
......@@ -23,6 +23,7 @@
#include "net/url_request/test_url_fetcher_factory.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/window/dialog_client_view.h"
......@@ -1233,4 +1234,128 @@ IN_PROC_BROWSER_TEST_F(
histogram_tester.ExpectTotalCount("Autofill.UploadAcceptedCardOrigin", 0);
}
// Tests the upload save bubble. Ensures that the bubble surfaces a pair of
// dropdowns requesting expiration date if expiration date is missing.
IN_PROC_BROWSER_TEST_F(
SaveCardBubbleViewsFullFormBrowserTest,
Upload_SubmittingFormWithMissingExpirationDateRequestsExpirationDate) {
// Enable the EditableExpirationDate experiment.
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableExpirationDate);
// Set up the Payments RPC.
SetUploadDetailsRpcPaymentsAccepts();
// Submitting the form should still show the upload save bubble and legal
// footer, along with a textfield specifically requesting the cardholder name.
// (Must wait for response from Payments before accessing the controller.)
ResetEventWaiterForSequence(
{DialogEvent::REQUESTED_UPLOAD_SAVE,
DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE});
FillAndSubmitFormWithoutExpirationDate();
WaitForObservedEvent();
EXPECT_TRUE(
FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible());
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible());
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_VIEW));
}
// Tests the upload save bubble. Ensures that the bubble is not shown when
// expiration date is missing, but the flag is disabled.
IN_PROC_BROWSER_TEST_F(
SaveCardBubbleViewsFullFormBrowserTest,
Logic_ShouldNotOfferToSaveIfMissingExpirationDateAndExpOff) {
// Disable the EditableExpirationDate experiment.
scoped_feature_list_.InitAndDisableFeature(
features::kAutofillUpstreamEditableExpirationDate);
// The credit card will not be imported if there is no expiration date and
// experiment is off.
FillAndSubmitFormWithoutExpirationDate();
EXPECT_FALSE(GetSaveCardBubbleViews());
}
// Tests the upload save bubble. Ensures that the bubble does not surface the
// expiration date dropdowns if it is not needed.
IN_PROC_BROWSER_TEST_F(SaveCardBubbleViewsFullFormBrowserTest,
Upload_ShouldNotRequestExpirationDateInHappyPath) {
// Enable the EditableExpirationDate experiment.
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableExpirationDate);
// Set up the Payments RPC.
SetUploadDetailsRpcPaymentsAccepts();
// Submitting the form should show the upload save bubble and legal footer.
// (Must wait for response from Payments before accessing the controller.)
ResetEventWaiterForSequence(
{DialogEvent::REQUESTED_UPLOAD_SAVE,
DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE});
FillAndSubmitForm();
WaitForObservedEvent();
EXPECT_TRUE(
FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible());
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible());
// Assert that expiration date was not explicitly requested in the bubble.
EXPECT_FALSE(FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_VIEW));
}
// Tests the upload save bubble. Ensures that if the expiration date drop down
// box is changing, [Save] button will change status correctly.
IN_PROC_BROWSER_TEST_F(
SaveCardBubbleViewsFullFormBrowserTest,
Upload_SaveButtonStatusResetBetweenExpirationDateSelectionChanges) {
// Enable the EditableExpirationDate experiment.
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamEditableExpirationDate);
// Set up the Payments RPC.
SetUploadDetailsRpcPaymentsAccepts();
// Submitting the form should still show the upload save bubble and legal
// footer, along with a pair of dropdowns specifically requesting the
// expiration date. (Must wait for response from Payments before accessing
// the controller.)
ResetEventWaiterForSequence(
{DialogEvent::REQUESTED_UPLOAD_SAVE,
DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE});
FillAndSubmitFormWithoutExpirationDate();
WaitForObservedEvent();
EXPECT_TRUE(
FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_UPLOAD)->visible());
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::FOOTNOTE_VIEW)->visible());
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_VIEW));
EXPECT_TRUE(FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_DROPBOX_YEAR));
EXPECT_TRUE(
FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_DROPBOX_MONTH));
// [Save] button is disabled by default when requesting expiration date,
// because there are no preselected values in the dropdown lists.
views::LabelButton* save_button = static_cast<views::LabelButton*>(
FindViewInBubbleById(DialogViewId::OK_BUTTON));
EXPECT_EQ(save_button->state(),
views::LabelButton::ButtonState::STATE_DISABLED);
views::Combobox* year_input = static_cast<views::Combobox*>(
FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_DROPBOX_YEAR));
views::Combobox* month_input = static_cast<views::Combobox*>(
FindViewInBubbleById(DialogViewId::EXPIRATION_DATE_DROPBOX_MONTH));
// Selecting only month or year will disable [Save] button.
year_input->SetSelectedRow(2);
EXPECT_EQ(save_button->state(),
views::LabelButton::ButtonState::STATE_DISABLED);
year_input->SetSelectedRow(0);
month_input->SetSelectedRow(2);
EXPECT_EQ(save_button->state(),
views::LabelButton::ButtonState::STATE_DISABLED);
// Selecting both month and year will enable [Save] button.
month_input->SetSelectedRow(2);
year_input->SetSelectedRow(2);
EXPECT_EQ(save_button->state(),
views::LabelButton::ButtonState::STATE_NORMAL);
}
} // namespace autofill
......@@ -293,33 +293,51 @@ void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutName() {
SubmitForm();
}
// Should be called for credit_card_upload_form_address_and_cc.html.
void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutAddress() {
// Should be called for credit_card_upload_form_shipping_address.html.
void SaveCardBubbleViewsBrowserTestBase::
FillAndSubmitFormWithConflictingName() {
content::WebContents* web_contents = GetActiveWebContents();
const std::string click_fill_button_js =
"(function() { document.getElementById('fill_form').click(); })();";
ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js));
const std::string click_clear_name_button_js =
"(function() { document.getElementById('clear_address').click(); })();";
ASSERT_TRUE(content::ExecuteScript(web_contents, click_clear_name_button_js));
const std::string click_conflicting_name_button_js =
"(function() { document.getElementById('conflicting_name').click(); "
"})();";
ASSERT_TRUE(
content::ExecuteScript(web_contents, click_conflicting_name_button_js));
SubmitForm();
}
// Should be called for credit_card_upload_form_shipping_address.html.
// Should be called for credit_card_upload_form_address_and_cc.html.
void SaveCardBubbleViewsBrowserTestBase::
FillAndSubmitFormWithConflictingName() {
FillAndSubmitFormWithoutExpirationDate() {
content::WebContents* web_contents = GetActiveWebContents();
const std::string click_fill_button_js =
"(function() { document.getElementById('fill_form').click(); })();";
ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js));
const std::string click_conflicting_name_button_js =
"(function() { document.getElementById('conflicting_name').click(); "
const std::string click_clear_expiration_date_button_js =
"(function() { document.getElementById('clear_expiration_date').click(); "
"})();";
ASSERT_TRUE(content::ExecuteScript(web_contents,
click_clear_expiration_date_button_js));
SubmitForm();
}
// Should be called for credit_card_upload_form_address_and_cc.html.
void SaveCardBubbleViewsBrowserTestBase::FillAndSubmitFormWithoutAddress() {
content::WebContents* web_contents = GetActiveWebContents();
const std::string click_fill_button_js =
"(function() { document.getElementById('fill_form').click(); })();";
ASSERT_TRUE(content::ExecuteScript(web_contents, click_fill_button_js));
const std::string click_clear_address_button_js =
"(function() { document.getElementById('clear_address').click(); })();";
ASSERT_TRUE(
content::ExecuteScript(web_contents, click_conflicting_name_button_js));
content::ExecuteScript(web_contents, click_clear_address_button_js));
SubmitForm();
}
......
......@@ -94,6 +94,7 @@ class SaveCardBubbleViewsBrowserTestBase
void FillAndSubmitFormWithInvalidCvc();
void FillAndSubmitFormWithoutName();
void FillAndSubmitFormWithConflictingName();
void FillAndSubmitFormWithoutExpirationDate();
void FillAndSubmitFormWithoutAddress();
void FillAndSubmitFormWithConflictingStreetAddress();
void FillAndSubmitFormWithConflictingPostalCode();
......
......@@ -230,17 +230,20 @@ SaveCardOfferBubbleViews::CreateRequestExpirationDateView() {
expiration_date_view->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kVertical, gfx::Insets(),
provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
expiration_date_view->set_id(DialogViewId::EXPIRATION_DATE_VIEW);
// Set up the month and year comboboxes.
month_input_dropdown_ = new views::Combobox(&month_combobox_model_);
month_input_dropdown_->set_listener(this);
month_input_dropdown_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH));
month_input_dropdown_->set_id(DialogViewId::EXPIRATION_DATE_DROPBOX_MONTH);
year_input_dropdown_ = new views::Combobox(&year_combobox_model_);
year_input_dropdown_->set_listener(this);
year_input_dropdown_->SetAccessibleName(
l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR));
year_input_dropdown_->set_id(DialogViewId::EXPIRATION_DATE_DROPBOX_YEAR);
auto input_row = std::make_unique<views::View>();
input_row->SetLayoutManager(std::make_unique<views::BoxLayout>(
......
......@@ -46,6 +46,7 @@ found in the LICENSE file.
<button id="fill_card_only" type="button">Fill the credit card number and expiration fields only</button>
<button id="clear_cvc" type="button">Clear the CVC field</button>
<button id="clear_name" type="button">Clear the name fields</button>
<button id="clear_expiration_date" type="button">Clear the expiration date fields</button>
<button id="clear_address" type="button">Clear the address fields</button>
<button id="submit" type="submit">Submit</button>
</form>
......@@ -105,6 +106,13 @@ found in the LICENSE file.
document.getElementsByName("name_cc")[0].value = "";
});
document.getElementById("clear_expiration_date").addEventListener(
"click",
function () {
document.getElementsByName("cc_month_exp")[0].value = "";
document.getElementsByName("cc_year_exp")[0].value = "";
});
document.getElementById("clear_address").addEventListener(
"click",
function() {
......
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