Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: chrome/browser/engagement/site_engagement_helper_unittest.cc

Issue 1388293002: Notify WebContentsObservers of user interactions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Refactoring site engagement to use DidGetUserInteraction Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "base/command_line.h"
6 #include "base/test/histogram_tester.h"
7 #include "base/timer/mock_timer.h"
8 #include "base/values.h"
9 #include "chrome/browser/engagement/site_engagement_helper.h"
10 #include "chrome/browser/engagement/site_engagement_service.h"
11 #include "chrome/browser/engagement/site_engagement_service_factory.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/tabs/tab_strip_model.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/test/base/browser_with_test_window_test.h"
16 #include "content/public/browser/page_navigator.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 class SiteEngagementHelperTest : public BrowserWithTestWindowTest {
20 public:
21 // Create a SiteEngagementHelper. Called here as friend class methods cannot
22 // be called in tests.
23 scoped_ptr<SiteEngagementHelper> CreateHelper(
24 content::WebContents* web_contents) {
25 scoped_ptr<SiteEngagementHelper> helper(
26 new SiteEngagementHelper(web_contents));
27 DCHECK(helper.get());
28
29 return helper.Pass();
30 }
31
32 void StartTracking(SiteEngagementHelper* helper) {
33 helper->input_tracker_.StartTracking();
34 }
35
36 // Simulate a user interaction event and handle it.
37 void HandleUserInput(SiteEngagementHelper* helper,
38 blink::WebInputEvent::Type type) {
39 helper->input_tracker_.DidGetUserInteraction(type);
40 }
41
42 // Simulate a user interaction event and handle it. Reactivates tracking
43 // immediately.
44 void HandleUserInputAndRestartTracking(SiteEngagementHelper* helper,
45 blink::WebInputEvent::Type type) {
46 helper->input_tracker_.DidGetUserInteraction(type);
47 helper->input_tracker_.StartTracking();
48 }
49
50 // Set a pause timer on the input tracker for test purposes.
51 void SetInputTrackerPauseTimer(SiteEngagementHelper* helper,
52 scoped_ptr<base::Timer> timer) {
53 helper->input_tracker_.SetPauseTimerForTesting(timer.Pass());
54 }
55
56 bool IsTracking(SiteEngagementHelper* helper) {
57 return helper->input_tracker_.is_tracking();
58 }
59
60 void NavigateWithDisposition(GURL& url, WindowOpenDisposition disposition) {
61 content::NavigationController* controller =
62 &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
63 browser()->OpenURL(
64 content::OpenURLParams(url, content::Referrer(), disposition,
65 ui::PAGE_TRANSITION_TYPED, false));
66 CommitPendingLoad(controller);
67 }
68
69 void UserInputAccumulation(const blink::WebInputEvent::Type type) {
70 AddTab(browser(), GURL("about:blank"));
71 GURL url1("https://www.google.com/");
72 GURL url2("http://www.google.com/");
73 content::WebContents* web_contents =
74 browser()->tab_strip_model()->GetActiveWebContents();
75
76 scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
77 SiteEngagementService* service =
78 SiteEngagementServiceFactory::GetForProfile(browser()->profile());
79 DCHECK(service);
80
81 // Check that navigation triggers engagement.
82 NavigateWithDisposition(url1, CURRENT_TAB);
83 StartTracking(helper.get());
84
85 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
86 EXPECT_EQ(0, service->GetScore(url2));
87
88 // Simulate a key press trigger and ensure it is treated correctly.
89 HandleUserInputAndRestartTracking(helper.get(), type);
90
91 EXPECT_DOUBLE_EQ(0.55, service->GetScore(url1));
92 EXPECT_EQ(0, service->GetScore(url2));
93
94 // Simulate three key presses, and ensure they are treated correctly.
95 HandleUserInputAndRestartTracking(helper.get(), type);
96 HandleUserInputAndRestartTracking(helper.get(), type);
97 HandleUserInputAndRestartTracking(helper.get(), type);
98
99 EXPECT_DOUBLE_EQ(0.7, service->GetScore(url1));
100 EXPECT_EQ(0, service->GetScore(url2));
101
102 // Simulate key presses for a different link.
103 NavigateWithDisposition(url2, CURRENT_TAB);
104 StartTracking(helper.get());
105
106 EXPECT_DOUBLE_EQ(0.7, service->GetScore(url1));
107 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
108 EXPECT_DOUBLE_EQ(1.2, service->GetTotalEngagementPoints());
109
110 HandleUserInputAndRestartTracking(helper.get(), type);
111 EXPECT_DOUBLE_EQ(0.7, service->GetScore(url1));
112 EXPECT_DOUBLE_EQ(0.55, service->GetScore(url2));
113 EXPECT_DOUBLE_EQ(1.25, service->GetTotalEngagementPoints());
114 }
115 };
116
117 TEST_F(SiteEngagementHelperTest, KeyPressEngagementAccumulation) {
118 UserInputAccumulation(blink::WebInputEvent::RawKeyDown);
119 }
120
121 TEST_F(SiteEngagementHelperTest, MouseEventEngagementAccumulation) {
122 UserInputAccumulation(blink::WebInputEvent::MouseDown);
123 }
124
125 TEST_F(SiteEngagementHelperTest, GestureEngagementAccumulation) {
126 UserInputAccumulation(blink::WebInputEvent::GestureTapDown);
127 }
128
129 TEST_F(SiteEngagementHelperTest, WheelEngagementAccumulation) {
130 UserInputAccumulation(blink::WebInputEvent::MouseWheel);
131 }
132
133 TEST_F(SiteEngagementHelperTest, MixedInputEngagementAccumulation) {
134 AddTab(browser(), GURL("about:blank"));
135 GURL url1("https://www.google.com/");
136 GURL url2("http://www.google.com/");
137 content::WebContents* web_contents =
138 browser()->tab_strip_model()->GetActiveWebContents();
139
140 scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
141 SiteEngagementService* service =
142 SiteEngagementServiceFactory::GetForProfile(browser()->profile());
143 DCHECK(service);
144
145 base::HistogramTester histograms;
146
147 // Histograms should start off empty.
148 histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
149 0);
150
151 NavigateWithDisposition(url1, CURRENT_TAB);
152 StartTracking(helper.get());
153
154 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
155 EXPECT_EQ(0, service->GetScore(url2));
156 histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
157 1);
158 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
159 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 1);
160
161 HandleUserInputAndRestartTracking(helper.get(),
162 blink::WebInputEvent::RawKeyDown);
163 HandleUserInputAndRestartTracking(helper.get(),
164 blink::WebInputEvent::GestureTapDown);
165 HandleUserInputAndRestartTracking(helper.get(),
166 blink::WebInputEvent::GestureTapDown);
167 HandleUserInputAndRestartTracking(helper.get(),
168 blink::WebInputEvent::MouseWheel);
169 HandleUserInputAndRestartTracking(helper.get(),
170 blink::WebInputEvent::MouseDown);
171
172 EXPECT_DOUBLE_EQ(0.75, service->GetScore(url1));
173 EXPECT_EQ(0, service->GetScore(url2));
174 histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
175 6);
176 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
177 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 1);
178 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
179 SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 1);
180 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
181 SiteEngagementMetrics::ENGAGEMENT_MOUSE, 1);
182 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
183 SiteEngagementMetrics::ENGAGEMENT_WHEEL, 1);
184 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
185 SiteEngagementMetrics::ENGAGEMENT_GESTURE, 2);
186
187 HandleUserInputAndRestartTracking(helper.get(),
188 blink::WebInputEvent::MouseDown);
189 HandleUserInputAndRestartTracking(helper.get(),
190 blink::WebInputEvent::MouseDown);
191 HandleUserInputAndRestartTracking(helper.get(),
192 blink::WebInputEvent::MouseWheel);
193
194 EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
195 EXPECT_EQ(0, service->GetScore(url2));
196 histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
197 9);
198 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
199 SiteEngagementMetrics::ENGAGEMENT_MOUSE, 3);
200 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
201 SiteEngagementMetrics::ENGAGEMENT_WHEEL, 2);
202
203 NavigateWithDisposition(url2, CURRENT_TAB);
204 StartTracking(helper.get());
205
206 EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
207 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
208 EXPECT_DOUBLE_EQ(1.4, service->GetTotalEngagementPoints());
209
210 HandleUserInputAndRestartTracking(helper.get(),
211 blink::WebInputEvent::GestureTapDown);
212 HandleUserInputAndRestartTracking(helper.get(),
213 blink::WebInputEvent::RawKeyDown);
214
215 EXPECT_DOUBLE_EQ(0.9, service->GetScore(url1));
216 EXPECT_DOUBLE_EQ(0.6, service->GetScore(url2));
217 EXPECT_DOUBLE_EQ(1.5, service->GetTotalEngagementPoints());
218 histograms.ExpectTotalCount(SiteEngagementMetrics::kEngagementTypeHistogram,
219 12);
220 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
221 SiteEngagementMetrics::ENGAGEMENT_NAVIGATION, 2);
222 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
223 SiteEngagementMetrics::ENGAGEMENT_KEYPRESS, 2);
224 histograms.ExpectBucketCount(SiteEngagementMetrics::kEngagementTypeHistogram,
225 SiteEngagementMetrics::ENGAGEMENT_GESTURE, 3);
226 }
227
228 TEST_F(SiteEngagementHelperTest, CheckTimerAndCallbacks) {
229 AddTab(browser(), GURL("about:blank"));
230 GURL url1("https://www.google.com/");
231 GURL url2("http://www.google.com/");
232 content::WebContents* web_contents =
233 browser()->tab_strip_model()->GetActiveWebContents();
234
235 base::MockTimer* input_tracker_timer = new base::MockTimer(true, false);
236 scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
237 SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer));
238
239 SiteEngagementService* service =
240 SiteEngagementServiceFactory::GetForProfile(browser()->profile());
241 DCHECK(service);
242
243 NavigateWithDisposition(url1, CURRENT_TAB);
244 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url1));
245 EXPECT_EQ(0, service->GetScore(url2));
246
247 // Timer should be running for navigation delay.
248 EXPECT_TRUE(input_tracker_timer->IsRunning());
249 EXPECT_FALSE(IsTracking(helper.get()));
250 input_tracker_timer->Fire();
251
252 // Timer should start running again after input.
253 EXPECT_FALSE(input_tracker_timer->IsRunning());
254 EXPECT_TRUE(IsTracking(helper.get()));
255 HandleUserInput(helper.get(), blink::WebInputEvent::RawKeyDown);
256 EXPECT_TRUE(input_tracker_timer->IsRunning());
257 EXPECT_FALSE(IsTracking(helper.get()));
258
259 EXPECT_DOUBLE_EQ(0.55, service->GetScore(url1));
260 EXPECT_EQ(0, service->GetScore(url2));
261
262 input_tracker_timer->Fire();
263 EXPECT_FALSE(input_tracker_timer->IsRunning());
264 EXPECT_TRUE(IsTracking(helper.get()));
265
266 // Timer should start running again after input.
267 HandleUserInput(helper.get(), blink::WebInputEvent::MouseWheel);
268 EXPECT_TRUE(input_tracker_timer->IsRunning());
269 EXPECT_FALSE(IsTracking(helper.get()));
270
271 EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
272 EXPECT_EQ(0, service->GetScore(url2));
273
274 input_tracker_timer->Fire();
275 EXPECT_FALSE(input_tracker_timer->IsRunning());
276 EXPECT_TRUE(IsTracking(helper.get()));
277
278 // Timer should be running for navigation delay.
279 NavigateWithDisposition(url2, CURRENT_TAB);
280 EXPECT_TRUE(input_tracker_timer->IsRunning());
281 EXPECT_FALSE(IsTracking(helper.get()));
282
283 EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
284 EXPECT_DOUBLE_EQ(0.5, service->GetScore(url2));
285
286 input_tracker_timer->Fire();
287 EXPECT_FALSE(input_tracker_timer->IsRunning());
288 EXPECT_TRUE(IsTracking(helper.get()));
289
290 HandleUserInput(helper.get(), blink::WebInputEvent::MouseDown);
291 EXPECT_TRUE(input_tracker_timer->IsRunning());
292 EXPECT_FALSE(IsTracking(helper.get()));
293
294 EXPECT_DOUBLE_EQ(0.6, service->GetScore(url1));
295 EXPECT_DOUBLE_EQ(0.55, service->GetScore(url2));
296 EXPECT_DOUBLE_EQ(1.15, service->GetTotalEngagementPoints());
297 }
298
299 // Ensure that navigation does not trigger input tracking until after a delay.
300 // We must manually call WasShown/WasHidden as they are not triggered
301 // automatically in this test environment.
302 TEST_F(SiteEngagementHelperTest, ShowAndHide) {
303 AddTab(browser(), GURL("about:blank"));
304 GURL url1("https://www.google.com/");
305 GURL url2("http://www.google.com/");
306 content::WebContents* web_contents =
307 browser()->tab_strip_model()->GetActiveWebContents();
308
309 base::MockTimer* input_tracker_timer = new base::MockTimer(true, false);
310 scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
311 SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer));
312
313 NavigateWithDisposition(url1, CURRENT_TAB);
314 input_tracker_timer->Fire();
315
316 EXPECT_FALSE(input_tracker_timer->IsRunning());
317 EXPECT_TRUE(IsTracking(helper.get()));
318
319 // Hiding the tab should stop input tracking.
320 NavigateWithDisposition(url2, NEW_FOREGROUND_TAB);
321 web_contents->WasHidden();
322 EXPECT_FALSE(IsTracking(helper.get()));
323
324 // Showing the tab should start tracking again after another delay.
325 browser()->tab_strip_model()->ActivateTabAt(0, true);
326 web_contents->WasShown();
327 EXPECT_TRUE(input_tracker_timer->IsRunning());
328 EXPECT_FALSE(IsTracking(helper.get()));
329
330 // New background tabs should not affect the current tab's input tracking.
331 NavigateWithDisposition(url2, NEW_BACKGROUND_TAB);
332 EXPECT_TRUE(input_tracker_timer->IsRunning());
333 EXPECT_FALSE(IsTracking(helper.get()));
334
335 input_tracker_timer->Fire();
336 EXPECT_FALSE(input_tracker_timer->IsRunning());
337 EXPECT_TRUE(IsTracking(helper.get()));
338
339 // New background tabs should not affect the current tab's input tracking.
340 NavigateWithDisposition(url2, NEW_BACKGROUND_TAB);
341 EXPECT_FALSE(input_tracker_timer->IsRunning());
342 EXPECT_TRUE(IsTracking(helper.get()));
343
344 // Ensure behavior holds when tab is hidden before the initial delay timer
345 // fires.
346 NavigateWithDisposition(url2, CURRENT_TAB);
347 EXPECT_TRUE(input_tracker_timer->IsRunning());
348 EXPECT_FALSE(IsTracking(helper.get()));
349
350 NavigateWithDisposition(url2, NEW_FOREGROUND_TAB);
351 browser()->tab_strip_model()->ActivateTabAt(4, true);
352 web_contents->WasHidden();
353 EXPECT_FALSE(input_tracker_timer->IsRunning());
354 EXPECT_FALSE(IsTracking(helper.get()));
355
356 // Showing the tab should start tracking again after another delay.
357 browser()->tab_strip_model()->ActivateTabAt(0, true);
358 web_contents->WasShown();
359 EXPECT_TRUE(input_tracker_timer->IsRunning());
360 EXPECT_FALSE(IsTracking(helper.get()));
361
362 input_tracker_timer->Fire();
363 EXPECT_TRUE(IsTracking(helper.get()));
364 }
365
366 // Ensure tracking behavior is correct for multiple navigations in a single tab.
367 TEST_F(SiteEngagementHelperTest, SingleTabNavigation) {
368 AddTab(browser(), GURL("about:blank"));
369 GURL url1("https://www.google.com/");
370 GURL url2("https://www.example.com/");
371 content::WebContents* web_contents =
372 browser()->tab_strip_model()->GetActiveWebContents();
373
374 base::MockTimer* input_tracker_timer = new base::MockTimer(true, false);
375 scoped_ptr<SiteEngagementHelper> helper(CreateHelper(web_contents));
376 SetInputTrackerPauseTimer(helper.get(), make_scoped_ptr(input_tracker_timer));
377
378 // Navigation should start the initial delay timer.
379 NavigateWithDisposition(url1, CURRENT_TAB);
380 EXPECT_TRUE(input_tracker_timer->IsRunning());
381 EXPECT_FALSE(IsTracking(helper.get()));
382
383 // Navigating before the timer fires should simply reset the timer.
384 NavigateWithDisposition(url2, CURRENT_TAB);
385 EXPECT_TRUE(input_tracker_timer->IsRunning());
386 EXPECT_FALSE(IsTracking(helper.get()));
387
388 // When the timer fires, callbacks are added.
389 input_tracker_timer->Fire();
390 EXPECT_FALSE(input_tracker_timer->IsRunning());
391 EXPECT_TRUE(IsTracking(helper.get()));
392
393 // Navigation should start the initial delay timer again.
394 NavigateWithDisposition(url1, CURRENT_TAB);
395 EXPECT_TRUE(input_tracker_timer->IsRunning());
396 EXPECT_FALSE(IsTracking(helper.get()));
397 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698