#!/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

TIMEOUT_ERROR_MSG = 'FAIL (timeout)'

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

def dromaeo_test_done(source):
  """Tests to see if our performance test is done by printing a score."""
  #TODO(efortuna): Access these elements in a nicer way using DOM parser.
  return '<body class="alldone">' in source

# TODO(vsm): Ideally, this wouldn't live in this file.
CONFIGURATIONS = {
    'correctness': correctness_test_done,
    'perf': perf_test_done,
    'dromaeo': dromaeo_test_done
}

def run_test_in_browser(browser, html_out, timeout, mode):
  """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)

  browser.get("file://" + html_out)
  try:
    test_done = CONFIGURATIONS[mode]
    element = WebDriverWait(browser, float(timeout)).until(
        lambda driver: test_done(driver.page_source))
    return browser.page_source
  except selenium.common.exceptions.TimeoutException:
    return TIMEOUT_ERROR_MSG

def run_test_in_browser_selenium_rc(sel, html_out, timeout, mode):
  """ 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('file://' + html_out)
  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')
  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

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':
    # 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.
    return selenium.webdriver.Chrome()
  elif browser == 'dartium':
    script_dir = os.path.dirname(os.path.abspath(__file__))
    dartium_dir = os.path.join(script_dir, '..', '..', 'client', 'tests',
                               'dartium')
    options = selenium.webdriver.chrome.options.Options()
    # 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)
    xpi = os.path.join(script_dir, 'extensions', 'firefox',                               'ConsoleCollector.xpi')
    profile.add_extension(xpi);
    return selenium.webdriver.Firefox(firefox_profile=profile)
  elif browser == 'ie9' 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", 'file://' + 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):
  # TODO(vsm): Add a failure check for Dromaeo.
  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")
      if type(browser) is selenium.webdriver.firefox.webdriver.WebDriver:
        logs = browser.execute_script("return window.ConsoleCollector.read()");
        for msg in logs:
          print('%s:%s:%s:%s %s' %(
              msg['source'], msg['line'], msg['column'],
              msg['category'], msg['message']))
      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:
    while True:
      line = sys.stdin.readline()
      if line == '--terminate\n':
        print("Terminating selenium driver")
        break

      (html_out, browser_name, executable_path,
       timeout, mode) = 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)

      # 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'
      else:
        print '>>> TEST FAIL'
      sys.stdout.flush()
  finally:
    print("Closing browser");
    close_browser(browser)


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 = parse_args()
  browser = start_browser(browser_name, executable_path, html_out)

  try:
    output = run_test_in_browser(browser, html_out, timeout, mode)
    return report_results(mode, output, browser)
  finally:
    close_browser(browser)

if __name__ == "__main__":
  sys.exit(main(sys.argv))
