# Copyright (c) 2011 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """SiteCompare command to invoke the same page in two versions of a browser. Does the easiest compatibility test: equality comparison between two different versions of the same browser. Invoked with a series of command line options that specify which URLs to check, which browser to use, where to store results, etc. """ import os # Functions for walking the directory tree import tempfile # Get a temporary directory to hold intermediates import command_line import drivers # Functions for driving keyboard/mouse/windows, OS-specific import operators # Functions that, given two bitmaps as input, produce # output depending on the performance of an operation import scrapers # Functions that know how to capture a render from # particular browsers def CreateCommand(cmdline): """Inserts the command and arguments into a command line for parsing.""" cmd = cmdline.AddCommand( ["compare2"], "Compares the output of two browsers on the same URL or list of URLs", ValidateCompare2, ExecuteCompare2) cmd.AddArgument( ["-b1", "--browser1"], "Full path to first browser's executable", type="readfile", metaname="PATH", required=True) cmd.AddArgument( ["-b2", "--browser2"], "Full path to second browser's executable", type="readfile", metaname="PATH", required=True) cmd.AddArgument( ["-b", "--browser"], "Which browser to use", type="string", default="chrome") cmd.AddArgument( ["-b1v", "--browser1ver"], "Version of first browser", metaname="VERSION") cmd.AddArgument( ["-b2v", "--browser2ver"], "Version of second browser", metaname="VERSION") cmd.AddArgument( ["-b1n", "--browser1name"], "Optional name for first browser (used in " "directory to hold intermediate files)", metaname="NAME") cmd.AddArgument( ["-b2n", "--browser2name"], "Optional name for second browser (used in " "directory to hold intermediate files)", metaname="NAME") cmd.AddArgument( ["-o", "--outdir"], "Directory to store scrape files", metaname="DIR") cmd.AddArgument( ["-u", "--url"], "URL to compare") cmd.AddArgument( ["-l", "--list"], "List of URLs to compare", type="readfile") cmd.AddMutualExclusion(["--url", "--list"]) cmd.AddArgument( ["-s", "--startline"], "First line of URL list", type="int") cmd.AddArgument( ["-e", "--endline"], "Last line of URL list (exclusive)", type="int") cmd.AddArgument( ["-c", "--count"], "Number of lines of URL file to use", type="int") cmd.AddDependency("--startline", "--list") cmd.AddRequiredGroup(["--url", "--list"]) cmd.AddDependency("--endline", "--list") cmd.AddDependency("--count", "--list") cmd.AddMutualExclusion(["--count", "--endline"]) cmd.AddDependency("--count", "--startline") cmd.AddArgument( ["-t", "--timeout"], "Amount of time (seconds) to wait for browser to " "finish loading", type="int", default=60) cmd.AddArgument( ["-log", "--logfile"], "File to write output", type="string", required=True) cmd.AddArgument( ["-sz", "--size"], "Browser window size", default=(800, 600), type="coords") cmd.AddArgument( ["-m", "--maskdir"], "Path that holds masks to use for comparison") cmd.AddArgument( ["-d", "--diffdir"], "Path to hold the difference of comparisons that fail") def ValidateCompare2(command): """Validate the arguments to compare2. Raises ParseError if failed.""" executables = [".exe", ".com", ".bat"] if (os.path.splitext(command["--browser1"])[1].lower() not in executables or os.path.splitext(command["--browser2"])[1].lower() not in executables): raise command_line.ParseError("Browser filename must be an executable") def ExecuteCompare2(command): """Executes the Compare2 command.""" if command["--url"]: url_list = [command["--url"]] else: startline = command["--startline"] if command["--count"]: endline = startline+command["--count"] else: endline = command["--endline"] url_list = [url.strip() for url in open(command["--list"], "r").readlines()[startline:endline]] log_file = open(command["--logfile"], "w") outdir = command["--outdir"] if not outdir: outdir = tempfile.gettempdir() scrape_info_list = [] class ScrapeInfo(object): """Helper class to hold information about a scrape.""" __slots__ = ["browser_path", "scraper", "outdir", "result"] for index in xrange(1, 3): scrape_info = ScrapeInfo() scrape_info.browser_path = command["--browser%d" % index] scrape_info.scraper = scrapers.GetScraper( (command["--browser"], command["--browser%dver" % index])) if command["--browser%dname" % index]: scrape_info.outdir = os.path.join(outdir, command["--browser%dname" % index]) else: scrape_info.outdir = os.path.join(outdir, str(index)) drivers.windowing.PreparePath(scrape_info.outdir) scrape_info_list.append(scrape_info) compare = operators.GetOperator("equals_with_mask") for url in url_list: success = True for scrape_info in scrape_info_list: scrape_info.result = scrape_info.scraper.Scrape( [url], scrape_info.outdir, command["--size"], (0, 0), command["--timeout"], path=scrape_info.browser_path) if not scrape_info.result: scrape_info.result = "success" else: success = False result = "unknown" if success: result = "equal" file1 = drivers.windowing.URLtoFilename( url, scrape_info_list[0].outdir, ".bmp") file2 = drivers.windowing.URLtoFilename( url, scrape_info_list[1].outdir, ".bmp") comparison_result = compare.Compare(file1, file2, maskdir=command["--maskdir"]) if comparison_result is not None: result = "not-equal" if command["--diffdir"]: comparison_result[1].save( drivers.windowing.URLtoFilename(url, command["--diffdir"], ".bmp")) # TODO(jhaas): maybe use the logging module rather than raw file writes log_file.write("%s %s %s %s\n" % (url, scrape_info_list[0].result, scrape_info_list[1].result, result))