In contrast to HTTP requests, WebSockets are much more quick, but also much more complicated to develop and maintain. Since there is no predefined way to check the sequence of messages, and if it even was, frquently you just don't know the exact order of them!
This page describes the usage and structure of flows and units. If you need to use the JS library itself, see extra info on the next page.
Any test in WS Testing Engine consists of flows (which may be considered as unit tests). And each flow may be an array or a dictionary with unit objects. If flow object is a list, all its units are run in the order of their positions by default. If flow object is a dictionary, all its units must provide a key of the next unit. Any flow object must have a string name at key 0 and entry unit object at 1 key. Each flow begins when the previous one ends (obviously, excluding the first one).Unit object structure:
All the fields are not strictly necessary. However, task may be skipped only in one case only (when a unit is entry poing of a flow; only enter function returning string key of other unit must present this way), so, don't forget to add it.
Function named task of each unit is run only if previous unit object succeeded. To assert it, condition, key and val are used. So, initially task of a unit object is run, then the Controller object waits for appropriate message. But if there is no result, after specific amount of time the unit object and its flow will be failed.
Function named task can return nothing or a single dictionary or an array of dictionaries to be send as JSON (in the second case multiple messages will be sent). Also, it can set value to ref.next to change next unit.
A unit object can follow these patterns for assertion:
If condition is specified, it will get parsed JSON as data argument and must return bool for going to next unit or failing (if flow object is an array), or an integer or string for going to specific unit object. String or integer result will override next unit specified by task function in ref.next.
If both key and val are specified, then expression data[key]==val will be used to assert. Also, val may be an array, then if any of its value equals to data[key], then assertion is true.
If key only is specified (not val), the value of data[key] will be used as bool.
Function named finalise is called on unit objects success. Its result is handled the same as the result of task function.
Function named enter is called if unit does not have task function, and must return key of next unit. This function is similar to operators continue, skip and pass in some languages.
You can manage WS Testing Engine behavior widely using provided GUI. The list below describes it. By the way, most of these parameters can be set from JS data file with args object.
Of course, you have to provide server address (args.server from code) for WebSockets connection and JS data file. This file may be loaded from the Internet (you have to put the url and click button) or from your computer (just choose the file).
You can set waiting time (args.waiting_time): amount of time before unit fails if has no appropriate messafe. The value 1000 means one second.
You can set delay (args.delay): amount of time before between end of one unit and beginning of another. The value 1000 means one second.
You can use "print messages content" checkbox. If it is set, you will see sent and received messages and come other comments.
You can use "split flows connections" checkbox (args.split). If it is set, each flow gets a new WebSockets connection.
There are plenty files ready to use and investigate WS Testing Engine on practice:
data_ether.js – example test of The Etherscan Block Explorer WebSocket API, 2 flows, 6 units. Run file (the API doesn't work since July 2018).
Features: data[key]==val; flow as a dictionary, ref.next; args.split.