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