1 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 """SiteCompare command to invoke the same page in two versions of a browser.
7 Does the easiest compatibility test: equality comparison between two different
8 versions of the same browser. Invoked with a series of command line options
9 that specify which URLs to check, which browser to use, where to store results,
13 import os
# Functions for walking the directory tree
14 import tempfile
# Get a temporary directory to hold intermediates
17 import drivers
# Functions for driving keyboard/mouse/windows, OS-specific
18 import operators
# Functions that, given two bitmaps as input, produce
19 # output depending on the performance of an operation
20 import scrapers
# Functions that know how to capture a render from
24 def CreateCommand(cmdline
):
25 """Inserts the command and arguments into a command line for parsing."""
26 cmd
= cmdline
.AddCommand(
28 "Compares the output of two browsers on the same URL or list of URLs",
33 ["-b1", "--browser1"], "Full path to first browser's executable",
34 type="readfile", metaname
="PATH", required
=True)
36 ["-b2", "--browser2"], "Full path to second browser's executable",
37 type="readfile", metaname
="PATH", required
=True)
39 ["-b", "--browser"], "Which browser to use", type="string",
42 ["-b1v", "--browser1ver"], "Version of first browser", metaname
="VERSION")
44 ["-b2v", "--browser2ver"], "Version of second browser", metaname
="VERSION")
46 ["-b1n", "--browser1name"], "Optional name for first browser (used in "
47 "directory to hold intermediate files)", metaname
="NAME")
49 ["-b2n", "--browser2name"], "Optional name for second browser (used in "
50 "directory to hold intermediate files)", metaname
="NAME")
52 ["-o", "--outdir"], "Directory to store scrape files", metaname
="DIR")
54 ["-u", "--url"], "URL to compare")
56 ["-l", "--list"], "List of URLs to compare", type="readfile")
57 cmd
.AddMutualExclusion(["--url", "--list"])
59 ["-s", "--startline"], "First line of URL list", type="int")
61 ["-e", "--endline"], "Last line of URL list (exclusive)", type="int")
63 ["-c", "--count"], "Number of lines of URL file to use", type="int")
64 cmd
.AddDependency("--startline", "--list")
65 cmd
.AddRequiredGroup(["--url", "--list"])
66 cmd
.AddDependency("--endline", "--list")
67 cmd
.AddDependency("--count", "--list")
68 cmd
.AddMutualExclusion(["--count", "--endline"])
69 cmd
.AddDependency("--count", "--startline")
71 ["-t", "--timeout"], "Amount of time (seconds) to wait for browser to "
73 type="int", default
=60)
75 ["-log", "--logfile"], "File to write output", type="string", required
=True)
77 ["-sz", "--size"], "Browser window size", default
=(800, 600), type="coords")
79 ["-m", "--maskdir"], "Path that holds masks to use for comparison")
81 ["-d", "--diffdir"], "Path to hold the difference of comparisons that fail")
84 def ValidateCompare2(command
):
85 """Validate the arguments to compare2. Raises ParseError if failed."""
86 executables
= [".exe", ".com", ".bat"]
87 if (os
.path
.splitext(command
["--browser1"])[1].lower() not in executables
or
88 os
.path
.splitext(command
["--browser2"])[1].lower() not in executables
):
89 raise command_line
.ParseError("Browser filename must be an executable")
92 def ExecuteCompare2(command
):
93 """Executes the Compare2 command."""
95 url_list
= [command
["--url"]]
97 startline
= command
["--startline"]
98 if command
["--count"]:
99 endline
= startline
+command
["--count"]
101 endline
= command
["--endline"]
102 url_list
= [url
.strip() for url
in
103 open(command
["--list"], "r").readlines()[startline
:endline
]]
105 log_file
= open(command
["--logfile"], "w")
107 outdir
= command
["--outdir"]
108 if not outdir
: outdir
= tempfile
.gettempdir()
110 scrape_info_list
= []
112 class ScrapeInfo(object):
113 """Helper class to hold information about a scrape."""
114 __slots__
= ["browser_path", "scraper", "outdir", "result"]
116 for index
in xrange(1, 3):
117 scrape_info
= ScrapeInfo()
118 scrape_info
.browser_path
= command
["--browser%d" % index
]
119 scrape_info
.scraper
= scrapers
.GetScraper(
120 (command
["--browser"], command
["--browser%dver" % index
]))
122 if command
["--browser%dname" % index
]:
123 scrape_info
.outdir
= os
.path
.join(outdir
,
124 command
["--browser%dname" % index
])
126 scrape_info
.outdir
= os
.path
.join(outdir
, str(index
))
128 drivers
.windowing
.PreparePath(scrape_info
.outdir
)
129 scrape_info_list
.append(scrape_info
)
131 compare
= operators
.GetOperator("equals_with_mask")
136 for scrape_info
in scrape_info_list
:
137 scrape_info
.result
= scrape_info
.scraper
.Scrape(
138 [url
], scrape_info
.outdir
, command
["--size"], (0, 0),
139 command
["--timeout"], path
=scrape_info
.browser_path
)
141 if not scrape_info
.result
:
142 scrape_info
.result
= "success"
151 file1
= drivers
.windowing
.URLtoFilename(
152 url
, scrape_info_list
[0].outdir
, ".bmp")
153 file2
= drivers
.windowing
.URLtoFilename(
154 url
, scrape_info_list
[1].outdir
, ".bmp")
156 comparison_result
= compare
.Compare(file1
, file2
,
157 maskdir
=command
["--maskdir"])
159 if comparison_result
is not None:
162 if command
["--diffdir"]:
163 comparison_result
[1].save(
164 drivers
.windowing
.URLtoFilename(url
, command
["--diffdir"], ".bmp"))
166 # TODO(jhaas): maybe use the logging module rather than raw file writes
167 log_file
.write("%s %s %s %s\n" % (url
,
168 scrape_info_list
[0].result
,
169 scrape_info_list
[1].result
,