summaryrefslogtreecommitdiffstats
path: root/chrome/browser/prefetch/prefetch_browsertest.cc
blob: 2119c83755c533d7d090236be309da492693e7eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2013 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/base_switches.h"
#include "base/command_line.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/net/prediction_options.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/network_change_notifier.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

using chrome_browser_net::NetworkPredictionOptions;
using net::NetworkChangeNotifier;

namespace {

const char kPrefetchPage[] = "/prerender/simple_prefetch.html";

class MockNetworkChangeNotifierWIFI : public NetworkChangeNotifier {
 public:
  ConnectionType GetCurrentConnectionType() const override {
    return NetworkChangeNotifier::CONNECTION_WIFI;
  }
};

class MockNetworkChangeNotifier4G : public NetworkChangeNotifier {
 public:
  ConnectionType GetCurrentConnectionType() const override {
    return NetworkChangeNotifier::CONNECTION_4G;
  }
};

class PrefetchBrowserTestBase : public InProcessBrowserTest {
 public:
  explicit PrefetchBrowserTestBase(bool disabled_via_field_trial)
      : disabled_via_field_trial_(disabled_via_field_trial) {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    if (disabled_via_field_trial_) {
      command_line->AppendSwitchASCII(switches::kForceFieldTrials,
                                      "Prefetch/ExperimentDisabled/");
    }
  }

  void SetUpOnMainThread() override {
    ASSERT_TRUE(embedded_test_server()->Start());
    InProcessBrowserTest::SetUpOnMainThread();
  }

  void SetPreference(NetworkPredictionOptions value) {
    browser()->profile()->GetPrefs()->SetInteger(
        prefs::kNetworkPredictionOptions, value);
  }

  bool RunPrefetchExperiment(bool expect_success, Browser* browser) {
    GURL url = embedded_test_server()->GetURL(kPrefetchPage);

    const base::string16 expected_title =
        expect_success ? base::ASCIIToUTF16("link onload")
                       : base::ASCIIToUTF16("link onerror");
    content::TitleWatcher title_watcher(
        browser->tab_strip_model()->GetActiveWebContents(), expected_title);
    ui_test_utils::NavigateToURL(browser, url);
    return expected_title == title_watcher.WaitAndGetTitle();
  }

 private:
  bool disabled_via_field_trial_;
};

class PrefetchBrowserTestPrediction : public PrefetchBrowserTestBase {
 public:
  PrefetchBrowserTestPrediction() : PrefetchBrowserTestBase(false) {}
};

class PrefetchBrowserTestPredictionDisabled : public PrefetchBrowserTestBase {
 public:
  PrefetchBrowserTestPredictionDisabled() : PrefetchBrowserTestBase(true) {}
};

// Prefetch is disabled via field experiment.  Prefetch should be dropped.
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPredictionDisabled,
                       ExperimentDisabled) {
  EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
  // Should not prefetch even if preference is ALWAYS.
  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_ALWAYS);
  EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
}

// Prefetch should be allowed depending on preference and network type.
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, PreferenceWorks) {
  // Set real NetworkChangeNotifier singleton aside.
  scoped_ptr<NetworkChangeNotifier::DisableForTest> disable_for_test(
      new NetworkChangeNotifier::DisableForTest);

  // Preference defaults to WIFI_ONLY: prefetch when not on cellular.
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
  }
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
  }

  // Set preference to ALWAYS: always prefetch.
  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_ALWAYS);
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
  }
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
    EXPECT_TRUE(RunPrefetchExperiment(true, browser()));
  }

  // Set preference to NEVER: never prefetch.
  SetPreference(NetworkPredictionOptions::NETWORK_PREDICTION_NEVER);
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifierWIFI);
    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
  }
  {
    scoped_ptr<NetworkChangeNotifier> mock(new MockNetworkChangeNotifier4G);
    EXPECT_TRUE(RunPrefetchExperiment(false, browser()));
  }
}

// Bug 339909: When in incognito mode the browser crashed due to an
// uninitialized preference member. Verify that it no longer does.
IN_PROC_BROWSER_TEST_F(PrefetchBrowserTestPrediction, IncognitoTest) {
  Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
  Browser* incognito_browser = new Browser(
      Browser::CreateParams(incognito_profile, browser()->host_desktop_type()));

  // Navigate just to have a tab in this window, otherwise there is no
  // WebContents for the incognito browser.
  OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));

  EXPECT_TRUE(RunPrefetchExperiment(true, incognito_browser));
}

}  // namespace