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
7import unittest
8
9from telemetry import decorators
10from telemetry import story
11from telemetry.page import page as page_module
12from telemetry.page import legacy_page_test
13from telemetry.testing import options_for_unittests
14from telemetry.testing import page_test_test_case
15from telemetry.util import wpr_modes
16from telemetry.wpr import archive_info
17
18
19class PageTestThatFails(legacy_page_test.LegacyPageTest):
20
21  def ValidateAndMeasurePage(self, page, tab, results):
22    raise legacy_page_test.Failure
23
24
25class PageTestForBlank(legacy_page_test.LegacyPageTest):
26
27  def ValidateAndMeasurePage(self, page, tab, results):
28    contents = tab.EvaluateJavaScript('document.body.textContent')
29    if contents.strip() != 'Hello world':
30      raise legacy_page_test.MeasurementFailure(
31          'Page contents were: ' + contents)
32
33
34class PageTestForReplay(legacy_page_test.LegacyPageTest):
35
36  def ValidateAndMeasurePage(self, page, tab, results):
37    # Web Page Replay returns '404 Not found' if a page is not in the archive.
38    contents = tab.EvaluateJavaScript('document.body.textContent')
39    if '404 Not Found' in contents.strip():
40      raise legacy_page_test.MeasurementFailure('Page not in archive.')
41
42
43class PageTestQueryParams(legacy_page_test.LegacyPageTest):
44
45  def ValidateAndMeasurePage(self, page, tab, results):
46    query = tab.EvaluateJavaScript('window.location.search')
47    expected = '?foo=1'
48    if query.strip() != expected:
49      raise legacy_page_test.MeasurementFailure(
50          'query was %s, not %s.' % (query, expected))
51
52
53class PageTestWithAction(legacy_page_test.LegacyPageTest):
54
55  def __init__(self):
56    super(PageTestWithAction, self).__init__()
57
58  def ValidateAndMeasurePage(self, page, tab, results):
59    pass
60
61
62class PageWithAction(page_module.Page):
63
64  def __init__(self, url, story_set):
65    super(PageWithAction, self).__init__(url, story_set, story_set.base_dir)
66    self.run_test_action_called = False
67
68  def RunPageInteractions(self, _):
69    self.run_test_action_called = True
70
71
72class PageTestUnitTest(page_test_test_case.PageTestTestCase):
73
74  def setUp(self):
75    self._options = options_for_unittests.GetCopy()
76    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
77
78  def testGotToBlank(self):
79    story_set = self.CreateStorySetFromFileInUnittestDataDir('blank.html')
80    measurement = PageTestForBlank()
81    all_results = self.RunMeasurement(
82        measurement, story_set, options=self._options)
83    self.assertEquals(0, len(all_results.failures))
84
85  def testGotQueryParams(self):
86    story_set = self.CreateStorySetFromFileInUnittestDataDir(
87        'blank.html?foo=1')
88    measurement = PageTestQueryParams()
89    all_results = self.RunMeasurement(
90        measurement, story_set, options=self._options)
91    self.assertEquals(0, len(all_results.failures))
92
93  def testFailure(self):
94    story_set = self.CreateStorySetFromFileInUnittestDataDir('blank.html')
95    measurement = PageTestThatFails()
96    all_results = self.RunMeasurement(
97        measurement, story_set, options=self._options)
98    self.assertEquals(1, len(all_results.failures))
99
100  # This test is disabled because it runs against live sites, and needs to be
101  # fixed. crbug.com/179038
102  @decorators.Disabled('all')
103  def testRecordAndReplay(self):
104    test_archive = '/tmp/google.wpr'
105    google_url = 'http://www.google.com/'
106    foo_url = 'http://www.foo.com/'
107    archive_info_template = ("""
108{
109"archives": {
110  "%s": ["%s"]
111}
112}
113""")
114    try:
115      story_set = story.StorySet.PageSet()
116      measurement = PageTestForReplay()
117
118      # First record an archive with only www.google.com.
119      self._options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
120
121      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
122          '', json.loads(archive_info_template % (test_archive, google_url)),
123          story_set.bucket)
124      story_set.pages = [page_module.Page(google_url, story_set)]
125      all_results = self.RunMeasurement(
126          measurement, story_set, options=self._options)
127      self.assertEquals(0, len(all_results.failures))
128
129      # Now replay it and verify that google.com is found but foo.com is not.
130      self._options.browser_options.wpr_mode = wpr_modes.WPR_REPLAY
131
132      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
133          '', json.loads(archive_info_template % (test_archive, foo_url)),
134          story_set.bucket)
135      story_set.pages = [page_module.Page(foo_url, story_set)]
136      all_results = self.RunMeasurement(
137          measurement, story_set, options=self._options)
138      self.assertEquals(1, len(all_results.failures))
139
140      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
141          '', json.loads(archive_info_template % (test_archive, google_url)),
142          story_set.bucket)
143      story_set.pages = [page_module.Page(google_url, story_set)]
144      all_results = self.RunMeasurement(
145          measurement, story_set, options=self._options)
146      self.assertEquals(0, len(all_results.failures))
147
148      self.assertTrue(os.path.isfile(test_archive))
149
150    finally:
151      if os.path.isfile(test_archive):
152        os.remove(test_archive)
153
154  def testRunActions(self):
155    story_set = self.CreateEmptyPageSet()
156    page = PageWithAction('file://blank.html', story_set)
157    story_set.AddStory(page)
158    measurement = PageTestWithAction()
159    self.RunMeasurement(measurement, story_set, options=self._options)
160    self.assertTrue(page.run_test_action_called)
161
162
163class MultiTabPageTestUnitTest(unittest.TestCase):
164
165  def testNoTabForPageReturnsFalse(self):
166    class PageTestWithoutTabForPage(legacy_page_test.LegacyPageTest):
167
168      def ValidateAndMeasurePage(self, *_):
169        pass
170    test = PageTestWithoutTabForPage()
171    self.assertFalse(test.is_multi_tab_test)
172
173  def testHasTabForPageReturnsTrue(self):
174    class PageTestWithTabForPage(legacy_page_test.LegacyPageTest):
175
176      def ValidateAndMeasurePage(self, *_):
177        pass
178
179      def TabForPage(self, *_):
180        pass
181    test = PageTestWithTabForPage()
182    self.assertTrue(test.is_multi_tab_test)
183
184  def testHasTabForPageInAncestor(self):
185    class PageTestWithTabForPage(legacy_page_test.LegacyPageTest):
186
187      def ValidateAndMeasurePage(self, *_):
188        pass
189
190      def TabForPage(self, *_):
191        pass
192
193    class PageTestWithTabForPageInParent(PageTestWithTabForPage):
194      pass
195    test = PageTestWithTabForPageInParent()
196    self.assertTrue(test.is_multi_tab_test)
197