#!/usr/bin/python
# Copyright (c) 2010 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.
import glob
import os
import re
import shutil
import tempfile
import urlparse
import pyauto_functional # Must be imported before pyauto
import pyauto
class OmniboxTest(pyauto.PyUITest):
"""TestCase for Omnibox."""
def Debug(self):
"""Test method for experimentation.
This method will not run automatically.
"""
import pprint
import time
pp = pprint.PrettyPrinter(indent=2)
while True:
pp.pprint(self.GetOmniboxInfo().omniboxdict)
time.sleep(1)
def testFocusOnStartup(self):
"""Verify that omnibox has focus on startup."""
self.WaitUntilOmniboxReadyHack()
self.assertTrue(self.GetOmniboxInfo().Properties('has_focus'))
def _GetOmniboxMatchesFor(self, text, windex=0, attr_dict=None):
"""Fetch omnibox matches with the given attributes for the given query.
Args:
text: the query text to use
windex: the window index to work on. Defaults to 0 (first window)
attr_dict: the dictionary of properties to be satisfied
Returns:
a list of match items
"""
self.SetOmniboxText(text, windex=windex)
self.WaitUntilOmniboxQueryDone(windex=windex)
if not attr_dict:
matches = self.GetOmniboxInfo(windex=windex).Matches()
else:
matches = self.GetOmniboxInfo(windex=windex).MatchesWithAttributes(
attr_dict=attr_dict)
return matches
def testHistoryResult(self):
"""Verify that omnibox can fetch items from history."""
url = self.GetFileURLForDataPath('title2.html')
title = 'Title Of Awesomeness'
self.AppendTab(pyauto.GURL(url))
def _VerifyHistoryResult(query_list, description, windex=0):
"""Verify result matching given description for given list of queries."""
for query_text in query_list:
matches = self._GetOmniboxMatchesFor(
query_text, windex=windex, attr_dict={'description': description})
self.assertTrue(matches)
self.assertEqual(1, len(matches))
item = matches[0]
self.assertEqual(url, item['destination_url'])
# Query using URL & title
_VerifyHistoryResult([url, title], title)
# Verify results in another tab
self.AppendTab(pyauto.GURL())
_VerifyHistoryResult([url, title], title)
# Verify results in another window
self.OpenNewBrowserWindow(True)
self.WaitUntilOmniboxReadyHack(windex=1)
_VerifyHistoryResult([url, title], title, windex=1)
# Verify results in an incognito window
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.WaitUntilOmniboxReadyHack(windex=2)
_VerifyHistoryResult([url, title], title, windex=2)
def _VerifyOmniboxURLMatches(self, url, description, windex=0):
"""Verify URL match results from the Omnibox.
Args:
url: the url to use
description: the string description within history page and google search
to match against
windex: the window index to work on. Defaults to 0 (first window)
"""
matches_description = self._GetOmniboxMatchesFor(
url, windex=windex, attr_dict={'description': description})
self.assertEqual(1, len(matches_description))
if description == 'Google Search':
self.assertTrue(re.match('http://www.google.com/search.+',
matches_description[0]['destination_url']))
else:
self.assertEqual(url, matches_description[0]['destination_url'])
def testFetchHistoryResultItems(self):
"""Verify omnibox fetches history items in second tab, win and Incognito."""
url = self.GetFileURLForDataPath('title2.html')
title = 'Title Of Awesomeness'
desc = 'Google Search'
# fetch history page item in the second tab.
self.AppendTab(pyauto.GURL(url))
self._VerifyOmniboxURLMatches(url, title)
# fetch history page items in the second window.
self.OpenNewBrowserWindow(True)
self.NavigateToURL(url, 1, 0)
self._VerifyOmniboxURLMatches(url, title, windex=1)
# fetch google search items in Incognito window.
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.NavigateToURL(url, 2, 0)
self._VerifyOmniboxURLMatches(url, desc, windex=2)
def testSelect(self):
"""Verify omnibox popup selection."""
url1 = self.GetFileURLForDataPath('title2.html')
url2 = self.GetFileURLForDataPath('title1.html')
title1 = 'Title Of Awesomeness'
self.NavigateToURL(url1)
self.NavigateToURL(url2)
matches = self._GetOmniboxMatchesFor('file://')
self.assertTrue(matches)
# Find the index of match for url1
index = None
for i, match in enumerate(matches):
if match['description'] == title1:
index = i
self.assertTrue(index is not None)
self.OmniboxMovePopupSelection(index) # Select url1 line in popup
self.assertEqual(url1, self.GetOmniboxInfo().Text())
self.OmniboxAcceptInput()
self.assertEqual(title1, self.GetActiveTabTitle())
def testGoogleSearch(self):
"""Verify Google search item in omnibox results."""
search_text = 'hello world'
verify_str = 'Google Search'
url_re = 'http://www.google.com/search\?.*q=hello\+world.*'
matches_description = self._GetOmniboxMatchesFor(
search_text, attr_dict={'description': verify_str})
self.assertTrue(matches_description)
self.assertEqual(1, len(matches_description))
item = matches_description[0]
self.assertTrue(re.search(url_re, item['destination_url']))
self.assertEqual('search-what-you-typed', item['type'])
def testInlinAutoComplete(self):
"""Verify inline autocomplete for a pre-visited url."""
self.NavigateToURL('http://www.google.com')
matches = self._GetOmniboxMatchesFor('goog')
self.assertTrue(matches)
# Omnibox should suggest auto completed url as the first item
matches_description = matches[0]
self.assertTrue('www.google.com' in matches_description['contents'])
self.assertEqual('history-url', matches_description['type'])
# The url should be inline-autocompleted in the omnibox
self.assertTrue('google.com' in self.GetOmniboxInfo().Text())
def testCrazyFilenames(self):
"""Test omnibox query with filenames containing special chars.
The files are created on the fly and cleaned after use.
"""
filename = os.path.join(self.DataDir(), 'downloads', 'crazy_filenames.txt')
zip_names = self.EvalDataFrom(filename)
# We got .zip filenames. Change them to .html
crazy_filenames = [x.replace('.zip', '.html') for x in zip_names]
title = 'given title'
def _CreateFile(name):
"""Create the given html file."""
fp = open(name, 'w') # name could be unicode
print >>fp, '
%s' % title
print >>fp, 'This is a junk file named %s
' % repr(name)
print >>fp, ''
fp.close()
crazy_fileurls = []
# Temp dir for hosting crazy filenames.
temp_dir = tempfile.mkdtemp(prefix='omnibox')
# Windows has a dual nature dealing with unicode filenames.
# While the files are internally saved as unicode, there's a non-unicode
# aware API that returns a locale-dependent coding on the true unicode
# filenames. This messes up things.
# Filesystem-interfacing functions like os.listdir() need to
# be given unicode strings to "do the right thing" on win.
# Ref: http://boodebr.org/main/python/all-about-python-and-unicode
try:
for filename in crazy_filenames: # filename is unicode.
file_path = os.path.join(temp_dir, filename.encode('utf-8'))
_CreateFile(os.path.join(temp_dir, filename))
file_url = self.GetFileURLForPath(file_path)
crazy_fileurls.append(file_url)
self.NavigateToURL(file_url)
# Verify omnibox queries.
for file_url in crazy_fileurls:
matches = self._GetOmniboxMatchesFor(
file_url, attr_dict={'type': 'url-what-you-typed',
'description': title})
self.assertTrue(matches)
self.assertEqual(1, len(matches))
self.assertTrue(os.path.basename(file_url) in
matches[0]['destination_url'])
finally:
shutil.rmtree(unicode(temp_dir)) # unicode so that win treats nicely.
def testSuggest(self):
"""Verify suggested results in omnibox."""
matches = self._GetOmniboxMatchesFor('apple')
self.assertTrue(matches)
self.assertTrue([x for x in matches if x['type'] == 'search-suggest'])
def testDifferentTypesOfResults(self):
"""Verify different types of results from omnibox.
This includes history result, bookmark result, suggest results.
"""
url = 'http://www.google.com/'
title = 'Google'
search_string = 'google'
self.AddBookmarkURL( # Add a bookmark
self.GetBookmarkModel().BookmarkBar()['id'], 0, title, url)
self.NavigateToURL(url) # Build up history
matches = self._GetOmniboxMatchesFor(search_string)
self.assertTrue(matches)
# Verify starred result (indicating bookmarked url)
self.assertTrue([x for x in matches if x['starred'] == True])
for item_type in ('history-url', 'search-what-you-typed',
'search-suggest',):
self.assertTrue([x for x in matches if x['type'] == item_type])
def testSuggestPref(self):
"""Verify no suggests for omnibox when suggested-services disabled."""
search_string = 'apple'
self.assertTrue(self.GetPrefsInfo().Prefs(pyauto.kSearchSuggestEnabled))
matches = self._GetOmniboxMatchesFor(search_string)
self.assertTrue(matches)
self.assertTrue([x for x in matches if x['type'] == 'search-suggest'])
# Disable suggest-service
self.SetPrefs(pyauto.kSearchSuggestEnabled, False)
self.assertFalse(self.GetPrefsInfo().Prefs(pyauto.kSearchSuggestEnabled))
matches = self._GetOmniboxMatchesFor(search_string)
self.assertTrue(matches)
# Verify there are no suggest results
self.assertFalse([x for x in matches if x['type'] == 'search-suggest'])
def testAutoCompleteForSearch(self):
"""Verify omnibox autocomplete for search."""
search_string = 'barac'
verify_string = 'barack'
matches = self._GetOmniboxMatchesFor(search_string)
# retrieve last contents element.
matches_description = matches[-1]['contents'].split()
self.assertEqual(verify_string, matches_description[0])
def _CheckBookmarkResultForVariousInputs(self, url, title, windex=0):
"""Check if we get the Bookmark for complete and partial inputs."""
# Check if the complete URL would get the bookmark.
url_matches = self._GetOmniboxMatchesFor(url, windex=windex)
self._VerifyHasBookmarkResult(url_matches)
# Check if the complete title would get the bookmark.
title_matches = self._GetOmniboxMatchesFor(title, windex=windex)
self._VerifyHasBookmarkResult(title_matches)
# Check if the partial URL would get the bookmark.
split_url = urlparse.urlsplit(url)
partial_url = self._GetOmniboxMatchesFor(split_url.scheme, windex=windex)
self._VerifyHasBookmarkResult(partial_url)
# Check if the partial title would get the bookmark.
split_title = title.split()
search_term = split_title[len(split_title) - 1]
partial_title = self._GetOmniboxMatchesFor(search_term, windex=windex)
self._VerifyHasBookmarkResult(partial_title)
def _GotNewMatches(self, old_matches_len, search_text):
"""Determines if omnibox has any new matches"""
# Omnibox doesn't change results if searching the same text repeatedly.
# So setting '' in omnibox before the next repeated search.
self.SetOmniboxText('')
new_matches = self._GetOmniboxMatchesFor(search_text)
if len(new_matches) > old_matches_len:
return True
return False
def testContentHistory(self):
"""Verify omnibox results when entering page content
Test verifies that visited page shows up in omnibox on entering page
content.
"""
search_text = 'British throne'
old_matches = self._GetOmniboxMatchesFor(search_text)
url = self.GetFileURLForPath(
os.path.join(self.DataDir(), 'find_in_page', 'largepage.html'))
self.AppendTab(pyauto.GURL(url))
self.assertTrue(self.WaitUntil(lambda: self._GotNewMatches(len(old_matches),
search_text), timeout=1))
matches = self._GetOmniboxMatchesFor(search_text)
matches_description = [x for x in matches if x['destination_url'] == url]
self.assertEqual(1, len(matches_description))
def _GotHistoryPageOption(self, search_text):
"""Determines if omnibox returns an 'open history page' option for given
search text"""
# Omnibox doesn't change results if searching the same text repeatedly.
# So setting '' in omnibox before the next repeated search.
self.SetOmniboxText('')
matches = self._GetOmniboxMatchesFor(search_text)
matches_description = [x for x in matches if x['type'] ==
'open-history-page']
return len(matches_description) != 0
def testRecentPageHistory(self):
"""Verify that omnibox shows recent history option in the visited
url list."""
search_text = 'file'
sites = glob.glob(os.path.join(self.DataDir(), 'find_in_page', '*.html'))
for site in sites:
self.NavigateToURL(self.GetFileURLForPath(site))
# Using max timeout as 120 seconds, since expected page only shows up
# after > 60 seconds on some machines and default timeout is less than that.
# TODO (Nirnimesh): design an api using which we can push history changes to
# omnibox results.
self.assertTrue(self.WaitUntil(
lambda: self._GotHistoryPageOption(search_text),
timeout=120))
def _VerifyHasBookmarkResult(self, matches):
"""Verify that we have a bookmark result."""
matches_starred = [result for result in matches if result['starred']]
self.assertTrue(matches_starred)
self.assertEqual(1, len(matches_starred))
def testBookmarkResultInNewTabAndWindow(self):
"""Verify that omnibox can recognize a bookmark within search options
in new tabs and windows."""
url = self.GetFileURLForDataPath('title2.html')
self.NavigateToURL(url)
title = 'This is Awesomeness'
bookmarks = self.GetBookmarkModel()
bar_id = bookmarks.BookmarkBar()['id']
self.AddBookmarkURL(bar_id, 0, title, url)
bookmarks = self.GetBookmarkModel()
nodes = bookmarks.FindByTitle(title)
self.AppendTab(pyauto.GURL(url))
self._CheckBookmarkResultForVariousInputs(url, title)
self.OpenNewBrowserWindow(True)
self.assertEqual(2, self.GetBrowserWindowCount())
self.NavigateToURL(url, 1, 0)
self._CheckBookmarkResultForVariousInputs(url, title, windex=1)
self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self.assertEqual(3, self.GetBrowserWindowCount())
self.NavigateToURL(url, 2, 0)
self._CheckBookmarkResultForVariousInputs(url, title, windex=2)
if __name__ == '__main__':
pyauto_functional.Main()