1#!/usr/bin/env python
2# Copyright (c) 2012 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
6import time
7
8import pyauto_functional  # Must be imported before pyauto
9import pyauto
10import test_utils
11
12from webdriver_pages import settings
13from webdriver_pages.settings import Behaviors, ContentTypes
14from webdriver_pages.settings import RestoreOnStartupType
15
16
17class PrefsUITest(pyauto.PyUITest):
18  """TestCase for Preferences UI."""
19
20  INFOBAR_TYPE = 'rph_infobar'
21
22  def setUp(self):
23    pyauto.PyUITest.setUp(self)
24    self._driver = self.NewWebDriver()
25
26  def Debug(self):
27    """Test method for experimentation.
28
29    This method will not run automatically.
30    """
31    driver = self.NewWebDriver()
32    page = settings.ContentSettingsPage.FromNavigation(driver)
33    import pdb
34    pdb.set_trace()
35
36  def _GetGeolocationContentSettingsBehavior(self):
37    """Get the Content Settings behavior for Geolocation.
38
39    Returns:
40      The exceptions behavior for the specified content type.
41      The content type is the available content setting available.
42    """
43    behavior_key = self.GetPrefsInfo().Prefs(
44        pyauto.kGeolocationDefaultContentSetting)
45    behaviors_dict = {1: 'ALLOW', 2: 'BLOCK', 3: 'ASK'}
46    self.assertTrue(
47        behavior_key in behaviors_dict,
48        msg=('Invalid default behavior key "%s" for "geolocation" content' %
49             behavior_key))
50    return behaviors_dict[behavior_key]
51
52  def _VerifyContentExceptionUI(self, content_type, hostname_pattern, behavior,
53                                incognito=False):
54    """Find hostname pattern and behavior within UI on content exceptions page.
55
56    Args:
57      content_type: The string content settings type to manage.
58      hostname_pattern: The URL or pattern associated with the behavior.
59      behavior: The exception to allow or block the hostname.
60      incognito: Incognito list displayed on exceptions settings page.
61                 Default to False.
62    """
63    page = settings.ManageExceptionsPage.FromNavigation(
64        self._driver, content_type)
65    self.assertTrue(page.GetExceptions(incognito).has_key(hostname_pattern),
66                     msg=('No displayed host name matches pattern "%s"'
67                          % hostname_pattern))
68    self.assertEqual(behavior, page.GetExceptions(incognito)[hostname_pattern],
69                     msg=('Displayed behavior "%s" does not match behavior "%s"'
70                          % (page.GetExceptions(incognito)[hostname_pattern],
71                             behavior)))
72
73  def testLocationSettingOptionsUI(self):
74    """Verify the location options setting UI.
75
76    Set the options through the UI using webdriver and verify the settings in
77    pyAuto.
78    """
79    page = settings.ContentSettingsPage.FromNavigation(self._driver)
80    page.SetContentTypeOption(ContentTypes.GEOLOCATION, Behaviors.ALLOW)
81    self.assertEqual(
82        1, self.GetPrefsInfo().Prefs(pyauto.kGeolocationDefaultContentSetting))
83    page.SetContentTypeOption(ContentTypes.GEOLOCATION, Behaviors.BLOCK)
84    self.assertEqual(
85        2, self.GetPrefsInfo().Prefs(pyauto.kGeolocationDefaultContentSetting))
86    page.SetContentTypeOption(ContentTypes.GEOLOCATION, Behaviors.ASK)
87    self.assertEqual(
88        3, self.GetPrefsInfo().Prefs(pyauto.kGeolocationDefaultContentSetting))
89
90  def testBehaviorValueCorrectlyDisplayed(self):
91    """Verify the set behavior value is correctly displayed."""
92    # Block all sites.
93    self.SetPrefs(pyauto.kGeolocationDefaultContentSetting, 2)
94    self.assertEqual(
95        self._GetGeolocationContentSettingsBehavior(), Behaviors.BLOCK.upper(),
96        msg='The behavior was incorrectly set.')
97    # Allow all sites.
98    self.SetPrefs(pyauto.kGeolocationDefaultContentSetting, 1)
99    self.assertEqual(
100        self._GetGeolocationContentSettingsBehavior(), Behaviors.ALLOW.upper(),
101        msg='The behavior was incorrectly set.')
102    # Ask for permission when site wants to track.
103    self.SetPrefs(pyauto.kGeolocationDefaultContentSetting, 3)
104    self.assertEqual(
105        self._GetGeolocationContentSettingsBehavior(), Behaviors.ASK.upper(),
106        msg='The behavior was incorrectly set.')
107
108  def testExceptionsEntryCorrectlyDisplayed(self):
109    """Verify the exceptions line entry is correctly displayed in the UI."""
110    geo_exception = (
111        {'http://maps.google.com:80,http://maps.google.com:80':
112            {'geolocation': 2}})
113    self.SetPrefs(pyauto.kContentSettingsPatternPairs, geo_exception)
114    self._VerifyContentExceptionUI(
115        ContentTypes.GEOLOCATION, 'http://maps.google.com:80',
116        Behaviors.BLOCK)
117    geo_exception = (
118        {'http://maps.google.com:80,http://maps.google.com:80':
119            {'geolocation': 1}})
120    self.SetPrefs(pyauto.kContentSettingsPatternPairs, geo_exception)
121    self._VerifyContentExceptionUI(
122        ContentTypes.GEOLOCATION, 'http://maps.google.com:80',
123        Behaviors.ALLOW)
124    geo_exception = (
125        {'http://maps.google.com:80,http://maps.google.com:80':
126            {'geolocation': 3}})
127    self.SetPrefs(pyauto.kContentSettingsPatternPairs, geo_exception)
128    self._VerifyContentExceptionUI(
129        ContentTypes.GEOLOCATION, 'http://maps.google.com:80', Behaviors.ASK)
130
131  def testAddNewExceptionUI(self):
132    """Verify new exception added for hostname pattern and behavior in UI."""
133    content_type = ContentTypes.PLUGINS
134    page = settings.ManageExceptionsPage.FromNavigation(
135        self._driver, content_type)
136
137    pattern, behavior = ('bing.com', Behaviors.BLOCK)
138    page.AddNewException(pattern, behavior)
139    self.assertEqual(page.GetExceptions()[pattern], Behaviors.BLOCK,
140                     msg='The behavior "%s" was not added for pattern "%s"'
141                     % (behavior, pattern))
142
143  def testChangeExceptionBehaviorUI(self):
144    """Verify behavior for hostname pattern is changed in the UI."""
145    content_type = ContentTypes.PLUGINS
146    page = settings.ManageExceptionsPage.FromNavigation(
147        self._driver, content_type)
148
149    pattern, behavior = ('bing.com', Behaviors.BLOCK)
150    page.AddNewException(pattern, behavior)
151    new_behavior = Behaviors.ALLOW
152    page.SetBehaviorForPattern(pattern, new_behavior)
153    self.assertEqual(page.GetExceptions()[pattern], Behaviors.ALLOW,
154                     msg='The behavior for "%s" did not change: "%s"'
155                     % (pattern, behavior))
156
157  def testDeleteExceptionUI(self):
158    """Verify exception deleted for hostname pattern and behavior in the UI."""
159    content_type = ContentTypes.PLUGINS
160    page = settings.ManageExceptionsPage.FromNavigation(
161        self._driver, content_type)
162
163    pattern, behavior = ('bing.com', Behaviors.BLOCK)
164    page.AddNewException(pattern, behavior)
165    self.assertEqual(page.GetExceptions()[pattern], Behaviors.BLOCK,
166                     msg='The behavior "%s" was not added for pattern "%s"'
167                     % (behavior, pattern))
168    page.DeleteException(pattern)
169    self.assertEqual(page.GetExceptions().get(pattern, KeyError), KeyError,
170                     msg='Pattern "%s" was not deleted' % pattern)
171
172  def testNoInitialLineEntryInUI(self):
173    """Verify no initial line entry is displayed in UI."""
174    # Ask for permission when site wants to track.
175    self.SetPrefs(pyauto.kGeolocationDefaultContentSetting, 3)
176    self.assertEqual(
177        3, self.GetPrefsInfo().Prefs(pyauto.kGeolocationDefaultContentSetting))
178    page = settings.ManageExceptionsPage.FromNavigation(
179        self._driver, ContentTypes.GEOLOCATION)
180    self.assertEqual(0, len(page.GetExceptions()))
181
182  def testCorrectCookiesSessionInUI(self):
183    """Verify exceptions for cookies in UI list entry."""
184    # Block cookies for for a session for google.com.
185    self.SetPrefs(pyauto.kContentSettingsPatternPairs,
186                  {'http://google.com:80': {'cookies': 2}})
187    self._VerifyContentExceptionUI(
188        ContentTypes.COOKIES, 'http://google.com:80', Behaviors.BLOCK)
189
190  def testInitialLineEntryInIncognitoUI(self):
191    """Verify initial line entry is displayed in Incognito UI."""
192    self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)  # Display incognito list.
193    page = settings.ManageExceptionsPage.FromNavigation(
194        self._driver, ContentTypes.PLUGINS)
195    self.assertEqual(1, len(page.GetExceptions(incognito=True)))
196
197  def testIncognitoExceptionsEntryCorrectlyDisplayed(self):
198    """Verify exceptions entry is correctly displayed in the incognito UI."""
199    self.RunCommand(pyauto.IDC_NEW_INCOGNITO_WINDOW)  # Display incognito list.
200    page = settings.ManageExceptionsPage.FromNavigation(
201        self._driver, ContentTypes.PLUGINS)
202    pattern, behavior = ('http://maps.google.com:80', Behaviors.BLOCK)
203    page.AddNewException(pattern, behavior, incognito=True)
204    self._VerifyContentExceptionUI(
205        ContentTypes.PLUGINS, 'http://maps.google.com:80',
206        Behaviors.BLOCK, incognito=True)
207
208  def testSetPasswordAndDelete(self):
209    """Verify a password can be deleted in the Content Settings UI."""
210    password_list = []
211    # Add two passwords, 1 for example0.com and 1 for example1.com.
212    for i in range(2):
213      # Construct a password dictionary with required fields.
214      password = {
215          'username_value': 'user%s@example.com'  % i,
216          'password_value': 'test.password',
217          'signon_realm': 'https://www.example%s.com/'  % i,
218          'time': 1279650942.0,
219          'origin_url': 'https://www.example%s.com/login'  % i,
220          'username_element': 'username%s',
221          'password_element': 'password',
222          'submit_element': 'submit',
223          'action_target': 'https://www.example%s.com/login/'  % i,
224          'blacklist': False,
225      }
226
227      password_list.append(password)
228      self.AddSavedPassword(password)
229
230    saved_passwords = self.GetSavedPasswords()
231    self.assertEquals(len(password_list), len(saved_passwords),
232                      msg='Not all Passwords were saved.')
233    for password in password_list:
234      self.assertTrue(password in saved_passwords,
235                      msg='Passwords were not saved correctly.')
236
237    page = settings.PasswordsSettings.FromNavigation(self._driver)
238    # Delete one of the passwords.
239    password = password_list[1]
240    page.DeleteItem(password['origin_url'], password['username_value'])
241    self.assertTrue(password not in self.GetSavedPasswords(),
242                    msg='Password was not deleted.')
243
244  def testSetCookieAndDeleteInContentSettings(self):
245    """Verify a cookie can be deleted in the Content Settings UI."""
246    # Create a cookie.
247    cookie_dict = {
248        'name': 'test_cookie',
249        'value': 'test_value',
250        'expiry': time.time() + 30,
251    }
252    site = '127.0.0.1'
253    self.NavigateToURL(self.GetHttpURLForDataPath('google', 'google.html'))
254    self._driver.add_cookie(cookie_dict)
255    page = settings.CookiesAndSiteDataSettings.FromNavigation(self._driver)
256    page.DeleteSiteData(site)
257    self.assertTrue(site not in page.GetSiteNameList(),
258                    'Site "%s" was not deleted.'  % site)
259
260  def testRemoveMailProtocolHandler(self):
261    """Verify the mail protocol handler is added and removed successfully."""
262    url = self.GetHttpURLForDataPath('settings', 'protocol_handler.html')
263    self.NavigateToURL(url)
264    # Returns a dictionary with the mail handler that was asked for
265    # registration.
266    asked_handler_dict = self._driver.execute_script(
267        'return registerMailClient()')
268    self.PerformActionOnInfobar(
269        'accept', infobar_index=test_utils.WaitForInfobarTypeAndGetIndex(
270            self, self.INFOBAR_TYPE))
271    self._driver.find_element_by_id('test_mail_protocol').click()
272
273    protocol_handlers_list = (
274        self.GetPrefsInfo().Prefs(pyauto.kRegisteredProtocolHandlers))
275    registered_mail_handler = {}
276    for handler_dict in protocol_handlers_list:
277      if (handler_dict['protocol'] == 'mailto' and
278          handler_dict['url'] == asked_handler_dict['url'] and
279          handler_dict['title'] == asked_handler_dict['title'] and
280          handler_dict.get('default')):
281        registered_mail_handler = handler_dict
282        break
283      # Verify the mail handler is registered as asked.
284      self.assertNotEqual(
285      registered_mail_handler, {},
286      msg='Mail protocol handler was not registered correctly.')
287      # Verify the registered mail handler works as expected.
288      self.assertTrue(
289          self._driver.execute_script(
290              'return doesQueryConformsToProtocol("%s", "%s")'
291              % (asked_handler_dict['query_key'],
292                 asked_handler_dict['query_value'])),
293              msg='Mail protocol did not register correctly.')
294
295    self._driver.get('chrome://settings-frame/handlers')
296    # There are 3 DIVs in a handler entry. The last one acts as a remove button.
297    # The remove button is also equivalent to setting the site to NONE.
298    self._driver.find_element_by_id('handlers-list').\
299        find_element_by_xpath('.//div[@role="listitem"]').\
300        find_element_by_xpath('.//div[@class="handlers-site-column"]').\
301        find_element_by_xpath('.//option[@value="-1"]').click()
302
303    self._driver.get(url)
304    self._driver.find_element_by_id('test_mail_protocol').click()
305    self.assertEqual(url, self._driver.current_url,
306                     msg='Mail protocol still registered.')
307
308class BasicSettingsUITest(pyauto.PyUITest):
309  """Testcases for uber page basic settings UI."""
310
311  def setUp(self):
312    pyauto.PyUITest.setUp(self)
313    self._driver = self.NewWebDriver()
314
315  def Debug(self):
316    """chrome://plugins test debug method.
317
318    This method will not run automatically.
319    """
320    driver = self.NewWebDriver()
321    page = settings.BasicSettingsPage.FromNavigation(driver)
322    import pdb
323    pdb.set_trace()
324
325  def testOnStartupSettings(self):
326    """Verify user can set startup options."""
327    page = settings.BasicSettingsPage.FromNavigation(self._driver)
328    page.SetOnStartupOptions(RestoreOnStartupType.NEW_TAB_PAGE)
329    self.assertEqual(RestoreOnStartupType.NEW_TAB_PAGE,
330        self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup))
331    page.SetOnStartupOptions(RestoreOnStartupType.RESTORE_SESSION)
332    self.assertEqual(RestoreOnStartupType.RESTORE_SESSION,
333        self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup))
334    page.SetOnStartupOptions(RestoreOnStartupType.RESTORE_URLS)
335    self.assertEqual(RestoreOnStartupType.RESTORE_URLS,
336        self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup))
337
338  def testSetStartupPages(self):
339    """Verify user can add urls for startup pages."""
340    page = settings.BasicSettingsPage.FromNavigation(self._driver)
341    for url in ['www.google.com', 'http://www.amazon.com', 'ebay.com']:
342      page.AddStartupPage(url)
343    self.assertEqual(RestoreOnStartupType.RESTORE_URLS,
344        self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup))
345    startup_urls = self.GetPrefsInfo().Prefs(pyauto.kURLsToRestoreOnStartup)
346    self.assertEqual(startup_urls[0], 'http://www.google.com/')
347    self.assertEqual(startup_urls[1], 'http://www.amazon.com/')
348    self.assertEqual(startup_urls[2], 'http://ebay.com/')
349
350  def testUseCurrentPagesForStartup(self):
351    """Verify user can start up browser using current pages."""
352    page = settings.BasicSettingsPage.FromNavigation(self._driver)
353    self.OpenNewBrowserWindow(True)
354    url1 = self.GetHttpURLForDataPath('title2.html')
355    url2 = self.GetHttpURLForDataPath('title3.html')
356    self.NavigateToURL(url1, 1, 0)
357    self.AppendTab(pyauto.GURL(url2), 1)
358    title_list = ['Title Of Awesomeness',
359                  'Title Of More Awesomeness']
360    page.UseCurrentPageForStartup(title_list)
361    page.VerifyStartupURLs(title_list)
362    self.assertEqual(RestoreOnStartupType.RESTORE_URLS,
363        self.GetPrefsInfo().Prefs(pyauto.kRestoreOnStartup))
364    startup_urls = self.GetPrefsInfo().Prefs(pyauto.kURLsToRestoreOnStartup)
365    self.assertEqual(len(startup_urls), 3)
366    self.assertEqual(startup_urls[1], url1)
367    self.assertEqual(startup_urls[2], url2)
368
369  def testCancelStartupURLSetting(self):
370    """Verify canceled start up URLs settings are not saved."""
371    page = settings.BasicSettingsPage.FromNavigation(self._driver)
372    for url in ['www.google.com', 'http://www.amazon.com']:
373      page.CancelStartupURLSetting(url)
374    startup_urls = self.GetPrefsInfo().Prefs(pyauto.kURLsToRestoreOnStartup)
375    self.assertEqual(len(startup_urls), 0)
376
377
378if __name__ == '__main__':
379  pyauto_functional.Main()
380