page_runner_unittest.py revision 3551c9c881056c480085172ff9840cab31610854
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(0, len(results.failures))
63    self.assertEquals(1, len(results.errors))
64
65  def testHandlingOfCrashedTabWithExpectedFailure(self):
66    ps = page_set.PageSet()
67    expectations = test_expectations.TestExpectations()
68    expectations.Fail('chrome://crash')
69    page1 = page_module.Page('chrome://crash', ps)
70    ps.pages.append(page1)
71
72    class Test(page_test.PageTest):
73      def RunTest(self, *args):
74        pass
75
76    options = options_for_unittests.GetCopy()
77    options.output_format = 'none'
78    results = page_runner.Run(Test('RunTest'), ps, expectations, options)
79    self.assertEquals(1, len(results.successes))
80    self.assertEquals(0, len(results.failures))
81    self.assertEquals(0, len(results.errors))
82
83  def testDiscardFirstResult(self):
84    ps = page_set.PageSet()
85    expectations = test_expectations.TestExpectations()
86    ps.pages.append(page_module.Page(
87        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir()))
88    ps.pages.append(page_module.Page(
89        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir()))
90
91    class Measurement(page_measurement.PageMeasurement):
92      @property
93      def discard_first_result(self):
94        return True
95      def MeasurePage(self, *args):
96        pass
97
98    options = options_for_unittests.GetCopy()
99    options.output_format = 'none'
100    options.reset_html_results = None
101
102    options.repeat_options.page_repeat_iters = 1
103    options.repeat_options.pageset_repeat_iters = 1
104    results = page_runner.Run(Measurement(), ps, expectations, options)
105    self.assertEquals(0, len(results.successes))
106    self.assertEquals(0, len(results.failures))
107
108    options.repeat_options.page_repeat_iters = 1
109    options.repeat_options.pageset_repeat_iters = 2
110    results = page_runner.Run(Measurement(), ps, expectations, options)
111    self.assertEquals(2, len(results.successes))
112    self.assertEquals(0, len(results.failures))
113
114    options.repeat_options.page_repeat_iters = 2
115    options.repeat_options.pageset_repeat_iters = 1
116    results = page_runner.Run(Measurement(), ps, expectations, options)
117    self.assertEquals(2, len(results.successes))
118    self.assertEquals(0, len(results.failures))
119
120    options.output_format = 'html'
121    options.repeat_options.page_repeat_iters = 1
122    options.repeat_options.pageset_repeat_iters = 1
123    results = page_runner.Run(Measurement(), ps, expectations, options)
124    self.assertEquals(0, len(results.successes))
125    self.assertEquals(0, len(results.failures))
126
127  def testCredentialsWhenLoginFails(self):
128    credentials_backend = StubCredentialsBackend(login_return_value=False)
129    did_run = self.runCredentialsTest(credentials_backend)
130    assert credentials_backend.did_get_login == True
131    assert credentials_backend.did_get_login_no_longer_needed == False
132    assert did_run == False
133
134  def testCredentialsWhenLoginSucceeds(self):
135    credentials_backend = StubCredentialsBackend(login_return_value=True)
136    did_run = self.runCredentialsTest(credentials_backend)
137    assert credentials_backend.did_get_login == True
138    assert credentials_backend.did_get_login_no_longer_needed == True
139    assert did_run
140
141  def runCredentialsTest(self, # pylint: disable=R0201
142                         credentials_backend):
143    ps = page_set.PageSet()
144    expectations = test_expectations.TestExpectations()
145    page = page_module.Page(
146        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir())
147    page.credentials = "test"
148    ps.pages.append(page)
149
150    did_run = [False]
151
152    try:
153      with tempfile.NamedTemporaryFile(delete=False) as f:
154        f.write(SIMPLE_CREDENTIALS_STRING)
155        ps.credentials_path = f.name
156
157      class TestThatInstallsCredentialsBackend(page_test.PageTest):
158        def __init__(self, credentials_backend):
159          super(TestThatInstallsCredentialsBackend, self).__init__('RunTest')
160          self._credentials_backend = credentials_backend
161
162        def DidStartBrowser(self, browser):
163          browser.credentials.AddBackend(self._credentials_backend)
164
165        def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
166          did_run[0] = True
167
168      test = TestThatInstallsCredentialsBackend(credentials_backend)
169      options = options_for_unittests.GetCopy()
170      options.output_format = 'none'
171      page_runner.Run(test, ps, expectations, options)
172    finally:
173      os.remove(f.name)
174
175    return did_run[0]
176
177  def testUserAgent(self):
178    ps = page_set.PageSet()
179    expectations = test_expectations.TestExpectations()
180    page = page_module.Page(
181        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir())
182    ps.pages.append(page)
183    ps.user_agent_type = 'tablet'
184
185    class TestUserAgent(page_test.PageTest):
186      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
187        actual_user_agent = tab.EvaluateJavaScript('window.navigator.userAgent')
188        expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet']
189        assert actual_user_agent.strip() == expected_user_agent
190
191        # This is so we can check later that the test actually made it into this
192        # function. Previously it was timing out before even getting here, which
193        # should fail, but since it skipped all the asserts, it slipped by.
194        self.hasRun = True # pylint: disable=W0201
195
196    test = TestUserAgent('RunTest')
197    options = options_for_unittests.GetCopy()
198    options.output_format = 'none'
199    page_runner.Run(test, ps, expectations, options)
200
201    self.assertTrue(hasattr(test, 'hasRun') and test.hasRun)
202
203  # Ensure that page_runner forces exactly 1 tab before running a page.
204  def testOneTab(self):
205    ps = page_set.PageSet()
206    expectations = test_expectations.TestExpectations()
207    page = page_module.Page(
208        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir())
209    ps.pages.append(page)
210
211    class TestOneTab(page_test.PageTest):
212      def __init__(self,
213                   test_method_name,
214                   action_name_to_run='',
215                   needs_browser_restart_after_each_run=False):
216        super(TestOneTab, self).__init__(test_method_name, action_name_to_run,
217                                         needs_browser_restart_after_each_run)
218        self._browser = None
219
220      def DidStartBrowser(self, browser):
221        self._browser = browser
222        if self._browser.supports_tab_control:
223          self._browser.tabs.New()
224
225      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
226        if not self._browser.supports_tab_control:
227          logging.warning('Browser does not support tab control, skipping test')
228          return
229        assert len(self._browser.tabs) == 1
230
231    test = TestOneTab('RunTest')
232    options = options_for_unittests.GetCopy()
233    options.output_format = 'none'
234    page_runner.Run(test, ps, expectations, options)
235
236  # Ensure that page_runner allows the test to customize the browser before it
237  # launches.
238  def testBrowserBeforeLaunch(self):
239    ps = page_set.PageSet()
240    expectations = test_expectations.TestExpectations()
241    page = page_module.Page(
242        'file:///blank.html', ps, base_dir=util.GetUnittestDataDir())
243    ps.pages.append(page)
244
245    class TestBeforeLaunch(page_test.PageTest):
246      def __init__(self,
247                   test_method_name,
248                   action_name_to_run=''):
249        super(TestBeforeLaunch, self).__init__(
250            test_method_name, action_name_to_run, False)
251        self._did_call_will_start = False
252        self._did_call_did_start = False
253
254      def WillStartBrowser(self, browser):
255        self._did_call_will_start = True
256        # TODO(simonjam): Test that the profile is available.
257
258      def DidStartBrowser(self, browser):
259        assert self._did_call_will_start
260        self._did_call_did_start = True
261
262      def RunTest(self, page, tab, results): # pylint: disable=W0613,R0201
263        assert self._did_call_did_start
264
265    test = TestBeforeLaunch('RunTest')
266    options = options_for_unittests.GetCopy()
267    options.output_format = 'none'
268    page_runner.Run(test, ps, expectations, options)
269