1 |
|
2 | testsuite = require './testsuite'
|
3 | runner = require './runner'
|
4 | subprocess = require './subprocess'
|
5 |
|
6 | debug = require('debug')('fbp-spec:cli')
|
7 |
|
8 |
|
9 | parse = (args) ->
|
10 | program = require 'commander'
|
11 |
|
12 | program
|
13 | .arguments('<suites>')
|
14 | .action( (suites) -> program.suites = suites )
|
15 | .option('--address <URL>', 'Address of runtime to connect to', String, 'ws://localhost:3569')
|
16 | .option('--secret <secret>', 'Runtime secret', String, null)
|
17 | .option('--command <command>', 'Command to launch runtime under test', String, null)
|
18 | .option('--start-timeout <seconds>', 'Time to wait for runtime to start', Number, 10)
|
19 | .parse(process.argv)
|
20 |
|
21 | return program
|
22 |
|
23 |
|
24 | startRuntime = (options, callback) ->
|
25 |
|
26 | if not options.command
|
27 | callback null
|
28 | return null
|
29 | subprocessOptions = {}
|
30 | return subprocess.start options.command, subprocessOptions, callback
|
31 |
|
32 | hasErrors = (suites) ->
|
33 | failures = 0
|
34 | for s in suites
|
35 | for c in s.cases
|
36 | failures += 1 if c.error
|
37 | return failures > 0
|
38 |
|
39 | runOptions = (options, onUpdate, callback) ->
|
40 | suites = []
|
41 | suites = testsuite.getSuitesSync options.suites if options.suites
|
42 | child = null
|
43 |
|
44 | cleanReturn = (err) ->
|
45 | child.kill() if child
|
46 | return callback err, suites
|
47 |
|
48 | def =
|
49 | protocol: 'websocket'
|
50 | address: options.address
|
51 | secret: options.secret
|
52 |
|
53 | debug 'runtime info', def
|
54 |
|
55 | runnerOptions =
|
56 | connectTimeout: options.startTimeout*1000
|
57 |
|
58 | ru = new runner.Runner def, runnerOptions
|
59 | child = startRuntime options, (err) ->
|
60 | cleanReturn err if err
|
61 |
|
62 | ru.connect (err) ->
|
63 | cleanReturn err if err
|
64 |
|
65 |
|
66 | runner.getComponentSuites ru, (err, componentSuites) ->
|
67 | cleanReturn err if err
|
68 | suites = suites.concat componentSuites
|
69 |
|
70 | runner.runAll ru, suites, onUpdate, (err) ->
|
71 | cleanReturn err if err
|
72 |
|
73 | ru.disconnect (err) ->
|
74 | cleanReturn err
|
75 |
|
76 | testStatusText = (suites) ->
|
77 | results = []
|
78 | ident = ' '
|
79 | for s in suites
|
80 | for c in s.cases
|
81 | continue if not c.passed? or c.shown
|
82 | results.push "#{s.name}" if not s.titleshown
|
83 | s.titleshown = true
|
84 | c.shown = true
|
85 | res = if c.passed then '✓' else "✗ Error: #{c.error}"
|
86 | res = "SKIP: #{c.skip}" if c.skip
|
87 | results.push "#{ident}#{c.name}\n#{ident+ident}#{c.assertion}: #{res}"
|
88 | return results
|
89 |
|
90 | main = () ->
|
91 | options = parse process.argv
|
92 |
|
93 | onUpdate = (suites) ->
|
94 | r = testStatusText suites
|
95 | console.log r.join('\n')
|
96 |
|
97 | runOptions options, onUpdate, (err, suites) ->
|
98 | throw err if err
|
99 | exitStatus = if hasErrors suites then 2 else 0
|
100 | process.exit exitStatus
|
101 |
|
102 |
|
103 | exports.main = main
|