1 #!/usr/bin/env python 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import glob 7 import os 8 import re 9 import shutil 10 import tempfile 11 import urlparse 12 13 import pyauto_functional # Must be imported before pyauto 14 import pyauto 15 import test_utils 16 17 18 class OmniboxTest(pyauto.PyUITest): 19 """Test cases for the omnibox.""" 20 21 def Debug(self): 22 """Test method for experimentation. 23 24 This method will not run automatically. 25 """ 26 import time 27 while True: 28 self.pprint(self.GetOmniboxInfo().omniboxdict) 29 time.sleep(1) 30 31 def testFocusOnStartup(self): 32 """Verify that the omnibox has focus on startup.""" 33 self.WaitUntilOmniboxReadyHack() 34 self.assertTrue(self.GetOmniboxInfo().Properties('has_focus')) 35 36 def testHistoryResult(self): 37 """Verify that the omnibox can fetch items from the history.""" 38 url = self.GetFileURLForDataPath('title2.html') 39 title = 'Title Of Awesomeness' 40 self.AppendTab(pyauto.GURL(url)) 41 def _VerifyHistoryResult(query_list, description, windex=0): 42 """Verify result matching given description for given list of queries.""" 43 for query_text in query_list: 44 matches = test_utils.GetOmniboxMatchesFor( 45 self, query_text, windex=windex, 46 attr_dict={'description': description}) 47 self.assertTrue(matches) 48 self.assertEqual(1, len(matches)) 49 item = matches[0] 50 self.assertEqual(url, item['destination_url']) 51 # Query using URL & title. 52 _VerifyHistoryResult([url, title], title) 53 # Verify results in another tab. 54 self.AppendTab(pyauto.GURL()) 55 _VerifyHistoryResult([url, title], title) 56 # Verify results in another window. 57 self.OpenNewBrowserWindow(True) 58 self.WaitUntilOmniboxReadyHack(windex=1) 59 _VerifyHistoryResult([url, title], title, windex=1) 60 # Verify results in an incognito window. 61 self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) 62 self.WaitUntilOmniboxReadyHack(windex=2) 63 _VerifyHistoryResult([url, title], title, windex=2) 64 65 def _VerifyOmniboxURLMatches(self, url, description, windex=0): 66 """Verify URL match results from the omnibox. 67 68 Args: 69 url: The URL to use. 70 description: The string description within the history page and Google 71 search to match against. 72 windex: The window index to work on. Defaults to 0 (first window). 73 """ 74 matches_description = test_utils.GetOmniboxMatchesFor( 75 self, url, windex=windex, attr_dict={'description': description}) 76 self.assertEqual(1, len(matches_description)) 77 if description == 'Google Search': 78 self.assertTrue(re.match('http://www.google.com/search.+', 79 matches_description[0]['destination_url'])) 80 else: 81 self.assertEqual(url, matches_description[0]['destination_url']) 82 83 def testFetchHistoryResultItems(self): 84 """Verify omnibox fetches history items in 2nd tab, window and incognito.""" 85 url = self.GetFileURLForDataPath('title2.html') 86 title = 'Title Of Awesomeness' 87 desc = 'Google Search' 88 # Fetch history page item in the second tab. 89 self.AppendTab(pyauto.GURL(url)) 90 self._VerifyOmniboxURLMatches(url, title) 91 # Fetch history page items in the second window. 92 self.OpenNewBrowserWindow(True) 93 self.NavigateToURL(url, 1, 0) 94 self._VerifyOmniboxURLMatches(url, title, windex=1) 95 # Fetch google search items in incognito window. 96 self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) 97 self.NavigateToURL(url, 2, 0) 98 self._VerifyOmniboxURLMatches(url, desc, windex=2) 99 100 def testSelect(self): 101 """Verify omnibox popup selection.""" 102 url1 = self.GetFileURLForDataPath('title2.html') 103 url2 = self.GetFileURLForDataPath('title1.html') 104 title1 = 'Title Of Awesomeness' 105 self.NavigateToURL(url1) 106 self.NavigateToURL(url2) 107 matches = test_utils.GetOmniboxMatchesFor(self, 'file://') 108 self.assertTrue(matches) 109 # Find the index of match for |url1|. 110 index = None 111 for i, match in enumerate(matches): 112 if match['description'] == title1: 113 index = i 114 self.assertTrue(index is not None) 115 self.OmniboxMovePopupSelection(index) # Select |url1| line in popup. 116 self.assertEqual(url1, self.GetOmniboxInfo().Text()) 117 self.OmniboxAcceptInput() 118 self.assertEqual(title1, self.GetActiveTabTitle()) 119 120 def testInlineAutoComplete(self): 121 """Verify inline autocomplete for a pre-visited URL.""" 122 self.NavigateToURL('http://www.google.com') 123 matches = test_utils.GetOmniboxMatchesFor(self, 'goog') 124 self.assertTrue(matches) 125 # Omnibox should suggest auto completed URL as the first item. 126 matches_description = matches[0] 127 self.assertTrue('www.google.com' in matches_description['contents']) 128 self.assertEqual('history-url', matches_description['type']) 129 # The URL should be inline-autocompleted in the omnibox. 130 self.assertTrue('google.com' in self.GetOmniboxInfo().Text()) 131 132 def testCrazyFilenames(self): 133 """Test omnibox query with filenames containing special chars. 134 135 The files are created on the fly and cleaned after use. 136 """ 137 filename = os.path.join(self.DataDir(), 'downloads', 'crazy_filenames.txt') 138 zip_names = self.EvalDataFrom(filename) 139 # We got .zip filenames. Change them to .html. 140 crazy_filenames = [x.replace('.zip', '.html') for x in zip_names] 141 title = 'given title' 142 143 def _CreateFile(name): 144 """Create the given html file.""" 145 fp = open(name, 'w') # |name| could be unicode. 146 print >>fp, '<html><title>%s</title><body>' % title 147 print >>fp, 'This is a junk file named <h2>%s</h2>' % repr(name) 148 print >>fp, '</body></html>' 149 fp.close() 150 151 crazy_fileurls = [] 152 # Temp dir for hosting crazy filenames. 153 temp_dir = tempfile.mkdtemp(prefix='omnibox') 154 # Windows has a dual nature dealing with unicode filenames. 155 # While the files are internally saved as unicode, there's a non-unicode 156 # aware API that returns a locale-dependent coding on the true unicode 157 # filenames. This messes up things. 158 # Filesystem-interfacing functions like os.listdir() need to 159 # be given unicode strings to "do the right thing" on win. 160 # Ref: http://boodebr.org/main/python/all-about-python-and-unicode 161 try: 162 for filename in crazy_filenames: # |filename| is unicode. 163 file_path = os.path.join(temp_dir, filename.encode('utf-8')) 164 _CreateFile(os.path.join(temp_dir, filename)) 165 file_url = self.GetFileURLForPath(file_path) 166 crazy_fileurls.append(file_url) 167 self.NavigateToURL(file_url) 168 169 # Verify omnibox queries. 170 for file_url in crazy_fileurls: 171 matches = test_utils.GetOmniboxMatchesFor(self, 172 file_url, attr_dict={'type': 'url-what-you-typed', 173 'description': title}) 174 self.assertTrue(matches) 175 self.assertEqual(1, len(matches)) 176 self.assertTrue(os.path.basename(file_url) in 177 matches[0]['destination_url']) 178 finally: 179 shutil.rmtree(unicode(temp_dir)) # Unicode so that Win treats nicely. 180 181 def testSuggest(self): 182 """Verify suggested results in omnibox.""" 183 matches = test_utils.GetOmniboxMatchesFor(self, 'apple') 184 self.assertTrue(matches) 185 self.assertTrue([x for x in matches if x['type'] == 'search-suggest']) 186 187 def testDifferentTypesOfResults(self): 188 """Verify different types of results from omnibox. 189 190 This includes history result, bookmark result, suggest results. 191 """ 192 url = 'http://www.google.com/' 193 title = 'Google' 194 search_string = 'google' 195 self.AddBookmarkURL( # Add a bookmark. 196 self.GetBookmarkModel().BookmarkBar()['id'], 0, title, url) 197 self.NavigateToURL(url) # Build up history. 198 matches = test_utils.GetOmniboxMatchesFor(self, search_string) 199 self.assertTrue(matches) 200 # Verify starred result (indicating bookmarked url). 201 self.assertTrue([x for x in matches if x['starred'] == True]) 202 for item_type in ('history-url', 'search-what-you-typed', 203 'search-suggest',): 204 self.assertTrue([x for x in matches if x['type'] == item_type]) 205 206 def testSuggestPref(self): 207 """Verify no suggests for omnibox when suggested-services disabled.""" 208 search_string = 'apple' 209 self.assertTrue(self.GetPrefsInfo().Prefs(pyauto.kSearchSuggestEnabled)) 210 matches = test_utils.GetOmniboxMatchesFor(self, search_string) 211 self.assertTrue(matches) 212 self.assertTrue([x for x in matches if x['type'] == 'search-suggest']) 213 # Disable suggest-service. 214 self.SetPrefs(pyauto.kSearchSuggestEnabled, False) 215 self.assertFalse(self.GetPrefsInfo().Prefs(pyauto.kSearchSuggestEnabled)) 216 matches = test_utils.GetOmniboxMatchesFor(self, search_string) 217 self.assertTrue(matches) 218 # Verify there are no suggest results. 219 self.assertFalse([x for x in matches if x['type'] == 'search-suggest']) 220 221 def testAutoCompleteForSearch(self): 222 """Verify omnibox autocomplete for search.""" 223 search_string = 'youtu' 224 verify_string = 'youtube' 225 matches = test_utils.GetOmniboxMatchesFor(self, search_string) 226 # Retrieve last contents element. 227 matches_description = matches[-1]['contents'].split() 228 self.assertEqual(verify_string, matches_description[0]) 229 230 def _GotContentHistory(self, search_text, url): 231 """Check if omnibox returns a previously-visited page for given search text. 232 233 Args: 234 search_text: The string search text. 235 url: The string URL to look for in the omnibox matches. 236 237 Returns: 238 True, if the omnibox returns the previously-visited page for the given 239 search text, or False otherwise. 240 """ 241 # Omnibox doesn't change results if searching the same text repeatedly. 242 # So setting '' in omnibox before the next repeated search. 243 self.SetOmniboxText('') 244 matches = test_utils.GetOmniboxMatchesFor(self, search_text) 245 matches_description = [x for x in matches if x['destination_url'] == url] 246 return 1 == len(matches_description) 247 248 def testContentHistory(self): 249 """Verify omnibox results when entering page content. 250 251 Test verifies that visited page shows up in omnibox on entering page 252 content. 253 """ 254 url = self.GetFileURLForPath( 255 os.path.join(self.DataDir(), 'find_in_page', 'largepage.html')) 256 self.NavigateToURL(url) 257 self.assertTrue(self.WaitUntil( 258 lambda: self._GotContentHistory('British throne', url))) 259 260 def testOmniboxSearchHistory(self): 261 """Verify page navigation/search from omnibox are added to the history.""" 262 url = self.GetFileURLForDataPath('title2.html') 263 self.NavigateToURL(url) 264 self.AppendTab(pyauto.GURL('about:blank')) 265 self.SetOmniboxText('java') 266 self.WaitUntilOmniboxQueryDone() 267 self.OmniboxAcceptInput() 268 history = self.GetHistoryInfo().History() 269 self.assertEqual(2, len(history)) 270 self.assertEqual(url, history[1]['url']) 271 self.assertEqual('java - Google Search', history[0]['title']) 272 273 def _VerifyHasBookmarkResult(self, matches): 274 """Verify that we have a bookmark result. 275 276 Args: 277 matches: A list of match items, as returned by 278 test_utils.GetOmniboxMatchesFor(). 279 """ 280 matches_starred = [result for result in matches if result['starred']] 281 self.assertTrue(matches_starred) 282 self.assertEqual(1, len(matches_starred)) 283 284 def _CheckBookmarkResultForVariousInputs(self, url, title, windex=0): 285 """Check if we get the bookmark for complete and partial inputs. 286 287 Args: 288 url: A string URL. 289 title: A string title for the given URL. 290 windex: The window index to use. Defaults to 0 (first window). 291 """ 292 # Check if the complete URL would get the bookmark. 293 url_matches = test_utils.GetOmniboxMatchesFor(self, url, windex=windex) 294 self._VerifyHasBookmarkResult(url_matches) 295 # Check if the complete title would get the bookmark. 296 title_matches = test_utils.GetOmniboxMatchesFor(self, title, windex=windex) 297 self._VerifyHasBookmarkResult(title_matches) 298 # Check if the partial URL would get the bookmark. 299 split_url = urlparse.urlsplit(url) 300 partial_url = test_utils.GetOmniboxMatchesFor( 301 self, split_url.scheme, windex=windex) 302 self._VerifyHasBookmarkResult(partial_url) 303 # Check if the partial title would get the bookmark. 304 split_title = title.split() 305 search_term = split_title[len(split_title) - 1] 306 partial_title = test_utils.GetOmniboxMatchesFor( 307 self, search_term, windex=windex) 308 self._VerifyHasBookmarkResult(partial_title) 309 310 def testBookmarkResultInNewTabAndWindow(self): 311 """Verify omnibox finds bookmarks in search options of new tabs/windows.""" 312 url = self.GetFileURLForDataPath('title2.html') 313 self.NavigateToURL(url) 314 title = 'This is Awesomeness' 315 bookmarks = self.GetBookmarkModel() 316 bar_id = bookmarks.BookmarkBar()['id'] 317 self.AddBookmarkURL(bar_id, 0, title, url) 318 bookmarks = self.GetBookmarkModel() 319 nodes = bookmarks.FindByTitle(title) 320 self.AppendTab(pyauto.GURL(url)) 321 self._CheckBookmarkResultForVariousInputs(url, title) 322 self.OpenNewBrowserWindow(True) 323 self.assertEqual(2, self.GetBrowserWindowCount()) 324 self.NavigateToURL(url, 1, 0) 325 self._CheckBookmarkResultForVariousInputs(url, title, windex=1) 326 self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW) 327 self.assertEqual(3, self.GetBrowserWindowCount()) 328 self.NavigateToURL(url, 2, 0) 329 self._CheckBookmarkResultForVariousInputs(url, title, windex=2) 330 331 def testAutoCompleteForNonAsciiSearch(self): 332 """Verify can search/autocomplete with non-ASCII incomplete keywords.""" 333 search_string = u'\u767e' 334 verify_string = u'\u767e\u5ea6\u4e00\u4e0b' 335 matches = test_utils.GetOmniboxMatchesFor(self, search_string) 336 self.assertTrue(verify_string in matches[-1]['contents']) 337 338 339 class OmniboxLiveTest(pyauto.PyUITest): 340 """Test cases for the omnibox that hit live servers (such as Google).""" 341 342 def ExtraChromeFlags(self): 343 """Override default list of extra flags used in pyauto tests.""" 344 # Force the suggest field trial group. This doesn't guarantee that there 345 # will be no experimental behaviour, but there's no other way to disable 346 # all suggest field trials at the moment. TODO(mpearson): Consider allowing 347 # the suggest_url to be overridden using a flag (so that we can omit the 348 # "sugexp=chrome,mod=<n>" CGI param), or provide some other way to turn off 349 # all suggest field trials. 350 return ['--force-fieldtrials=OmniboxSearchSuggest/10/'] 351 352 def testGoogleSearch(self): 353 """Verify Google search item in omnibox results.""" 354 search_text = 'hello world' 355 verify_str = 'Google Search' 356 url_re = 'http://www.google.com/search\?.*q=hello\+world.*' 357 matches_description = test_utils.GetOmniboxMatchesFor( 358 self, search_text, attr_dict={'description': verify_str}) 359 self.assertTrue(matches_description) 360 # There should be a least one entry with the description Google. Suggest 361 # results may end up having 'Google Search' in them, so use >=. 362 self.assertTrue(len(matches_description) >= 1) 363 item = matches_description[0] 364 self.assertTrue(re.search(url_re, item['destination_url'])) 365 self.assertEqual('search-what-you-typed', item['type']) 366 367 368 if __name__ == '__main__': 369 pyauto_functional.Main() 370