1 // Copyright 2013 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 "chrome/browser/ui/search/instant_test_utils.h" 6 7 #include "base/command_line.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "chrome/browser/chrome_notification_types.h" 11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/search/instant_service.h" 13 #include "chrome/browser/search/instant_service_factory.h" 14 #include "chrome/browser/search_engines/template_url_service.h" 15 #include "chrome/browser/search_engines/template_url_service_factory.h" 16 #include "chrome/browser/ui/omnibox/omnibox_view.h" 17 #include "chrome/browser/ui/search/instant_ntp.h" 18 #include "chrome/browser/ui/search/instant_ntp_prerenderer.h" 19 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/pref_names.h" 21 #include "chrome/test/base/interactive_test_utils.h" 22 #include "chrome/test/base/ui_test_utils.h" 23 #include "components/variations/entropy_provider.h" 24 #include "content/public/browser/notification_service.h" 25 #include "content/public/browser/render_process_host.h" 26 #include "content/public/browser/web_contents.h" 27 #include "content/public/common/result_codes.h" 28 #include "content/public/test/browser_test_utils.h" 29 30 namespace { 31 32 std::string WrapScript(const std::string& script) { 33 return "domAutomationController.send(" + script + ")"; 34 } 35 36 } // namespace 37 38 // InstantTestBase ----------------------------------------------------------- 39 40 InstantTestBase::InstantTestBase() 41 : https_test_server_( 42 net::SpawnedTestServer::TYPE_HTTPS, 43 net::BaseTestServer::SSLOptions(), 44 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))), 45 init_suggestions_url_(false) { 46 } 47 48 InstantTestBase::~InstantTestBase() {} 49 50 void InstantTestBase::SetupInstant(Browser* browser) { 51 browser_ = browser; 52 53 // TODO(samarth): update tests to work with cacheable NTP and remove this. 54 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( 55 "InstantExtended", "Group1 use_cacheable_ntp:0")); 56 57 TemplateURLService* service = 58 TemplateURLServiceFactory::GetForProfile(browser_->profile()); 59 ui_test_utils::WaitForTemplateURLServiceToLoad(service); 60 61 TemplateURLData data; 62 // Necessary to use exact URL for both the main URL and the alternate URL for 63 // search term extraction to work in InstantExtended. 64 data.short_name = ASCIIToUTF16("name"); 65 data.SetURL(instant_url_.spec() + 66 "q={searchTerms}&is_search&{google:omniboxStartMarginParameter}"); 67 data.instant_url = instant_url_.spec(); 68 if (init_suggestions_url_) 69 data.suggestions_url = instant_url_.spec() + "#q={searchTerms}"; 70 data.alternate_urls.push_back(instant_url_.spec() + "#q={searchTerms}"); 71 data.search_terms_replacement_key = "strk"; 72 73 TemplateURL* template_url = new TemplateURL(browser_->profile(), data); 74 service->Add(template_url); // Takes ownership of |template_url|. 75 service->SetDefaultSearchProvider(template_url); 76 77 InstantService* instant_service = 78 InstantServiceFactory::GetForProfile(browser_->profile()); 79 ASSERT_NE(static_cast<InstantService*>(NULL), instant_service); 80 instant_service->ntp_prerenderer()->ReloadInstantNTP(); 81 } 82 83 void InstantTestBase::SetInstantURL(const std::string& url) { 84 TemplateURLService* service = 85 TemplateURLServiceFactory::GetForProfile(browser_->profile()); 86 ui_test_utils::WaitForTemplateURLServiceToLoad(service); 87 88 TemplateURLData data; 89 data.short_name = ASCIIToUTF16("name"); 90 data.SetURL(url); 91 data.instant_url = url; 92 93 TemplateURL* template_url = new TemplateURL(browser_->profile(), data); 94 service->Add(template_url); // Takes ownership of |template_url|. 95 service->SetDefaultSearchProvider(template_url); 96 } 97 98 void InstantTestBase::Init(const GURL& instant_url, bool init_suggestions_url) { 99 instant_url_ = instant_url; 100 init_suggestions_url_ = init_suggestions_url; 101 } 102 103 void InstantTestBase::FocusOmnibox() { 104 // If the omnibox already has focus, just notify Instant. 105 if (omnibox()->model()->has_focus()) { 106 instant()->OmniboxFocusChanged(OMNIBOX_FOCUS_VISIBLE, 107 OMNIBOX_FOCUS_CHANGE_EXPLICIT, NULL); 108 } else { 109 browser_->window()->GetLocationBar()->FocusLocation(false); 110 } 111 } 112 113 void InstantTestBase::FocusOmniboxAndWaitForInstantNTPSupport() { 114 content::WindowedNotificationObserver ntp_observer( 115 chrome::NOTIFICATION_INSTANT_NTP_SUPPORT_DETERMINED, 116 content::NotificationService::AllSources()); 117 FocusOmnibox(); 118 119 InstantService* instant_service = 120 InstantServiceFactory::GetForProfile(browser_->profile()); 121 ASSERT_NE(static_cast<InstantService*>(NULL), instant_service); 122 if (!instant_service->ntp_prerenderer()->ntp() || 123 !instant_service->ntp_prerenderer()->ntp()->supports_instant()) 124 ntp_observer.Wait(); 125 } 126 127 void InstantTestBase::SetOmniboxText(const std::string& text) { 128 FocusOmnibox(); 129 omnibox()->SetUserText(UTF8ToUTF16(text)); 130 } 131 132 void InstantTestBase::PressEnterAndWaitForNavigation() { 133 content::WindowedNotificationObserver nav_observer( 134 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 135 content::NotificationService::AllSources()); 136 browser_->window()->GetLocationBar()->AcceptInput(); 137 nav_observer.Wait(); 138 } 139 140 bool InstantTestBase::GetBoolFromJS(content::WebContents* contents, 141 const std::string& script, 142 bool* result) { 143 return content::ExecuteScriptAndExtractBool( 144 contents, WrapScript(script), result); 145 } 146 147 bool InstantTestBase::GetIntFromJS(content::WebContents* contents, 148 const std::string& script, 149 int* result) { 150 return content::ExecuteScriptAndExtractInt( 151 contents, WrapScript(script), result); 152 } 153 154 bool InstantTestBase::GetStringFromJS(content::WebContents* contents, 155 const std::string& script, 156 std::string* result) { 157 return content::ExecuteScriptAndExtractString( 158 contents, WrapScript(script), result); 159 } 160 161 bool InstantTestBase::ExecuteScript(const std::string& script) { 162 InstantService* instant_service = 163 InstantServiceFactory::GetForProfile(browser_instant()->profile()); 164 if (!instant_service) 165 return false; 166 return content::ExecuteScript(instant_service->GetNTPContents(), script); 167 } 168 169 bool InstantTestBase::CheckVisibilityIs(content::WebContents* contents, 170 bool expected) { 171 bool actual = !expected; // Purposely start with a mis-match. 172 // We can only use ASSERT_*() in a method that returns void, hence this 173 // convoluted check. 174 return GetBoolFromJS(contents, "!document.hidden", &actual) && 175 actual == expected; 176 } 177 178 std::string InstantTestBase::GetOmniboxText() { 179 return UTF16ToUTF8(omnibox()->GetText()); 180 } 181 182 bool InstantTestBase::LoadImage(content::RenderViewHost* rvh, 183 const std::string& image, 184 bool* loaded) { 185 std::string js_chrome = 186 "var img = document.createElement('img');" 187 "img.onerror = function() { domAutomationController.send(false); };" 188 "img.onload = function() { domAutomationController.send(true); };" 189 "img.src = '" + image + "';"; 190 return content::ExecuteScriptAndExtractBool(rvh, js_chrome, loaded); 191 } 192 193 base::string16 InstantTestBase::GetBlueText() { 194 size_t start = 0, end = 0; 195 omnibox()->GetSelectionBounds(&start, &end); 196 if (start > end) 197 std::swap(start, end); 198 return omnibox()->GetText().substr(start, end - start); 199 } 200