page_runner_unittest.py revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
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