Index: tests/selenium/main.py |
=================================================================== |
--- tests/selenium/main.py (revision 26154) |
+++ tests/selenium/main.py (working copy) |
@@ -61,12 +61,13 @@ |
import unittest |
import gflags |
import javascript_unit_tests |
-# Import custom testrunner for pulse |
-import pulse_testrunner |
+import test_runner |
import selenium |
import samples_tests |
import selenium_constants |
import selenium_utilities |
+import pdiff_test |
+import Queue |
if sys.platform == 'win32' or sys.platform == 'cygwin': |
default_java_exe = "java.exe" |
@@ -114,6 +115,7 @@ |
"30", |
"Specifies the timeout value, in seconds, for the selenium server.") |
+ |
# Browsers to choose from (for browser flag). |
# use --browser $BROWSER_NAME to run |
# tests for that browser |
@@ -133,7 +135,6 @@ |
"", |
"specifies the path from the web root to the samples.") |
- |
class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): |
"""Hook to handle HTTP server requests. |
@@ -147,7 +148,9 @@ |
pass |
# TODO: might be nice to have a verbose option for debugging. |
+ |
+ |
class LocalFileHTTPServer(threading.Thread): |
"""Minimal HTTP server that serves local files. |
@@ -348,139 +351,106 @@ |
return selenium_server |
-class SeleniumSession(object): |
- """A selenium browser session, with support servers. |
+class SeleniumSessionBuilder: |
+ def __init__(self, sel_port, sel_timeout, http_port, browserpath): |
- The support servers include a Selenium Remote Control server, and |
- a local HTTP server to serve static test files. |
+ self.sel_port = sel_port |
+ self.sel_timeout = sel_timeout |
+ self.http_port = http_port |
+ self.browserpath = browserpath |
- Members: |
- session: a selenium() instance |
- selenium_server: a SeleniumRemoteControl() instance |
- http_server: a LocalFileHTTPServer() instance |
- runner: a TestRunner() instance |
- """ |
- |
- def __init__(self, verbose, java_path, selenium_server, server_timeout, |
- http_root=None): |
- """Initializes a Selenium Session. |
- |
- Args: |
- verbose: boolean verbose flag |
- java_path: path to java used to run selenium. |
- selenium_server: path to jar containing selenium server. |
- server_timeout: server timeout value, in seconds. |
- http_root: Serve http pages using this path as the document root. When |
- None, use the default. |
- """ |
- # Start up a static file server, to serve the test pages. |
- |
- if not http_root: |
- http_root = FLAGS.product_dir |
- |
- self.http_server = LocalFileHTTPServer.StartServer(http_root) |
- |
- if self.http_server: |
- # Start up the Selenium Remote Control Server |
- self.selenium_server = SeleniumRemoteControl.StartServer(verbose, |
- java_path, |
- selenium_server, |
- server_timeout) |
- if not self.http_server or not self.selenium_server: |
- return |
- |
- # Set up a testing runner |
- self.runner = pulse_testrunner.PulseTestRunner() |
- |
- # Set up a phantom selenium session so we can call shutdown if needed. |
- self.session = selenium.selenium( |
- "localhost", self.selenium_server.selenium_port, "*firefox", |
- "http://" + socket.gethostname() + ":" + |
- str(self.http_server.http_port)) |
- |
- def StartSession(self, browser): |
- """Starts the Selenium Session and connects to the HTTP server. |
- |
- Args: |
- browser: selenium browser name |
- """ |
- |
+ def NewSeleniumSession(self, browser): |
if browser == "*googlechrome": |
# TODO: Replace socket.gethostname() with "localhost" |
# once Chrome local proxy fix is in. |
server_url = "http://" + socket.gethostname() + ":" |
else: |
server_url = "http://localhost:" |
- server_url += str(self.http_server.http_port) |
+ server_url += str(self.http_port) |
browser_path_with_space = "" |
- if FLAGS.browserpath: |
- browser_path_with_space = " " + FLAGS.browserpath |
+ if self.browserpath: |
+ browser_path_with_space = " " + self.browserpath |
- self.session = selenium.selenium("localhost", |
- self.selenium_server.selenium_port, |
- browser + browser_path_with_space, |
- server_url) |
- self.session.start() |
- def CloseSession(self): |
- """Closes the selenium sesssion.""" |
- self.session.stop() |
+ new_session = selenium.selenium("localhost", |
+ self.sel_port, |
+ browser + browser_path_with_space, |
+ server_url) |
+ |
+ new_session.start() |
+ new_session.set_timeout(self.sel_timeout) |
+ |
+ return new_session |
- def TearDown(self): |
- """Stops the selenium server.""" |
- self.session.shut_down_selenium_server() |
- def TestBrowser(self, browser, test_list, test_prefix, test_suffixes, |
- server_timeout): |
- """Runs Selenium tests for a specific browser. |
+def TestBrowser(session_builder, browser, test_list): |
+ """Runs Selenium tests for a specific browser. |
- Args: |
- browser: selenium browser name (eg. *iexplore, *firefox). |
- test_list: list to add tests to. |
- test_prefix: prefix of tests to run. |
- test_suffixes: comma separated suffixes of tests to run. |
- server_timeout: server timeout value, in milliseconds |
+ Args: |
+ session_builder: session_builder for creating new selenium sessions. |
+ browser: selenium browser name (eg. *iexplore, *firefox). |
+ test_list: list of tests. |
+ |
+ Returns: |
+ summary_result: result of test runners. |
+ """ |
+ print "Testing %s..." % browser |
+ |
+ summary_result = test_runner.TestResult(test_runner.StringBuffer(), browser) |
+ |
+ # Fill up the selenium test queue. |
+ test_queue = Queue.Queue() |
+ for test in test_list: |
+ test_queue.put(test) |
- Returns: |
- result: result of test runner. |
- """ |
- print "Testing %s..." % browser |
- self.StartSession(browser) |
- self.session.set_timeout(server_timeout) |
- self.runner.setBrowser(browser) |
- try: |
- result = self.runner.run( |
- SeleniumSuite(self.session, browser, test_list, |
- test_prefix, test_suffixes)) |
- finally: |
- self.CloseSession() |
+ pdiff_queue = None |
+ if FLAGS.screenshots: |
+ # Need to do screen comparisons. |
+ # |pdiff_queue| is the queue of perceptual diff tests that need to be done. |
+ # This queue is added to by individual slenium test runners. |
+ # |pdiff_result_queue| is the result of the perceptual diff tests. |
+ pdiff_queue = Queue.Queue() |
+ pdiff_result_queue = Queue.Queue() |
+ pdiff_worker = test_runner.PDiffTestRunner(pdiff_queue, |
+ pdiff_result_queue, |
+ browser) |
+ pdiff_worker.start() |
+ |
+ # Start initial selenium test runner. |
+ worker = test_runner.SeleniumTestRunner(session_builder, browser, |
+ test_queue, pdiff_queue) |
+ worker.start() |
- return result |
+ # Run through all selenium tests. |
+ while not worker.IsCompletelyDone(): |
+ if worker.IsTesting() and worker.IsPastDeadline(): |
+ # Test has taken more than allotted. Abort and go to next test. |
+ worker.AbortTest() |
+ elif worker.DidFinishTest(): |
+ # Do this so that a worker does not grab test off queue till we tell it. |
+ result = worker.Continue() |
+ result.printAll(sys.stdout) |
+ summary_result.merge(result) |
-class LocalTestSuite(unittest.TestSuite): |
- """Wrapper for unittest.TestSuite so we can collect the tests.""" |
+ if FLAGS.screenshots: |
+ # Finish screenshot comparisons. |
+ pdiff_worker.EndTesting() |
+ while not pdiff_worker.IsCompletelyDone(): |
+ time.sleep(1) |
- def __init__(self): |
- unittest.TestSuite.__init__(self) |
- self.test_list = [] |
+ # Be careful here, make sure no one else is editing |pdiff_reult_queue|. |
+ while not pdiff_result_queue.empty(): |
+ result = pdiff_result_queue.get() |
+ result.printAll(sys.stdout) |
+ summary_result.merge(result) |
+ |
+ return summary_result |
- def addTest(self, name, test): |
- """Adds a test to the TestSuite and records its name and test_path. |
- Args: |
- name: name of test. |
- test: test to pass to unittest.TestSuite. |
- """ |
- unittest.TestSuite.addTest(self, test) |
- try: |
- self.test_list.append((name, test.options)) |
- except AttributeError: |
- self.test_list.append((name, [])) |
- |
def MatchesSuffix(name, suffixes): |
"""Checks if a name ends in one of the suffixes. |
@@ -500,21 +470,20 @@ |
return True |
-def AddTests(test_suite, session, browser, module, filename, prefix, |
- test_prefix_filter, test_suffixes, path_to_html): |
- """Add tests defined in filename. |
+def _GetTestsFromFile(filename, prefix, test_prefix_filter, test_suffixes, |
+ browser, module, path_to_html): |
+ """Add tests defined in filename, and associated perceptual diff test, if |
+ needed. |
Assumes module has a method "GenericTest" that uses self.args to run. |
Args: |
- test_suite: A Selenium test_suite to add tests to. |
- session: a Selenium instance. |
- browser: browser name. |
- module: module which will have method GenericTest() called to run each test. |
filename: filename of file with list of tests. |
prefix: prefix to add to the beginning of each test. |
test_prefix_filter: Only adds a test if it starts with this. |
test_suffixes: list of suffixes to filter by. An empty list = pass all. |
+ browser: browser name. |
+ module: module which will have method GenericTest() called to run each test. |
path_to_html: Path from server root to html |
""" |
# See comments in that file for the expected format. |
@@ -524,6 +493,8 @@ |
samples = test_list_file.readlines() |
test_list_file.close() |
+ tests = [] |
+ |
for sample in samples: |
sample = sample.strip() |
if not sample or sample[0] == ";" or sample[0] == "#": |
@@ -535,13 +506,17 @@ |
options = arguments[2:] |
# TODO: Add filter based on test_type |
+ if test_path.startswith("Test"): |
+ name = test_path |
+ else: |
+ # Need to make a name. |
+ name = ("Test" + prefix + re.sub("\W", "_", test_path) + |
+ test_type.capitalize()) |
- name = ("Test" + prefix + re.sub("\W", "_", test_path) + |
- test_type.capitalize()) |
- |
# Only execute this test if the current browser is not in the list |
# of skipped browsers. |
test_skipped = False |
+ screenshot_count = 0 |
for option in options: |
if option.startswith("except"): |
skipped_platforms = selenium_utilities.GetArgument(option) |
@@ -549,390 +524,92 @@ |
skipped_platforms = skipped_platforms.split(",") |
if browser in skipped_platforms: |
test_skipped = True |
+ elif option.startswith("screenshots"): |
+ screenshot_count += int(selenium_utilities.GetArgument(option)) |
+ elif option.startswith("screenshot"): |
+ screenshot_count += 1 |
+ if (test_prefix_filter and not name.startswith(test_prefix_filter) or |
+ test_suffixes and not MatchesSuffix(name, test_suffixes)): |
+ test_skipped = True |
+ |
if not test_skipped: |
- # Check if there is already a test function by this name in the module. |
- if (test_path.startswith(test_prefix_filter) and |
- hasattr(module, test_path) and callable(getattr(module, test_path))): |
- test_suite.addTest(test_path, module(test_path, session, browser, |
- path_to_html, options=options)) |
- elif (name.startswith(test_prefix_filter) and |
- MatchesSuffix(name, test_suffixes)): |
- # no, so add a method that will run a test generically. |
+ # Add a test method with this name if it doesn't exist. |
+ if not (hasattr(module, name) and callable(getattr(module, name))): |
setattr(module, name, module.GenericTest) |
- test_suite.addTest(name, module(name, session, browser, path_to_html, |
- test_type, test_path, options)) |
+ |
+ new_test = module(name, browser, path_to_html, test_type, test_path, |
+ options) |
+ |
+ if screenshot_count and FLAGS.screenshots: |
+ pdiff_name = name + 'Screenshots' |
+ screenshot = selenium_utilities.ScreenshotNameFromTestName(test_path) |
+ setattr(pdiff_test.PDiffTest, pdiff_name, |
+ pdiff_test.PDiffTest.PDiffTest) |
+ new_pdiff = pdiff_test.PDiffTest(pdiff_name, |
+ screenshot_count, |
+ screenshot, |
+ FLAGS.screencompare, |
+ FLAGS.screenshotsdir, |
+ FLAGS.referencedir, |
+ options) |
+ tests += [(new_test, new_pdiff)] |
+ else: |
+ tests += [new_test] |
+ |
+ return tests |
-def SeleniumSuite(session, browser, test_list, test_prefix, test_suffixes): |
- """Creates a test suite to run the unit tests. |
+def GetTestsForBrowser(browser, test_prefix, test_suffixes): |
+ """Returns list of tests from test files. |
+ |
Args: |
- session: a selenium() instance |
browser: browser name |
- test_list: list to add tests to. |
test_prefix: prefix of tests to run. |
test_suffixes: A comma separated string of suffixes to filter by. |
Returns: |
- A selenium test suite. |
+ A list of unittest.TestCase. |
""" |
- |
- test_suite = LocalTestSuite() |
- |
+ tests = [] |
suffixes = test_suffixes.split(",") |
# add sample tests. |
filename = os.path.abspath(os.path.join(script_dir, "sample_list.txt")) |
- AddTests(test_suite, |
- session, |
- browser, |
- samples_tests.SampleTests, |
- filename, |
- "Sample", |
- test_prefix, |
- suffixes, |
- FLAGS.samplespath.replace("\\", "/")) |
- |
+ tests += _GetTestsFromFile(filename, "Sample", test_prefix, suffixes, browser, |
+ samples_tests.SampleTests, |
+ FLAGS.samplespath.replace("\\","/")) |
+ |
# add javascript tests. |
filename = os.path.abspath(os.path.join(script_dir, |
"javascript_unit_test_list.txt")) |
- AddTests(test_suite, |
- session, |
- browser, |
- javascript_unit_tests.JavaScriptUnitTests, |
- filename, |
- "UnitTest", |
- test_prefix, |
- suffixes, |
- '') |
+ tests += _GetTestsFromFile(filename, "UnitTest", test_prefix, suffixes, |
+ browser, javascript_unit_tests.JavaScriptUnitTests, |
+ "") |
- test_list += test_suite.test_list |
+ return tests |
- return test_suite |
+def GetChromePath(): |
+ value = None |
+ if sys.platform == "win32" or sys.platform == "cygwin": |
+ import _winreg |
+ try: |
+ key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, |
+ "Applications\\chrome.exe\\shell\\open\\command") |
+ (value, type) = _winreg.QueryValueEx(key, None) |
+ _winreg.CloseKey(key) |
+ value = os.path.dirname(value) |
+ |
+ except WindowsError: |
+ value = None |
+ if '*googlechrome' in FLAGS.browser: |
+ raise Exception("Unable to determine location for Chrome -- " + |
+ "is it installed?") |
+ |
+ return value |
-def CompareScreenshots(browser, test_list, screencompare, screenshotsdir, |
- screencompare_tool, verbose): |
- """Performs the image validation for test-case frame captures. |
- Args: |
- browser: selenium browser name |
- test_list: list of tests that ran. |
- screencompare: True to actually run tests. |
- screenshotsdir: path of directory containing images to compare. |
- screencompare_tool: path to image diff tool. |
- verbose: If True then outputs verbose info. |
- |
- Returns: |
- A Results object. |
- """ |
- print "Validating captured frames against reference data..." |
- |
- class Results(object): |
- """An object to return results of screenshot compares. |
- |
- Similar to unittest.TestResults. |
- """ |
- |
- def __init__(self): |
- object.__init__(self) |
- self.tests_run = 0 |
- self.current_test = None |
- self.errors = [] |
- self.failures = [] |
- self.start_time = 0 |
- |
- def StartTest(self, test): |
- """Adds a test. |
- |
- Args: |
- test: name of test. |
- """ |
- self.start_time = time.time() |
- self.tests_run += 1 |
- self.current_test = test |
- |
- def TimeTaken(self): |
- """Returns the time since the last call to StartTest.""" |
- return time.time() - self.start_time |
- |
- def AddFailure(self, test, browser, message): |
- """Adds a failure. |
- |
- Args: |
- test: name of the test. |
- browser: name of the browser. |
- message: error message to print |
- """ |
- self.failures.append(test) |
- print "ERROR: ", message |
- print("SELENIUMRESULT %s <%s> [%.3fs]: FAIL" |
- % (test, browser, self.TimeTaken())) |
- |
- def AddSuccess(self, test): |
- """Adds a success. |
- |
- Args: |
- test: name of the test. |
- """ |
- print("SELENIUMRESULT %s <%s> [%.3fs]: PASS" |
- % (test, browser, self.TimeTaken())) |
- |
- def WasSuccessful(self): |
- """Returns true if all tests were successful.""" |
- return not self.errors and not self.failures |
- |
- results = Results() |
- |
- if not screencompare: |
- return results |
- |
- base_path = os.getcwd() |
- |
- reference_files = os.listdir(os.path.join( |
- base_path, |
- selenium_constants.REFERENCE_SCREENSHOT_PATH)) |
- |
- generated_files = os.listdir(os.path.join(base_path, screenshotsdir)) |
- |
- # Prep the test list for matching |
- temp = [] |
- for (test, options) in test_list: |
- test = selenium_utilities.StripTestTypeSuffix(test) |
- temp.append((test.lower(), options)) |
- test_list = temp |
- |
- # Create regex object for filename |
- # file is in format "FILENAME_reference.png" |
- reference_file_name_regex = re.compile(r"^(.*)_reference\.png") |
- generated_file_name_regex = re.compile(r"^(.*)\.png") |
- |
- # check that there is a reference file for each generated file. |
- for file_name in generated_files: |
- match = generated_file_name_regex.search(file_name) |
- |
- if match is None: |
- # no matches |
- continue |
- |
- # Generated file name without png extension |
- actual_name = match.group(1) |
- |
- # Get full paths to reference and generated files |
- reference_file = os.path.join( |
- base_path, |
- selenium_constants.REFERENCE_SCREENSHOT_PATH, |
- actual_name + "_reference.png") |
- generated_file = os.path.join( |
- base_path, |
- screenshotsdir, |
- actual_name + ".png") |
- |
- test_name = "TestReferenceScreenshotExists_" + actual_name |
- results.StartTest(test_name) |
- if not os.path.exists(reference_file): |
- # reference file does not exist |
- results.AddFailure( |
- test_name, browser, |
- "Missing reference file %s for generated file %s." % |
- (reference_file, generated_file)) |
- else: |
- results.AddSuccess(test_name) |
- |
- # Assuming both the result and reference image sets are the same size, |
- # verify that corresponding images are similar within tolerance. |
- for file_name in reference_files: |
- match = reference_file_name_regex.search(file_name) |
- |
- if match is None: |
- # no matches |
- continue |
- |
- # Generated file name without png extension |
- actual_name = match.group(1) |
- # Get full paths to reference and generated files |
- reference_file = os.path.join( |
- base_path, |
- selenium_constants.REFERENCE_SCREENSHOT_PATH, |
- file_name) |
- platform_specific_reference_file = os.path.join( |
- base_path, |
- selenium_constants.PLATFORM_SPECIFIC_REFERENCE_SCREENSHOT_PATH, |
- actual_name + "_reference.png") |
- generated_file = os.path.join( |
- base_path, |
- screenshotsdir, |
- actual_name + ".png") |
- |
- # Generate a test case name |
- test_name = "TestScreenCompare_" + actual_name |
- |
- # skip the reference file if the test is not in the test list. |
- basename = os.path.splitext(os.path.basename(file_name))[0] |
- basename = re.sub("\d+_reference", "", basename).lower() |
- basename = re.sub("\W", "_", basename) |
- test_was_run = False |
- test_options = [] |
- for (test, options) in test_list: |
- if test.endswith(basename): |
- test_was_run = True |
- test_options = options or [] |
- break |
- |
- if test_was_run: |
- results.StartTest(test_name) |
- else: |
- # test was not planned to run for this reference image. |
- if os.path.exists(generated_file): |
- # a generated file exists? The test name does not match the screenshot. |
- results.StartTest(test_name) |
- results.AddFailure(test_name, browser, |
- "Test name and screenshot name do not match.") |
- continue |
- |
- # Check if there is a platform specific version of the reference image |
- if os.path.exists(platform_specific_reference_file): |
- reference_file = platform_specific_reference_file |
- |
- # Check if perceptual diff exists |
- pdiff_path = os.path.join(base_path, screencompare_tool) |
- if not os.path.exists(pdiff_path): |
- # Perceptualdiff.exe does not exist, fail. |
- results.AddFailure( |
- test_name, browser, |
- "Perceptual diff %s does not exist." % pdiff_path) |
- continue |
- |
- pixel_threshold = "10" |
- alpha_threshold = "1.0" |
- use_colorfactor = False |
- use_downsample = False |
- use_edge = True |
- edge_threshold = "5" |
- |
- # Find out if the test specified any options relating to perceptual diff |
- # that will override the defaults. |
- for opt in test_options: |
- if opt.startswith("pdiff_threshold"): |
- pixel_threshold = selenium_utilities.GetArgument(opt) |
- elif (opt.startswith("pdiff_threshold_mac") and |
- sys.platform == "darwin"): |
- pixel_threshold = selenium_utilities.GetArgument(opt) |
- elif (opt.startswith("pdiff_threshold_win") and |
- sys.platform == 'win32' or sys.platform == "cygwin"): |
- pixel_threshold = selenium_utilities.GetArgument(opt) |
- elif (opt.startswith("pdiff_threshold_linux") and |
- sys.platform[:5] == "linux"): |
- pixel_threshold = selenium_utilities.GetArgument(opt) |
- elif (opt.startswith("colorfactor")): |
- colorfactor = selenium_utilities.GetArgument(opt) |
- use_colorfactor = True |
- elif (opt.startswith("downsample")): |
- downsample_factor = selenium_utilities.GetArgument(opt) |
- use_downsample = True |
- elif (opt.startswith("pdiff_edge_ignore_off")): |
- use_edge = False |
- elif (opt.startswith("pdiff_edge_threshold")): |
- edge_threshold = selenium_utilities.GetArgument(opt) |
- |
- # Check if file exists |
- if os.path.exists(generated_file): |
- diff_file = os.path.join(base_path, screenshotsdir, |
- "compare_%s.png" % actual_name) |
- |
- # Run perceptual diff |
- arguments = [pdiff_path, |
- reference_file, |
- generated_file, |
- "-output", diff_file, |
- "-fov", "45", |
- "-alphaThreshold", alpha_threshold, |
- # Turn on verbose output for the percetual diff so we |
- # can see how far off we are on the threshold. |
- "-verbose", |
- # Set the threshold to zero so we can get a count |
- # of the different pixels. This causes the program |
- # to return failure for most images, but we can compare |
- # the values ourselves below. |
- "-threshold", "0"] |
- if use_colorfactor: |
- arguments += ["-colorfactor", colorfactor] |
- if use_downsample: |
- arguments += ["-downsample", downsample_factor] |
- if use_edge: |
- arguments += ["-ignoreEdges", edge_threshold] |
- |
- # Print the perceptual diff command line so we can debug easier. |
- if verbose: |
- print " ".join(arguments) |
- |
- # diff tool should return 0 on success |
- expected_result = 0 |
- |
- pdiff_pipe = subprocess.Popen(arguments, |
- stdout=subprocess.PIPE, |
- stderr=subprocess.PIPE) |
- (pdiff_stdout, pdiff_stderr) = pdiff_pipe.communicate() |
- result = pdiff_pipe.returncode |
- |
- # Find out how many pixels were different by looking at the output. |
- pixel_re = re.compile("(\d+) pixels are different", re.DOTALL) |
- pixel_match = pixel_re.search(pdiff_stdout) |
- different_pixels = "0" |
- if pixel_match: |
- different_pixels = pixel_match.group(1) |
- |
- alpha_re = re.compile("max alpha delta of ([0-9\.]+)", re.DOTALL) |
- alpha_delta = "0.0" |
- alpha_match = alpha_re.search(pdiff_stdout) |
- if alpha_match: |
- alpha_delta = alpha_match.group(1) |
- |
- if (result == expected_result or (pixel_match and |
- int(different_pixels) <= int(pixel_threshold))): |
- # The perceptual diff passed. |
- pass_re = re.compile("PASS: (.*?)\n", re.DOTALL) |
- pass_match = pass_re.search(pdiff_stdout) |
- reason = "Images are not perceptually different." |
- if pass_match: |
- reason = pass_match.group(1) |
- print ("%s PASSED with %s different pixels " |
- "(threshold %s) because: %s" % (test_name, |
- different_pixels, |
- pixel_threshold, |
- reason)) |
- results.AddSuccess(test_name) |
- else: |
- # The perceptual diff failed. |
- if pixel_match and int(different_pixels) > int(pixel_threshold): |
- results.AddFailure( |
- test_name, browser, |
- ("Reference framebuffer (%s) does not match generated " |
- "file (%s): %s non-matching pixels, max alpha delta: %s, " |
- "threshold: %s, alphaThreshold: %s." % |
- (reference_file, generated_file, different_pixels, alpha_delta, |
- pixel_threshold, alpha_threshold))) |
- else: |
- # The perceptual diff failed for some reason other than |
- # pixel differencing. |
- fail_re = re.compile("FAIL: (.*?)\n", re.DOTALL) |
- fail_match = fail_re.search(pdiff_stdout) |
- reason = "Unknown failure" |
- if fail_match: |
- reason = fail_match.group(1) |
- results.AddFailure( |
- test_name, browser, |
- ("Perceptual diff of reference (%s) and generated (%s) files " |
- "failed because: %s" % |
- (reference_file, generated_file, reason))) |
- else: |
- # Generated file does not exist |
- results.AddFailure(test_name, browser, |
- "File %s does not exist." % generated_file) |
- |
- return results |
- |
- |
def main(unused_argv): |
# Boolean to record if all tests passed. |
all_tests_passed = True |
@@ -945,45 +622,84 @@ |
FLAGS.referencedir, |
selenium_constants.PLATFORM_SCREENSHOT_DIR, |
"") |
+ |
+ # Launch HTTP server. |
+ http_server = LocalFileHTTPServer.StartServer(FLAGS.product_dir) |
- # Open a new session to Selenium Remote Control |
- selenium_session = SeleniumSession(FLAGS.verbose, FLAGS.java, |
- os.path.abspath(FLAGS.selenium_server), |
- FLAGS.servertimeout) |
- if not selenium_session.http_server or not selenium_session.selenium_server: |
+ if not http_server: |
+ print "Could not start a local http server with root." % FLAGS.product_dir |
return 1 |
+ |
+ |
+ # Start Selenium Remote Control and Selenium Session Builder. |
+ sel_server_jar = os.path.abspath(FLAGS.selenium_server) |
+ sel_server = SeleniumRemoteControl.StartServer( |
+ FLAGS.verbose, FLAGS.java, sel_server_jar, |
+ FLAGS.servertimeout) |
+ if not sel_server: |
+ print "Could not start selenium server at %s." % sel_server_jar |
+ return 1 |
+ |
+ session_builder = SeleniumSessionBuilder( |
+ sel_server.selenium_port, |
+ int(FLAGS.servertimeout) * 1000, |
+ http_server.http_port, |
+ FLAGS.browserpath) |
+ |
+ all_tests_passed = True |
+ # Test browsers. |
for browser in FLAGS.browser: |
if browser in set(selenium_constants.SELENIUM_BROWSER_SET): |
- test_list = [] |
- result = selenium_session.TestBrowser(browser, test_list, |
- FLAGS.testprefix, |
- FLAGS.testsuffixes, |
- int(FLAGS.servertimeout) * 1000) |
+ test_list = GetTestsForBrowser(browser, FLAGS.testprefix, |
+ FLAGS.testsuffixes) |
- # Compare screenshots |
- compare_result = CompareScreenshots(browser, |
- test_list, |
- FLAGS.screenshots, |
- FLAGS.screenshotsdir, |
- FLAGS.screencompare, |
- FLAGS.verbose) |
- if not result.wasSuccessful() or not compare_result.WasSuccessful(): |
+ result = TestBrowser(session_builder, browser, test_list) |
+ |
+ if not result.wasSuccessful(): |
all_tests_passed = False |
- # Log results |
- print "Results for %s:" % browser |
- print " %d tests run." % (result.testsRun + compare_result.tests_run) |
- print " %d errors." % (len(result.errors) + len(compare_result.errors)) |
- print " %d failures.\n" % (len(result.failures) + |
- len(compare_result.failures)) |
+ # Log non-succesful tests, for convenience. |
+ print "" |
+ print "Failures for %s:" % browser |
+ print "[Selenium tests]" |
+ for entry in test_list: |
+ if type(entry) == tuple: |
+ test = entry[0] |
+ else: |
+ test = entry |
+ |
+ if test in result.results: |
+ if result.results[test] != 'PASS': |
+ print test.name |
+ |
+ print "" |
+ print "[Perceptual Diff tests]" |
+ for entry in test_list: |
+ if type(entry) == tuple: |
+ pdiff_test = entry[1] |
+ if pdiff_test in result.results: |
+ if result.results[pdiff_test] != 'PASS': |
+ print pdiff_test.name |
+ |
+ |
+ # Log summary results. |
+ print "" |
+ print "Summary for %s:" % browser |
+ print " %d tests run." % result.testsRun |
+ print " %d errors." % len(result.errors) |
+ print " %d failures.\n" % len(result.failures) |
+ |
else: |
print "ERROR: Browser %s is invalid." % browser |
print "Run with --help to view list of supported browsers.\n" |
all_tests_passed = False |
- # Wrap up session |
- selenium_session.TearDown() |
+ # Shut down remote control |
+ shutdown_session = selenium.selenium("localhost", |
+ sel_server.selenium_port, "*firefox", |
+ "http://%s:%d" % (socket.gethostname(), http_server.http_port)) |
+ shutdown_session.shut_down_selenium_server() |
if all_tests_passed: |
# All tests successful. |
@@ -992,21 +708,6 @@ |
# Return error code 1. |
return 1 |
-def GetChromePath(): |
- value = None |
- if sys.platform == "win32" or sys.platform == "cygwin": |
- import _winreg |
- try: |
- key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, |
- "Applications\\chrome.exe\\shell\\open\\command") |
- (value, type) = _winreg.QueryValueEx(key, None) |
- _winreg.CloseKey(key) |
- except WindowsError: |
- raise Exception("Unable to determine location for Chrome -- " |
- "it is installed?") |
- value = os.path.dirname(value) |
- return value |
- |
if __name__ == "__main__": |
remaining_argv = FLAGS(sys.argv) |