[infra] Remove obsolete webdriver/selenium support from testing
After this removal, the only thing in tools/testing is the checked-in
jsshell (Mozilla command-line JavaScript runner) executable. Discussions
for removing that as well have been started.
Change-Id: I28505154de9fa7df3a2d5f84f3f778c596f52fcc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106087
Reviewed-by: Bob Nystrom <rnystrom@google.com>
diff --git a/tools/testing/__init__.py b/tools/testing/__init__.py
deleted file mode 100644
index 4df76e2..0000000
--- a/tools/testing/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-
-import test_runner
-import utils
-
-
-# Constants used for test outcomes
-SKIP = 'skip'
-FAIL = 'fail'
-PASS = 'pass'
-OKAY = 'okay'
-TIMEOUT = 'timeout'
-CRASH = 'crash'
-SLOW = 'slow'
-
-HOST_CPUS = utils.GuessCpus()
-USE_DEFAULT_CPUS = -1
diff --git a/tools/testing/browser_README.txt b/tools/testing/browser_README.txt
deleted file mode 100644
index 2ec2f35..0000000
--- a/tools/testing/browser_README.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Overview:
- These are the instructions to run a wide variety of browser tests using
- test.dart or dart/tools/testing/perf_testing/run_perf_tests.py. Currently
- the results of run_perf_tests are uploaded to
- https://dartperf.googleplex.com/.
-
-========= General Browser Setup ==========
-
-See instructions on:
-https://code.google.com/p/dart/wiki/BrowserTestSetup
-
-========= Proceed further only if you also want to run performance tests.======
-
-1) Pull down benchmarks from internal repo (Google only): goto/dartbrowsersetup
-
-2) Create a directory in called appengine-python in third_party. Download the
- Linux/Other Platforms .zip file, and place the contents in the directory
- you just created.
- http://code.google.com/appengine/downloads.html#Google_App_Engine_SDK_for_Python
-
-3) Run the tests! While standing in dart/tools/testing/perf_testing, run
- $> python run_perf_tests.py --forever --verbose
- to run all the tests (browser performance, language correctness in the
- browser, command line performance, and self-hosted compile time and compiled
- code size).
-
- You can run individual tests by adding the particular option (such as
- --language) when running create_graph.py. Type "create_graph.py -h" for a
- full list of the options.
diff --git a/tools/testing/extensions/chrome/ConsoleCollector.crx b/tools/testing/extensions/chrome/ConsoleCollector.crx
deleted file mode 100644
index f853917..0000000
--- a/tools/testing/extensions/chrome/ConsoleCollector.crx
+++ /dev/null
Binary files differ
diff --git a/tools/testing/extensions/chrome/ConsoleCollector/background.js b/tools/testing/extensions/chrome/ConsoleCollector/background.js
deleted file mode 100644
index 21ae577..0000000
--- a/tools/testing/extensions/chrome/ConsoleCollector/background.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * This is the background window. It can access the necessary APIs to get
- * at the console messages. It can only communicate with the content
- * window through message passing.
- *
- * There is no way to query the console messages, as such, but we can
- * set up a handler that is called when there are console messages. This
- * will be called with any console messages already present, so it can be set
- * up after the fact. However, if there are no messages it won't be called.
- * To handle the end of the messages (or no messages) we have to use a
- * sentinel message that is logged by the content page.
- */
-var version = "1.0";
-var messages = []; // An array that we can put messages in.
-var debuggeeId; // An object that identifies the browser tab we are talking to.
-var callback; // For passing back the response to the content window.
-var timer; // To time out if no messages are available.
-
-/**
- * When we have collected all the messages, we send them back to the
- * content page via the callback, turn off message collection, and
- * detach the debugger from the browser tab.
- */
-function allDone() {
- callback(messages);
- chrome.debugger.sendCommand(debuggeeId, "Console.clearMessages", {},
- function() {
- chrome.debugger.sendCommand(debuggeeId, "Console.disable", {},
- function() {});
- chrome.debugger.detach(debuggeeId, function() {});
- });
- messages = [];
-}
-
-/**
- * Debugger event handler. We only care about console.messageAdded
- * events, in which case we add a new message object with the fields
- * we care about to our messages array.
- */
-function onEvent(debuggeeId, method, params) {
- var tabId = debuggeeId.tabId;
- if (method == "Console.messageAdded") {
- var msg = params.message;
- // More fields are available if we want them later. See
- // https://developers.google.com/chrome-developer-tools/docs/protocol/1.0/console#type-ConsoleMessage
- if (msg.text == 'getMessages/end') {
- allDone();
- } else {
- messages.push({"source":msg.url, "line": msg.line,
- "category":msg.source, "message":msg.text });
- }
- }
-}
-
-/**
- * Handle requests sent by the content script. We save the callback,
- * get the window and tab that is currently active, attach the
- * debugger to that tab, and then turn on console message event
- * handling, which will result in onEvent calls for each console
- * message, including the ones that are already present in the console.
- */
-function onRequest(request, sender, sendResponse) {
- if (request.command == "getMessages") {
- callback = sendResponse;
- chrome.windows.getCurrent(function(win) {
- chrome.tabs.getSelected(win.id, function(tab) {
- debuggeeId = {tabId:tab.id};
- chrome.debugger.attach(debuggeeId, version, function() {
- if (chrome.extension.lastError) {
- // Attach failed; send an empty response.
- callback([]);
- } else {
- chrome.debugger.sendCommand(debuggeeId, "Console.enable", {},
- function() {});
- //timer = setTimeout(allDone, 1000);
- }
- });
- });
- });
- }
-}
-
-// Set up the general handler for debug events.
-chrome.debugger.onEvent.addListener(onEvent);
-// Listen for the content script to send a message to the background page.
-chrome.extension.onRequest.addListener(onRequest);
diff --git a/tools/testing/extensions/chrome/ConsoleCollector/content.js b/tools/testing/extensions/chrome/ConsoleCollector/content.js
deleted file mode 100644
index 6339f81..0000000
--- a/tools/testing/extensions/chrome/ConsoleCollector/content.js
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * This is the content page script. This runs in the context of the browser
- * page, and communicates with the background page by relaying a getMessages
- * request, and the forwarding the messages back to the browser page as a
- * gotMessages message.
- */
-window.addEventListener("message", function(event) {
- if (event.source == window && event.data == "getMessages") {
- // Log a special sentinel message to mark the end of the messages.
- console.log('getMessages/end');
- chrome.extension.sendRequest({command: "getMessages"}, function(messages) {
- window.postMessage({ "type": "gotMessages", "messages" : messages}, "*");
- });
- }
-}, false);
diff --git a/tools/testing/extensions/chrome/ConsoleCollector/manifest.json b/tools/testing/extensions/chrome/ConsoleCollector/manifest.json
deleted file mode 100644
index 6f6b439..0000000
--- a/tools/testing/extensions/chrome/ConsoleCollector/manifest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "name": "Console Collector",
- "version": "1.0",
- "manifest_version": 2,
- "description": "Allow querying of the Javascript console.",
- "browser_action": {
- "name": "ConsoleCollector"
- },
- "background": {
- "scripts": ["background.js"],
- "persistent": true
- },
- "content_scripts": [
- {
- "matches": ["http://*/*", "file://*" ],
- "js": [ "content.js" ]
- }
- ],
- "permissions": [
- "tabs", "http://*/*", "file://*", "debugger"
- ]
-}
diff --git a/tools/testing/extensions/firefox/ConsoleCollector.xpi b/tools/testing/extensions/firefox/ConsoleCollector.xpi
deleted file mode 100644
index 40c261e..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector.xpi
+++ /dev/null
Binary files differ
diff --git a/tools/testing/extensions/firefox/ConsoleCollector/Makefile b/tools/testing/extensions/firefox/ConsoleCollector/Makefile
deleted file mode 100644
index f6c8610..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-../ConsoleCollector.xpi: chrome.manifest install.rdf chrome/content/console.js chrome/content/overlay.xul
- zip -r ../ConsoleCollector.xpi chrome.manifest install.rdf chrome/content/console.js chrome/content/overlay.xul
diff --git a/tools/testing/extensions/firefox/ConsoleCollector/chrome.manifest b/tools/testing/extensions/firefox/ConsoleCollector/chrome.manifest
deleted file mode 100644
index 5425ba6..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector/chrome.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-content ConsoleCollector chrome/content/
-overlay chrome://browser/content/browser.xul chrome://ConsoleCollector/content/overlay.xul
diff --git a/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/console.js b/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/console.js
deleted file mode 100644
index af46de4..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/console.js
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// This Firefox add-on exposes the Javascript console contents to Javascript
-// running in the browser. Once this is installed there will be a new
-// window.ConsoleCollector object with read() and clear() functions.
-
-var ConsoleCollector = {};
-
-(function() {
- // An array for collecting the messages.
- var messages = [];
-
- // Add a console message to the collection.
- this.add = function(message) {
- messages.push(message);
- };
-
- // Read the message collection. As a side effect we clear the message list.
- this.read = function(type) {
- var rtn = [];
- for (var i = 0; i < messages.length; i++) {
- var message = messages[i];
- if (message.errorMessage) {
- rtn.push({ 'time' : message.timeStamp,
- 'source' : message.sourceName,
- 'line': message.lineNumber,
- 'column': message.columnNumber,
- 'category': message.category,
- 'message' : message.errorMessage });
- }
- }
- messages = [];
- return rtn;
- };
-
- // Clear the message list.
- this.clear = function() {
- messages = [];
- };
-}).apply(ConsoleCollector);
-
-// A Console Listener.
-// See https://developer.mozilla.org/en-US/docs/Console_service for
-// details.
-(function() {
-
- var consoleService;
-
- var consoleListener = {
- observe: function(e) {
- try {
- var message = e.QueryInterface(Components.interfaces.nsIScriptError);
- ConsoleCollector.add(message);
- } catch (exception) {
- ConsoleCollector.add(e);
- }
- },
-
- QueryInterface: function (iid) {
- if (!iid.equals(Components.interfaces.nsIConsoleListener) &&
- !iid.equals(Components.interfaces.nsISupports)) {
- throw Components.results.NS_ERROR_NO_INTERFACE;
- }
- return this;
- }
- };
-
- // Start collecting console messages.
- function initialize(event) {
- consoleService = Components.classes['@mozilla.org/consoleservice;1']
- .getService(Components.interfaces.nsIConsoleService);
- if (consoleService) {
- consoleService.registerListener(consoleListener);
- }
- // Add the handler for hooking in to each page's DOM. This handler
- // is for each "gBrowser", representing a tab/window.
- window.getBrowser().addEventListener("load", onPageLoad, true);
- }
-
- // Stop collecting console messages.
- function shutdown(event) {
- window.getBrowser().removeEventListener("load", onPageLoad);
- consoleService.unregisterListener(consoleListener);
- ConsoleCollector.clear();
- }
-
- // Hook the ConsoleCollector into the DOM as window.ConsoleCollector.
- var onPageLoad = function(e) {
- var win = e.originalTarget.defaultView;
- if (win) {
- win.wrappedJSObject.ConsoleCollector = ConsoleCollector;
- }
- };
-
- // Add the handlers to initialize the add-on and shut it down.
- // These handlers are for the application as a whole.
- window.addEventListener('load', initialize, false);
- window.addEventListener('unload', shutdown, false);
-}());
-
-
-
diff --git a/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/overlay.xul b/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/overlay.xul
deleted file mode 100644
index 21347fb..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector/chrome/content/overlay.xul
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<overlay id="ConsoleCollector-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script src="console.js"/>
-</overlay>
diff --git a/tools/testing/extensions/firefox/ConsoleCollector/install.rdf b/tools/testing/extensions/firefox/ConsoleCollector/install.rdf
deleted file mode 100644
index 3966143..0000000
--- a/tools/testing/extensions/firefox/ConsoleCollector/install.rdf
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
- <Description about="urn:mozilla:install-manifest">
- <em:id>ConsoleCollector@google.com</em:id>
- <em:name>Console collector</em:name>
- <em:version>0.2</em:version>
- <em:description>Exposes the Javascript console to each browser window.
- </em:description>
- <em:creator>Graham Wheeler</em:creator>
- <em:homepageURL>http://www.dartlang.org</em:homepageURL>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
- <em:minVersion>3.0</em:minVersion>
- <em:maxVersion>15.0</em:maxVersion>
- </Description>
- </em:targetApplication>
- </Description>
-</RDF>
diff --git a/tools/testing/run_selenium.py b/tools/testing/run_selenium.py
deleted file mode 100755
index e270619..0000000
--- a/tools/testing/run_selenium.py
+++ /dev/null
@@ -1,390 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-#
-
-"""Script to actually open a browser and perform the test, and reports back with
-the result. It uses Selenium WebDriver when possible for running the tests. It
-uses Selenium RC for Safari.
-
-If started with --batch this script runs a batch of in-browser tests in
-the same browser process.
-
-Normal mode:
-$ python run_selenium.py --browser=ff --timeout=60 path/to/test.html
-
-Exit code indicates pass or fail
-
-Batch mode:
-$ python run_selenium.py --batch
-stdin: --browser=ff --timeout=60 path/to/test.html
-stdout: >>> TEST PASS
-stdin: --browser=ff --timeout=60 path/to/test2.html
-stdout: >>> TEST FAIL
-stdin: --terminate
-$
-"""
-
-import os
-import optparse
-import platform
-import selenium
-from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
-from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
-from selenium.webdriver.support.ui import WebDriverWait
-import shutil
-import signal
-import socket
-import sys
-import time
-import urllib2
-import threading
-
-TIMEOUT_ERROR_MSG = 'FAIL (timeout)'
-CRASH_ERROR_MSG = 'CRASH'
-
-def correctness_test_done(source):
- """Checks if test has completed."""
- return ('PASS' in source) or ('FAIL' in source)
-
-def perf_test_done(source):
- """Tests to see if our performance test is done by printing a score."""
- #This code is written this way to work around a current instability in the
- # python webdriver bindings if you call driver.get_element_by_id.
- #TODO(efortuna): Access these elements in a nicer way using DOM parser.
- string = '<div id="status">'
- index = source.find(string)
- end_index = source.find('</div>', index+1)
- source = source[index + len(string):end_index]
- return 'Score:' in source
-
-# TODO(vsm): Ideally, this wouldn't live in this file.
-CONFIGURATIONS = {
- 'correctness': correctness_test_done,
- 'perf': perf_test_done
-}
-
-def run_test_in_browser(browser, html_out, timeout, mode, refresh):
- """Run the desired test in the browser using Selenium 2.0 WebDriver syntax,
- and wait for the test to complete. This is the newer syntax, that currently
- supports Firefox, Chrome, IE, Opera (and some mobile browsers)."""
-
- if isinstance(browser, selenium.selenium):
- return run_test_in_browser_selenium_rc(browser, html_out, timeout, mode,
- refresh)
-
- browser.get(html_out)
- if refresh:
- browser.refresh()
- try:
- def pythonTimeout():
- # The builtin quit call for chrome will call close on the RemoteDriver
- # which may hang. Explicitly call browser.service.stop()
- if (type(browser) is selenium.webdriver.chrome.webdriver.WebDriver):
- # Browser may be dead
- try:
- browser.service.stop()
- except:
- print("Trying to close browser that has already been closed")
- # If the browser is crashing selenium may not time out.
- # Explicitly catch this case with a python timer.
- t = threading.Timer(timeout, pythonTimeout)
- t.start()
- test_done = CONFIGURATIONS[mode]
- element = WebDriverWait(browser, float(timeout)).until(
- lambda driver: test_done(driver.page_source))
- t.cancel()
- return browser.page_source
- except selenium.common.exceptions.TimeoutException:
- return TIMEOUT_ERROR_MSG
- except:
- return CRASH_ERROR_MSG
-
-def run_test_in_browser_selenium_rc(sel, html_out, timeout, mode, refresh):
- """ Run the desired test in the browser using Selenium 1.0 syntax, and wait
- for the test to complete. This is used for Safari, since it is not currently
- supported on Selenium 2.0."""
- sel.open(html_out)
- if refresh:
- sel.refresh()
- source = sel.get_html_source()
- end_condition = CONFIGURATIONS[mode]
-
- elapsed = 0
- while (not end_condition(source)) and elapsed <= timeout:
- sec = .25
- time.sleep(sec)
- elapsed += sec
- source = sel.get_html_source()
- return source
-
-def parse_args(args=None):
- parser = optparse.OptionParser()
- parser.add_option('--out', dest='out',
- help = 'The path for html output file that we will running our test from',
- action = 'store', default = '')
- parser.add_option('--browser', dest='browser',
- help = 'The browser type (default = chrome)',
- action = 'store', default = 'chrome')
- parser.add_option('--executable', dest='executable',
- help = 'The browser executable path (only for browser=dartium)',
- action = 'store', default = None)
- # TODO(efortuna): Put this back up to be more than the default timeout in
- # test.dart. Right now it needs to be less than 60 so that when test.dart
- # times out, this script also closes the browser windows.
- parser.add_option('--timeout', dest = 'timeout',
- help = 'Amount of time (seconds) to wait before timeout', type = 'int',
- action = 'store', default=58)
- parser.add_option('--mode', dest = 'mode',
- help = 'The type of test we are running',
- action = 'store', default='correctness')
- parser.add_option('--force-refresh', dest='refresh',
- help='Force the browser to refresh before getting results from this test '
- '(used for browser multitests).', action='store_true', default=False)
- args, _ = parser.parse_args(args=args)
- args.out = args.out.strip('"')
- if args.executable and args.browser != 'dartium':
- print 'Executable path only supported when browser=dartium.'
- sys.exit(1)
- return (args.out, args.browser, args.executable, args.timeout, args.mode,
- args.refresh)
-
-def print_server_error():
- """Provide the user an informative error message if we attempt to connect to
- the Selenium remote control server, but cannot access it. Then exit the
- program."""
- print ('ERROR: Could not connect to Selenium RC server. Are you running'
- ' java -jar tools/testing/selenium-server-standalone-*.jar? If not, '
- 'start it before running this test.')
- sys.exit(1)
-
-def start_browser(browser, executable_path, html_out):
- if browser == 'chrome' or browser == 'dartium':
- # Note: you need ChromeDriver *in your path* to run Chrome, in addition to
- # installing Chrome. Also note that the build bot runs have a different path
- # from a normal user -- check the build logs.
- options = selenium.webdriver.chrome.options.Options()
- if browser == 'dartium':
- script_dir = os.path.dirname(os.path.abspath(__file__))
- dartium_dir = os.path.join(script_dir, '..', '..', 'client', 'tests',
- 'dartium')
- # enable ShadowDOM and style scoped for Dartium
- options.add_argument('--enable-shadow-dom')
- options.add_argument('--enable-style-scoped')
- if executable_path is not None:
- options.binary_location = executable_path
- elif platform.system() == 'Windows':
- options.binary_location = os.path.join(dartium_dir, 'chrome.exe')
- elif platform.system() == 'Darwin':
- options.binary_location = os.path.join(dartium_dir, 'Chromium.app',
- 'Contents', 'MacOS', 'Chromium')
- else:
- options.binary_location = os.path.join(dartium_dir, 'chrome')
- return selenium.webdriver.Chrome(chrome_options=options)
- elif browser == 'ff':
- script_dir = os.path.dirname(os.path.abspath(__file__))
- profile = selenium.webdriver.firefox.firefox_profile.FirefoxProfile()
- profile.set_preference('dom.max_script_run_time', 0)
- profile.set_preference('dom.max_chrome_script_run_time', 0)
- profile.set_preference('app.update.auto', True)
- profile.set_preference('app.update.enabled', True)
- return selenium.webdriver.Firefox(firefox_profile=profile)
- elif ((browser == 'ie9' or browser == 'ie10') and
- platform.system() == 'Windows'):
- return selenium.webdriver.Ie()
- elif browser == 'safari' and platform.system() == 'Darwin':
- # TODO(efortuna): Ensure our preferences (no pop-up blocking) file is the
- # same (Safari auto-deletes when it has too many "crashes," or in our case,
- # timeouts). Come up with a less hacky way to do this.
- backup_safari_prefs = os.path.dirname(__file__) + '/com.apple.Safari.plist'
- if os.path.exists(backup_safari_prefs):
- shutil.copy(backup_safari_prefs,
- '/Library/Preferences/com.apple.Safari.plist')
- sel = selenium.selenium('localhost', 4444, "*safari", html_out)
- try:
- sel.start()
- return sel
- except socket.error:
- print_server_error()
- elif browser == 'opera':
- try:
- driver = RemoteWebDriver(desired_capabilities=DesiredCapabilities.OPERA)
- # By default, Opera sets their script timeout (the amount of time they
- # expect to hear back from the JavaScript file) to be 10 seconds. We just
- # make it an impossibly large number so that it doesn't time out for this
- # reason, so it behaves like all of the other browser drivers.
- driver.set_script_timeout(9000)
- # If the webpage contains document.onreadystatechanged = function() {...}
- # page load event does not correctly get fired and caught (OperaDriver
- # bug). This is a band-aid.
- driver.set_page_load_timeout(1)
- return driver
- except urllib2.URLError:
- print_server_error()
- else:
- raise Exception('Incompatible browser and platform combination.')
-
-def close_browser(browser):
- if browser is None:
- return
- if isinstance(browser, selenium.selenium):
- browser.stop()
- return
-
- # A timeout exception is thrown if nothing happens within the time limit.
- if (type(browser) is not selenium.webdriver.chrome.webdriver.WebDriver and
- type(browser) is not selenium.webdriver.ie.webdriver.WebDriver):
- browser.close()
-
- browser.quit()
-
-def report_results(mode, source, browser):
- if mode != 'correctness':
- # We're running a performance test.
- print source.encode('utf8')
- sys.stdout.flush()
- if 'NaN' in source:
- return 1
- else:
- return 0
- else:
- # We're running a correctness test. Mark test as passing if all individual
- # test cases pass.
- if 'FAIL' not in source and 'PASS' in source:
- print 'Content-Type: text/plain\nPASS'
- return 0
- else:
- #The hacky way to get document.getElementById('body').innerHTML for this
- # webpage, without the JavaScript.
- #TODO(efortuna): Access these elements in a nicer way using DOM parser.
- index = source.find('<body>')
- index += len('<body>')
- end_index = source.find('</body')
- print unicode(source[index : end_index]).encode("utf-8")
- return 1
-
-
-def run_batch_tests():
- '''
- Runs a batch of in-browser tests in the same browser process. Batching
- gives faster throughput and makes tests less subject to browser starting
- flakiness, issues with too many browser processes running, etc.
-
- When running this function, stdin/stdout is used to communicate with the test
- framework. See BatchRunnerProcess in test_runner.dart for the other side of
- this communication channel
-
- Example of usage:
- $ python run_selenium.py --batch
- stdin: --browser=ff --timeout=60 path/to/test.html
- stdout: >>> TEST PASS
- stdin: --browser=ff --timeout=60 path/to/test2.html
- stdout: >>> TEST FAIL
- stdin: --terminate
- $
- '''
-
- print '>>> BATCH START'
- browser = None
- current_browser_name = None
-
- # TODO(jmesserly): It'd be nice to shutdown gracefully in the event of a
- # SIGTERM. Unfortunately dart:io cannot send SIGTERM, see dartbug.com/1756.
- signal.signal(signal.SIGTERM, lambda number, frame: close_browser(browser))
-
- try:
- try:
- while True:
- line = sys.stdin.readline()
- if line == '--terminate\n':
- print("Terminating selenium driver")
- break
-
- (html_out, browser_name, executable_path,
- timeout, mode, refresh) = parse_args(line.split())
-
- # Sanity checks that test.dart is passing flags we can handle.
- if mode != 'correctness':
- print 'Batch test runner not compatible with perf testing'
- return 1
- if browser and current_browser_name != browser_name:
- print('Batch test runner got multiple browsers: %s and %s'
- % (current_browser_name, browser_name))
- return 1
-
- # Start the browser on the first run
- if browser is None:
- current_browser_name = browser_name
- browser = start_browser(browser_name, executable_path, html_out)
-
- source = run_test_in_browser(browser, html_out, timeout, mode, refresh)
-
- # Test is done. Write end token to stderr and flush.
- sys.stderr.write('>>> EOF STDERR\n')
- sys.stderr.flush()
-
- # print one of:
- # >>> TEST {PASS, FAIL, OK, CRASH, FAIL, TIMEOUT}
- status = report_results(mode, source, browser)
- if status == 0:
- print '>>> TEST PASS'
- elif source == TIMEOUT_ERROR_MSG:
- print '>>> TEST TIMEOUT'
- elif source == CRASH_ERROR_MSG:
- print '>>> TEST CRASH'
- # The browser crashed, set the browser to None so that we will
- # create a new instance on next iteration.
- browser = None
- else:
- print '>>> TEST FAIL'
- sys.stdout.flush()
- except:
- type, value, traceback = sys.exc_info()
- print "run_selenium.py: Unexpected exception occured: "
- print " type: ", type
- print " value: ", value
- print " traceback: ", traceback
- raise
- finally:
- sys.stdin.close()
- print("Closing browser");
-
- def close_output_streams():
- sys.stdout.flush()
- sys.stdout.close()
- sys.stderr.flush()
- sys.stderr.close()
-
- def close_and_exit():
- print("Timed out waiting for browser to close")
- close_output_streams()
- exit(1)
-
- timer = threading.Timer(5.0, close_and_exit)
- timer.start()
- try:
- close_browser(browser)
- timer.cancel()
- finally:
- close_output_streams()
-
-def main(args):
- # Run in batch mode if the --batch flag is passed.
- # TODO(jmesserly): reconcile with the existing args parsing
- if '--batch' in args:
- return run_batch_tests()
-
- # Run a single test
- html_out, browser_name, executable_path, timeout, mode, refresh = parse_args()
- browser = start_browser(browser_name, executable_path, html_out)
-
- try:
- output = run_test_in_browser(browser, html_out, timeout, mode, refresh)
- return report_results(mode, output, browser)
- finally:
- close_browser(browser)
-
-if __name__ == "__main__":
- sys.exit(main(sys.argv))
diff --git a/tools/testing/webdriver_test_setup.py b/tools/testing/webdriver_test_setup.py
deleted file mode 100755
index c68543b..0000000
--- a/tools/testing/webdriver_test_setup.py
+++ /dev/null
@@ -1,434 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Run to install the necessary components to run webdriver on the buildbots or
-# on your local machine.
-# Note: The setup steps can be done fairly easily by hand. This script is
-# intended to simply and reduce the time for setup since there are a fair number
-# of steps.
-
-# TODO(efortuna): Rewrite this script in Dart when the Process module has a
-# better high level API.
-import HTMLParser
-import optparse
-import os
-import platform
-import re
-import shutil
-import string
-import subprocess
-import sys
-import urllib
-import urllib2
-import zipfile
-
-def run_cmd(cmd, stdin=None):
- """Run the command on the command line in the shell. We print the output of
- the command.
- """
- print cmd
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- stdin=subprocess.PIPE, shell=True)
- output, stderr = p.communicate(input=stdin)
- if output:
- print output
- if stderr:
- print stderr
-
-def parse_args():
- parser = optparse.OptionParser()
- parser.add_option('--firefox', '-f', dest='firefox',
- help="Don't install Firefox", action='store_true', default=False)
- parser.add_option('--opera', '-o', dest='opera', default=False,
- help="Don't install Opera", action='store_true')
- parser.add_option('--chromedriver', '-c', dest='chromedriver',
- help="Don't install chromedriver.", action='store_true', default=False)
- parser.add_option('--iedriver', '-i', dest='iedriver',
- help="Don't install iedriver (only used on Windows).",
- action='store_true', default=False)
- parser.add_option('--seleniumrc', '-s', dest='seleniumrc',
- help="Don't install the Selenium RC server (used for Safari and Opera "
- "tests).", action='store_true', default=False)
- parser.add_option('--python', '-p', dest='python',
- help="Don't install Selenium python bindings.", action='store_true',
- default=False)
- parser.add_option('--buildbot', '-b', dest='buildbot', action='store_true',
- help='Perform a buildbot selenium setup (buildbots have a different' +
- 'location for their python executable).', default=False)
- args, _ = parser.parse_args()
- return args
-
-def find_depot_tools_location(is_buildbot):
- """Depot_tools is our default install location for chromedriver, so we find
- its location on the filesystem.
- Arguments:
- is_buildbot - True if we are running buildbot machine setup (we can't detect
- this automatically because this script is not run at build time).
- """
- if is_buildbot:
- depot_tools = os.sep + os.path.join('b', 'depot_tools')
- if 'win32' in sys.platform or 'cygwin' in sys.platform:
- depot_tools = os.path.join('e:', depot_tools)
- return depot_tools
- else:
- path = os.environ['PATH'].split(os.pathsep)
- for loc in path:
- if 'depot_tools' in loc:
- return loc
- raise Exception("Could not find depot_tools in your path.")
-
-class GoogleBasedInstaller(object):
- """Install a project from a Google source, pulling latest version."""
-
- def __init__(self, project_name, destination, download_path_func):
- """Create an object that will install the project.
- Arguments:
- project_name - Google code name of the project, such as "selenium" or
- "chromedriver."
- destination - Where to download the desired file on our filesystem.
- download_path_func - A function that takes a dictionary (currently with keys
- "os" and "version", but more can be added) that calculates the string
- representing the path of the download we want.
- """
- self.project_name = project_name
- self.destination = destination
- self.download_path_func = download_path_func
-
- @property
- def get_os_str(self):
- """The strings to indicate what OS a download is for."""
- os_str = 'win'
- if 'darwin' in sys.platform:
- os_str = 'mac'
- elif 'linux' in sys.platform:
- os_str = 'linux32'
- if '64bit' in platform.architecture()[0]:
- os_str = 'linux64'
- if self.project_name == 'chromedriver' and (
- os_str == 'mac' or os_str == 'win'):
- os_str += '32'
- return os_str
-
- def run(self):
- """Download and install the project."""
- print 'Installing %s' % self.project_name
- os_str = self.get_os_str
- version = self.find_latest_version()
- download_path = self.download_path_func({'os': os_str, 'version': version})
- download_name = os.path.basename(download_path)
- urllib.urlretrieve(os.path.join(self.source_path(), download_path),
- os.path.join(self.destination, download_name))
- if download_name.endswith('.zip'):
- if platform.system() != 'Windows':
- # The Python zip utility does not preserve executable permissions, but
- # this does not seem to be a problem for Windows, which does not have a
- # built in zip utility. :-/
- run_cmd('unzip -u %s -d %s' % (os.path.join(self.destination,
- download_name), self.destination), stdin='y')
- else:
- z = zipfile.ZipFile(os.path.join(self.destination, download_name))
- z.extractall(self.destination)
- z.close()
- os.remove(os.path.join(self.destination, download_name))
- chrome_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
- 'orig-chromedriver')
- if self.project_name == 'chromedriver' and os.path.exists(chrome_path):
- # We have one additional location to make sure chromedriver is updated.
- # TODO(efortuna): Remove this. See move_chrome_driver_if_needed in
- # perf_testing/run_perf_tests.py
- driver = 'chromedriver'
- if platform.system() == 'Windows':
- driver += '.exe'
- shutil.copy(os.path.join(self.destination, driver),
- os.path.join(chrome_path, driver))
-
-class ChromeDriverInstaller(GoogleBasedInstaller):
- """Install chromedriver from Google Storage."""
-
- def __init__(self, destination):
- """Create an object to install ChromeDriver
- destination - Where to download the desired file on our filesystem.
- """
- super(ChromeDriverInstaller, self).__init__('chromedriver', destination,
- lambda x: '%(version)s/chromedriver_%(os)s.zip' % x)
-
- def find_latest_version(self):
- """Find the latest version number of ChromeDriver."""
- source_page = urllib2.urlopen(self.source_path())
- source_text = source_page.read()
- regex = re.compile('(?:<Key>)(\d+\.\d+)')
- latest = max(regex.findall(source_text))
- return latest
-
- def source_path(self):
- return 'http://chromedriver.storage.googleapis.com'
-
-class GoogleCodeInstaller(GoogleBasedInstaller):
- """Install a project from Google Code."""
-
- def google_code_downloads_page(self):
- return 'http://code.google.com/p/%s/downloads/list' % self.project_name
-
- def find_latest_version(self):
- """Find the latest version number of some code available for download on a
- Google code page. This was unfortunately done in an ad hoc manner because
- Google Code does not seem to have an API for their list of current
- downloads(!).
- """
- google_code_site = self.google_code_downloads_page()
- f = urllib2.urlopen(google_code_site)
- latest = ''
-
- download_regex_str = self.download_path_func({'os': self.get_os_str,
- 'version': '.+'})
-
- for line in f.readlines():
- if re.search(download_regex_str, line):
- suffix_index = line.find(
- download_regex_str[download_regex_str.rfind('.'):])
- name_end = download_regex_str.rfind('.+')
- name = self.download_path_func({'os': self.get_os_str, 'version': ''})
- name = name[:name.rfind('.')]
- version_str = line[line.find(name) + len(name) : suffix_index]
- orig_version_str = version_str
- if version_str.count('.') == 0:
- version_str = version_str.replace('_', '.')
- version_str = re.compile(r'[^\d.]+').sub('', version_str)
- if latest == '':
- latest = '0.' * version_str.count('.')
- latest += '0'
- orig_latest_str = latest
- else:
- orig_latest_str = latest
- latest = latest.replace('_', '.')
- latest = re.compile(r'[^\d.]+').sub('', latest)
- nums = version_str.split('.')
- latest_nums = latest.split('.')
- for (num, latest_num) in zip(nums, latest_nums):
- if int(num) > int(latest_num):
- latest = orig_version_str
- break
- else:
- latest = orig_latest_str
- if latest == '':
- raise Exception("Couldn't find the desired download on " + \
- ' %s.' % google_code_site)
- return latest
-
- def source_path(self):
- return 'http://%s.googlecode.com/files/' % self.project_name
-
-
-class FirefoxInstaller(object):
- """Installs the latest version of Firefox on the machine."""
-
- def ff_download_site(self, os_name):
- return 'http://releases.mozilla.org/pub/mozilla.org/firefox/releases/' + \
- 'latest/%s/en-US/' % os_name
-
- @property
- def get_os_str(self):
- """Returns the string that Mozilla uses to denote which operating system a
- Firefox binary is for."""
- os_str = ('win32', '.exe')
- if 'darwin' in sys.platform:
- os_str = ('mac', '.dmg')
- elif 'linux' in sys.platform:
- os_str = ('linux-i686', '.tar.bz2')
- if '64bit' in platform.architecture()[0]:
- os_str = ('linux-x86_64', '.tar.bz2')
- return os_str
-
- def get_download_url(self):
- """Parse the html on the page to determine what is the latest download
- appropriate for our system."""
- f = urllib2.urlopen(self.ff_download_site(self.get_os_str[0]))
- download_name = ''
- for line in f.readlines():
- suffix = self.get_os_str[1]
- if (suffix + '"') in line:
- link_str = '<a href="'
- download_name = line[line.find(link_str) + len(link_str) : \
- line.find(suffix) + len(suffix)]
- break
- return '%s%s' % (self.ff_download_site(self.get_os_str[0]), download_name)
-
- def run(self):
- print 'Installing Firefox'
- if 'darwin' in sys.platform:
- urllib.urlretrieve(self.get_download_url(), 'firefox.dmg')
- run_cmd('hdiutil mount firefox.dmg')
- run_cmd('sudo cp -R /Volumes/firefox/Firefox.app /Applications')
- run_cmd('hdiutil unmount /Volumes/firefox/')
- elif 'win' in sys.platform:
- urllib.urlretrieve(self.get_download_url(), 'firefox_install.exe')
- run_cmd('firefox_install.exe -ms')
- else:
- run_cmd('wget -O - %s | tar -C ~ -jxv' % self.get_download_url())
-
-
-class SeleniumBindingsInstaller(object):
- """Install the Selenium Webdriver bindings for Python."""
-
- SETUPTOOLS_SITE = 'http://python-distribute.org/distribute_setup.py'
- PIP_SITE = 'https://raw.github.com/pypa/pip/master/contrib/get-pip.py'
- def __init__(self, is_buildbot):
- self.is_buildbot = is_buildbot
-
- def run(self):
- print 'Installing Selenium Python Bindings'
- admin_keyword = ''
- python_cmd = 'python'
- pip_cmd = 'pip'
- if 'win32' not in sys.platform and 'cygwin' not in sys.platform:
- admin_keyword = 'sudo'
- pip_cmd = '/usr/local/bin/pip'
- else:
- # The python installation is "special" on Windows buildbots.
- if self.is_buildbot:
- python_loc = os.path.join(
- find_depot_tools_location(self.is_buildbot), 'python_bin')
- python_cmd = os.path.join(python_loc, 'python')
- pip_cmd = os.path.join(python_loc, 'Scripts', pip_cmd)
- else:
- path = os.environ['PATH'].split(os.pathsep)
- for loc in path:
- if 'python' in loc or 'Python' in loc:
- pip_cmd = os.path.join(loc, 'Scripts', pip_cmd)
- break
- page = urllib2.urlopen(self.SETUPTOOLS_SITE)
- run_cmd('%s %s' % (admin_keyword, python_cmd), page.read())
- page = urllib2.urlopen(self.PIP_SITE)
- run_cmd('%s %s' % (admin_keyword, python_cmd), page.read())
- run_cmd('%s %s install -U selenium' % (admin_keyword, pip_cmd))
-
-class OperaHtmlParser(HTMLParser.HTMLParser):
- """A helper class to parse Opera pages listing available downloads to find the
- correct download we want."""
-
- def initialize(self, rejection_func, accept_func):
- """Initialize some state for our parser.
- Arguments:
- rejection_func: A function that accepts the value of the URL and determines
- if it is of the type we are looking for.
- accept_func: A function that takes the URL and the "current best" URL and
- determines if it is better than our current download url."""
- self.latest = 0
- self.rejection_func = rejection_func
- self.accept_func = accept_func
-
- def handle_starttag(self, tag, attrs):
- """Find the latest version."""
- if (tag == 'a' and attrs[0][0] == 'href' and
- self.rejection_func(attrs[0][1])):
- self.latest = self.accept_func(attrs[0][1], self.latest)
-
-class OperaInstaller(object):
- """Install from the Opera FTP website."""
-
- def find_latest_version(self, download_page, rejection_func, accept_func):
- """Get the latest non-beta version.
- Arguments:
- download_page: The initial page that lists all the download options.
- rejection_func: A function that accepts the value of the URL and determines
- if it is of the type we are looking for.
- accept_func: A function that takes the URL and the "current best" URL and
- determines if it is better than our current download url."""
- f = urllib2.urlopen(download_page)
- parser = OperaHtmlParser()
- parser.initialize(rejection_func, accept_func)
- parser.feed(f.read())
- return str(parser.latest)
-
- def run(self):
- """Download and install Opera."""
- print 'Installing Opera'
- os_str = self.get_os_str
- download_name = 'http://ftp.opera.com/pub/opera/%s/' % os_str
-
- def higher_revision(new_version_str, current):
- version_string = new_version_str[:-1]
- if int(version_string) > current:
- return int(version_string)
- return current
-
- version = self.find_latest_version(
- download_name,
- lambda x: x[0] in string.digits and 'b' not in x and 'rc' not in x,
- higher_revision)
- download_name += version
- if ('linux' in sys.platform and
- platform.linux_distribution()[0] == 'Ubuntu'):
- # Last time I tried, the .deb file you download directly from opera was
- # not installing correctly on Ubuntu. This installs Opera more nicely.
- os.system("sudo sh -c 'wget -O - http://deb.opera.com/archive.key | "
- "apt-key add -'")
- os.system("""sudo sh -c 'echo "deb http://deb.opera.com/opera/ """
- """stable non-free" > /etc/apt/sources.list.d/opera.list'""")
- run_cmd('sudo apt-get update')
- run_cmd('sudo apt-get install opera', stdin='y')
- else:
- if 'darwin' in sys.platform:
- dotted_version = '%s.%s' % (version[:2], version[2:])
- download_name += '/Opera_%s_Setup_Intel.dmg' % dotted_version
- urllib.urlretrieve(download_name, 'opera.dmg')
- run_cmd('hdiutil mount opera.dmg', stdin='qY\n')
- run_cmd('sudo cp -R /Volumes/Opera/Opera.app /Applications')
- run_cmd('hdiutil unmount /Volumes/Opera/')
- elif 'win' in sys.platform:
- download_name += '/en/Opera_%s_en_Setup.exe' % version
- urllib.urlretrieve(download_name, 'opera_install.exe')
- run_cmd('opera_install.exe -ms')
- else:
- # For all other flavors of linux, download the tar.
- download_name += '/'
- extension = '.tar.bz2'
- if '64bit' in platform.architecture()[0]:
- platform_str = '.x86_64'
- else:
- platform_str = '.i386'
- def get_acceptable_file(new_version_str, current):
- return new_version_str
- latest = self.find_latest_version(
- download_name,
- lambda x: x.startswith('opera') and x.endswith(extension)
- and platform_str in x,
- get_acceptable_file)
- download_name += latest
- run_cmd('wget -O - %s | tar -C ~ -jxv' % download_name)
- print ('PLEASE MANUALLY RUN "~/%s/install" TO COMPLETE OPERA '
- 'INSTALLATION' %
- download_name[download_name.rfind('/') + 1:-len(extension)])
-
- @property
- def get_os_str(self):
- """The strings to indicate what OS a download is."""
- os_str = 'win'
- if 'darwin' in sys.platform:
- os_str = 'mac'
- elif 'linux' in sys.platform:
- os_str = 'linux'
- return os_str
-
-def main():
- args = parse_args()
- if not args.python:
- SeleniumBindingsInstaller(args.buildbot).run()
- if not args.chromedriver:
- ChromeDriverInstaller(find_depot_tools_location(args.buildbot)).run()
- if not args.seleniumrc:
- GoogleCodeInstaller('selenium', os.path.dirname(os.path.abspath(__file__)),
- lambda x: 'selenium-server-standalone-%(version)s.jar' % x).run()
- if not args.iedriver and platform.system() == 'Windows':
- GoogleCodeInstaller('selenium', find_depot_tools_location(args.buildbot),
- lambda x: 'IEDriverServer_Win32_%(version)s.zip' % x).run()
- if not args.firefox:
- FirefoxInstaller().run()
- if not args.opera:
- OperaInstaller().run()
-
-if __name__ == '__main__':
- main()