1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/banners/app_banner_data_fetcher.h"
7 #include "base/command_line.h"
8 #include "base/location.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "chrome/browser/banners/app_banner_data_fetcher_desktop.h"
14 #include "chrome/browser/banners/app_banner_settings_helper.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/test/test_navigation_observer.h"
22 #include "net/test/embedded_test_server/embedded_test_server.h"
26 class TestObserver
: public AppBannerDataFetcher::Observer
{
28 TestObserver(AppBannerDataFetcher
* fetcher
, base::Closure quit_closure
)
30 quit_closure_(quit_closure
) {
31 fetcher_
->AddObserverForTesting(this);
34 virtual ~TestObserver() {
36 fetcher_
->RemoveObserverForTesting(this);
39 void OnDecidedWhetherToShow(AppBannerDataFetcher
* fetcher
,
40 bool will_show
) override
{
41 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, quit_closure_
);
42 ASSERT_FALSE(will_show_
.get());
43 will_show_
.reset(new bool(will_show
));
46 void OnFetcherDestroyed(AppBannerDataFetcher
* fetcher
) override
{
47 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, quit_closure_
);
51 bool will_show() { return will_show_
.get() && *will_show_
; }
54 AppBannerDataFetcher
* fetcher_
;
55 base::Closure quit_closure_
;
56 scoped_ptr
<bool> will_show_
;
59 class AppBannerDataFetcherBrowserTest
: public InProcessBrowserTest
,
60 public AppBannerDataFetcher::Delegate
{
62 AppBannerDataFetcherBrowserTest() : weak_factory_(this) {
65 void SetUpOnMainThread() override
{
66 AppBannerSettingsHelper::SetEngagementWeights(1, 1);
67 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
68 InProcessBrowserTest::SetUpOnMainThread();
71 bool HandleNonWebApp(const std::string
& platform
,
73 const std::string
& id
) override
{
74 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
, quit_closure_
);
75 non_web_platform_
= platform
;
79 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
80 command_line
->AppendSwitch(
81 switches::kEnableExperimentalWebPlatformFeatures
);
82 // Make sure app banners are disabled in the browser, otherwise they will
83 // interfere with the test.
84 command_line
->AppendSwitch(switches::kDisableAddToShelf
);
88 void RunFetcher(const GURL
& url
,
89 const std::string
& expected_non_web_platform
,
90 ui::PageTransition transition
,
91 bool expected_to_show
) {
92 content::WebContents
* web_contents
=
93 browser()->tab_strip_model()->GetActiveWebContents();
94 scoped_refptr
<AppBannerDataFetcherDesktop
> fetcher(
95 new AppBannerDataFetcherDesktop(web_contents
,
96 weak_factory_
.GetWeakPtr(), 128));
98 base::RunLoop run_loop
;
99 quit_closure_
= run_loop
.QuitClosure();
100 scoped_ptr
<TestObserver
> observer(new TestObserver(fetcher
.get(),
101 run_loop
.QuitClosure()));
102 fetcher
->Start(url
, transition
);
105 EXPECT_EQ(expected_non_web_platform
, non_web_platform_
);
106 EXPECT_EQ(expected_to_show
, observer
->will_show());
107 ASSERT_FALSE(fetcher
->is_active());
110 void LoadURLAndWaitForServiceWorker(const GURL
& url
) {
111 content::WebContents
* web_contents
=
112 browser()->tab_strip_model()->GetActiveWebContents();
113 content::TestNavigationObserver
observer(web_contents
, 2);
114 ui_test_utils::NavigateToURL(browser(), url
);
116 EXPECT_EQ("sw_activated", observer
.last_navigation_url().ref());
119 void RunBannerTest(const std::string
& manifest_page
,
120 ui::PageTransition transition
,
121 unsigned int unshown_repetitions
,
123 std::string
valid_page(manifest_page
);
124 GURL test_url
= embedded_test_server()->GetURL(valid_page
);
125 content::WebContents
* web_contents
=
126 browser()->tab_strip_model()->GetActiveWebContents();
128 for (unsigned int i
= 0; i
< unshown_repetitions
; ++i
) {
129 LoadURLAndWaitForServiceWorker(test_url
);
130 RunFetcher(web_contents
->GetURL(), std::string(), transition
, false);
131 AppBannerDataFetcher::SetTimeDeltaForTesting(i
+1);
134 // On the final loop, check whether the banner triggered or not as expected.
135 LoadURLAndWaitForServiceWorker(test_url
);
136 RunFetcher(web_contents
->GetURL(), std::string(), transition
, expectation
);
140 std::string non_web_platform_
;
141 base::Closure quit_closure_
;
142 base::WeakPtrFactory
<AppBannerDataFetcherBrowserTest
> weak_factory_
;
145 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
146 WebAppBannerCreatedDirect
) {
147 RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_TYPED
,
151 // http://crbug.com/517307
153 #define MAYBE_WebAppBannerCreatedDirectSingle \
154 DISABLED_WebAppBannerCreatedDirectSingle
156 #define MAYBE_WebAppBannerCreatedDirectSingle WebAppBannerCreatedDirectSingle
158 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
159 MAYBE_WebAppBannerCreatedDirectSingle
) {
160 AppBannerSettingsHelper::SetEngagementWeights(2, 1);
161 RunBannerTest("/banners/manifest_test_page.html",
162 ui::PAGE_TRANSITION_GENERATED
, 0, true);
165 // http://crbug.com/517307
167 #define MAYBE_WebAppBannerCreatedDirectMultiple \
168 DISABLED_WebAppBannerCreatedDirectMultiple
170 #define MAYBE_WebAppBannerCreatedDirectMultiple \
171 WebAppBannerCreatedDirectMultiple
173 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
174 MAYBE_WebAppBannerCreatedDirectMultiple
) {
175 AppBannerSettingsHelper::SetEngagementWeights(0.5, 1);
176 RunBannerTest("/banners/manifest_test_page.html",
177 ui::PAGE_TRANSITION_GENERATED
, 3, true);
180 // http://crbug.com/517307
182 #define MAYBE_WebAppBannerCreatedIndirect DISABLED_WebAppBannerCreatedIndirect
184 #define MAYBE_WebAppBannerCreatedIndirect WebAppBannerCreatedIndirect
186 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
187 MAYBE_WebAppBannerCreatedIndirect
) {
188 RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK
,
192 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
193 WebAppBannerCreatedIndirectSingle
) {
194 AppBannerSettingsHelper::SetEngagementWeights(1, 3);
195 RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_RELOAD
,
199 // http://crbug.com/517307
201 #define MAYBE_WebAppBannerCreatedIndirectMultiple \
202 DISABLED_WebAppBannerCreatedIndirectMultiple
204 #define MAYBE_WebAppBannerCreatedIndirectMultiple \
205 WebAppBannerCreatedIndirectMultiple
207 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
208 MAYBE_WebAppBannerCreatedIndirectMultiple
) {
209 AppBannerSettingsHelper::SetEngagementWeights(1, 0.5);
210 RunBannerTest("/banners/manifest_test_page.html", ui::PAGE_TRANSITION_LINK
,
214 // http://crbug.com/517307
216 #define MAYBE_WebAppBannerCreatedVarious DISABLED_WebAppBannerCreatedVarious
218 #define MAYBE_WebAppBannerCreatedVarious WebAppBannerCreatedVarious
220 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
221 MAYBE_WebAppBannerCreatedVarious
) {
222 AppBannerSettingsHelper::SetEngagementWeights(0.5, 0.25);
224 std::string
valid_page("/banners/manifest_test_page.html");
225 GURL test_url
= embedded_test_server()->GetURL(valid_page
);
226 content::WebContents
* web_contents
=
227 browser()->tab_strip_model()->GetActiveWebContents();
229 // Add a direct nav on day 1.
230 LoadURLAndWaitForServiceWorker(test_url
);
231 RunFetcher(web_contents
->GetURL(), std::string(), ui::PAGE_TRANSITION_TYPED
,
234 // Add an indirect nav on day 1 which is ignored.
235 LoadURLAndWaitForServiceWorker(test_url
);
236 RunFetcher(web_contents
->GetURL(), std::string(), ui::PAGE_TRANSITION_LINK
,
238 AppBannerDataFetcher::SetTimeDeltaForTesting(1);
240 // Add an indirect nav on day 2.
241 LoadURLAndWaitForServiceWorker(test_url
);
242 RunFetcher(web_contents
->GetURL(), std::string(),
243 ui::PAGE_TRANSITION_MANUAL_SUBFRAME
, false);
245 // Add a direct nav on day 2 which overrides.
246 LoadURLAndWaitForServiceWorker(test_url
);
247 RunFetcher(web_contents
->GetURL(), std::string(),
248 ui::PAGE_TRANSITION_GENERATED
, false);
249 AppBannerDataFetcher::SetTimeDeltaForTesting(2);
251 // Add a direct nav on day 3.
252 LoadURLAndWaitForServiceWorker(test_url
);
253 RunFetcher(web_contents
->GetURL(), std::string(),
254 ui::PAGE_TRANSITION_GENERATED
, false);
255 AppBannerDataFetcher::SetTimeDeltaForTesting(3);
257 // Add an indirect nav on day 4.
258 LoadURLAndWaitForServiceWorker(test_url
);
259 RunFetcher(web_contents
->GetURL(), std::string(),
260 ui::PAGE_TRANSITION_FORM_SUBMIT
, false);
262 // Add a direct nav on day 4 which should trigger the banner.
263 LoadURLAndWaitForServiceWorker(test_url
);
264 RunFetcher(web_contents
->GetURL(), std::string(),
265 ui::PAGE_TRANSITION_TYPED
, true);
268 // http://crbug.com/517307
270 #define MAYBE_WebAppBannerNoTypeInManifest DISABLED_WebAppBannerNoTypeInManifest
272 #define MAYBE_WebAppBannerNoTypeInManifest WebAppBannerNoTypeInManifest
274 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
275 MAYBE_WebAppBannerNoTypeInManifest
) {
276 RunBannerTest("/banners/manifest_no_type_test_page.html",
277 ui::PAGE_TRANSITION_TYPED
, 1, true);
280 // http://crbug.com/517307
282 #define MAYBE_WebAppBannerNoTypeInManifestCapsExtension DISABLED_WebAppBannerNoTypeInManifestCapsExtension
284 #define MAYBE_WebAppBannerNoTypeInManifestCapsExtension WebAppBannerNoTypeInManifestCapsExtension
286 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
287 MAYBE_WebAppBannerNoTypeInManifestCapsExtension
) {
288 RunBannerTest("/banners/manifest_no_type_caps_test_page.html",
289 ui::PAGE_TRANSITION_TYPED
, 1, true);
292 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
, PlayAppManifest
) {
293 std::string
valid_page("/banners/play_app_test_page.html");
294 GURL test_url
= embedded_test_server()->GetURL(valid_page
);
295 content::WebContents
* web_contents
=
296 browser()->tab_strip_model()->GetActiveWebContents();
298 // Native banners do not require the SW, so we can just load the URL.
299 ui_test_utils::NavigateToURL(browser(), test_url
);
300 std::string
play_platform("play");
301 RunFetcher(web_contents
->GetURL(), play_platform
, ui::PAGE_TRANSITION_TYPED
,
304 // The logic to get the details for a play app banner are only on android
305 // builds, so this test does not check that the banner is shown.
308 // http://crbug.com/517307
310 #define MAYBE_NoManifest DISABLED_NoManifest
312 #define MAYBE_NoManifest NoManifest
314 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
, MAYBE_NoManifest
) {
315 RunBannerTest("/banners/no_manifest_test_page.html",
316 ui::PAGE_TRANSITION_TYPED
, 1, false);
319 // http://crbug.com/517307
321 #define MAYBE_CancelBannerDirect DISABLED_CancelBannerDirect
323 #define MAYBE_CancelBannerDirect CancelBannerDirect
325 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
326 MAYBE_CancelBannerDirect
) {
327 RunBannerTest("/banners/cancel_test_page.html", ui::PAGE_TRANSITION_TYPED
, 1,
331 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
, CancelBannerIndirect
) {
332 AppBannerSettingsHelper::SetEngagementWeights(1, 0.5);
333 RunBannerTest("/banners/cancel_test_page.html", ui::PAGE_TRANSITION_TYPED
, 3,
337 // http://crbug.com/517307
339 #define MAYBE_PromptBanner DISABLED_PromptBanner
341 #define MAYBE_PromptBanner PromptBanner
343 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
, MAYBE_PromptBanner
) {
344 RunBannerTest("/banners/prompt_test_page.html", ui::PAGE_TRANSITION_TYPED
, 1,
348 // http://crbug.com/517307
350 #define MAYBE_PromptBannerInHandler DISABLED_PromptBannerInHandler
352 #define MAYBE_PromptBannerInHandler PromptBannerInHandler
354 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
,
355 MAYBE_PromptBannerInHandler
) {
356 RunBannerTest("/banners/prompt_in_handler_test_page.html",
357 ui::PAGE_TRANSITION_TYPED
, 1, true);
360 IN_PROC_BROWSER_TEST_F(AppBannerDataFetcherBrowserTest
, WebAppBannerInIFrame
) {
361 RunBannerTest("/banners/iframe_test_page.html", ui::PAGE_TRANSITION_TYPED
, 1,
365 } // namespace banners