Сделали следующее:
Файл .travis.yml, в корне репозитория GitHub:
dist: xenial
sudo: yes
addons:
chrome: stable
apt:
packages:
- chromium-chromedriver
before_script:
- ln -s /usr/lib/chromium-browser/chromedriver ~/bin/chromedriver
language: python
python:
- '3.7'
script:
- bash ./transcrypt/development/continuous_integration/run.sh
Файл run.sh:
# Install Python modules
pip install mypy
pip install selenium
# Show where we are and what's there
pwd
ls -a -l
# Make everything executable and the rest
chmod -R 777 .
# Enable shipment_test.py to find run_python
export PATH=$PATH:./transcrypt
# Run the shipment test
python ./transcrypt/development/shipment/shipment_test.py --unattended
Файл shipment_test.py:
import os
import os.path
import sys
import datetime
import webbrowser
import argparse
import time
import traceback
import selenium
import selenium.webdriver.chrome.options
import pathlib
# ======== Command args singleton
class CommandArgs:
def __init__ (self):
self.argParser = argparse.ArgumentParser ()
self.argParser.add_argument ('-de', '--dextex', help = "show extended exception reports", action = 'store_true')
self.argParser.add_argument ('-f', '--fcall', help = 'test fast calls', action = 'store_true')
self.argParser.add_argument ('-i', '--inst', help = 'installed version rather than new one', action = 'store_true')
self.argParser.add_argument ('-b', '--blind', help = 'don\'t start browser', action = 'store_true')
self.argParser.add_argument ('-u', '--unattended', help = 'unattended mode', action = 'store_true')
self.__dict__.update (self.argParser.parse_args () .__dict__)
commandArgs = CommandArgs ()
# ======== Browser controller singleton
class BrowserController:
def __init__ (self):
self.options = selenium.webdriver.chrome.options.Options ()
self.options.add_argument ('start-maximized')
if commandArgs.unattended:
self.options.add_argument ('--headless') # Runs Chrome in headless mode.
self.options.add_argument ('--no-sandbox') # Bypass OS security model
self.options.add_argument ('--disable-gpu') # Applicable to windows OS only
self.options.add_argument ('disable-infobars')
self.options.add_argument ('--disable-extensions')
self.webDriver = selenium.webdriver.Chrome (chrome_options = self.options)
self.browserIsRunning = False
def open (self, url):
print (f'Browser controller is opening URL: {url}')
if self.browserIsRunning:
if commandArgs.unattended:
# ---- Show in existing tab
self.webDriver.execute_script (f'window.location.href = "{url}";')
else:
# ---- Open new tab
self.webDriver.execute_script (f'window.open ("{url}","_blank");')
else:
# ---- Open browser and default tab
self.webDriver.get (url)
self.browserIsRunning = True
try:
self.message = self.webDriver.find_element_by_id ('message')
print (f'Back to back autotest, result: {self.message.text.upper ()}')
if 'succeeded' in self.message.text:
return True
else:
return False
except:
print ('No back to back autotest')
return True
browserController = BrowserController ()
# ======== Preparations
relSourcePrepathsOfErrors = []
nodeServerUrl = 'http://localhost:8090'
pythonHttpServerUrl = 'http://localhost:8000'
transpileCommand = 'transcrypt' if commandArgs.inst else 'run_transcrypt'
shipDir = os.path.dirname (os.path.abspath (__file__)) .replace ('\\', '/')
appRootDir = '/'.join (shipDir.split ('/')[ : -2])
print (f'\nApplication root directory: {appRootDir}\n')
def getAbsPath (relPath):
return '{}/{}'.format (appRootDir, relPath)
os.system ('cls' if os.name == 'nt' else 'clear')
# ---- Start an http server in the Transcryp/transcrypt directory
if not commandArgs.blind:
if commandArgs.unattended:
os.system (f'python -m http.server --directory {appRootDir} &')
else:
os.system (f'start python -m http.server --directory {appRootDir}')
# ---- Allow visual check of all command line options
os.system (f'{transpileCommand} -h')
# ======== Individual test function
def test (relSourcePrepath, run, extraSwitches, messagePrename = '', nodeJs = False, build = True, pause = 0, needsAttention = False):
if commandArgs.unattended and needsAttention:
return # This test shouldn't be done, since it can't run unattended
print (f'\n\n******** BEGIN TEST {relSourcePrepath} ********\n')
time.sleep (pause)
# ---- Compute some slugs
sourcePrepath = getAbsPath (relSourcePrepath)
sourcePrepathSplit = relSourcePrepath.split ("/")
relTargetDir = f'{"/".join (sourcePrepathSplit [:-1])}/__target__'
targetDir = getAbsPath (relTargetDir)
moduleName = sourcePrepathSplit [-1]
targetPrepath = f'{targetDir}/{moduleName}'
relMessagePrepath = f'{relTargetDir}/{messagePrename}'
messagePrepath = getAbsPath (relMessagePrepath)
# ---- If there are relevant console messages of the compilation process,
# like with the static typechecking tests, write them into a file that can be served for a visual check
if not os.path.exists (targetDir):
os.makedirs (targetDir) # Transcrypt will make targetDir too late, so it has to happen here
redirect = f' > {messagePrepath}.out' if messagePrename else ''
# ---- Default switches
defaultSwitches = '-da -sf -de -m -n '
if commandArgs.dextex:
defaultSwitches += '-de '
if build:
defaultSwitches += '-b '
# ---- Compile with Transcrypt
os.system (f'{transpileCommand} {defaultSwitches}{extraSwitches}{sourcePrepath}{redirect}')
# ---- Run with CPython to generate HTML file with back to back reference info
if run:
os.system (f'{transpileCommand} -r {defaultSwitches}{extraSwitches}{sourcePrepath}')
# ---- Apply rollup to obtain monolith, since node doesn't support named imports and exports
if nodeJs:
os.system (f'rollup {targetPrepath}.js --o {targetPrepath}.bundle.js --f cjs')
if not commandArgs.blind:
if nodeJs:
os.system (f'start cmd /k node {targetPrepath}.bundle.js'.format (moduleName))
time.sleep (5)
url = nodeServerUrl
else:
url = f'{pythonHttpServerUrl}/{relSourcePrepath}.html'
success = browserController.open (url)
if commandArgs.unattended and not success:
relSourcePrepathsOfErrors.append (relSourcePrepath)
print (f'\n******** END TEST {relSourcePrepath} ********\n\n')
# ======== Perform individual tests
for switches in (('', '-f ') if commandArgs.fcall else ('',)):
test ('development/automated_tests/hello/autotest', True, switches)
test ('development/automated_tests/transcrypt/autotest', True, switches + '-c -xr -xg ')
test ('development/automated_tests/time/autotest', True, switches, needsAttention = True)
test ('development/automated_tests/re/autotest', True, switches)
test ('development/manual_tests/module_random/module_random', False, switches)
test ('development/manual_tests/transcrypt_only/transcrypt_only', False, switches)
test ('development/manual_tests/transcrypt_and_python_results_differ/results', False, switches)
test ('development/manual_tests/static_types/static_types', False, switches + '-ds -dc ', messagePrename = 'static_types')
test ('development/manual_tests/async_await/test', False, switches)
test ('demos/nodejs_demo/nodejs_demo', False, switches, nodeJs = True)
test ('demos/terminal_demo/terminal_demo', False, switches, needsAttention = True)
test ('demos/hello/hello', False, switches, needsAttention = False)
test ('demos/jquery_demo/jquery_demo', False, switches)
test ('demos/d3js_demo/d3js_demo', False, switches)
test ('demos/ios_app/ios_app', False, switches)
test ('demos/react_demo/react_demo', False, switches)
test ('demos/riot_demo/riot_demo', False, switches)
test ('demos/plotly_demo/plotly_demo', False, switches)
test ('demos/three_demo/three_demo', False, switches)
test ('demos/pong/pong', False, switches)
test ('demos/pysteroids_demo/pysteroids', False, switches)
test ('demos/turtle_demos/star', False, switches, pause = 2)
test ('demos/turtle_demos/snowflake', False, switches, pause = 2)
test ('demos/turtle_demos/mondrian', False, switches, pause = 2)
test ('demos/turtle_demos/mandala', False, switches, pause = 2)
test ('demos/cyclejs_demo/cyclejs_demo', False, switches)
test ('demos/cyclejs_demo/cyclejs_http_demo', False, switches, build = False)
test ('demos/cyclejs_demo/component_demos/isolated_bmi_slider/bmi', False, switches)
test ('demos/cyclejs_demo/component_demos/labeled_slider/labeled_slider', False, switches)
test ('tutorials/baseline/bl_010_hello_world/hello_world', False, switches)
test ('tutorials/baseline/bl_020_assign/assign', False, switches)
test ('tutorials/baseline/bl_030_if_else_prompt/if_else_prompt', False, switches, needsAttention = True)
test ('tutorials/baseline/bl_035_if_else_event/if_else_event', False, switches, needsAttention = True)
test ('tutorials/baseline/bl_040_for_simple/for_simple', False, switches)
test ('tutorials/baseline/bl_042_for_nested/for_nested', False, switches)
test ('tutorials/baseline/bl_045_while_simple/while_simple', False, switches, needsAttention = True)
test ('tutorials/static_typing/static_typing', False, switches + '-c -ds ', messagePrename = 'static_typing')
if relSourcePrepathsOfErrors:
print ('\n\n!!!!!!!!!!!!!!!!!!!!\n')
for relSourcePrepathOfError in relSourcePrepathsOfErrors:
print (f'SHIPMENT TEST ERROR: {relSourcePrepathOfError}')
print ('\n!!!!!!!!!!!!!!!!!!!!\n\n')
print ('\nSHIPMENT TEST FAILED\n')
sys.exit (1)
else:
# ---- Make docs, the resulting files are untracked
if not commandArgs.unattended:
origDir = os.getcwd ()
sphinxDir = '/'.join ([appRootDir, 'docs/sphinx'])
os.chdir (sphinxDir)
os.system ('touch *.rst')
os.system ('make html')
os.chdir (origDir)
# ---- Terminate
print ('\nSHIPMENT TEST SUCCEEDED\n')
sys.exit (0)