15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""SiteCompare command to time page loads 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loads a series of URLs in a series of browsers (and browser versions) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)and measures how long the page takes to load in each. Outputs a 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)comma-delimited file. The first line is "URL,[browser names", each 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)additional line is a URL follored by comma-delimited times (in seconds), 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)or the string "timeout" or "crashed". 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os # Functions for walking the directory tree 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import tempfile # Get a temporary directory to hold intermediates 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import command_line 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import drivers # Functions for driving keyboard/mouse/windows, OS-specific 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import operators # Functions that, given two bitmaps as input, produce 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # output depending on the performance of an operation 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import scrapers # Functions that know how to capture a render from 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # particular browsers 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def CreateCommand(cmdline): 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Inserts the command and arguments into a command line for parsing.""" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd = cmdline.AddCommand( 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["timeload"], 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Measures how long a series of URLs takes to load in one or more browsers.", 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) None, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExecuteTimeLoad) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-b", "--browsers"], "List of browsers to use. Comma-separated", 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type="string", required=True) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-bp", "--browserpaths"], "List of paths to browsers. Comma-separated", 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type="string", required=False) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-bv", "--browserversions"], 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "List of versions of browsers. Comma-separated", 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type="string", required=False) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-u", "--url"], "URL to time") 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-l", "--list"], "List of URLs to time", type="readfile") 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddMutualExclusion(["--url", "--list"]) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-s", "--startline"], "First line of URL list", type="int") 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-e", "--endline"], "Last line of URL list (exclusive)", type="int") 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-c", "--count"], "Number of lines of URL file to use", type="int") 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddDependency("--startline", "--list") 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddRequiredGroup(["--url", "--list"]) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddDependency("--endline", "--list") 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddDependency("--count", "--list") 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddMutualExclusion(["--count", "--endline"]) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddDependency("--count", "--startline") 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-t", "--timeout"], "Amount of time (seconds) to wait for browser to " 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "finish loading", 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type="int", default=60) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-log", "--logfile"], "File to write output", type="string", required=True) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cmd.AddArgument( 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ["-sz", "--size"], "Browser window size", default=(800, 600), type="coords") 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def ExecuteTimeLoad(command): 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Executes the TimeLoad command.""" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browsers = command["--browsers"].split(",") 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_browsers = len(browsers) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if command["--browserversions"]: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_versions = command["--browserversions"].split(",") 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_versions = [None] * num_browsers 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if command["--browserpaths"]: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_paths = command["--browserpaths"].split(",") 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_paths = [None] * num_browsers 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(browser_versions) != num_browsers: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ValueError( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--browserversions must be same length as --browser_paths") 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(browser_paths) != num_browsers: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ValueError( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "--browserversions must be same length as --browser_paths") 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if [b for b in browsers if b not in ["chrome", "ie", "firefox"]]: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ValueError("unknown browsers: %r" % b) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scraper_list = [] 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for b in xrange(num_browsers): 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version = browser_versions[b] 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not version: version = None 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scraper = scrapers.GetScraper( (browsers[b], version) ) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not scraper: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ValueError("could not find scraper for (%r, %r)" % 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (browsers[b], version)) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scraper_list.append(scraper) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if command["--url"]: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_list = [command["--url"]] 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) startline = command["--startline"] 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if command["--count"]: 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) endline = startline+command["--count"] 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) endline = command["--endline"] 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_list = [url.strip() for url in 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open(command["--list"], "r").readlines()[startline:endline]] 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file = open(command["--logfile"], "w") 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.write("URL") 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for b in xrange(num_browsers): 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.write(",%s" % browsers[b]) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if browser_versions[b]: log_file.write(" %s" % browser_versions[b]) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.write("\n") 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results = {} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for url in url_list: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results[url] = [None] * num_browsers 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for b in xrange(num_browsers): 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = scraper_list[b].Time(url_list, command["--size"], 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command["--timeout"], 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path=browser_paths[b]) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (url, time) in result: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results[url][b] = time 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # output the results 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for url in url_list: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.write(url) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for b in xrange(num_browsers): 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.write(",%r" % results[url][b]) 145