diff options
8 files changed, 110 insertions, 28 deletions
diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py index e47e421..640c64f 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py +++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_backend.py @@ -112,7 +112,7 @@ class InspectorBackend(object): # Displays other than 0 mean we are likely running in something like # xvfb where screenshotting doesn't work. return False - return not self._runtime.Evaluate(""" + return not self.EvaluateJavaScript(""" window.chrome.gpuBenchmarking === undefined || window.chrome.gpuBenchmarking.beginWindowSnapshotPNG === undefined """) @@ -120,7 +120,7 @@ class InspectorBackend(object): def Screenshot(self, timeout): assert self.screenshot_supported, 'Browser does not support screenshotting' - self._runtime.Evaluate(""" + self.EvaluateJavaScript(""" if(!window.__telemetry) { window.__telemetry = {} } @@ -135,11 +135,12 @@ class InspectorBackend(object): """) def IsSnapshotComplete(): - return self._runtime.Evaluate('window.__telemetry.snapshotComplete') + return self.EvaluateJavaScript( + 'window.__telemetry.snapshotComplete') util.WaitFor(IsSnapshotComplete, timeout) - snap = self._runtime.Evaluate(""" + snap = self.EvaluateJavaScript(""" (function() { var data = window.__telemetry.snapshotData; delete window.__telemetry.snapshotComplete; @@ -184,11 +185,11 @@ class InspectorBackend(object): # Runtime public methods. - def ExecuteJavaScript(self, expr, timeout): - self._runtime.Execute(expr, timeout) + def ExecuteJavaScript(self, expr, context_id=None, timeout=60): + self._runtime.Execute(expr, context_id, timeout) - def EvaluateJavaScript(self, expr, timeout): - return self._runtime.Evaluate(expr, timeout) + def EvaluateJavaScript(self, expr, context_id=None, timeout=60): + return self._runtime.Evaluate(expr, context_id, timeout) # Timeline public methods. diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime.py index 529d128..3b8d19d 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime.py +++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime.py @@ -10,6 +10,7 @@ class InspectorRuntime(object): 'Runtime', self._OnNotification, self._OnClose) + self._contexts_enabled = False def _OnNotification(self, msg): pass @@ -17,25 +18,11 @@ class InspectorRuntime(object): def _OnClose(self): pass - def Execute(self, expr, timeout=60): - """Executes expr in javascript. Does not return the result. + def Execute(self, expr, context_id, timeout): + self.Evaluate(expr + '; 0;', context_id, timeout) - If the expression failed to evaluate, EvaluateException will be raised. - """ - self.Evaluate(expr + '; 0;', timeout) - - def Evaluate(self, expr, timeout=60): - """Evalutes expr in javascript and returns the JSONized result. - - Consider using Execute for cases where the result of the expression is not - needed. - - If evaluation throws in javascript, a python EvaluateException will - be raised. - - If the result of the evaluation cannot be JSONized, then an - EvaluationException will be raised. - """ + def Evaluate(self, expr, context_id, timeout): + self._EnableAllContexts(context_id) request = { 'method': 'Runtime.evaluate', 'params': { @@ -43,6 +30,8 @@ class InspectorRuntime(object): 'returnByValue': True } } + if context_id is not None: + request['params']['contextId'] = context_id res = self._inspector_backend.SyncRequest(request, timeout) if 'error' in res: raise exceptions.EvaluateException(res['error']['message']) @@ -54,3 +43,10 @@ class InspectorRuntime(object): if res['result']['result']['type'] == 'undefined': return None return res['result']['result']['value'] + + def _EnableAllContexts(self, context_id): + """Allow access to iframes as necessary.""" + if context_id is not None and not self._contexts_enabled: + self._inspector_backend.SyncRequest({'method': 'Runtime.enable'}, + timeout=30) + self._contexts_enabled = True diff --git a/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime_unittest.py b/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime_unittest.py index c5687dd..ed5c47b 100644 --- a/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime_unittest.py +++ b/tools/telemetry/telemetry/core/backends/chrome/inspector_runtime_unittest.py @@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from telemetry.core import exceptions +from telemetry.core import util from telemetry.unittest import tab_test_case class InspectorRuntimeTest(tab_test_case.TabTestCase): @@ -29,3 +30,28 @@ class InspectorRuntimeTest(tab_test_case.TabTestCase): def testRuntimeExecuteOfSomethingThatCantJSONize(self): self._tab.ExecuteJavaScript('window') + + def testIFrame(self): + self._browser.SetHTTPServerDirectories(util.GetUnittestDataDir()) + self._tab.Navigate(self._browser.http_server.UrlOf('host.html')) + + # Access host page. + self._tab.WaitForJavaScriptExpression( + "typeof(testVar) != 'undefined'", timeout=5) + self.assertEquals(self._tab.EvaluateJavaScript('testVar'), 'host') + + # Access parent page using EvaluateJavaScriptInContext. + self.assertEquals(self._tab.EvaluateJavaScriptInContext('testVar', + context_id=1), 'host') + + # Access the iframes. + self.assertEquals(self._tab.EvaluateJavaScriptInContext('testVar', + context_id=2), 'iframe1') + self.assertEquals(self._tab.EvaluateJavaScriptInContext('testVar', + context_id=3), 'iframe2') + self.assertEquals(self._tab.EvaluateJavaScriptInContext('testVar', + context_id=4), 'iframe3') + + # Accessing a non-existent iframe throws an exception. + self.assertRaises(exceptions.EvaluateException, + lambda: self._tab.EvaluateJavaScriptInContext('1+1', context_id=5)) diff --git a/tools/telemetry/telemetry/core/web_contents.py b/tools/telemetry/telemetry/core/web_contents.py index 4e29c7d..a89fb04 100644 --- a/tools/telemetry/telemetry/core/web_contents.py +++ b/tools/telemetry/telemetry/core/web_contents.py @@ -51,7 +51,8 @@ class WebContents(object): If the expression failed to evaluate, EvaluateException will be raised. """ - self._inspector_backend.ExecuteJavaScript(expr, timeout) + return self.ExecuteJavaScriptInContext( + expr, context_id=None, timeout=timeout) def EvaluateJavaScript(self, expr, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): """Evalutes expr in JavaScript and returns the JSONized result. @@ -65,7 +66,24 @@ class WebContents(object): If the result of the evaluation cannot be JSONized, then an EvaluationException will be raised. """ - return self._inspector_backend.EvaluateJavaScript(expr, timeout) + return self.EvaluateJavaScriptInContext( + expr, context_id=None, timeout=timeout) + + def ExecuteJavaScriptInContext(self, expr, context_id, + timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): + """Similar to ExecuteJavaScript, except context_id can refer to an iframe. + The main page has context_id=1, the first iframe context_id=2, etc. + """ + return self._inspector_backend.ExecuteJavaScript( + expr, context_id=context_id, timeout=timeout) + + def EvaluateJavaScriptInContext(self, expr, context_id, + timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): + """Similar to ExecuteJavaScript, except context_id can refer to an iframe. + The main page has context_id=1, the first iframe context_id=2, etc. + """ + return self._inspector_backend.EvaluateJavaScript( + expr, context_id=context_id, timeout=timeout) @property def message_output_stream(self): diff --git a/tools/telemetry/unittest_data/host.html b/tools/telemetry/unittest_data/host.html new file mode 100644 index 0000000..46cfb06 --- /dev/null +++ b/tools/telemetry/unittest_data/host.html @@ -0,0 +1,12 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="text/javascript">var testVar = "host";</script> +</head> +<body> +This is the host page. +<br> +<iframe src="iframe1.html"></iframe> +<iframe src="iframe3.html"></iframe> +</body> +</html> diff --git a/tools/telemetry/unittest_data/iframe1.html b/tools/telemetry/unittest_data/iframe1.html new file mode 100644 index 0000000..972b8fb --- /dev/null +++ b/tools/telemetry/unittest_data/iframe1.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="text/javascript">var testVar="iframe1";</script> +</head> +<body> +This is IFrame 1. +<br> +<iframe src="iframe2.html"></iframe> +</body> +</html> diff --git a/tools/telemetry/unittest_data/iframe2.html b/tools/telemetry/unittest_data/iframe2.html new file mode 100644 index 0000000..778f8a0 --- /dev/null +++ b/tools/telemetry/unittest_data/iframe2.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="text/javascript">var testVar="iframe2";</script> +</head> +<body> +This is IFrame 2. +</body> +</html> diff --git a/tools/telemetry/unittest_data/iframe3.html b/tools/telemetry/unittest_data/iframe3.html new file mode 100644 index 0000000..f992152 --- /dev/null +++ b/tools/telemetry/unittest_data/iframe3.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<head> +<script type="text/javascript">var testVar="iframe3";</script> +</head> +<body> +This is IFrame 3. +</body> +</html> |