blob: fb86dda9f6d64696e1d0290acb05ea4d100c2715 [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.
#include "chrome/browser/payments/secure_payment_confirmation_browsertest.h"
#include "components/autofill/core/browser/test_utils/test_event_waiter.h"
#include "components/payments/content/secure_payment_confirmation_app.h"
#include "components/payments/content/web_payments_web_data_service.h"
#include "components/payments/core/secure_payment_confirmation_credential.h"
#include "components/webdata_services/web_data_service_wrapper_factory.h"
#include "content/public/test/browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace payments {
namespace {
using SecurePaymentConfirmationOptOutTest = SecurePaymentConfirmationTest;
using Event2 = JourneyLogger::Event2;
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutOfferedAndTaken) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The opt-out link should be visible and clickable. Clicking it should cause
// the PaymentRequest to be aborted.
EXPECT_TRUE(test_controller()->ClickOptOut());
EXPECT_EQ(
"OptOutError: User opted out of the process.",
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
// Verify that opt out was recorded as both offered and chosen.
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kHadInitialFormOfPayment,
Event2::kOptOutOffered, Event2::kUserOptedOut,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutOfferedButNotTaken) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was recorded as offered but not taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kOptOutOffered,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutNotOffered) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out disabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = false;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The opt-out link should not be available.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutDefaultsToNotOffered) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, without specifying a value for showOptOut.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
ExecuteScriptAsync(GetActiveWebContents(),
"getSecurePaymentConfirmationStatus()");
WaitForObservedEvent();
// The default for showOptOut is false, so the link shouldn't be available.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutNoMatchingCredsOfferedAndTaken) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The no matching creds UI should render the opt-out link.
EXPECT_TRUE(test_controller()->ClickOptOut());
EXPECT_EQ(
"OptOutError: User opted out of the process.",
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
// Verify that opt out was recorded as both offered and chosen.
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kOptOutOffered, Event2::kUserOptedOut,
Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutNoMatchingCredsOfferedButNotTaken) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was recorded as offered but not taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kOptOutOffered,
Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutNoMatchingCredsNotOffered) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out disabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = false;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The no matching creds UI should not render the opt-out link.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutTest,
ShowOptOutNoMatchingCredsDefaultsToNotOffered) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, without specifying a value for showOptOut.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
ExecuteScriptAsync(GetActiveWebContents(),
"getSecurePaymentConfirmationStatus()");
WaitForObservedEvent();
// The no matching creds UI should not render the opt-out link.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
class SecurePaymentConfirmationOptOutDisabledTest
: public SecurePaymentConfirmationOptOutTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
SecurePaymentConfirmationTest::SetUpCommandLine(command_line);
command_line->AppendSwitchASCII(switches::kDisableBlinkFeatures,
"SecurePaymentConfirmationOptOut");
}
};
// The SPC opt-out experience should not be available if the Blink runtime flag
// is disabled.
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutDisabledTest,
RequiresRuntimeFlag) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Because the runtime flag isn't set, showOptOut should still have been set
// to false, and so there is no opt-out link to click.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetWebAuthnErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
#if BUILDFLAG(IS_ANDROID)
class SecurePaymentConfirmationOptOutUxRefreshTest
: public SecurePaymentConfirmationOptOutTest {
private:
base::test::ScopedFeatureList feature_list_{
blink::features::kSecurePaymentConfirmationUxRefresh};
};
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutOfferedButNotTaken) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was recorded as offered but not taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kOptOutOffered,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutNotOffered) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out disabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = false;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The opt-out link should not be available.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutDefaultsToNotOffered) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, without specifying a value for showOptOut.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
ExecuteScriptAsync(GetActiveWebContents(),
"getSecurePaymentConfirmationStatus()");
WaitForObservedEvent();
// The default for showOptOut is false, so the link shouldn't be available.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutNoMatchingCredsOfferedAndTaken) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The no matching creds UI should render the opt-out link.
EXPECT_TRUE(test_controller()->ClickOptOut());
EXPECT_EQ(
"OptOutError: User opted out of the process.",
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
// Verify that opt out was recorded as both offered and chosen.
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kHadInitialFormOfPayment,
Event2::kOptOutOffered, Event2::kUserOptedOut,
Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutNoMatchingCredsOfferedButNotTaken) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was recorded as offered but not taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kOptOutOffered, Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutNoMatchingCredsNotOffered) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, with opt-out disabled.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
const bool show_opt_out = false;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// The no matching creds UI should not render the opt-out link.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutUxRefreshTest,
ShowOptOutNoMatchingCredsDefaultsToNotOffered) {
// Don't install a credential, so that the 'No Matching Credentials' UI will
// be shown.
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
// Initiate SPC, without specifying a value for showOptOut.
ResetEventWaiterForSingleEvent(TestEvent::kErrorDisplayed);
ExecuteScriptAsync(GetActiveWebContents(),
"getSecurePaymentConfirmationStatus()");
WaitForObservedEvent();
// The no matching creds UI should not render the opt-out link.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kNoMatchingCredentials,
Event2::kRequestMethodSecurePaymentConfirmation});
}
class SecurePaymentConfirmationOptOutDisabledUxRefreshTest
: public SecurePaymentConfirmationOptOutDisabledTest {
private:
base::test::ScopedFeatureList feature_list_{
blink::features::kSecurePaymentConfirmationUxRefresh};
};
// The SPC opt-out experience should not be available if the Blink runtime flag
// is disabled.
IN_PROC_BROWSER_TEST_F(SecurePaymentConfirmationOptOutDisabledUxRefreshTest,
RequiresRuntimeFlag) {
test_controller()->SetHasAuthenticator(true);
NavigateTo("a.com", "/secure_payment_confirmation.html");
std::vector<uint8_t> credential_id = {'c', 'r', 'e', 'd'};
std::vector<uint8_t> user_id = {'u', 's', 'e', 'r'};
webdata_services::WebDataServiceWrapperFactory::
GetWebPaymentsWebDataServiceForBrowserContext(
GetActiveWebContents()->GetBrowserContext(),
ServiceAccessType::EXPLICIT_ACCESS)
->AddSecurePaymentConfirmationCredential(
std::make_unique<SecurePaymentConfirmationCredential>(
std::move(credential_id), "a.com", std::move(user_id)),
/*consumer=*/this);
// Initiate SPC, with opt-out enabled.
ResetEventWaiterForSingleEvent(TestEvent::kUIDisplayed);
const bool show_opt_out = true;
ExecuteScriptAsync(
GetActiveWebContents(),
content::JsReplace(
"getSecurePaymentConfirmationStatus(undefined, undefined, $1)",
show_opt_out));
WaitForObservedEvent();
// Because the runtime flag isn't set, showOptOut should still have been set
// to false, and so there is no opt-out link to click.
EXPECT_FALSE(test_controller()->ClickOptOut());
// Close the dialog to trigger JourneyLogger metrics, and verify that opt out
// was not recorded as offered or taken.
test_controller()->CloseDialog();
// EXPECT_EQ(
// GetWebAuthnErrorMessage(),
// content::EvalJs(GetActiveWebContents(),
// "getOutstandingStatusPromise()"));
EXPECT_EQ(
GetCancelErrorMessage(),
content::EvalJs(GetActiveWebContents(), "getOutstandingStatusPromise()"));
ExpectEvent2Histogram({Event2::kInitiated, Event2::kShown,
Event2::kUserAborted, Event2::kHadInitialFormOfPayment,
Event2::kRequestMethodSecurePaymentConfirmation});
}
#endif // BUILDFLAG(IS_ANDROID)
} // namespace
} // namespace payments