Home | History | Annotate | Download | only in functional
      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