1# Copyright 2014 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
5from telemetry import benchmark
6from telemetry.core import exceptions
7from telemetry.core import util
8from telemetry.core.platform import tracing_category_filter
9from telemetry.core.platform import tracing_options
10from telemetry.page.actions import action_runner as action_runner_module
11from telemetry.page.actions import page_action
12from telemetry.timeline import model
13from telemetry.unittest import tab_test_case
14from telemetry.web_perf import timeline_interaction_record as tir_module
15
16
17class ActionRunnerInteractionTest(tab_test_case.TabTestCase):
18
19  def GetInteractionRecords(self, trace_data):
20    timeline_model = model.TimelineModel(trace_data)
21    renderer_thread = timeline_model.GetRendererThreadFromTabId(self._tab.id)
22    return [
23        tir_module.TimelineInteractionRecord.FromAsyncEvent(e)
24        for e in renderer_thread.async_slices
25        if tir_module.IsTimelineInteractionRecord(e.name)
26        ]
27
28  def VerifyIssuingInteractionRecords(self, **interaction_kwargs):
29    action_runner = action_runner_module.ActionRunner(self._tab,
30                                                      skip_waits=True)
31    self.Navigate('interaction_enabled_page.html')
32    action_runner.Wait(1)
33    options = tracing_options.TracingOptions()
34    options.enable_chrome_trace = True
35    self._browser.platform.tracing_controller.Start(
36        options, tracing_category_filter.CreateNoOverheadFilter())
37    interaction = action_runner.BeginInteraction('InteractionName',
38                                                 **interaction_kwargs)
39    interaction.End()
40    trace_data = self._browser.platform.tracing_controller.Stop()
41
42    records = self.GetInteractionRecords(trace_data)
43    self.assertEqual(
44        1, len(records),
45        'Failed to issue the interaction record on the tracing timeline.'
46        ' Trace data:\n%s' % repr(trace_data.EventData()))
47    self.assertEqual('InteractionName', records[0].label)
48    for attribute_name in interaction_kwargs:
49      self.assertTrue(getattr(records[0], attribute_name))
50
51  @benchmark.Disabled('chromeos')
52  def testIssuingMultipleMeasurementInteractionRecords(self):
53    self.VerifyIssuingInteractionRecords(is_fast=True)
54    self.VerifyIssuingInteractionRecords(is_responsive=True)
55    self.VerifyIssuingInteractionRecords(is_smooth=True)
56    self.VerifyIssuingInteractionRecords(is_fast=True, is_smooth=True)
57
58
59class ActionRunnerTest(tab_test_case.TabTestCase):
60  def testExecuteJavaScript(self):
61    action_runner = action_runner_module.ActionRunner(self._tab,
62                                                      skip_waits=True)
63    self.Navigate('blank.html')
64    action_runner.ExecuteJavaScript('var testing = 42;')
65    self.assertEqual(42, self._tab.EvaluateJavaScript('testing'))
66
67  def testWaitForNavigate(self):
68    self.Navigate('page_with_link.html')
69    action_runner = action_runner_module.ActionRunner(self._tab,
70                                                      skip_waits=True)
71    action_runner.ClickElement('#clickme')
72    action_runner.WaitForNavigate()
73
74    self.assertTrue(self._tab.EvaluateJavaScript(
75        'document.readyState == "interactive" || '
76        'document.readyState == "complete"'))
77    self.assertEqual(
78        self._tab.EvaluateJavaScript('document.location.pathname;'),
79        '/blank.html')
80
81  def testWait(self):
82    action_runner = action_runner_module.ActionRunner(self._tab)
83    self.Navigate('blank.html')
84
85    action_runner.ExecuteJavaScript(
86        'window.setTimeout(function() { window.testing = 101; }, 50);')
87    action_runner.Wait(0.1)
88    self.assertEqual(101, self._tab.EvaluateJavaScript('window.testing'))
89
90    action_runner.ExecuteJavaScript(
91        'window.setTimeout(function() { window.testing = 102; }, 100);')
92    action_runner.Wait(0.2)
93    self.assertEqual(102, self._tab.EvaluateJavaScript('window.testing'))
94
95  def testWaitForJavaScriptCondition(self):
96    action_runner = action_runner_module.ActionRunner(self._tab,
97                                                      skip_waits=True)
98    self.Navigate('blank.html')
99
100    action_runner.ExecuteJavaScript('window.testing = 219;')
101    action_runner.WaitForJavaScriptCondition(
102        'window.testing == 219', timeout_in_seconds=0.1)
103    action_runner.ExecuteJavaScript(
104        'window.setTimeout(function() { window.testing = 220; }, 50);')
105    action_runner.WaitForJavaScriptCondition(
106        'window.testing == 220', timeout_in_seconds=0.1)
107    self.assertEqual(220, self._tab.EvaluateJavaScript('window.testing'))
108
109  def testWaitForElement(self):
110    action_runner = action_runner_module.ActionRunner(self._tab,
111                                                      skip_waits=True)
112    self.Navigate('blank.html')
113
114    action_runner.ExecuteJavaScript(
115        '(function() {'
116        '  var el = document.createElement("div");'
117        '  el.id = "test1";'
118        '  el.textContent = "foo";'
119        '  document.body.appendChild(el);'
120        '})()')
121    action_runner.WaitForElement('#test1', timeout_in_seconds=0.1)
122    action_runner.WaitForElement(text='foo', timeout_in_seconds=0.1)
123    action_runner.WaitForElement(
124        element_function='document.getElementById("test1")')
125    action_runner.ExecuteJavaScript(
126        'window.setTimeout(function() {'
127        '  var el = document.createElement("div");'
128        '  el.id = "test2";'
129        '  document.body.appendChild(el);'
130        '}, 50)')
131    action_runner.WaitForElement('#test2', timeout_in_seconds=0.1)
132    action_runner.ExecuteJavaScript(
133        'window.setTimeout(function() {'
134        '  document.getElementById("test2").textContent = "bar";'
135        '}, 50)')
136    action_runner.WaitForElement(text='bar', timeout_in_seconds=0.1)
137    action_runner.ExecuteJavaScript(
138        'window.setTimeout(function() {'
139        '  var el = document.createElement("div");'
140        '  el.id = "test3";'
141        '  document.body.appendChild(el);'
142        '}, 50)')
143    action_runner.WaitForElement(
144        element_function='document.getElementById("test3")')
145
146  def testWaitForElementWithWrongText(self):
147    action_runner = action_runner_module.ActionRunner(self._tab,
148                                                      skip_waits=True)
149    self.Navigate('blank.html')
150
151    action_runner.ExecuteJavaScript(
152        '(function() {'
153        '  var el = document.createElement("div");'
154        '  el.id = "test1";'
155        '  el.textContent = "foo";'
156        '  document.body.appendChild(el);'
157        '})()')
158    action_runner.WaitForElement('#test1', timeout_in_seconds=0.2)
159    def WaitForElement():
160      action_runner.WaitForElement(text='oo', timeout_in_seconds=0.2)
161    self.assertRaises(util.TimeoutException, WaitForElement)
162
163  def testClickElement(self):
164    self.Navigate('page_with_clickables.html')
165    action_runner = action_runner_module.ActionRunner(self._tab,
166                                                      skip_waits=True)
167
168    action_runner.ExecuteJavaScript('valueSettableByTest = 1;')
169    action_runner.ClickElement('#test')
170    self.assertEqual(1, action_runner.EvaluateJavaScript('valueToTest'))
171
172    action_runner.ExecuteJavaScript('valueSettableByTest = 2;')
173    action_runner.ClickElement(text='Click/tap me')
174    self.assertEqual(2, action_runner.EvaluateJavaScript('valueToTest'))
175
176    action_runner.ExecuteJavaScript('valueSettableByTest = 3;')
177    action_runner.ClickElement(
178        element_function='document.body.firstElementChild;')
179    self.assertEqual(3, action_runner.EvaluateJavaScript('valueToTest'))
180
181    def WillFail():
182      action_runner.ClickElement('#notfound')
183    self.assertRaises(exceptions.EvaluateException, WillFail)
184
185  @benchmark.Disabled('debug')
186  def testTapElement(self):
187    self.Navigate('page_with_clickables.html')
188    action_runner = action_runner_module.ActionRunner(self._tab,
189                                                      skip_waits=True)
190
191    action_runner.ExecuteJavaScript('valueSettableByTest = 1;')
192    action_runner.TapElement('#test')
193    self.assertEqual(1, action_runner.EvaluateJavaScript('valueToTest'))
194
195    action_runner.ExecuteJavaScript('valueSettableByTest = 2;')
196    action_runner.TapElement(text='Click/tap me')
197    self.assertEqual(2, action_runner.EvaluateJavaScript('valueToTest'))
198
199    action_runner.ExecuteJavaScript('valueSettableByTest = 3;')
200    action_runner.TapElement(
201        element_function='document.body.firstElementChild')
202    self.assertEqual(3, action_runner.EvaluateJavaScript('valueToTest'))
203
204    def WillFail():
205      action_runner.TapElement('#notfound')
206    self.assertRaises(exceptions.EvaluateException, WillFail)
207
208  def testScroll(self):
209    if not page_action.IsGestureSourceTypeSupported(
210        self._tab, 'touch'):
211      return
212
213    self.Navigate('page_with_swipeables.html')
214    action_runner = action_runner_module.ActionRunner(self._tab,
215                                                      skip_waits=True)
216
217    action_runner.ScrollElement(
218        selector='#left-right', direction='right', left_start_ratio=0.9)
219    self.assertTrue(action_runner.EvaluateJavaScript(
220        'document.querySelector("#left-right").scrollLeft') > 75)
221    action_runner.ScrollElement(
222        selector='#top-bottom', direction='down', top_start_ratio=0.9)
223    self.assertTrue(action_runner.EvaluateJavaScript(
224        'document.querySelector("#top-bottom").scrollTop') > 75)
225
226    action_runner.ScrollPage(direction='right', left_start_ratio=0.9,
227                             distance=100)
228    self.assertTrue(action_runner.EvaluateJavaScript(
229        'document.body.scrollLeft') > 75)
230
231  def testSwipe(self):
232    if not page_action.IsGestureSourceTypeSupported(
233        self._tab, 'touch'):
234      return
235
236    self.Navigate('page_with_swipeables.html')
237    action_runner = action_runner_module.ActionRunner(self._tab,
238                                                      skip_waits=True)
239
240    action_runner.SwipeElement(
241        selector='#left-right', direction='left', left_start_ratio=0.9)
242    self.assertTrue(action_runner.EvaluateJavaScript(
243        'document.querySelector("#left-right").scrollLeft') > 75)
244    action_runner.SwipeElement(
245        selector='#top-bottom', direction='up', top_start_ratio=0.9)
246    self.assertTrue(action_runner.EvaluateJavaScript(
247        'document.querySelector("#top-bottom").scrollTop') > 75)
248
249    action_runner.SwipePage(direction='left', left_start_ratio=0.9)
250    self.assertTrue(action_runner.EvaluateJavaScript(
251        'document.body.scrollLeft') > 75)
252