1# Copyright 2013 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.
4
5import json
6import os
7
8from telemetry import benchmark
9from telemetry.core import exceptions
10from telemetry.core import wpr_modes
11from telemetry.page import page as page_module
12from telemetry.page import page_set
13from telemetry.page import page_set_archive_info
14from telemetry.page import page_test
15from telemetry.unittest import options_for_unittests
16from telemetry.unittest import page_test_test_case
17from telemetry.value import scalar
18
19
20class PageTestThatFails(page_test.PageTest):
21  def ValidateAndMeasurePage(self, page, tab, results):
22    raise exceptions.IntentionalException
23
24
25class PageTestThatHasDefaults(page_test.PageTest):
26  def AddCommandLineArgs(self, parser):
27    parser.add_option('-x', dest='x', default=3)
28
29  def ValidateAndMeasurePage(self, page, tab, results):
30    if not hasattr(self.options, 'x'):
31      raise page_test.MeasurementFailure('Default option was not set.')
32    if self.options.x != 3:
33      raise page_test.MeasurementFailure(
34          'Expected x == 3, got x == ' + self.options.x)
35    results.AddValue(scalar.ScalarValue(page, 'x', 'ms', 7))
36
37
38class PageTestForBlank(page_test.PageTest):
39  def ValidateAndMeasurePage(self, page, tab, results):
40    contents = tab.EvaluateJavaScript('document.body.textContent')
41    if contents.strip() != 'Hello world':
42      raise page_test.MeasurementFailure(
43          'Page contents were: ' + contents)
44
45
46class PageTestForReplay(page_test.PageTest):
47  def ValidateAndMeasurePage(self, page, tab, results):
48    # Web Page Replay returns '404 Not found' if a page is not in the archive.
49    contents = tab.EvaluateJavaScript('document.body.textContent')
50    if '404 Not Found' in contents.strip():
51      raise page_test.MeasurementFailure('Page not in archive.')
52
53
54class PageTestQueryParams(page_test.PageTest):
55  def ValidateAndMeasurePage(self, page, tab, results):
56    query = tab.EvaluateJavaScript('window.location.search')
57    expected = '?foo=1'
58    if query.strip() != expected:
59      raise page_test.MeasurementFailure(
60          'query was %s, not %s.' % (query, expected))
61
62
63class PageTestWithAction(page_test.PageTest):
64  def __init__(self):
65    super(PageTestWithAction, self).__init__('RunTestAction')
66
67  def ValidateAndMeasurePage(self, page, tab, results):
68    pass
69
70
71class PageWithAction(page_module.Page):
72  def __init__(self, url, ps):
73    super(PageWithAction, self).__init__(url, ps, ps.base_dir)
74    self.run_test_action_called = False
75
76  def RunTestAction(self, _):
77    self.run_test_action_called = True
78
79
80class PageTestUnitTest(page_test_test_case.PageTestTestCase):
81
82  def setUp(self):
83    self._options = options_for_unittests.GetCopy()
84    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
85
86  def testGotToBlank(self):
87    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html')
88    measurement = PageTestForBlank()
89    all_results = self.RunMeasurement(measurement, ps, options=self._options)
90    self.assertEquals(0, len(all_results.failures))
91
92  def testGotQueryParams(self):
93    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html?foo=1')
94    measurement = PageTestQueryParams()
95    all_results = self.RunMeasurement(measurement, ps, options=self._options)
96    self.assertEquals(0, len(all_results.failures))
97
98  def testFailure(self):
99    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html')
100    measurement = PageTestThatFails()
101    all_results = self.RunMeasurement(measurement, ps, options=self._options)
102    self.assertEquals(1, len(all_results.failures))
103
104  def testDefaults(self):
105    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html')
106    measurement = PageTestThatHasDefaults()
107    all_results = self.RunMeasurement(measurement, ps, options=self._options)
108    self.assertEquals(len(all_results.all_page_specific_values), 1)
109    self.assertEquals(
110      all_results.all_page_specific_values[0].value, 7)
111
112  # This test is disabled because it runs against live sites, and needs to be
113  # fixed. crbug.com/179038
114  @benchmark.Disabled
115  def testRecordAndReplay(self):
116    test_archive = '/tmp/google.wpr'
117    google_url = 'http://www.google.com/'
118    foo_url = 'http://www.foo.com/'
119    archive_info_template = ("""
120{
121"archives": {
122  "%s": ["%s"]
123}
124}
125""")
126    try:
127      ps = page_set.PageSet()
128      measurement = PageTestForReplay()
129
130      # First record an archive with only www.google.com.
131      self._options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
132
133      ps.wpr_archive_info = page_set_archive_info.PageSetArchiveInfo(
134          '', '', json.loads(archive_info_template %
135                             (test_archive, google_url)))
136      ps.pages = [page_module.Page(google_url, ps)]
137      all_results = self.RunMeasurement(measurement, ps, options=self._options)
138      self.assertEquals(0, len(all_results.failures))
139
140      # Now replay it and verify that google.com is found but foo.com is not.
141      self._options.browser_options.wpr_mode = wpr_modes.WPR_REPLAY
142
143      ps.wpr_archive_info = page_set_archive_info.PageSetArchiveInfo(
144          '', '', json.loads(archive_info_template % (test_archive, foo_url)))
145      ps.pages = [page_module.Page(foo_url, ps)]
146      all_results = self.RunMeasurement(measurement, ps, options=self._options)
147      self.assertEquals(1, len(all_results.failures))
148
149      ps.wpr_archive_info = page_set_archive_info.PageSetArchiveInfo(
150          '', '', json.loads(archive_info_template %
151                             (test_archive, google_url)))
152      ps.pages = [page_module.Page(google_url, ps)]
153      all_results = self.RunMeasurement(measurement, ps, options=self._options)
154      self.assertEquals(0, len(all_results.failures))
155
156      self.assertTrue(os.path.isfile(test_archive))
157
158    finally:
159      if os.path.isfile(test_archive):
160        os.remove(test_archive)
161
162  def testRunActions(self):
163    ps = self.CreateEmptyPageSet()
164    page = PageWithAction('file://blank.html', ps)
165    ps.AddPage(page)
166    measurement = PageTestWithAction()
167    self.RunMeasurement(measurement, ps, options=self._options)
168    self.assertTrue(page.run_test_action_called)
169