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