The capture server captures browsers as slaves, and offers a completely generic API for carrying out work across those slaves. A workload is known as a “session”, and a test run is typically a session. Other uses include for instance synced-across-devices slide shows (for which a POC has been built).
In general, the server knows nothing specifically of testing. It knows how to accept and serve web pages (in the form of resource sets), capture and command browser slaves, and coordinate every piece using messaging (Bayeux on the HTTP level, or websockets if available).
The server is the central hub for all work in buster-capture-server. It needs to be manually attached to an existing node HTTP server.
var server = captureServerModule.createServer();
Creates a server instance.
server.attach(httpServer);
Attaches the buster-capture-server to a Node.js HTTP server. All HTTP requests that buster-capture-server handles is “consumed”, and won’t trigger any “request” event listeners on the Node.js HTTP server.
To interact with a server, you always use a server client. This has the benefit of making the API for interacting with the server identical whether the server runs in the same process as your own code, or the server is in another process (or even on another computer).
var serverClient = captureServerModule.createServerClient(opts);
Creates a new server client.
Options
var promise = serverClient.createSession(opts);
Creates and queues a new session.
The promise resolves with the session object, and rejects with an error object.
Options
serverClient.connect();
Connects the server client to the server. Needs to be called manually, typically immediately after the server client is created.
serverClient.disconnect();
Disconnecting is not mandatory, it’s only provided as a convenience if you want to clean up the connections. You can also just kill the process without disconnecting first, the server will be fine.
A session client is created for each session you want to interact with. It provides lifecycle events, and user specific pubsub events to send data to and from the slaves.
var sessionClient = captureServerModule.createSessionClient(opts);
Creates a new session client.
Options
sessionClient.connect();
Connects the session client. Needs to be called manually for every session client create, typically immediately after the session client is created.
sessionClient.disconnect();
Disconnecting is not mandatory, it’s only provided as a convenience if you want to clean up the connections. You can also just kill the process without disconnecting first, the server will be fine.
sessionClient.emit(event[, data]);
Emit an event to all slaves.
The event is a string. Examples: "goto", "slide:next", "testcase:state:timeout".
The data is optional, and will be JSON serialized in the form of {data: /* <your data here> */}, so it can be an array, and object, a string, or a number.
sessionClient.emit("slide:goto", 5); sessionClient.emit("slide:next");
sessionClient.on(event, handler);
Listens to events from all slaves.
The event string is identical in format to the one in sessionClient.emit().
The handler is a function, taking one argument which is the data that was emitted.
sessionClient.on("test:success", function (testInfo) { reporter.reportSuccess(testInfo); }); sessionClient.on("test:failure", function (testInfo) { reporter.reportFailure(testInfop); });
sessionClient.end();
Ends the session.
Promises are used for lifecycle events. These events only trigger once per session.
Note
TODO
We also need events for slave join and leave.
var sessionClient = bCapServ.createSessionClient({ host: "0.0.0.0", port: 8080, session: aSession }); sessionClient.connect(); // Emit an event to slaves when all slaves have loaded the session. sessionClient.loaded.then(function () { sessionClient.emit("some:event", 123); });
The slave environment for your sessions is a frame in a frameset. APIs are made available so you can send messages to and from the slave and the session client.
The ID of the current slave.
The context path to where the session resource set resources are available. If you have a resource with the path "/foo/bar.js", you can dynamically create a script tag for it like so:
var scriptTag = document.createElement("script"); scriptTag.src(buster.env.contextPath + "/foo/bar.js"); document.body.appendChild(scriptTag);
Note that a relative path would also work:
var scriptTag = document.createElement("script"); scriptTag.src("foo/bar.js"); document.body.appendChild(scriptTag);
buster.emit(event, [data]);
Emits the event to session client and all slaves, including itself.
buster.emit("slide:goto", 1); window.addEventListener("keyup", function (e) { if (e.keyCode == 37) buster.emit("slide:prev"); if (e.keyCode == 39) buster.emit("slide:next"); });
buster.on(event, handler);
Listens to the event.
buster.on("slide:goto", function (num) { currentSlide = num; loadCurrentSlide(); }); buster.on("slide:next", function () { ++currentSlide; loadCurrentSlide(); });