def Stop(self, tab): # End the smooth marker for all actions. runner = action_runner.ActionRunner(None, tab) runner.EndInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH]) # Stop tracing. timeline_data = tab.browser.StopTracing() self._model = TimelineModel(timeline_data) self._renderer_process = self._model.GetRendererProcessFromTab(tab) renderer_thread = self.model.GetRendererThreadFromTab(tab) run_smooth_actions_record = None self._smooth_records = [] for event in renderer_thread.async_slices: if not tir_module.IsTimelineInteractionRecord(event.name): continue r = tir_module.TimelineInteractionRecord.FromEvent(event) if r.logical_name == RUN_SMOOTH_ACTIONS: assert run_smooth_actions_record is None, ( 'TimelineController cannot issue more than 1 %s record' % RUN_SMOOTH_ACTIONS) run_smooth_actions_record = r elif r.is_smooth: self._smooth_records.append( smooth_gesture_util.GetAdjustedInteractionIfContainGesture( self.model, r)) # If there is no other smooth records, we make measurements on time range # marked by timeline_controller itself. # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that # page sets are responsible for issueing the markers themselves. if len(self._smooth_records) == 0 and run_smooth_actions_record: self._smooth_records = [run_smooth_actions_record]
def RunPage(self, page, tab, results): # When recording, sleep to catch any resources that load post-onload. tab.WaitForDocumentReadyStateToBeComplete() if self.test: dummy_results = page_measurement_results.PageMeasurementResults() dummy_results.WillMeasurePage(page) self.test.MeasurePage(page, tab, dummy_results) dummy_results.DidMeasurePage() else: # TODO(tonyg): This should probably monitor resource timing for activity # and sleep until 2s since the last network event with some timeout like # 20s. We could wrap this up as WaitForNetworkIdle() and share with the # speed index metric. time.sleep(3) # Run the actions for all measurements. Reload the page between # actions. should_reload = False interactive = self.options and self.options.interactive for action_name in self._action_names: if not hasattr(page, action_name): continue if should_reload: self.RunNavigateSteps(page, tab) action_runner = action_runner_module.ActionRunner(page, tab, self) if interactive: action_runner.RunAction(interact.InteractAction()) else: self._RunMethod(page, action_name, action_runner) should_reload = True
def RunNavigateSteps(self, page, tab): """Navigates the tab to the page URL attribute. Runs the 'navigate_steps' page attribute as a compound action. """ action_runner = action_runner_module.ActionRunner(tab) page.RunNavigateSteps(action_runner)
def testScroll(self): if not page_action.IsGestureSourceTypeSupported(self._tab, 'touch'): return self.Navigate('page_with_swipeables.html') action_runner = action_runner_module.ActionRunner(self._tab, skip_waits=True) action_runner.ScrollElement(selector='#left-right', direction='right', left_start_ratio=0.9) self.assertTrue( action_runner.EvaluateJavaScript( 'document.querySelector("#left-right").scrollLeft') > 75) action_runner.ScrollElement(selector='#top-bottom', direction='down', top_start_ratio=0.9) self.assertTrue( action_runner.EvaluateJavaScript( 'document.querySelector("#top-bottom").scrollTop') > 75) action_runner.ScrollPage(direction='right', left_start_ratio=0.9, distance=100) self.assertTrue( action_runner.EvaluateJavaScript('document.body.scrollLeft') > 75)
def RunNavigateSteps(self, page, tab): """Navigates the tab to the page URL attribute. Runs the 'navigate_steps' page attribute as a compound action. """ action_runner = action_runner_module.ActionRunner(page, tab, None) self._RunMethod(page, "RunNavigateSteps", action_runner)
def testPinchByApiCalledWithCorrectArguments(self): self.Navigate('blank.html') if not page_action.IsGestureSourceTypeSupported(self._tab, 'touch'): return action_runner = action_runner_module.ActionRunner(self._tab) action_runner.ExecuteJavaScript(''' chrome.gpuBenchmarking.pinchBy = function( scaleFactor, anchorLeft, anchorTop, callback, speed) { window.__test_scaleFactor = scaleFactor; window.__test_anchorLeft = anchorLeft; window.__test_anchorTop = anchorTop; window.__test_callback = callback; window.__test_speed = speed; window.__pinchActionDone = true; };''') action_runner.PinchPage(scale_factor=2) self.assertEqual( 2, action_runner.EvaluateJavaScript('window.__test_scaleFactor')) self.assertTrue( action_runner.EvaluateJavaScript('!isNaN(window.__test_anchorLeft)')) self.assertTrue( action_runner.EvaluateJavaScript('!isNaN(window.__test_anchorTop)')) self.assertTrue( action_runner.EvaluateJavaScript('!!window.__test_callback')) self.assertEqual( 800, action_runner.EvaluateJavaScript('window.__test_speed'))
def testIssuingInteractionRecord(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('interaction_enabled_page.html') action_runner.Wait(1) self._browser.StartTracing(tracing_backend.DEFAULT_TRACE_CATEGORIES) interaction = action_runner.BeginInteraction('TestInteraction', is_smooth=True) interaction.End() trace_data = self._browser.StopTracing() timeline_model = model.TimelineModel(trace_data) records = [] renderer_thread = timeline_model.GetRendererThreadFromTabId( self._tab.id) for event in renderer_thread.async_slices: if not tir_module.IsTimelineInteractionRecord(event.name): continue records.append( tir_module.TimelineInteractionRecord.FromAsyncEvent(event)) self.assertEqual( 1, len(records), 'Fail to issue the interaction record on tracing timeline.' ' Trace data:\n%s' % repr(trace_data.EventData())) self.assertEqual('TestInteraction', records[0].logical_name) self.assertTrue(records[0].is_smooth)
def testWaitForElement(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('blank.html') action_runner.ExecuteJavaScript( '(function() {' ' var el = document.createElement("div");' ' el.id = "test1";' ' el.textContent = "foo";' ' document.body.appendChild(el);' '})()') action_runner.WaitForElement('#test1', timeout=1) action_runner.WaitForElement(text='foo', timeout=1) action_runner.WaitForElement( element_function='document.getElementById("test1")') action_runner.ExecuteJavaScript( 'window.setTimeout(function() {' ' var el = document.createElement("div");' ' el.id = "test2";' ' document.body.appendChild(el);' '}, 500)') action_runner.WaitForElement('#test2', timeout=2) action_runner.ExecuteJavaScript( 'window.setTimeout(function() {' ' document.getElementById("test2").textContent = "bar";' '}, 500)') action_runner.WaitForElement(text='bar', timeout=2) action_runner.ExecuteJavaScript( 'window.setTimeout(function() {' ' var el = document.createElement("div");' ' el.id = "test3";' ' document.body.appendChild(el);' '}, 500)') action_runner.WaitForElement( element_function='document.getElementById("test3")')
def testEvaluateCallbackWithElement(self): self.Navigate('blank.html') runner = action_runner.ActionRunner(self._tab) runner.ExecuteJavaScript(''' (function() { function createElement(id, textContent) { var el = document.createElement("div"); el.id = id; el.textContent = textContent; document.body.appendChild(el); } createElement('test-1', 'foo'); createElement('test-2', 'bar'); createElement('test-3', 'baz'); })();''') self.assertEqual( 'foo', page_action.EvaluateCallbackWithElement( self._tab, 'function(el) { return el.textContent; }', selector='#test-1')) self.assertEqual( 'bar', page_action.EvaluateCallbackWithElement( self._tab, 'function(el) { return el.textContent; }', text='bar')) self.assertEqual( 'baz', page_action.EvaluateCallbackWithElement( self._tab, 'function(el) { return el.textContent; }', element_function='document.getElementById("test-3")')) self.assertEqual( 'baz', page_action.EvaluateCallbackWithElement( self._tab, 'function(el) { return el.textContent; }', element_function=''' (function() { return document.getElementById("test-3"); })()''')) # Test for when the element is not found. self.assertEqual( None, page_action.EvaluateCallbackWithElement( self._tab, 'function(el) { return el; }', element_function='document.getElementById("test-4")')) # Test the info message. self.assertEqual( 'using selector "#test-1"', page_action.EvaluateCallbackWithElement( self._tab, 'function(el, info) { return info; }', selector='#test-1'))
def LoginNeeded(self, tab, credentials_type): if credentials_type not in self._backends: raise CredentialsError( 'Unrecognized credentials type: %s', credentials_type) if credentials_type not in self._credentials: return False runner = action_runner.ActionRunner(tab) return self._backends[credentials_type].LoginNeeded( tab, runner, self._credentials[credentials_type])
def Start(self, page, tab): custom_categories = ['webkit.console', 'benchmark'] custom_categories += page.GetSyntheticDelayCategories() tab.browser.StartTracing(','.join(custom_categories), 60) if tab.browser.platform.IsRawDisplayFrameRateSupported(): tab.browser.platform.StartRawDisplayFrameRateMeasurement() # Start the smooth marker for all smooth actions. runner = action_runner.ActionRunner(None, tab) runner.BeginInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH])
def Stop(self, tab): # End the smooth marker for all smooth actions. runner = action_runner.ActionRunner(None, tab) runner.EndInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH]) # Stop tracing for smoothness metric. if tab.browser.platform.IsRawDisplayFrameRateSupported(): tab.browser.platform.StopRawDisplayFrameRateMeasurement() self._tracing_timeline_data = tab.browser.StopTracing() self._timeline_model = TimelineModel( timeline_data=self._tracing_timeline_data)
def RunPage(self, page, tab, results): interactive = self.options and self.options.interactive action_runner = action_runner_module.ActionRunner(page, tab, self) self.WillRunActions(page, tab) if interactive: action_runner.RunAction(interact.InteractAction()) else: self._RunMethod(page, self._action_name_to_run, action_runner) self.DidRunActions(page, tab) self._test_method(page, tab, results)
def RunAction(self, page, tab): runner = action_runner.ActionRunner(None, tab) if self.wait_action: interaction_name = 'Action_%s' % self.__class__.__name__ else: interaction_name = 'Gesture_%s' % self.__class__.__name__ runner.BeginInteraction(interaction_name, [tir_module.IS_SMOOTH]) self.RunGesture(page, tab) if self.wait_action: self.wait_action.RunAction(page, tab) runner.EndInteraction(interaction_name, [tir_module.IS_SMOOTH])
def Start(self, page, tab): # FIXME: Remove webkit.console when blink.console lands in chromium and # the ref builds are updated. crbug.com/386847 custom_categories = ['webkit.console', 'blink.console', 'benchmark'] custom_categories += page.GetSyntheticDelayCategories() tab.browser.StartTracing(','.join(custom_categories), 60) if tab.browser.platform.IsRawDisplayFrameRateSupported(): tab.browser.platform.StartRawDisplayFrameRateMeasurement() # Start the smooth marker for all smooth actions. runner = action_runner.ActionRunner(tab) self._interaction = runner.BeginInteraction(RUN_SMOOTH_ACTIONS, is_smooth=True)
def testWaitForJavaScriptCondition(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('blank.html') action_runner.ExecuteJavaScript('window.testing = 219;') action_runner.WaitForJavaScriptCondition('window.testing == 219', timeout=1) action_runner.ExecuteJavaScript( 'window.setTimeout(function() { window.testing = 220; }, 1000);') action_runner.WaitForJavaScriptCondition('window.testing == 220', timeout=2) self.assertEqual(220, self._tab.EvaluateJavaScript('window.testing'))
def RunPage(self, page, tab, results): # Run actions. interactive = self.options and self.options.interactive action_runner = action_runner_module.ActionRunner( tab, skip_waits=page.skip_waits) self.WillRunActions(page, tab) if interactive: action_runner.PauseInteractive() else: self._RunMethod(page, self._action_name_to_run, action_runner) self.DidRunActions(page, tab) self.ValidateAndMeasurePage(page, tab, results)
def testWaitForNavigate(self): self.Navigate('page_with_link.html') action_runner = action_runner_module.ActionRunner(self._tab) action_runner.ClickElement('#clickme') action_runner.WaitForNavigate() self.assertTrue( self._tab.EvaluateJavaScript( 'document.readyState == "interactive" || ' 'document.readyState == "complete"')) self.assertEqual( self._tab.EvaluateJavaScript('document.location.pathname;'), '/blank.html')
def testWait(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('blank.html') action_runner.ExecuteJavaScript( 'window.setTimeout(function() { window.testing = 101; }, 50);') action_runner.Wait(0.1) self.assertEqual(101, self._tab.EvaluateJavaScript('window.testing')) action_runner.ExecuteJavaScript( 'window.setTimeout(function() { window.testing = 102; }, 100);') action_runner.Wait(0.2) self.assertEqual(102, self._tab.EvaluateJavaScript('window.testing'))
def testWaitForElementWithWrongText(self): action_runner = action_runner_module.ActionRunner(self._tab) self.Navigate('blank.html') action_runner.ExecuteJavaScript( '(function() {' ' var el = document.createElement("div");' ' el.id = "test1";' ' el.textContent = "foo";' ' document.body.appendChild(el);' '})()') action_runner.WaitForElement('#test1', timeout=1) def WaitForElement(): action_runner.WaitForElement(text='oo', timeout=1) self.assertRaises(util.TimeoutException, WaitForElement)
def Start(self, page, tab): """Starts gathering timeline data. """ # Resets these member variables incase this object is reused. self._model = None self._renderer_process = None if not tab.browser.supports_tracing: raise Exception('Not supported') if self.trace_categories: categories = [self.trace_categories] + \ page.GetSyntheticDelayCategories() else: categories = page.GetSyntheticDelayCategories() tab.browser.StartTracing(','.join(categories)) # Start the smooth marker for all actions. runner = action_runner.ActionRunner(None, tab) runner.BeginInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH])
def testTapElement(self): self.Navigate('page_with_clickables.html') action_runner = action_runner_module.ActionRunner(self._tab) action_runner.ExecuteJavaScript('valueSettableByTest = 1;') action_runner.TapElement('#test') self.assertEqual(1, action_runner.EvaluateJavaScript('valueToTest')) action_runner.ExecuteJavaScript('valueSettableByTest = 2;') action_runner.TapElement(text='Click/tap me') self.assertEqual(2, action_runner.EvaluateJavaScript('valueToTest')) action_runner.ExecuteJavaScript('valueSettableByTest = 3;') action_runner.TapElement( element_function='document.body.firstElementChild') self.assertEqual(3, action_runner.EvaluateJavaScript('valueToTest')) def WillFail(): action_runner.TapElement('#notfound') self.assertRaises(exceptions.EvaluateException, WillFail)
def VerifyIssuingInteractionRecords(self, **interaction_kwargs): action_runner = action_runner_module.ActionRunner(self._tab, skip_waits=True) self.Navigate('interaction_enabled_page.html') action_runner.Wait(1) options = tracing_options.TracingOptions() options.enable_chrome_trace = True self._browser.platform.tracing_controller.Start( options, tracing_category_filter.CreateNoOverheadFilter()) interaction = action_runner.BeginInteraction('InteractionName', **interaction_kwargs) interaction.End() trace_data = self._browser.platform.tracing_controller.Stop() records = self.GetInteractionRecords(trace_data) self.assertEqual( 1, len(records), 'Failed to issue the interaction record on the tracing timeline.' ' Trace data:\n%s' % repr(trace_data._raw_data)) self.assertEqual('InteractionName', records[0].label) for attribute_name in interaction_kwargs: self.assertTrue(getattr(records[0], attribute_name))
def Start(self, tab): # Start the smooth marker for all smooth actions. runner = action_runner.ActionRunner(tab) self._interaction = runner.BeginInteraction(RUN_SMOOTH_ACTIONS, is_smooth=True)
def WillRunActions(self, page, tab): runner = action_runner.ActionRunner(tab) self._interaction = runner.BeginInteraction(_RUN_SMOOTH_ACTIONS, is_smooth=True)
def testExecuteJavaScript(self): action_runner = action_runner_module.ActionRunner(self._tab, skip_waits=True) self.Navigate('blank.html') action_runner.ExecuteJavaScript('var testing = 42;') self.assertEqual(42, self._tab.EvaluateJavaScript('testing'))