Refactor integration tests and add WebDriver mode

This commit is contained in:
Tom Robinson 2013-07-30 14:23:20 -07:00
parent e185e15558
commit cd7c899f3c
7 changed files with 200 additions and 124 deletions

2
.gitignore vendored
View File

@ -12,3 +12,5 @@ logs
results
npm-debug.log
node_modules
activemq-data

View File

@ -27,6 +27,9 @@
console.log("connected");
socket.emit("subscribe", push_id);
console.log("subscribed to push_id:", push_id);
// Used in integration tests:
window.messages = [];
});
socket.on("disconnect", function () {
console.log("disconnected");
@ -35,6 +38,7 @@
console.log("error", error);
});
socket.on("message", function (data) {
messages.push(data)
console.log("message:", JSON.stringify(data, null, 2));
});
@ -67,7 +71,7 @@
console._log = console.log;
console.log = function() {
console._log.apply(console, arguments);
document.getElementById("log").innerText += new Date() + ": " + Array.prototype.join.call(arguments, " ") + "\n";
document.getElementById("log").textContent += new Date() + ": " + Array.prototype.join.call(arguments, " ") + "\n";
}
</script>

View File

@ -27,6 +27,9 @@
"chai-as-promised": "~3.3.1",
"q": "~0.9.6",
"socket.io-client": "~0.9.16",
"node-uuid": "~1.4.0"
"node-uuid": "~1.4.0",
"q-step": "0.0.1",
"wd": "0.0.33",
"q-proxy": "0.0.1"
}
}

View File

@ -1,122 +0,0 @@
require("mocha-as-promised")()
chai = require "chai"
chai.use require "chai-as-promised"
{ expect } = chai
Q = require "q"
io = require "socket.io-client"
merge = require "deepmerge"
uuid = require "node-uuid"
activepush = require "../index"
{ ActivePush } = activepush
# Delay before checking received messages to ensure all messages get delivered.
# Increase this value if tests are failiing non-deterministically.
# TODO: better way to detect all messages have been delivered?
WAIT_TIME = 200
config = activepush.config.loadConfiguration "test"
# config.logging.level = "DEBUG"
configureActivePush = (config) ->
activepush = new ActivePush(config)
activepush.start()
configureSocketIO = (port, push_id, options = {}) ->
deferred = Q.defer()
socket = io.connect "http://localhost:#{port}", merge(options, "force new connection": true)
# For some reason socket.io-client doesn't respect the "transports" option so we have to set it manually
socket.socket.options.transports = options.transports if options.transports?
socket.on "connect", ->
socket.emit "subscribe", push_id
deferred.resolve collectMessages(socket)
deferred.promise
uniqueInbox = ->
"/topic/activepush-test-"+uuid.v1()
# Use unique messages to ensure we don't messages from other tests, etc.
uniqueMessage = (prefix="") ->
prefix+(if prefix then "-" else "")+uuid.v1()
# Helper to collect messages into an array
collectMessages = (socket) ->
messages = []
socket.on "message", (message) ->
messages.push message
messages
describe "Single ActivePush instance", ->
ap = null
before ->
# Use a unique inbox in case we're running multiple tests using the same ActiveMQ server concurrently etc
inbox = uniqueInbox()
configureActivePush(merge(config, stomp:inbox:inbox)).then (activePush) ->
ap = activePush
after ->
ap.stop()
it "should not buffer messages (treat as transient)", ->
expected = uniqueMessage("NO")
ap.producer.publish "my_push_id", expected
configureSocketIO(ap.config.http.port, "my_push_id").then (receivedMessages) ->
Q.delay(WAIT_TIME).then ->
expect(receivedMessages).to.deep.equal []
it "should relay the correct messages to a single client", ->
expected = uniqueMessage("YES")
configureSocketIO(ap.config.http.port, "my_push_id").then (receivedMessages) ->
ap.producer.publish "my_push_id", expected
ap.producer.publish "other_push_id", uniqueMessage("NO")
Q.delay(WAIT_TIME).then ->
expect(receivedMessages).to.deep.equal [expected]
it "should relay the correct messages to multiple clients", (done) ->
expected = uniqueMessage("YES")
Q.all(for index in [0..1]
configureSocketIO(ap.config.http.port, "my_push_id")
).then (allReceivedMessages) ->
ap.producer.publish "my_push_id", expected
ap.producer.publish "other_push_id", uniqueMessage("NO")
Q.delay(WAIT_TIME).then ->
expect(allReceivedMessages).to.deep.equal [[expected], [expected]]
it "should relay multiple messages when using XHR transport", ->
expected = uniqueMessage("YES")
# FIXME: figure out how to get rid of this delay
configureSocketIO(ap.config.http.port, "my_push_id", transports: ["xhr-polling"], 'try multiple transports': false).delay(1000).then (receivedMessages) ->
ap.producer.publish "my_push_id", expected
ap.producer.publish "my_push_id", expected
Q.delay(WAIT_TIME).then ->
expect(receivedMessages).to.deep.equal [expected, expected]
describe "Multiple ActivePush instances", ->
aps = null
before ->
# Use a unique inbox in case we're running multiple tests using the same ActiveMQ server concurrently etc
inbox = uniqueInbox()
Q.all(for index in [0..1]
configureActivePush(merge(config,
stomp:inbox: inbox
http:port: config.http.port + index + 1 # Don't re-use the same port from first test
))
).then (activePushArr) ->
aps = activePushArr
after ->
Q.all(ap.stop() for ap in aps)
it "should relay the correct messages to multiple clients", (done) ->
Q.all(for ap in aps
configureSocketIO(ap.config.http.port, "my_push_id")
).then (allReceivedMessages) ->
expected = for ap, index in aps
msg = uniqueMessage("YES#{index}")
ap.producer.publish "my_push_id", msg
ap.producer.publish "other_push_id", uniqueMessage("NO")
msg
Q.delay(WAIT_TIME*2).then ->
allReceivedMessages = (messages.sort() for messages in allReceivedMessages)
allExpectedMessages = (expected.sort() for messages in allReceivedMessages)
expect(allReceivedMessages).to.deep.equal allExpectedMessages

View File

@ -0,0 +1,108 @@
require("mocha-as-promised")()
chai = require "chai"
chai.use require "chai-as-promised"
{ expect } = chai
Q = require "q"
merge = require "deepmerge"
uuid = require "node-uuid"
activepush = require "../index"
{ ActivePush } = activepush
TIMEOUT = 20000
createServer = (config) ->
new ActivePush(config).start()
# These tests can be run either using socket.io-client within Node to simulate a browser, or using WebDriver to test real browsers
exports.initIntegrationTests = (options) ->
{ name, createClient } = options
config = activepush.config.loadConfiguration "test"
# config.logging.level = "DEBUG"
describe "Single ActivePush instance (#{name})", ->
@timeout TIMEOUT
server = null
before ->
# Use a unique inbox in case we're running multiple tests using the same ActiveMQ server concurrently etc
inbox = uniqueInbox()
createServer(merge(config, stomp:inbox:inbox)).then (activePush) ->
server = activePush
after ->
server.stop()
it "should not buffer messages (treat as transient)", ->
expected = uniqueMessage("NO")
server.producer.publish "my_push_id", expected
createClient(server.config.http.port, "my_push_id").then (getMessages) ->
getMessages().then (receivedMessages) ->
expect(receivedMessages).to.deep.equal []
it "should relay the correct messages to a single client", ->
expected = uniqueMessage("YES")
createClient(server.config.http.port, "my_push_id").then (getMessages) ->
server.producer.publish "my_push_id", expected
server.producer.publish "other_push_id", uniqueMessage("NO")
getMessages().then (receivedMessages) ->
expect(receivedMessages).to.deep.equal [expected]
it "should relay the correct messages to multiple clients", (done) ->
expected = uniqueMessage("YES")
Q.all(for index in [0..1]
createClient(server.config.http.port, "my_push_id")
).then (allGetMessages) ->
server.producer.publish "my_push_id", expected
server.producer.publish "other_push_id", uniqueMessage("NO")
Q.all(getMessages() for getMessages in allGetMessages).then (allReceivedMessages) ->
expect(allReceivedMessages).to.deep.equal [[expected], [expected]]
it "should relay multiple messages when using XHR transport", ->
expected = uniqueMessage("YES")
# FIXME: figure out how to get rid of this delay
createClient(server.config.http.port, "my_push_id", transports: ["xhr-polling"], 'try multiple transports': false).delay(1000).then (getMessages) ->
server.producer.publish "my_push_id", expected
server.producer.publish "my_push_id", expected
getMessages().then (receivedMessages) ->
expect(receivedMessages).to.deep.equal [expected, expected]
describe "Multiple ActivePush instances (#{name})", ->
@timeout TIMEOUT
servers = null
before ->
# Use a unique inbox in case we're running multiple tests using the same ActiveMQ server concurrently etc
inbox = uniqueInbox()
Q.all(for index in [0..1]
createServer(merge(config,
stomp:inbox: inbox
http:port: config.http.port + index + 1 # Don't re-use the same port from first test
))
).then (_servers) ->
servers = _servers
after ->
Q.all(server.stop() for server in servers)
it "should relay the correct messages to multiple clients", (done) ->
Q.all(for server in servers
createClient(server.config.http.port, "my_push_id")
).then (allGetMessages) ->
expected = for server, index in servers
msg = uniqueMessage("YES#{index}")
server.producer.publish "my_push_id", msg
server.producer.publish "other_push_id", uniqueMessage("NO")
msg
Q.all(getMessages() for getMessages in allGetMessages).then (allReceivedMessages) ->
allReceivedMessages = (messages.sort() for messages in allReceivedMessages)
allExpectedMessages = (expected.sort() for messages in allReceivedMessages)
expect(allReceivedMessages).to.deep.equal allExpectedMessages
uniqueInbox = ->
"/topic/activepush-test-"+uuid.v1()
# Use unique messages to ensure we don't messages from other tests, etc.
uniqueMessage = (prefix="") ->
prefix+(if prefix then "-" else "")+uuid.v1()

View File

@ -0,0 +1,31 @@
Q = require "q"
io = require "socket.io-client"
merge = require "deepmerge"
integration = require "./integration-common"
# HACK: Delay before checking received messages to ensure all messages get delivered.
# Increase this value if tests are failiing non-deterministically.
# TODO: better way to detect all messages have been delivered?
WAIT_TIME = 200
exports.initIntegrationTests = ->
integration.initIntegrationTests
name: "socket.io"
createClient: (port, push_id, options = {}) ->
deferred = Q.defer()
socket = io.connect "http://localhost:#{port}", merge(options, "force new connection": true)
# For some reason socket.io-client doesn't respect the "transports" option so we have to set it manually
socket.socket.options.transports = options.transports if options.transports?
socket.on "connect", ->
socket.emit "subscribe", push_id
messages = []
socket.on "message", (message) ->
messages.push message
deferred.resolve ->
Q.delay(WAIT_TIME).then -> messages
deferred.promise
exports.initIntegrationTests()

View File

@ -0,0 +1,50 @@
Q = require "q"
QStep = require "q-step"
wd = require "wd"
merge = require "deepmerge"
integration = require "./integration-common"
# HACK: Delay before checking received messages to ensure all messages get delivered.
# Increase this value if tests are failiing non-deterministically.
# TODO: better way to detect all messages have been delivered?
WAIT_TIME = 500
DEFAULT_BROWSER =
browserName: "firefox"
LOCAL_CONFIG =
host: "localhost"
port: 4444
SAUCE_CONFIG =
host: "ondemand.saucelabs.com"
port: 80
username: process.env["SAUCE_USER"]
password: process.env["SAUCE_KEY"]
DEFAULT_CONFIG = LOCAL_CONFIG
exports.initIntegrationTests = (config = {}) ->
config = merge(DEFAULT_CONFIG, config)
integration.initIntegrationTests
name: "webdriver-#{config.browser.browserName}"
createClient: (port, push_id) ->
browser = wd.promiseRemote(config.host, config.port, config.username, config.password)
QStep(
-> browser.init(config.browser)
-> browser.get("http://localhost:#{port}/\##{push_id}")
-> browser.waitForCondition("!!window.messages", 5000)
->
->
Q.delay(WAIT_TIME).then ->
browser.eval("window.messages").then (messages) ->
messages
.fin ->
browser.quit()
)
# exports.initIntegrationTests()
exports.initIntegrationTests(browser: browserName: "chrome")