Commit 3e058c0b authored by Liquan (Max) Gu's avatar Liquan (Max) Gu Committed by Commit Bot

[PaymentHandler] Add Android Browser Tests for Expandable PH UI

This CL is to add a test for Expandable Payment Handler UI.

Main Change:
* add 1 test
* add maxpay.com payment app

Flag enabled: ScrollToExpandPaymentHandler. With this flag, Payment
Request will open the Expandable PH UI instead of the CCT PH UI.

Test Steps:
1. install payment app - maxpay.com
2. launch the app
3. when the app is on load, invoke a callback to respond "success" to
the PaymentRequest.

Bug: 1042892

Change-Id: I8a64a6f892eff8c9ae3c6c98acd948938b7eb173
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1980187
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732937}
parent b7276d1a
// Copyright 2020 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.
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "chrome/browser/android/chrome_feature_list.h"
#include "chrome/test/base/android/android_browser_test.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/payments/payment_request_test_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
namespace payments {
namespace {
class ExpandablePaymentHandlerBrowserTest : public PlatformBrowserTest {
public:
ExpandablePaymentHandlerBrowserTest()
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
scoped_feature_list_.InitWithFeatures(
/*enabled_features=*/{chrome::android::kScrollToExpandPaymentHandler},
/*disabled_features=*/{});
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(
switches::kEnableExperimentalWebPlatformFeatures);
}
void SetUpOnMainThread() override {
https_server_.ServeFilesFromSourceDirectory(
"components/test/data/payments/");
ASSERT_TRUE(https_server_.Start());
ASSERT_TRUE(content::NavigateToURL(
GetActiveWebContents(),
https_server_.GetURL("/maxpay.com/merchant.html")));
test_controller_.SetUpOnMainThread();
PlatformBrowserTest::SetUpOnMainThread();
}
content::WebContents* GetActiveWebContents() {
return chrome_test_utils::GetActiveWebContents(this);
}
private:
PaymentRequestTestController test_controller_;
net::EmbeddedTestServer https_server_;
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ExpandablePaymentHandlerBrowserTest, Launch) {
std::string expected = "success";
EXPECT_EQ(expected, content::EvalJs(GetActiveWebContents(), "install()"));
EXPECT_EQ(expected, content::EvalJs(GetActiveWebContents(), "launch()"));
}
} // namespace
} // namespace payments
...@@ -523,6 +523,7 @@ if (is_android) { ...@@ -523,6 +523,7 @@ if (is_android) {
"../browser/engagement/important_sites_util_browsertest.cc", "../browser/engagement/important_sites_util_browsertest.cc",
"../browser/games/games_service_browsertest.cc", "../browser/games/games_service_browsertest.cc",
"../browser/payments/empty_parameters_browsertest.cc", "../browser/payments/empty_parameters_browsertest.cc",
"../browser/payments/expandable_payment_handler_browsertest.cc",
"../browser/payments/has_enrolled_instrument_browsertest.cc", "../browser/payments/has_enrolled_instrument_browsertest.cc",
"../browser/payments/has_enrolled_instrument_query_quota_browsertest.cc", "../browser/payments/has_enrolled_instrument_query_quota_browsertest.cc",
"../browser/payments/hybrid_request_skip_ui_browsertest.cc", "../browser/payments/hybrid_request_skip_ui_browsertest.cc",
......
The tests in this folder is meant for both manual test and automated test, for
both Mobile and Desktop. To run these tests manually, take the following steps:
* start a http server to serve the directory "components/test/data/payments/"
* start Chrome with "--ignore-certificate-errors"
* for mobile, setup port-forwarding if necessary
* use the browser to open merchant.html
/*
* Copyright 2020 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.
*/
const methodName = window.location.origin + '/pay';
const swSrcUrl = './payment_handler_sw.js';
/**
* Update the installation status in the widget called 'installationStatus'.
*/
async function updateStatusView() {
const installationStatusViewId = 'installationStatus';
const registration = await navigator.serviceWorker.getRegistration(swSrcUrl);
if (registration) {
document.getElementById(installationStatusViewId).innerHTML = 'installed';
} else {
document.getElementById(installationStatusViewId).innerHTML = 'uninstalled';
}
}
/**
* Insert a message to the widget called 'log'.
* @param {Promise<string>} text - the text that is intended to be inserted
* into the log.
*/
async function updateLogView(text) {
const messageElement = document.getElementById('log');
messageElement.innerHTML = (await text) + '\n' + messageElement.innerHTML;
}
/**
* Installs the payment handler.
* @return {string} - the message about the installation result.
*/
async function install() { // eslint-disable-line no-unused-vars
try {
let registration =
await navigator.serviceWorker.getRegistration(swSrcUrl);
if (registration) {
return 'The payment handler is already installed.';
}
await navigator.serviceWorker.register(swSrcUrl);
registration = await navigator.serviceWorker.ready;
await updateStatusView();
if (!registration.paymentManager) {
return 'PaymentManager API not found.';
}
await registration.paymentManager.instruments.set('instrument-id', {
name: 'Instrument Name',
method: methodName,
});
return 'success';
} catch (e) {
return e.message;
}
}
/**
* Uninstall the payment handler.
* @return {string} - the message about the uninstallation result.
*/
async function uninstall() { // eslint-disable-line no-unused-vars
let registration = await navigator.serviceWorker.getRegistration(swSrcUrl);
if (!registration) {
return 'The Payment handler has not been installed yet.';
}
await registration.unregister();
await updateStatusView();
return 'Uninstall successfully.';
}
/**
* Launches the payment handler.
* @return {string} - the message about the launch result.
*/
async function launch() { // eslint-disable-line no-unused-vars
try {
const request = new PaymentRequest([{supportedMethods: methodName}], {
total: {label: 'Total', amount: {currency: 'USD', value: '0.01'}},
});
const paymentResponse = await request.show();
const status = paymentResponse.details.status;
await updateLogView(
`Payment App has been shown and completed with status(${status}).`);
// status has to be either fail, success, or unknown.
await paymentResponse.complete(status);
return 'success';
} catch (e) {
return e.message;
}
}
updateStatusView();
<!DOCTYPE html>
<!--
Copyright 2020 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.
-->
<html lang="en">
<head>
<meta charset="utf-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
<title>Max Pay Payment Handler Test</title>
<link rel="manifest" href="../manifest.json">
<link rel="stylesheet" type="text/css" href="../style.css">
</head>
<style>
#controllers button {
font-size: medium;
height: 3em;
width: auto;
}
#log
{
font-size: small;
height: 100%;
overflow-x: scroll;
width: 100%;
}
</style>
<body>
<h1>Use Max Pay</h1>
<div id="controllers">
<button onclick="updateLogView(install())" id="install">Install</button>
<button onclick="updateLogView(uninstall())" id="uninstall">Uninstall</button>
<button onclick="updateLogView(launch())" id="testNoHandler">Launch</button>
</div>
<div>
<div>Installation Status: <span id="installationStatus"></span></div>
<div>Messages:</div>
<pre id="log"></pre>
</div>
<script src="./installer.js"></script>
</body>
</html>
/*
* Copyright 2020 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.
*/
let paymentRequestResponder;
let methodName;
self.addEventListener('canmakepayment', (evt) => {
evt.respondWith(true);
});
self.addEventListener('message', (evt) => {
// Sent from the Payment app.
if (evt.data === 'confirm') {
paymentRequestResponder({methodName, details: {status: 'success'}});
return;
} else if (evt.data === 'cancel') {
paymentRequestResponder({methodName, details: {status: 'fail'}});
return;
}
});
self.addEventListener('paymentrequest', (evt) => {
methodName = evt.methodData[0].supportedMethods;
evt.respondWith(new Promise((responder) => {
paymentRequestResponder = responder;
evt.openWindow('./payment_handler_window.html');
}));
});
<!DOCTYPE html>
<!--
Copyright 2020 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.
-->
<script>navigator.serviceWorker.controller.postMessage('confirm');</script>
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