diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..60a3e9b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +node_js: + - "6" + - "6.1" + - "4.4" + - "5.11" + - "0.10" + - "0.12" +before_script: + - npm install -g uglifyjs +script: + - ./tools/build.sh diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..94b60f6 --- /dev/null +++ b/circle.yml @@ -0,0 +1,31 @@ +dependencies: + post: + - npm install -g uglifyjs + - pip install selenium + - wget https://saucelabs.com/downloads/sc-latest-linux.tar.gz + - tar -xzf sc-latest-linux.tar.gz + - wget https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz + - tar -xvzf geckodriver-v0.11.1-linux64.tar.gz +test: + override: + # First start the tunnel because it takes time to setup. + - cd sc-*-linux && ./bin/sc --user $SAUCE_USERNAME --api-key $SAUCE_ACCESS_KEY --readyfile ~/sauce_is_ready --tunnel-identifier numeric-$CIRCLE_BUILD_NUM: + background: true + # Build and test locally. + - ./tools/build.sh + # Server files. + - python ./tools/serve.py: + background: true + # Wait for server to be ready. + - curl --retry 10 --retry-delay 2 -s http://localhost:8000/ > /dev/null + # Run selenium tests. + - python ./tools/selenium_tests.py Chrome http://localhost:8000/ + - PATH=.:$PATH ; python ./tools/selenium_tests.py Firefox http://localhost:8000/ + # Wait for tunnel to be ready. + - while [ ! -e ~/sauce_is_ready ]; do sleep 1; done + # TODO: We should upgrade to HTTPS once selenium Python package is released with this pull request: https://github.com/SeleniumHQ/selenium/pull/3179 + - SELENIUM_REMOTE_CAPABILITIES="{\"browserName\":\"internet explorer\",\"platform\":\"Windows 10\",\"version\":\"11.103\",\"name\":\"numeric\",\"build\":\"$CIRCLE_BUILD_NUM\",\"tunnelIdentifier\":\"numeric-$CIRCLE_BUILD_NUM\"}" SELENIUM_REMOTE_URL=http://$SAUCE_USERNAME:$SAUCE_ACCESS_KEY@ondemand.saucelabs.com:80/wd/hub python ./tools/selenium_tests.py Remote http://localhost:8000/ + post: + # Wait for Sauce Connect to close the tunnel. + - killall --wait sc + - killall --wait python diff --git a/tools/build.sh b/tools/build.sh index fe3be4b..a209852 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -47,7 +47,8 @@ cd .. runjs=`which d8 || which jsdb || which node` echo Using $runjs $runjs ./tools/unit2.js & -echo $! > tools/nodepid.log +nodepid=$! +echo $nodepid > tools/nodepid.log cd lib rm -rf numeric-$ver @@ -78,7 +79,11 @@ rm -f numeric-$ver.tar.gz tar cfz numeric-$ver.tar.gz numeric-$ver rm -rf numeric-$ver cd ../tools -wait +set +e +wait "$nodepid" +testexit=$? +set -e rm -f buildpid.log rm -f nodepid.log echo "Build complete" +exit $testexit diff --git a/tools/selenium_tests.py b/tools/selenium_tests.py index debe505..05cd005 100644 --- a/tools/selenium_tests.py +++ b/tools/selenium_tests.py @@ -6,7 +6,10 @@ import sys import urllib import re +import json +import os +# Returns True if any test failed. def test(name,driver): p = 0 f = 0 @@ -31,9 +34,11 @@ def test(name,driver): print k,"FAIL:",tests[k][0],'==>',foo,"reason:",str(ex) f=f+1 print name,'testing complete. PASS:',p,'FAIL:',f,'Total:',t + return bool(f) except: print "FAIL: "+name+" selenium tests. Details:" traceback.print_exc() + return True url = "" if len(sys.argv) > 1: @@ -50,7 +55,8 @@ def test(name,driver): print 'Fetching',u0 njs = urllib.urlopen(u0).read() y = re.findall(r'
[\s\S]*?(?=<\/pre>)',njs) -tests = []; +tests = [] +failure = True print "In-browser unit tests." for x in y: @@ -60,17 +66,28 @@ def test(name,driver): tests.append((re.sub(r'\s',' ',foo[0:bar]),re.sub(r'\s','',foo[bar+5:]))) driver=0 try: - driver = eval('webdriver.'+client+'()') + if client == 'Remote': + driver = webdriver.Remote( + # Example: http://YOUR_SAUCE_USERNAME:YOUR_SAUCE_ACCESSKEY@ondemand.saucelabs.com:80/wd/hub + command_executor=os.environ['SELENIUM_REMOTE_URL'], + # Example: {"browserName": "chrome", "platform": "Linux", "version": "48.0"} + desired_capabilities=json.loads(os.environ['SELENIUM_REMOTE_CAPABILITIES']), + ) + else: + driver = eval('webdriver.'+client+'()') print "Using",client driver.implicitly_wait(2) driver.get(url+'workshop.php') try: WebDriverWait(driver, 30).until(lambda driver : driver.find_element_by_id("text_1")) - test(client,driver) + failure=test(client,driver) except Exception as ex: print "FAIL: text_1 not found. ",ex except Exception as ex: print "Could not use browser",client print ex + if(driver): driver.quit() + +sys.exit(failure) \ No newline at end of file diff --git a/tools/serve.py b/tools/serve.py new file mode 100755 index 0000000..06ac5b0 --- /dev/null +++ b/tools/serve.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +import SimpleHTTPServer +import SocketServer + +HOST = 'localhost' +PORT = 8000 + +Handler = SimpleHTTPServer.SimpleHTTPRequestHandler +Handler.extensions_map.update({ + '.php': 'text/html', +}); + +httpd = SocketServer.TCPServer((HOST, PORT), Handler) + +print "Serving at", HOST, PORT +httpd.serve_forever() \ No newline at end of file diff --git a/tools/unit2.js b/tools/unit2.js index 8d4223c..b05165d 100644 --- a/tools/unit2.js +++ b/tools/unit2.js @@ -76,3 +76,4 @@ for(_j=0;_j<_bar.length;_j++) { runner(_bar[_j].replace(//g,'').split('\nIN> ')); } console.log('unit2: '+_k1+' tests, '+_unit_pass+' pass and '+_unit_fail+' fail.'); +if(typeof process !== "undefined") { process.exit(!!_unit_fail); } diff --git a/tools/workshop_in.php b/tools/workshop_in.php index fbf2ffe..98d1121 100644 --- a/tools/workshop_in.php +++ b/tools/workshop_in.php @@ -23,6 +23,13 @@ function con() { WORKSHOPHTML + + + + +