1# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4import logging 5import os 6import tempfile 7import unittest 8 9from telemetry.core import user_agent 10from telemetry.core import util 11from telemetry.page import page as page_module 12from telemetry.page import page_measurement 13from telemetry.page import page_set 14from telemetry.page import page_test 15from telemetry.page import page_runner 16from telemetry.unittest import options_for_unittests 17from telemetry.page import test_expectations 18 19SIMPLE_CREDENTIALS_STRING = """ 20{ 21 "test": { 22 "username": "example", 23 "password": "asdf" 24 } 25} 26""" 27class StubCredentialsBackend(object): 28 def __init__(self, login_return_value): 29 self.did_get_login = False 30 self.did_get_login_no_longer_needed = False 31 self.login_return_value = login_return_value 32 33 @property 34 def credentials_type(self): # pylint: disable=R0201 35 return 'test' 36 37 def LoginNeeded(self, tab, config): # pylint: disable=W0613 38 self.did_get_login = True 39 return self.login_return_value 40 41 def LoginNoLongerNeeded(self, tab): # pylint: disable=W0613 42 self.did_get_login_no_longer_needed = True 43 44class PageRunnerTests(unittest.TestCase): 45 # TODO(nduca): Move the basic "test failed, test succeeded" tests from 46 # page_measurement_unittest to here. 47 48 def testHandlingOfCrashedTab(self): 49 ps = page_set.PageSet() 50 expectations = test_expectations.TestExpectations() 51 page1 = page_module.Page('chrome://crash', ps) 52 ps.pages.append(page1) 53 54 class Test(page_test.PageTest): 55 def RunTest(self, *args): 56 pass 57 58 options = options_for_unittests.GetCopy() 59 options.output_format = 'none' 60 results = page_runner.Run(Test('RunTest'), ps, expectations, options) 61 self.assertEquals(0, len(results.successes)) 62 self.assertEquals(1, len(results.errors)) 63 64 def testDiscardFirstResult(self): 65 ps = page_set.PageSet() 66 expectations = test_expectations.TestExpectations() 67 ps.pages.append(page_module.Page( 68 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 69 ps, 70 base_dir=os.path.dirname(__file__))) 71 ps.pages.append(page_module.Page( 72 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 73 ps, 74 base_dir=os.path.dirname(__file__))) 75 76 class Measurement(page_measurement.PageMeasurement): 77 @property 78 def discard_first_result(self): 79 return True 80 def MeasurePage(self, *args): 81 pass 82 83 options = options_for_unittests.GetCopy() 84 options.output_format = 'none' 85 options.reset_html_results = None 86 87 options.repeat_options.page_repeat_iters = 1 88 options.repeat_options.pageset_repeat_iters = 1 89 results = page_runner.Run(Measurement(), ps, expectations, options) 90 self.assertEquals(0, len(results.successes)) 91 self.assertEquals(0, len(results.failures)) 92 93 options.repeat_options.page_repeat_iters = 1 94 options.repeat_options.pageset_repeat_iters = 2 95 results = page_runner.Run(Measurement(), ps, expectations, options) 96 self.assertEquals(2, len(results.successes)) 97 self.assertEquals(0, len(results.failures)) 98 99 options.repeat_options.page_repeat_iters = 2 100 options.repeat_options.pageset_repeat_iters = 1 101 results = page_runner.Run(Measurement(), ps, expectations, options) 102 self.assertEquals(2, len(results.successes)) 103 self.assertEquals(0, len(results.failures)) 104 105 options.output_format = 'html' 106 options.repeat_options.page_repeat_iters = 1 107 options.repeat_options.pageset_repeat_iters = 1 108 results = page_runner.Run(Measurement(), ps, expectations, options) 109 self.assertEquals(0, len(results.successes)) 110 self.assertEquals(0, len(results.failures)) 111 112 def testCredentialsWhenLoginFails(self): 113 credentials_backend = StubCredentialsBackend(login_return_value=False) 114 did_run = self.runCredentialsTest(credentials_backend) 115 assert credentials_backend.did_get_login == True 116 assert credentials_backend.did_get_login_no_longer_needed == False 117 assert did_run == False 118 119 def testCredentialsWhenLoginSucceeds(self): 120 credentials_backend = StubCredentialsBackend(login_return_value=True) 121 did_run = self.runCredentialsTest(credentials_backend) 122 assert credentials_backend.did_get_login == True 123 assert credentials_backend.did_get_login_no_longer_needed == True 124 assert did_run 125 126 def runCredentialsTest(self, # pylint: disable=R0201 127 credentials_backend): 128 ps = page_set.PageSet() 129 expectations = test_expectations.TestExpectations() 130 page = page_module.Page( 131 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 132 ps, 133 base_dir=os.path.dirname(__file__)) 134 page.credentials = "test" 135 ps.pages.append(page) 136 137 did_run = [False] 138 139 try: 140 with tempfile.NamedTemporaryFile(delete=False) as f: 141 f.write(SIMPLE_CREDENTIALS_STRING) 142 ps.credentials_path = f.name 143 144 class TestThatInstallsCredentialsBackend(page_test.PageTest): 145 def __init__(self, credentials_backend): 146 super(TestThatInstallsCredentialsBackend, self).__init__('RunTest') 147 self._credentials_backend = credentials_backend 148 149 def DidStartBrowser(self, browser): 150 browser.credentials.AddBackend(self._credentials_backend) 151 152 def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201 153 did_run[0] = True 154 155 test = TestThatInstallsCredentialsBackend(credentials_backend) 156 options = options_for_unittests.GetCopy() 157 options.output_format = 'none' 158 page_runner.Run(test, ps, expectations, options) 159 finally: 160 os.remove(f.name) 161 162 return did_run[0] 163 164 def testUserAgent(self): 165 ps = page_set.PageSet() 166 expectations = test_expectations.TestExpectations() 167 page = page_module.Page( 168 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 169 ps, 170 base_dir=os.path.dirname(__file__)) 171 ps.pages.append(page) 172 ps.user_agent_type = 'tablet' 173 174 class TestUserAgent(page_test.PageTest): 175 def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201 176 actual_user_agent = tab.EvaluateJavaScript('window.navigator.userAgent') 177 expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet'] 178 assert actual_user_agent.strip() == expected_user_agent 179 180 # This is so we can check later that the test actually made it into this 181 # function. Previously it was timing out before even getting here, which 182 # should fail, but since it skipped all the asserts, it slipped by. 183 self.hasRun = True # pylint: disable=W0201 184 185 test = TestUserAgent('RunTest') 186 options = options_for_unittests.GetCopy() 187 options.output_format = 'none' 188 page_runner.Run(test, ps, expectations, options) 189 190 self.assertTrue(hasattr(test, 'hasRun') and test.hasRun) 191 192 # Ensure that page_runner forces exactly 1 tab before running a page. 193 def testOneTab(self): 194 ps = page_set.PageSet() 195 expectations = test_expectations.TestExpectations() 196 page = page_module.Page( 197 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 198 ps, 199 base_dir=os.path.dirname(__file__)) 200 ps.pages.append(page) 201 202 class TestOneTab(page_test.PageTest): 203 def __init__(self, 204 test_method_name, 205 action_name_to_run='', 206 needs_browser_restart_after_each_run=False): 207 super(TestOneTab, self).__init__(test_method_name, action_name_to_run, 208 needs_browser_restart_after_each_run) 209 self._browser = None 210 211 def DidStartBrowser(self, browser): 212 self._browser = browser 213 if self._browser.supports_tab_control: 214 self._browser.tabs.New() 215 216 def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201 217 if not self._browser.supports_tab_control: 218 logging.warning('Browser does not support tab control, skipping test') 219 return 220 assert len(self._browser.tabs) == 1 221 222 test = TestOneTab('RunTest') 223 options = options_for_unittests.GetCopy() 224 options.output_format = 'none' 225 page_runner.Run(test, ps, expectations, options) 226 227 # Ensure that page_runner allows the test to customize the browser before it 228 # launches. 229 def testBrowserBeforeLaunch(self): 230 ps = page_set.PageSet() 231 expectations = test_expectations.TestExpectations() 232 page = page_module.Page( 233 'file:///' + os.path.join(util.GetUnittestDataDir(), 'blank.html'), 234 ps, 235 base_dir=os.path.dirname(__file__)) 236 ps.pages.append(page) 237 238 class TestBeforeLaunch(page_test.PageTest): 239 def __init__(self, 240 test_method_name, 241 action_name_to_run=''): 242 super(TestBeforeLaunch, self).__init__( 243 test_method_name, action_name_to_run, False) 244 self._did_call_will_start = False 245 self._did_call_did_start = False 246 247 def WillStartBrowser(self, browser): 248 self._did_call_will_start = True 249 # TODO(simonjam): Test that the profile is available. 250 251 def DidStartBrowser(self, browser): 252 assert self._did_call_will_start 253 self._did_call_did_start = True 254 255 def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201 256 assert self._did_call_did_start 257 258 test = TestBeforeLaunch('RunTest') 259 options = options_for_unittests.GetCopy() 260 options.output_format = 'none' 261 page_runner.Run(test, ps, expectations, options) 262