wsdirector-core 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 582448a4834a77dbe5efc80bc149a3bef0eba766
4
- data.tar.gz: 9d5ef63857c5da95552ff953a186d1d449c1c5d0
2
+ SHA256:
3
+ metadata.gz: e7a99e2e1bbcbf4e63a8c7fcda1653260b0294e0ffc0f3a78c279425c59336f1
4
+ data.tar.gz: 7dc4ee111ce35d7de921e385cfb860500eaa465109a1bb910fa7a592dee9c86e
5
5
  SHA512:
6
- metadata.gz: fd1a5cba842b179f8a8f4acb864dbefbe9789225c8b8af87833ddaf580600075a5bf3e4916aedc4b88acecf0cee0a2962d840eb8aeea44696e703de1b2ebdaa2
7
- data.tar.gz: 831e35a16c6da9f99e09e8b36918d48348503cfeb1c38c57e2d39a5ba66469d223425376ee123a91f4a0a954af267633850a82461e0c4a77845dddb9317d551b
6
+ metadata.gz: f149a7b303f7fbbb60c8a5c79431f73ab89abeaa25a8a17725172d43100079d63d6ea636f36c67dbe9c51af08d9e882c49780bfd144d488b762d012148c32a38
7
+ data.tar.gz: b4de9feedaa87184c63490b81c8f3c9b8b04e23918b48c8783a2f74e190498425ab58d6cb04df5e7b9ddd1292def023af3d848c43bcc39c102f13c0b8e8c5ae5
data/CHANGELOG.md ADDED
@@ -0,0 +1,148 @@
1
+ # Change log
2
+
3
+ ## master
4
+
5
+ ## 1.0.1 (2022-09-29)
6
+
7
+ - Fix `wsdirector-cli` dependencies.
8
+
9
+ ## 1.0.0 (2022-09-19)
10
+
11
+ - Add Phoenix Channels protocol support. ([@palkan][])
12
+
13
+ - Make `receive` order-independent. ([@palkan][])
14
+
15
+ Using `receive` now looks up a matching message through all the mailbox (already received or newly arrived messages).
16
+ If you need strict order guarantees, add `ordered: true` to `receive`.
17
+
18
+ - Add `WSDirector::Snapshot`. ([@palkan][])
19
+
20
+ - Add `locals` support when running scenarios programmatically. ([@palkan][])
21
+
22
+ - Add partial receive data matching support (via `data>` field). ([@palkan][])
23
+
24
+ - Add `connection_options` support (headers, cookies, query). ([@palkan][])
25
+
26
+ - Add loading custom protocols support. ([@palkan][])
27
+
28
+ - Allow passing URL without a scheme part. ([@palkan][])
29
+
30
+ - Add `-vv` option to print action logs. ([@palkan][])
31
+
32
+ - Add `--subprotocol` support and `connection_options` in the scenario files. ([@palkan][])
33
+
34
+ - Add `-f/--file` option to specify scenario path. ([@palkan][])
35
+
36
+ - Drop Ruby 2.5 support.
37
+
38
+ ## 0.5.0 (2021-10-13)
39
+
40
+ - Add JSON support. ([@wazzuper][])
41
+
42
+ - Add new commands to CLI.
43
+
44
+ You can pass a JSON scenario directly to the CLI without creating a file:
45
+
46
+ ```bash
47
+ wsdirector -i '[{"receive": {"data":"welcome"}},{"send":{"data":"send message"}},{"receive":{"data":"receive message"}}]' -u ws://websocket.server:9876
48
+ ```
49
+
50
+ or you can pass it as a JSON file:
51
+
52
+ ```bash
53
+ wsdirector scenario.json -u ws://websocket.server:9876
54
+ ```
55
+
56
+ - Add loop option support. ([@last-in-japan][])
57
+
58
+ You can specify a `loop` option to perform a similar set of actions multiple times:
59
+
60
+ ```yml
61
+ # script.yml
62
+ - client:
63
+ name: "listeners"
64
+ loop:
65
+ multiplier: ":scale" # :scale take number from -s param, and run :scale number of clients in this group
66
+ actions:
67
+ - receive:
68
+ data:
69
+ type: "welcome"
70
+ - send:
71
+ data:
72
+ command: "subscribe"
73
+ identifier: "{\"channel\":\"Channel\"}"
74
+ - receive:
75
+ data:
76
+ identifier: "{\"channel\":\"Channel\"}"
77
+ type: "confirm_subscription"
78
+ - wait_all
79
+ - receive:
80
+ multiplier: ":scale + 1"
81
+ ```
82
+
83
+ Useful in combination with `:scale`.
84
+
85
+ ## 0.4.0 (2020-08-24)
86
+
87
+ - **Drop Ruby 2.4 support**. ([@palkan][])
88
+
89
+ - Add sampling support. ([@palkan][])
90
+
91
+ You can specify a `sample` option for a step to only run this step by specified number of clients from the group:
92
+
93
+ ```yml
94
+ - perform:
95
+ sample: ":scale / 2"
96
+ channel: "chat"
97
+ params:
98
+ id: 2
99
+ action: "speak"
100
+ data:
101
+ message: "Hello!"
102
+ ```
103
+
104
+ Useful in combination with `:scale`.
105
+
106
+ **NOTE:** Sample size is always greater or equal to 1.
107
+
108
+ - Add ERB support. ([@palkan][])
109
+
110
+ Now you can, for example, access `ENV` from scenarios.
111
+
112
+ ## 0.3.0 (2018-05-02)
113
+
114
+ - Add `debug` action and options. ([@palkan][])
115
+
116
+ Allows to print arbitrary messages during the execution.
117
+
118
+ - Add `sleep` action. ([@palkan][])
119
+
120
+ - Add `receive_all` action. ([@palkan][])
121
+
122
+ Allows to handle multiple messages with unspecified order:
123
+
124
+ ```yml
125
+ - receive_all:
126
+ messages:
127
+ - data:
128
+ text: "Hello!"
129
+ multiplier: ":scale + :scale"
130
+ channel: "chat"
131
+ params:
132
+ id: 2
133
+ - data:
134
+ text: "message sent"
135
+ channel: "chat"
136
+ params:
137
+ id: 2
138
+ ```
139
+
140
+ ## 0.2.0 (2017-11-05)
141
+
142
+ - Initial version. ([@palkan][], [@Kirillvs][], [@Grandman][])
143
+
144
+ [@palkan]: https://github.com/palkan
145
+ [@Kirillvs]: https://github.com/Kirillvs
146
+ [@Grandman]: https://github.com/Grandman
147
+ [@wazzuper]: https://github.com/wazzuper
148
+ [@last-in-japan]: https://github.com/last-in-japan
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Vladimir Dementyev
3
+ Copyright (c) 2017-2022 palkan
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,38 +1,355 @@
1
- # Wsdirector::Core
1
+ [![Cult Of Martians](http://cultofmartians.com/assets/badges/badge.svg)](http://cultofmartians.com/tasks/websocket-director.html)
2
+ [![Gem Version](https://badge.fury.io/rb/wsdirector-cli.svg)](https://rubygems.org/gems/wsdirector-cli)
3
+ [![Build](https://github.com/palkan/wsdirector/workflows/Build/badge.svg)](https://github.com/palkan/wsdirector/actions)
2
4
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/wsdirector/core`. To experiment with that code, run `bin/console` for an interactive prompt.
5
+ # WebSocket Director
4
6
 
5
- TODO: Delete this and the text above, and describe your gem
7
+ Command line tool for testing WebSocket servers using scenarios.
8
+
9
+ Suitable for testing any websocket server implementation, like [Action Cable](https://github.com/rails/rails/tree/master/actioncable), [AnyCable](https://anycable.io), [Phoenix Channels](https://hexdocs.pm/phoenix/channels.html), [GraphQL WS](https://github.com/enisdenjo/graphql-ws) and so on.
10
+
11
+ > 📖 Read also [WebSocket Director: scenario-based integration tests for realtime apps](https://evilmartians.com/chronicles/websocket-director-scenario-based-integration-tests-for-real-time-apps)
6
12
 
7
13
  ## Installation
8
14
 
9
- Add this line to your application's Gemfile:
15
+ Install CLI:
16
+
17
+ ```sh
18
+ gem install wsdirector-cli
19
+ ```
20
+
21
+ Or use WebSockets Director as a library (see below for intructions):
10
22
 
11
23
  ```ruby
12
- gem 'wsdirector-core'
24
+ # Gemfile
25
+ gem "wsdirector-core", "~> 1.0"
13
26
  ```
14
27
 
15
- And then execute:
28
+ ## Usage
16
29
 
17
- $ bundle
30
+ Create YAML file with simple testing script:
18
31
 
19
- Or install it yourself as:
32
+ ```yml
33
+ # script.yml
34
+ - receive: "Welcome" # expect to receive message
35
+ - send:
36
+ data: "send message" # send message, all messages in data will be parse to json
37
+ - receive:
38
+ data: "receive message" # expect to receive json message
39
+ ```
20
40
 
21
- $ gem install wsdirector-core
41
+ and run it with this command:
22
42
 
23
- ## Usage
43
+ ```bash
44
+ wsdirector -f script.yml -u ws://websocket.server:9876/ws
45
+
46
+ #=> 1 clients, 0 failures
47
+ ```
48
+
49
+ You can also use positional arguments:
50
+
51
+ ```sh
52
+ wsdirector script.yml ws://websocket.server:9876/ws
53
+ ```
54
+
55
+ You can create more complex scenarios with multiple client groups:
56
+
57
+ ```yml
58
+ # script.yml
59
+ - client: # first clients group
60
+ name: "publisher" # optional group name
61
+ multiplier: ":scale" # :scale take number from -s param, and run :scale number of clients in this group
62
+ actions:
63
+ - receive:
64
+ data: "Welcome"
65
+ - wait_all # makes all clients in all groups wait untill every client get this point (global barrier)
66
+ - send:
67
+ data: "test message"
68
+ - client:
69
+ name: "listeners"
70
+ multiplier: ":scale * 2"
71
+ actions:
72
+ - receive:
73
+ data: "Welcome"
74
+ - wait_all
75
+ - receive:
76
+ multiplier: ":scale" # you can use multiplier with any action
77
+ data: "test message"
78
+ ```
79
+
80
+ Run with scale factor:
81
+
82
+ ```bash
83
+ wsdirector -f script.yml -u ws://websocket.server:9876 -s 10
84
+
85
+ #=> Group publisher: 10 clients, 0 failures
86
+ #=> Group listeners: 20 clients, 0 failures
87
+ ```
88
+
89
+ The simpliest scenario is just checking that socket is succesfully connected:
90
+
91
+ ```yml
92
+ - client:
93
+ name: connection check
94
+ # no actions
95
+ ```
96
+
97
+ Run with loop option:
98
+
99
+ ```yml
100
+ # script.yml
101
+ - client:
102
+ name: "listeners"
103
+ loop:
104
+ multiplier: ":scale" # :scale take number from -s param, and run :scale number of clients in this group
105
+ actions:
106
+ - receive:
107
+ data:
108
+ type: "welcome"
109
+ - send:
110
+ data:
111
+ command: "subscribe"
112
+ identifier: "{\"channel\":\"Channel\"}"
113
+ - receive:
114
+ data:
115
+ identifier: "{\"channel\":\"Channel\"}"
116
+ type: "confirm_subscription"
117
+ - wait_all
118
+ - receive:
119
+ multiplier: ":scale + 1"
120
+ ```
121
+
122
+ By default, `receive` action expects the exact `data` match. In some cases, it's useful to only match the specified keys (inclusion). For that, you can use `data>` field instead:
123
+
124
+ ```yml
125
+ - client:
126
+ actions:
127
+ - receive:
128
+ data:
129
+ type: "welcome"
130
+ - send:
131
+ data:
132
+ command: "subscribe"
133
+ identifier: "{\"channel\":\"Channel\"}"
134
+ - receive:
135
+ data>:
136
+ type: "confirm_subscription"
137
+ ```
138
+
139
+ Also you can pass a JSON file with some testing scripts:
140
+
141
+ ```bash
142
+ wsdirector -f scenario.json -u ws://websocket.server:9876
143
+ ```
144
+
145
+ or pass a JSON scenario directly to the CLI without creating a file:
146
+
147
+ ```bash
148
+ wsdirector -i '[{"receive": {"data":"welcome"}},{"send":{"data":"send message"}},{"receive":{"data":"receive message"}}]' -u ws://websocket.server:9876
149
+ ```
150
+
151
+ Type `wsdirector --help` to check all commands.
152
+
153
+ ### Receive order
154
+
155
+ By default, the `receive` action scans through all available or newly added message to find a matching one.
156
+ If you want to check the order of incoming messages, add the `ordered: true` option to the `receive` action.
157
+
158
+ ### Connection configuration
159
+
160
+ You can specify client's headers, cookies or query string params via the `connection_options` directive:
161
+
162
+ ```yml
163
+ - client:
164
+ connection_options:
165
+ headers:
166
+ "X-API-KEY": "secret"
167
+ query:
168
+ token: "123"
169
+ cookies:
170
+ session_id: "2022"
171
+ ```
172
+
173
+ **NOTE**: Query string params could also be passed as a part of the URL. Specifying them in the scenario allows you to provide values via the interpolation.
174
+
175
+ ### Using as a library
24
176
 
25
- TODO: Write usage instructions here
177
+ You can integrate WS Director into your library or application by using its APIs:
178
+
179
+ ```ruby
180
+ # Could be a file path or JSON-encoded string as well
181
+ scenario = [
182
+ {
183
+ send: {
184
+ data: "ping"
185
+ }
186
+ },
187
+ {
188
+ receive: {
189
+ data: "pong"
190
+ }
191
+ }
192
+ ]
193
+
194
+ result = WSDirector.run(scenario, url: "ws://my.ws.server:4949/live")
195
+ result.success? #=> true of false
196
+ result.groups #=> result data for each client group
197
+ ```
198
+
199
+ If you're using YAML-based scenarios, you can also pass local variables to be used with ERB via the `locals` option:
200
+
201
+ ```yml
202
+ - client:
203
+ connection_options:
204
+ headers:
205
+ "X-API-TOKEN": <%= token %>
206
+ ```
207
+
208
+ ```ruby
209
+ token = UserToken.generate
210
+ WSDirector.run(scenario, url: "ws://my.ws.server:4949/live", locals: {token:})
211
+ ```
212
+
213
+ ### Protocols
214
+
215
+ WSDirector uses protocols to handle provide convinient actions for some popular protocols.
216
+
217
+ #### ActionCable Example
218
+
219
+ Channel code:
220
+
221
+ ```ruby
222
+ class ChatChannel < ApplicationCable::Channel
223
+ def subscribed
224
+ stream_from "chat_test"
225
+ end
226
+
227
+ def echo(data)
228
+ transmit data
229
+ end
230
+
231
+ def broadcast(data)
232
+ ActionCable.server.broadcast "chat_test", data
233
+ end
234
+ end
235
+ ```
236
+
237
+ Scenario:
238
+
239
+ ```yml
240
+ - client:
241
+ multiplier: ":scale"
242
+ name: "publisher"
243
+ protocol: "action_cable"
244
+ actions:
245
+ - subscribe:
246
+ channel: "ChatChannel"
247
+ - wait_all
248
+ - perform:
249
+ channel: "ChatChannel"
250
+ action: "broadcast"
251
+ data:
252
+ text: "hello"
253
+ - client:
254
+ name: "listener"
255
+ protocol: "action_cable"
256
+ actions:
257
+ - subscribe:
258
+ channel: "ChatChannel"
259
+ - wait_all
260
+ - receive:
261
+ channel: "ChatChannel"
262
+ data:
263
+ text: "hello"
264
+ ```
265
+
266
+ #### Phoenix Channels
267
+
268
+ With "phoenix" protocol, you can use communicate with a [Phoenix Channels](https://hexdocs.pm/phoenix/channels.html) server:
269
+
270
+ ```yml
271
+ - client:
272
+ protocol: phoenix
273
+ multiplier: ":scale"
274
+ actions:
275
+ - join:
276
+ topic: room:lobby
277
+ - wait_all
278
+ - send:
279
+ topic: room:lobby
280
+ event: new_msg
281
+ data:
282
+ body: "Hey from WS director!"
283
+ - receive:
284
+ topic: room:lobby
285
+ multiplier: ":scale"
286
+ event: new_msg
287
+ data:
288
+ body: "Hey from WS director!"
289
+ ```
290
+
291
+ **IMPORTANT**: We support only v2 version of the Channels protocol.
292
+
293
+ #### Custom protocols
294
+
295
+ You can define your own protocol and load it dynamically:
296
+
297
+ ```ruby
298
+ # It's important to put a custom protocol class under WSDirector::Protocols
299
+ module WSDirector::Protocols
300
+ class CustomProtocol < Base
301
+ def send_ping_and_receive_pong
302
+ send("data" => {"type" => "ping"})
303
+ receive("data" => {"type" => "pong"})
304
+ end
305
+ end
306
+ end
307
+ ```
308
+
309
+ Now you can load it via the `-r` option:
310
+
311
+ ```sh
312
+ $ wsdirector -u localhost:3232/ws -i '["send_ping_and_receive_pong"]' -r ./path/to/custom_protocol.rb -vv
313
+
314
+ hh:mm:ss client=default_1 Connecting
315
+ hh:mm:ss client=default_1 Connected (45ms)
316
+ hh:mm:ss client=default_1 Sent message: {"type":"ping"}
317
+ hh:mm:ss client=default_1 Receive message: {"type":"pong"}
318
+ hh:mm:ss client=default_1 Received message: {"type":"pong"} (21ms)
319
+ ```
320
+
321
+ ## Testing frameworks integration
322
+
323
+ WSDirector does not provide any specific helpers for RSpec or Minitest. Instead, we provide an example setup, which you could adjust to your needs (and which is too small to be a part of the library).
324
+
325
+ The example below implies running tests against an Action Cable server with a token-based authentication
326
+
327
+ ```ruby
328
+ module WSDirectorTestHelper
329
+ def run_websocket_scenario(path, token:, url: ActionCable.server.config.url, **options)
330
+ url = "#{url}?jid=#{token}"
331
+ scenario = Rails.root.join "spec" / "fixtures" / "wsdirector" / path
332
+
333
+ WSDirector.run(scenario, url:, **options)
334
+ end
335
+ end
336
+
337
+ # In RSpec, you can include this modules via the configuration
338
+ RSpec.configure do |config|
339
+ # Here we only add this helper to system tests
340
+ config.include WSDirectorTestHelper, type: :system
341
+ end
342
+ ```
26
343
 
27
- ## Development
344
+ ## Future Ideas
28
345
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
346
+ - Report timings (per-client and aggregates)
30
347
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
348
+ - What else? [Submit an issue!](https://github.com/palkan/wsdirector/issues/new)
32
349
 
33
350
  ## Contributing
34
351
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/wsdirector-core.
352
+ Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/wsdirector.
36
353
 
37
354
  ## License
38
355
 
data/bin/wsdirector ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_path = File.expand_path("../lib", __dir__)
4
+ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
5
+
6
+ require "wsdirector-cli"
7
+
8
+ begin
9
+ WSDirector::CLI.new.run
10
+ rescue => e
11
+ raise e if $DEBUG
12
+ STDERR.puts e.message
13
+ STDERR.puts e.backtrace.take(10).join("\n") if ENV["WSDIRECTOR_DEBUG"] == "1"
14
+ exit 1
15
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "uri"
5
+
6
+ require "wsdirector"
7
+
8
+ module WSDirector
9
+ # Command line interface for WsDirector
10
+ class CLI
11
+ class Configuration
12
+ attr_accessor :ws_url, :scenario_path, :colorize, :scale,
13
+ :sync_timeout, :json_scenario, :subprotocol, :verbose
14
+
15
+ def initialize
16
+ reset!
17
+ end
18
+
19
+ def colorize?
20
+ colorize == true
21
+ end
22
+
23
+ # Restore to defaults
24
+ def reset!
25
+ @scale = 1
26
+ @colorize = $stdout.tty?
27
+ @sync_timeout = 5
28
+ end
29
+ end
30
+
31
+ attr_reader :config
32
+
33
+ def run
34
+ @config = Configuration.new
35
+
36
+ parse_args!
37
+
38
+ begin
39
+ require "colorize" if config.colorize?
40
+ rescue LoadError
41
+ config.colorize = false
42
+ warn "Install colorize to use colored output"
43
+ end
44
+
45
+ connection_options = {
46
+ subprotocol: config.subprotocol
47
+ }.compact
48
+
49
+ scenario = config.scenario_path || config.json_scenario
50
+
51
+ config.ws_url = "ws://#{config.ws_url}" unless config.ws_url.start_with?(/wss?:\/\//)
52
+
53
+ url = config.ws_url
54
+ scale = config.scale
55
+ sync_timeout = config.sync_timeout
56
+ colorize = config.colorize
57
+
58
+ logger = $stdout if config.verbose
59
+
60
+ result = WSDirector.run(
61
+ scenario,
62
+ url:,
63
+ connection_options:,
64
+ scale:,
65
+ sync_timeout:,
66
+ logger:,
67
+ colorize:
68
+ )
69
+
70
+ puts "\n\n" if config.verbose
71
+
72
+ result.print_summary(colorize: config.colorize?)
73
+ result.success? || exit(1)
74
+ end
75
+
76
+ private
77
+
78
+ FILE_FORMAT = /.+.(json|yml)\z/
79
+ private_constant :FILE_FORMAT
80
+
81
+ def parse_args!
82
+ parser = OptionParser.new do |opts|
83
+ opts.banner = "Usage: wsdirector scenario_path ws_url [options]"
84
+
85
+ opts.on("-s SCALE", "--scale=SCALE", Integer, "Scale factor") do
86
+ config.scale = _1
87
+ end
88
+
89
+ opts.on("-t TIMEOUT", "--timeout=TIMEOUT", Integer, "Synchronization (wait_all) timeout") do
90
+ config.sync_timeout = _1
91
+ end
92
+
93
+ opts.on("-i JSON", "--include=JSON", String, "Include JSON to parse") do
94
+ config.json_scenario = _1
95
+ end
96
+
97
+ opts.on("-u URL", "--url=URL", Object, "Websocket server URL") do
98
+ config.ws_url = _1
99
+ end
100
+
101
+ opts.on("-f PATH", "--file=PATH", String, "Scenario path") do
102
+ config.scenario_path = _1
103
+ end
104
+
105
+ opts.on("--subprotocol=VALUE", String, "WebSocket subprotocol") do
106
+ config.subprotocol = _1
107
+ end
108
+
109
+ opts.on("-c", "--[no-]color", "Colorize output") do
110
+ config.colorize = _1
111
+ end
112
+
113
+ opts.on("-v", "--version", "Print version") do
114
+ $stdout.puts WSDirector::VERSION
115
+ exit 0
116
+ end
117
+
118
+ opts.on("-vv", "Print verbose logs") do
119
+ config.verbose = true
120
+ end
121
+
122
+ opts.on("-r", "--require=PATH", "Load Ruby file (e.g., protocol)") do
123
+ Kernel.load(_1)
124
+ end
125
+ end
126
+
127
+ parser.parse!
128
+
129
+ unless config.scenario_path
130
+ config.scenario_path = ARGV.grep(FILE_FORMAT).last
131
+ end
132
+
133
+ unless config.ws_url
134
+ config.ws_url = ARGV.grep(URI::DEFAULT_PARSER.make_regexp).last
135
+ end
136
+
137
+ check_for_errors
138
+ end
139
+
140
+ def check_for_errors
141
+ if config.json_scenario.nil?
142
+ raise(Error, "Scenario is missing") unless config.scenario_path
143
+
144
+ unless File.file?(config.scenario_path)
145
+ raise(Error, "File doesn't exist # config.scenario_path}")
146
+ end
147
+ end
148
+
149
+ raise(Error, "Websocket server url is missing") unless config.ws_url
150
+ end
151
+ end
152
+ end