Skip to content
Snippets Groups Projects
run.py 7 KiB
Newer Older
#!/usr/bin/python

import optparse
import os
import platform
import subprocess
import sys


# used to check for existence of virtualenv and pip.
# lifted from: http://stackoverflow.com/questions/377017
def which(program):
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None
    # get path to python: virtualenv location differs on windows
    # TODO platform detection is brittle. is there a better way?
    if platform.system() == 'Windows':
        env_path = 'bid_selenium\Scripts\\'
    else:
        env_path = 'bid_selenium/bin/'
    env_py = env_path + 'python'

    # parse command line options
    parser = optparse.OptionParser()
    parser.add_option('--install', '-i', dest='install', action="store_true",
                      help='install python dependencies inside a virtualenv')
    parser.add_option('--all', '-a', dest='run_all', action="store_true",
                      help='run all tests. requires test account credentials' +
                           ' to be created and added to credentials.yaml')
    parser.add_option('--target', '-t', dest='target_hostname', 
                      default="dev", help='run tests against an ephemeral' +
                      ' instance. Specify your instance\'s hostname ("foo"),' +
                      ' not the full domain name ("foo.123done.org")')
    parser.add_option('--everywhere', '-e', dest='run_everywhere', action='store_true',
                      help='like --all, but run all tests on all supported' +
                           ' browsers using sauce labs credentials either' +
                           ' specified in sauce.yaml or in environment' +
                           ' variables PERSONA_SAUCE_USER, PERSONA_SAUCE_PASSWORD,' +
                           ' and PERSONA_SAUCE_APIKEY.')
    options, arguments = parser.parse_args()

    # you can't specify both --all and --everywhere
    if options.run_everywhere and options.run_all:
            sys.stderr.write("either use --all or --everywhere, not both")
            exit(1)

    # 1. check that python is the right version 
    # TODO: would 2.6 actually work?
    if sys.version_info < (2,7,0):
        sys.stderr.write('python 2.7 or later is required to run the tests\n')
        exit(1)

    # 2. check that virtualenv and pip exist. if not, bail.
    if not which('pip'):
        sys.stderr.write('pip must be installed; do "easy_install pip", ' +
                         ' then try again\n')
        exit(1)
    if not which('virtualenv'):
        sys.stderr.write('virtualenv must be installed; do "pip install ' +
                         'virtualenv", then try again\n')
        exit(1)
    # 3. create the virtualenv if they asked you to install it or it's missing
    if options.install or not os.path.exists(env_py):
        subprocess.call('virtualenv bid_selenium', shell=True)
        # 4. pip install requirements (or verify they're installed).
        subprocess.call(env_path + 'pip install -Ur requirements.txt', 
                        shell=True)
    # 4. check the ephemeral instance to hit.
    host = options.target_hostname

    # 5. check for/create sauce.yaml, if necessary
    if options.run_everywhere:
        # if sauce.yaml does not exist,
        if not os.path.isfile('sauce.yaml'):
            # look for environmental variables PERSONA_SAUCE_*
            try:
                username = os.environ['PERSONA_SAUCE_USER']
                password = os.environ['PERSONA_SAUCE_PASSWORD']
                api_key  = os.environ['PERSONA_SAUCE_APIKEY']
            # if they are missing, bail
            except KeyError:
                sys.stderr.write('Sauce labs credentials are needed to run' +
                    ' tests everywhere. Add credentials to sauce.yaml or, if' +
                    ' you have access to persona dev secrets, check that' +
                    ' the PERSONA_SAUCE_USER, PERSONA_SAUCE_PASSWORD, and' +
                    ' PERSONA_SAUCE_APIKEY environmental variables are set.\n')
                exit(1)
            # if they are present, write them out to sauce.yaml
            try:
                saucefile = open('sauce.yaml', 'w')
                saucefile.write('username: ' + username + '\n')
                saucefile.write('password: ' + password + '\n')
                saucefile.write('api-key: ' + api_key + '\n')
                saucefile.close()
            # if you can't open the file for editing, bail
            except IOError:
                sys.stderr.write('Unable to open sauce.yaml to write out' +
                    ' credentials. Either create sauce.yaml manually, or' +
                    ' ensure the test process has permission to create the file.\n')
                exit(1)

    # 6. run the tests

    # TODO move the run_everywhere list into a config file?
    if options.run_everywhere:
        browsers = ['--platform=LINUX --browsername=firefox --browserver=13 ',
            '--platform=LINUX --browsername=opera   --browserver=12 ',
            '--platform=MAC   --browsername=firefox --browserver=14 ',
            '--platform=VISTA --browsername=chrome ',
            '--platform=VISTA --browsername=firefox --browserver=13 ',
            '--platform=VISTA --browsername="internet explorer" --browserver=9 ',
            '--platform=XP    --browsername="internet explorer" --browserver=8 ']
        sauce = '--saucelabs=sauce.yaml '
    else:
        browsers = ['--driver=firefox ']
        sauce = ''

    for browser in browsers:
        if options.run_everywhere or options.run_all:
            subprocess.call(env_py + ' -m py.test --destructive ' +
                '--credentials=credentials.yaml ' + sauce + browser + 
                ' --webqatimeout=90 -m travis' +
                ' --baseurl=http://' + host + '.123done.org -q browserid', shell=True)
            subprocess.call(env_py + ' -m py.test --destructive ' +
                '--credentials=credentials.yaml ' + sauce + browser + 
                ' --webqatimeout=90' +
                ' --baseurl=http://' + host + '.123done.org -q 123done', shell=True)
            subprocess.call(env_py + ' -m py.test --destructive ' +
                '--credentials=credentials.yaml ' + sauce + browser + 
                ' --webqatimeout=90' +
                ' --baseurl=http://' + host + '.myfavoritebeer.org -q myfavoritebeer', shell=True)
        # only run one test in the default case
        else:
            subprocess.call(env_py + ' -m py.test --destructive ' +
                '--credentials=credentials.yaml ' + sauce + browser +
                ' --baseurl=http://' + host + '.123done.org ' +
                '-q 123done/tests/test_new_user.py', shell=True)

    # 7. TODO deactivate/destroy virtualenv?? maybe '--cleanup' argument?


if __name__ == '__main__':
    main()