Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: telemetry/telemetry/internal/snap_page_util.py

Issue 3017573002: Make sure snap_page combined iframe serialized dom
Patch Set: . Created 3 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | telemetry/telemetry/internal/snap_page_util_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2017 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import os 5 import os
6 import json
7 import sys
6 8
7 from telemetry.core import util 9 from telemetry.core import util
8 from telemetry.internal.browser import browser_finder 10 from telemetry.internal.browser import browser_finder
9 11
10 12
13 def _TransmitLargeJSONToTab(tab, json_obj, js_holder_name):
14 tab.ExecuteJavaScript(
15 'var {{ @js_holder_name }} = "";', js_holder_name=js_holder_name)
16
17 # To avoid crashing devtool connection (details in crbug.com/763119#c16),
18 # we break down the json string to chunks which each chunk has a maximum
19 # size of 100000 characters (100000 seems to not break the connection and
20 # makes sending data reasonably fast).
21 k = 0
22 step_size = 100000
23 json_obj_string = json.dumps(json_obj)
24 while k < len(json_obj_string):
25 sub_string_chunk = json_obj_string[k: k + step_size]
26 k += step_size
27 tab.ExecuteJavaScript(
28 '{{ @js_holder_name }} += {{ sub_string_chunk }};',
29 js_holder_name=js_holder_name, sub_string_chunk=sub_string_chunk)
30
31 tab.ExecuteJavaScript(
32 '{{ @js_holder_name }} = JSON.parse({{ @js_holder_name }});',
33 js_holder_name=js_holder_name)
34
11 def SnapPage(finder_options, url, interactive, snapshot_file): 35 def SnapPage(finder_options, url, interactive, snapshot_file):
12 """ Save the HTML snapshot of the page whose address is |url| to 36 """ Save the HTML snapshot of the page whose address is |url| to
13 |snapshot_file|. 37 |snapshot_file|.
14 """ 38 """
15 possible_browser = browser_finder.FindBrowser(finder_options) 39 possible_browser = browser_finder.FindBrowser(finder_options)
16 browser = possible_browser.Create(finder_options) 40 browser = possible_browser.Create(finder_options)
17 try: 41 try:
18 tab = browser.tabs[0] 42 tab = browser.tabs[0]
19 tab.Navigate(url) 43 tab.Navigate(url)
20 tab.WaitForDocumentReadyStateToBeComplete()
21 if interactive: 44 if interactive:
22 raw_input( 45 raw_input(
23 'Activating interactive mode. Press enter after you finish ' 46 'Activating interactive mode. Press enter after you finish '
24 "interacting with the page to snapshot the page's DOM content.") 47 "interacting with the page to snapshot the page's DOM content.")
25 with open( 48
26 os.path.join(util.GetTelemetryThirdPartyDir(), 'snap-it', 49 sys.stdout.write(
27 'HTMLSerializer.js')) as f: 50 'Snapshotting content of %s. This could take a while...\n' % url)
51 tab.WaitForDocumentReadyStateToBeComplete()
52 tab.action_runner.WaitForNetworkQuiescence()
53
54 with open(os.path.join(util.GetTelemetryThirdPartyDir(), 'snap-it',
55 'HTMLSerializer.js')) as f:
28 snapit_script = f.read() 56 snapit_script = f.read()
29 tab.ExecuteJavaScript(snapit_script) 57
30 tab.ExecuteJavaScript( 58 with open(os.path.join(util.GetTelemetryThirdPartyDir(), 'snap-it',
31 ''' 59 'popup.js')) as f:
32 var serializedDomArray; 60 dom_combining_script = f.read()
33 var htmlSerializer = new HTMLSerializer(); 61
34 htmlSerializer.processDocument(document); 62 serialized_doms = []
35 htmlSerializer.fillHolesAsync(document, function(s) { 63
36 serializedDomArray = s.html; 64 # Serialize the dom in each frame.
37 }); 65 for context_id in tab.EnableAllContexts():
38 ''') 66 tab.ExecuteJavaScript(snapit_script, context_id=context_id)
39 print 'Snapshotting content of %s. This could take a while...' % url 67 tab.ExecuteJavaScript(
40 tab.WaitForJavaScriptCondition('serializedDomArray !== undefined') 68 '''
41 serialized_dom = ''.join(tab.EvaluateJavaScript('serializedDomArray')) 69 var serializedDom;
42 snapshot_file.write(serialized_dom) 70 var htmlSerializer = new HTMLSerializer();
71 htmlSerializer.processDocument(document);
72 htmlSerializer.fillHolesAsync(document, function(s) {
73 serializedDom = s.asDict();
74 });
75 ''', context_id=context_id)
76 tab.WaitForJavaScriptCondition(
77 'serializedDom !== undefined', context_id=context_id)
78 serialized_doms.append(tab.EvaluateJavaScript(
79 'serializedDom', context_id=context_id))
80
81 # Execute doms combining code in blank page to minimize the chance of V8
82 # OOM.
83 tab.Navigate('about:blank')
84 tab.WaitForDocumentReadyStateToBeComplete()
85
86 # Sending all the serialized doms back to tab execution context.
87 tab.ExecuteJavaScript('var serializedDoms = [];')
88 for i in xrange(len(serialized_doms)):
89 sys.stdout.write('Processing dom of frame #%i / %i\r' %
90 (i, len(serialized_doms)))
91 sys.stdout.flush()
92 _TransmitLargeJSONToTab(tab, serialized_doms[i], 'sub_dom')
93 tab.ExecuteJavaScript('serializedDoms.push(sub_dom);')
94
95 # Combine all the doms to one HTML string.
96 tab.EvaluateJavaScript(dom_combining_script)
97 page_snapshot = tab.EvaluateJavaScript('outputHTMLString(serializedDoms);')
98
99 snapshot_file.write(page_snapshot)
43 finally: 100 finally:
44 browser.Close() 101 browser.Close()
OLDNEW
« no previous file with comments | « no previous file | telemetry/telemetry/internal/snap_page_util_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698