| OLD | NEW |
| (Empty) |
| 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 | |
| 6 import logging | |
| 7 import os | |
| 8 | |
| 9 import pyauto_functional # Must be imported before pyauto | |
| 10 import pyauto | |
| 11 import test_utils | |
| 12 | |
| 13 class SpecialTabsTest(pyauto.PyUITest): | |
| 14 """TestCase for Special Tabs like about:version, chrome://history, etc.""" | |
| 15 | |
| 16 @staticmethod | |
| 17 def GetSpecialAcceleratorTabs(): | |
| 18 """Get a dict of accelerators and corresponding tab titles.""" | |
| 19 ret = { | |
| 20 pyauto.IDC_SHOW_HISTORY: 'History', | |
| 21 pyauto.IDC_MANAGE_EXTENSIONS: 'Extensions', | |
| 22 pyauto.IDC_SHOW_DOWNLOADS: 'Downloads', | |
| 23 } | |
| 24 return ret | |
| 25 | |
| 26 special_url_redirects = { | |
| 27 'about:': 'chrome://version', | |
| 28 'about:about': 'chrome://about', | |
| 29 'about:appcache-internals': 'chrome://appcache-internals', | |
| 30 'about:credits': 'chrome://credits', | |
| 31 'about:dns': 'chrome://dns', | |
| 32 'about:histograms': 'chrome://histograms', | |
| 33 'about:plugins': 'chrome://plugins', | |
| 34 'about:sync': 'chrome://sync-internals', | |
| 35 'about:sync-internals': 'chrome://sync-internals', | |
| 36 'about:version': 'chrome://version', | |
| 37 } | |
| 38 | |
| 39 special_url_tabs = { | |
| 40 'chrome://about': { 'title': 'Chrome URLs' }, | |
| 41 'chrome://appcache-internals': { 'title': 'AppCache Internals' }, | |
| 42 'chrome://blob-internals': { 'title': 'Blob Storage Internals' }, | |
| 43 'chrome://feedback': {}, | |
| 44 'chrome://chrome-urls': { 'title': 'Chrome URLs' }, | |
| 45 'chrome://crashes': { 'title': 'Crashes' }, | |
| 46 'chrome://credits': { 'title': 'Credits' }, | |
| 47 'chrome://downloads': { 'title': 'Downloads' }, | |
| 48 'chrome://dns': { 'title': 'About DNS' }, | |
| 49 'chrome://extensions': { 'title': 'Extensions' }, | |
| 50 'chrome://flags': {}, | |
| 51 'chrome://flash': {}, | |
| 52 'chrome://gpu-internals': {}, | |
| 53 'chrome://invalidations': { 'title': 'Invalidations' }, | |
| 54 'chrome://histograms': { 'title': 'About Histograms' }, | |
| 55 'chrome://history': { 'title': 'History' }, | |
| 56 'chrome://inspect': { 'title': 'Inspect with Chrome Developer Tools' }, | |
| 57 'chrome://media-internals': { 'title': 'Media Internals' }, | |
| 58 'chrome://memory-redirect': { 'title': 'About Memory' }, | |
| 59 'chrome://net-internals': {}, | |
| 60 'chrome://net-internals/help.html': {}, | |
| 61 'chrome://newtab': { 'title': 'New Tab', 'CSP': False }, | |
| 62 'chrome://plugins': { 'title': 'Plug-ins' }, | |
| 63 'chrome://settings': { 'title': 'Settings' }, | |
| 64 'chrome://settings/autofill': { 'title': 'Settings - Autofill settings' }, | |
| 65 'chrome://settings/clearBrowserData': | |
| 66 { 'title': 'Settings - Clear browsing data' }, | |
| 67 'chrome://settings/content': { 'title': 'Settings - Content settings' }, | |
| 68 'chrome://settings/languages': | |
| 69 { 'title': 'Settings - Languages' }, | |
| 70 'chrome://settings/passwords': { 'title': 'Settings - Passwords' }, | |
| 71 'chrome://stats': {}, | |
| 72 'chrome://sync': { 'title': 'Sync Internals' }, | |
| 73 'chrome://sync-internals': { 'title': 'Sync Internals' }, | |
| 74 'chrome://terms': {}, | |
| 75 'chrome://version': { 'title': 'About Version' }, | |
| 76 'chrome://view-http-cache': {}, | |
| 77 'chrome://webrtc-internals': { 'title': 'WebRTC Internals' }, | |
| 78 } | |
| 79 broken_special_url_tabs = { | |
| 80 # crashed under debug when invoked from location bar (bug 88223). | |
| 81 'chrome://devtools': { 'CSP': False }, | |
| 82 | |
| 83 # returns "not available" despite having an URL constant. | |
| 84 'chrome://dialog': { 'CSP': False }, | |
| 85 | |
| 86 # separate window on mac, PC untested, not implemented elsewhere. | |
| 87 'chrome://ipc': { 'CSP': False }, | |
| 88 | |
| 89 # race against redirects via meta-refresh. | |
| 90 'chrome://memory': { 'CSP': False }, | |
| 91 } | |
| 92 | |
| 93 chromeos_special_url_tabs = { | |
| 94 'chrome://choose-mobile-network': { 'title': 'undefined', 'CSP': True }, | |
| 95 'chrome://flags': { 'CSP': True }, | |
| 96 'chrome://imageburner': { 'title':'Create a Recovery Media', 'CSP': True }, | |
| 97 'chrome://keyboardoverlay': { 'title': 'Keyboard Overlay', 'CSP': True }, | |
| 98 'chrome://network': { 'title': 'About Network' }, | |
| 99 'chrome://os-credits': { 'title': 'Credits', 'CSP': False }, | |
| 100 'chrome://proxy-settings': { 'CSP': False }, | |
| 101 'chrome://register': { 'CSP': False }, | |
| 102 'chrome://settings/languages': | |
| 103 { 'title': 'Settings - Languages and input' }, | |
| 104 'chrome://sim-unlock': { 'title': 'Enter SIM card PIN', 'CSP': False }, | |
| 105 'chrome://system': { 'title': 'About System', 'CSP': False }, | |
| 106 | |
| 107 # OVERRIDE - title and page different on CrOS | |
| 108 'chrome://settings/accounts': { 'title': 'Settings - Users' }, | |
| 109 } | |
| 110 broken_chromeos_special_url_tabs = { | |
| 111 # returns "not available" page on chromeos=1 linux but has an URL constant. | |
| 112 'chrome://activationmessage': { 'CSP': False }, | |
| 113 'chrome://cloudprintresources': { 'CSP': False }, | |
| 114 'chrome://cloudprintsetup': { 'CSP': False }, | |
| 115 'chrome://collected-cookies': { 'CSP': False }, | |
| 116 'chrome://constrained-test': { 'CSP': False }, | |
| 117 'chrome://enterprise-enrollment': { 'CSP': False }, | |
| 118 'chrome://http-auth': { 'CSP': False }, | |
| 119 'chrome://login-container': { 'CSP': False }, | |
| 120 'chrome://media-player': { 'CSP': False }, | |
| 121 'chrome://screenshots': { 'CSP': False }, | |
| 122 'chrome://slideshow': { 'CSP': False }, | |
| 123 'chrome://syncresources': { 'CSP': False }, | |
| 124 'chrome://theme': { 'CSP': False }, | |
| 125 'chrome://view-http-cache': { 'CSP': False }, | |
| 126 | |
| 127 # crashes on chromeos=1 on linux, possibly missing real CrOS features. | |
| 128 'chrome://cryptohome': { 'CSP': False}, | |
| 129 'chrome://mobilesetup': { 'CSP': False }, | |
| 130 'chrome://print': { 'CSP': False }, | |
| 131 } | |
| 132 | |
| 133 linux_special_url_tabs = { | |
| 134 'chrome://linux-proxy-config': { 'title': 'Proxy Configuration Help' }, | |
| 135 'chrome://tcmalloc': { 'title': 'tcmalloc stats' }, | |
| 136 'chrome://sandbox': { 'title': 'Sandbox Status' }, | |
| 137 } | |
| 138 broken_linux_special_url_tabs = {} | |
| 139 | |
| 140 mac_special_url_tabs = { | |
| 141 'chrome://settings/languages': { 'title': 'Settings - Languages' }, | |
| 142 } | |
| 143 broken_mac_special_url_tabs = {} | |
| 144 | |
| 145 win_special_url_tabs = { | |
| 146 'chrome://conflicts': {}, | |
| 147 } | |
| 148 broken_win_special_url_tabs = { | |
| 149 # Sync on windows badly broken at the moment. | |
| 150 'chrome://sync': {}, | |
| 151 } | |
| 152 | |
| 153 google_special_url_tabs = { | |
| 154 # OVERRIDE - different title for Google Chrome vs. Chromium. | |
| 155 'chrome://terms': { | |
| 156 'title': 'Google Chrome Terms of Service', | |
| 157 }, | |
| 158 } | |
| 159 broken_google_special_url_tabs = {} | |
| 160 | |
| 161 google_chromeos_special_url_tabs = { | |
| 162 # OVERRIDE - different title for Google Chrome OS vs. Chromium OS. | |
| 163 'chrome://terms': { | |
| 164 'title': 'Google Chrome OS Terms', | |
| 165 }, | |
| 166 } | |
| 167 broken_google_chromeos_special_url_tabs = {} | |
| 168 | |
| 169 google_win_special_url_tabs = {} | |
| 170 broken_google_win_special_url_tabs = {} | |
| 171 | |
| 172 google_mac_special_url_tabs = {} | |
| 173 broken_google_mac_special_url_tabs = {} | |
| 174 | |
| 175 google_linux_special_url_tabs = {} | |
| 176 broken_google_linux_special_url_tabs = {} | |
| 177 | |
| 178 def _VerifyAppCacheInternals(self): | |
| 179 """Confirm about:appcache-internals contains expected content for Caches. | |
| 180 Also confirms that the about page populates Application Caches.""" | |
| 181 # Navigate to html page to activate DNS prefetching. | |
| 182 self.NavigateToURL('http://futtta.be/html5/offline.php') | |
| 183 # Wait for page to load and display sucess or fail message. | |
| 184 self.WaitUntil( | |
| 185 lambda: self.GetDOMValue('document.getElementById("status").innerHTML'), | |
| 186 expect_retval='cached') | |
| 187 self.TabGoBack() | |
| 188 test_utils.StringContentCheck( | |
| 189 self, self.GetTabContents(), | |
| 190 ['Manifest', | |
| 191 'http://futtta.be/html5/manifest.php'], | |
| 192 []) | |
| 193 | |
| 194 def _VerifyAboutDNS(self): | |
| 195 """Confirm about:dns contains expected content related to DNS info. | |
| 196 Also confirms that prefetching DNS records propogate.""" | |
| 197 # Navigate to a page to activate DNS prefetching. | |
| 198 self.NavigateToURL('http://www.google.com') | |
| 199 self.TabGoBack() | |
| 200 test_utils.StringContentCheck(self, self.GetTabContents(), | |
| 201 ['Host name', 'How long ago', 'Motivation'], | |
| 202 []) | |
| 203 | |
| 204 def _GetPlatformSpecialURLTabs(self): | |
| 205 tabs = self.special_url_tabs.copy() | |
| 206 broken_tabs = self.broken_special_url_tabs.copy() | |
| 207 if self.IsChromeOS(): | |
| 208 tabs.update(self.chromeos_special_url_tabs) | |
| 209 broken_tabs.update(self.broken_chromeos_special_url_tabs) | |
| 210 elif self.IsLinux(): | |
| 211 tabs.update(self.linux_special_url_tabs) | |
| 212 broken_tabs.update(self.broken_linux_special_url_tabs) | |
| 213 elif self.IsMac(): | |
| 214 tabs.update(self.mac_special_url_tabs) | |
| 215 broken_tabs.update(self.broken_mac_special_url_tabs) | |
| 216 elif self.IsWin(): | |
| 217 tabs.update(self.win_special_url_tabs) | |
| 218 broken_tabs.update(self.broken_win_special_url_tabs) | |
| 219 for key, value in broken_tabs.iteritems(): | |
| 220 if key in tabs: | |
| 221 del tabs[key] | |
| 222 broken_tabs = {} | |
| 223 if self.GetBrowserInfo()['properties']['branding'] == 'Google Chrome': | |
| 224 tabs.update(self.google_special_url_tabs) | |
| 225 broken_tabs.update(self.broken_google_special_url_tabs) | |
| 226 if self.IsChromeOS(): | |
| 227 tabs.update(self.google_chromeos_special_url_tabs) | |
| 228 broken_tabs.update(self.broken_google_chromeos_special_url_tabs) | |
| 229 elif self.IsLinux(): | |
| 230 tabs.update(self.google_linux_special_url_tabs) | |
| 231 broken_tabs.update(self.broken_google_linux_special_url_tabs) | |
| 232 elif self.IsMac(): | |
| 233 tabs.update(self.google_mac_special_url_tabs) | |
| 234 broken_tabs.update(self.broken_google_mac_special_url_tabs) | |
| 235 elif self.IsWin(): | |
| 236 tabs.update(self.google_win_special_url_tabs) | |
| 237 broken_tabs.update(self.broken_google_win_special_url_tabs) | |
| 238 for key, value in broken_tabs.iteritems(): | |
| 239 if key in tabs: | |
| 240 del tabs[key] | |
| 241 return tabs | |
| 242 | |
| 243 def testSpecialURLRedirects(self): | |
| 244 """Test that older about: URLs are implemented by newer chrome:// URLs. | |
| 245 The location bar may not get updated in all cases, so checking the | |
| 246 tab URL is misleading, instead check for the same contents as the | |
| 247 chrome:// page.""" | |
| 248 tabs = self._GetPlatformSpecialURLTabs() | |
| 249 for url, redirect in self.special_url_redirects.iteritems(): | |
| 250 if redirect in tabs: | |
| 251 logging.debug('Testing redirect from %s to %s.' % (url, redirect)) | |
| 252 self.NavigateToURL(url) | |
| 253 self.assertEqual(self.special_url_tabs[redirect]['title'], | |
| 254 self.GetActiveTabTitle()) | |
| 255 | |
| 256 def testSpecialURLTabs(self): | |
| 257 """Test special tabs created by URLs like chrome://downloads, | |
| 258 chrome://settings/extensionSettings, chrome://history etc. | |
| 259 Also ensures they specify content-security-policy and not inline | |
| 260 scripts for those pages that are expected to do so. Patches which | |
| 261 break this test by including new inline javascript are security | |
| 262 vulnerabilities and should be reverted.""" | |
| 263 tabs = self._GetPlatformSpecialURLTabs() | |
| 264 for url, properties in tabs.iteritems(): | |
| 265 logging.debug('Testing URL %s.' % url) | |
| 266 self.NavigateToURL(url) | |
| 267 expected_title = 'title' in properties and properties['title'] or url | |
| 268 actual_title = self.GetActiveTabTitle() | |
| 269 self.assertTrue(self.WaitUntil( | |
| 270 lambda: self.GetActiveTabTitle(), expect_retval=expected_title), | |
| 271 msg='Title did not match for %s. Expected: %s. Got %s' % ( | |
| 272 url, expected_title, self.GetActiveTabTitle())) | |
| 273 include_list = [] | |
| 274 exclude_list = [] | |
| 275 no_csp = 'CSP' in properties and not properties['CSP'] | |
| 276 if no_csp: | |
| 277 exclude_list.extend(['Content-Security-Policy']) | |
| 278 else: | |
| 279 exclude_list.extend(['<script>', 'onclick=', 'onload=', | |
| 280 'onchange=', 'onsubmit=', 'javascript:']) | |
| 281 if 'includes' in properties: | |
| 282 include_list.extend(properties['includes']) | |
| 283 if 'excludes' in properties: | |
| 284 exclude_list.extend(properties['exlcudes']) | |
| 285 test_utils.StringContentCheck(self, self.GetTabContents(), | |
| 286 include_list, exclude_list) | |
| 287 result = self.ExecuteJavascript(""" | |
| 288 var r = 'blocked'; | |
| 289 var f = 'executed'; | |
| 290 var s = document.createElement('script'); | |
| 291 s.textContent = 'r = f'; | |
| 292 document.body.appendChild(s); | |
| 293 window.domAutomationController.send(r); | |
| 294 """) | |
| 295 logging.debug('has csp %s, result %s.' % (not no_csp, result)) | |
| 296 if no_csp: | |
| 297 self.assertEqual(result, 'executed', | |
| 298 msg='Got %s for %s' % (result, url)) | |
| 299 else: | |
| 300 self.assertEqual(result, 'blocked', | |
| 301 msg='Got %s for %s' % (result, url)) | |
| 302 | |
| 303 # Restart browser so that every URL gets a fresh instance. | |
| 304 self.RestartBrowser(clear_profile=True) | |
| 305 | |
| 306 def testAboutAppCacheTab(self): | |
| 307 """Test App Cache tab to confirm about page populates caches.""" | |
| 308 self.NavigateToURL('about:appcache-internals') | |
| 309 self._VerifyAppCacheInternals() | |
| 310 self.assertEqual('AppCache Internals', self.GetActiveTabTitle()) | |
| 311 | |
| 312 def testAboutDNSTab(self): | |
| 313 """Test DNS tab to confirm DNS about page propogates records.""" | |
| 314 self.NavigateToURL('about:dns') | |
| 315 self._VerifyAboutDNS() | |
| 316 self.assertEqual('About DNS', self.GetActiveTabTitle()) | |
| 317 | |
| 318 def testSpecialAcceratorTabs(self): | |
| 319 """Test special tabs created by accelerators.""" | |
| 320 for accel, title in self.GetSpecialAcceleratorTabs().iteritems(): | |
| 321 self.RunCommand(accel) | |
| 322 self.assertTrue(self.WaitUntil( | |
| 323 self.GetActiveTabTitle, expect_retval=title), | |
| 324 msg='Expected "%s", got "%s"' % (title, self.GetActiveTabTitle())) | |
| 325 | |
| 326 | |
| 327 if __name__ == '__main__': | |
| 328 pyauto_functional.Main() | |
| OLD | NEW |