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