From b62eef513e1daf30f55d3cf90ddf4426ff0ca68d Mon Sep 17 00:00:00 2001 From: apendua Date: Mon, 22 Dec 2014 20:13:06 +0100 Subject: [PATCH 01/13] Use low-dash for call/applyWebDriver --- lib/browserPromiseChain.js | 18 +++++++++--------- lib/helpers.js | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/browserPromiseChain.js b/lib/browserPromiseChain.js index 3c533fe..bc743e3 100644 --- a/lib/browserPromiseChain.js +++ b/lib/browserPromiseChain.js @@ -71,14 +71,14 @@ webdriverMethods.forEach(function (name) { "use strict"; BrowserPromiseChain.prototype[name] = function () { - return this.applyWebDriver(name, Array.prototype.slice.call(arguments, 0)); + return this._applyWebDriver(name, Array.prototype.slice.call(arguments, 0)); }; }); BrowserPromiseChain.methods = webdriverMethods.concat([ - 'applyWebDriver', - 'callWebDriver', + '_applyWebDriver', + '_callWebDriver', 'always', 'sleep', 'expectError', @@ -90,7 +90,7 @@ BrowserPromiseChain.methods = webdriverMethods.concat([ /** * Update the current promise and return this to allow chaining. */ -BrowserPromiseChain.prototype.applyWebDriver = function (name, args, custom) { +BrowserPromiseChain.prototype._applyWebDriver = function (name, args, custom) { "use strict"; args = Array.prototype.slice.call(args, 0); // shallow copy the arguments @@ -117,10 +117,10 @@ BrowserPromiseChain.prototype.applyWebDriver = function (name, args, custom) { return self; } -BrowserPromiseChain.prototype.callWebDriver = function (name) { +BrowserPromiseChain.prototype._callWebDriver = function (name) { "use strict"; - return this.applyWebDriver(name, Array.prototype.slice.call(arguments, 1)); + return this._applyWebDriver(name, Array.prototype.slice.call(arguments, 1)); } BrowserPromiseChain.prototype.always = function (callback) { @@ -185,7 +185,7 @@ BrowserPromiseChain.prototype.execute = function (code, args) { throw new Error('`args` has to be an array'); } - return self.applyWebDriver('execute', arguments, function (operand, name, myArgs) { + return self._applyWebDriver('execute', arguments, function (operand, name, myArgs) { var closure = operand.closure ? operand.closure() : {}; var cb = myArgs[myArgs.length-1]; @@ -219,7 +219,7 @@ BrowserPromiseChain.prototype.promise = function (code, args) { } // we could set this 5000 globally, right? - return self.callWebDriver('setAsyncScriptTimeout', self._timeout || 5000).applyWebDriver('executeAsync', arguments, function (operand, name, myArgs) { + return self._callWebDriver('setAsyncScriptTimeout', self._timeout || 5000)._applyWebDriver('executeAsync', arguments, function (operand, name, myArgs) { var closure = operand.closure ? operand.closure() : {}; var cb = myArgs[myArgs.length-1]; // the last argument is callback @@ -298,7 +298,7 @@ BrowserPromiseChain.prototype.wait = function (timeout, message, code, args) { var self = this; - return self.callWebDriver('setAsyncScriptTimeout', 2 * timeout).applyWebDriver('executeAsync', arguments, function (operand, name, myArgs) { + return self._callWebDriver('setAsyncScriptTimeout', 2 * timeout)._applyWebDriver('executeAsync', arguments, function (operand, name, myArgs) { var closure = operand.closure ? operand.closure() : {}; var cb = myArgs[myArgs.length-1]; // callback is always the last one diff --git a/lib/helpers.js b/lib/helpers.js index bae0c19..92a41c3 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -88,7 +88,7 @@ exports.client = { }, click: function (selector, keys) { - return this.callWebDriver('elementByCssSelectorOrNull', selector) + return this._callWebDriver('elementByCssSelectorOrNull', selector) .then(function (element) { if (!element) { throw new Error('element ' + selector + ' does not exists'); @@ -109,7 +109,7 @@ exports.client = { //}, sendKeys: function (selector, keys) { - return this.callWebDriver('elementByCssSelectorOrNull', selector) + return this._callWebDriver('elementByCssSelectorOrNull', selector) .then(function (element) { if (!element) { throw new Error('element ' + selector + ' does not exists'); From 321baf9b6b2c3c6fe6ca1942b66de33237b566db Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Mon, 22 Dec 2014 21:27:38 +0100 Subject: [PATCH 02/13] Added note about Selenium WebDriver --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 8a422de..f13eb10 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,22 @@ describe('You can also use browser in your tests', function () { }); ``` +## Testing with Selenium WebDriver + +Lets assume that you have a copy of `selenium-server-standalone-*.jar` available at `/path/to/selenium.jar`. First start a selenium "hub" with the following command: +``` +java -jar /path/to/selenium.jar -role hub +``` +Selenium server should be listening on port `4444` by default. Then start a selenium "node" with +``` +java -jar /path/to/selenium.jar -role node -hub http://localhost:4444 +``` +Finally run your Gagarin tests providing `--webdriver` option +``` +gagarin --webdriver http://localhost:4444/wd/hub +``` +We've been testing Gagarin with `chrome` (38) and `firefox` (34). At this moment we cannot guarantee it will work with other browsers. + # Examples Since we don't have a comprehensive documentation yet, please consider the following set of simple examples as a current API reference. Note that this document will evolve in the nearest future. From fb67348e8b9c708218fde3dd75e52af33bbd9ccf Mon Sep 17 00:00:00 2001 From: apendua Date: Mon, 22 Dec 2014 21:09:10 +0100 Subject: [PATCH 03/13] Code cleanup --- backdoor.js | 1 - lib/browser.js | 14 ++++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/backdoor.js b/backdoor.js index b51d1fe..2a9fdaf 100644 --- a/backdoor.js +++ b/backdoor.js @@ -1,4 +1,3 @@ -"use strict"; var vm = Npm.require('vm'); var Fiber = Npm.require('fibers'); diff --git a/lib/browser.js b/lib/browser.js index 8030b24..add08b6 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -39,10 +39,13 @@ function Browser (options) { } reject(err); } + var driverLocationParsed = URL.parse(driverLocation); - portscanner.checkPortStatus(driverLocationParsed.port, driverLocationParsed.hostname, function(error, status) { - if(status != 'open') + + portscanner.checkPortStatus(driverLocationParsed.port, driverLocationParsed.hostname, function (error, status) { + if (status !== 'open') { _reject('webdriver not found on ' + driverLocation); + } browser.init(capabilities, function (err) { if (err) { return _reject(err); @@ -88,10 +91,9 @@ function Browser (options) { }); }); }); - } - - }); - }); + } // after resize + }); // init + }); // checkPortStatus }); // Promise } From d6c29892dc8571bb39c1cd41ff1c405b4dfe9085 Mon Sep 17 00:00:00 2001 From: apendua Date: Mon, 22 Dec 2014 21:11:27 +0100 Subject: [PATCH 04/13] Make sure custom helpers and chaining works --- lib/browserPromiseChain.js | 10 +++++++-- lib/meteor.js | 25 ++++++++++++++++----- lib/meteorPromiseChain.js | 27 ++++++++++++++++------ tests/specs/chaining.js | 37 ++++++++++++++++++++++++++++++ tests/specs/helpers.js | 46 +++++++++++++++++++++++++++++--------- 5 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 tests/specs/chaining.js diff --git a/lib/browserPromiseChain.js b/lib/browserPromiseChain.js index bc743e3..1a27ad4 100644 --- a/lib/browserPromiseChain.js +++ b/lib/browserPromiseChain.js @@ -20,12 +20,13 @@ function BrowserPromiseChain (operand, helpers) { this._promise = operand; this._helpers = helpers; - // TODO: check for conflicts // install helpers Object.keys(helpers).forEach(function (key) { + if (self[key] !== undefined) { + console.warn('helper ' + key + ' conflicts with some BrowserPromiseChain method'); + } self[key] = helpers[key]; }); - } [ 'then', 'catch' ].forEach(function (name) { @@ -79,10 +80,15 @@ webdriverMethods.forEach(function (name) { BrowserPromiseChain.methods = webdriverMethods.concat([ '_applyWebDriver', '_callWebDriver', + 'catch', + 'then', 'always', 'sleep', 'expectError', + 'noWait', + 'yet', 'execute', + 'timeout', 'promise', 'wait', ]); diff --git a/lib/meteor.js b/lib/meteor.js index 1418918..f1300c9 100644 --- a/lib/meteor.js +++ b/lib/meteor.js @@ -26,6 +26,8 @@ module.exports.BuildAsPromise = BuildAsPromise; function Meteor (options) { "use strict"; + var self = this; + options = options || {}; if (typeof options === 'string') { @@ -41,7 +43,8 @@ function Meteor (options) { remoteServer = url.parse(remoteServer); } - var databasePromise = new DatabaseAsPromise({ pathToApp: pathToApp }); + //XXX when using a remote server, we don't really need database promise here + var databasePromise = remoteServer ? Promise.resolve({}) : new DatabaseAsPromise({ pathToApp: pathToApp }); var ddpClientAsPromise = makeDDPClientFactory(ddpSetupProvider); var instance = null; @@ -94,14 +97,24 @@ function Meteor (options) { }, }; - this.location = meteorLocation; - this.helpers = options.helpers || {}; + self.location = meteorLocation; + self.helpers = {}; + + // set-up helpers + self.helpers = {}; + + Object.keys(options.helpers || {}).forEach(function (key) { + if (self[key] !== undefined) { + console.warn('helper ' + key + ' conflicts with some Meteor method'); + } + self[key] = self.helpers[key] = options.helpers[key]; + }); - this.useClosure = function (objectOrGetter) { + self.useClosure = function (objectOrGetter) { remote.useClosure(objectOrGetter); }; - this.meteorRemoteAsPromise = Promise.resolve(remote); + self.meteorRemoteAsPromise = Promise.resolve(remote); function cleanUpThen(callback) { meteorPromise = null; @@ -265,7 +278,7 @@ MeteorPromiseChain.methods.forEach(function (name) { "use strict"; Meteor.prototype[name] = function () { - var chain = new MeteorPromiseChain(this.meteorRemoteAsPromise, this.helpers); + var chain = new MeteorPromiseChain(this.meteorRemoteAsPromise, this._helpers); return chain[name].apply(chain, arguments); }; diff --git a/lib/meteorPromiseChain.js b/lib/meteorPromiseChain.js index ad4317e..a69725a 100644 --- a/lib/meteorPromiseChain.js +++ b/lib/meteorPromiseChain.js @@ -18,9 +18,10 @@ function MeteorPromiseChain (operand, helpers) { this._promise = operand; this._helpers = helpers; - // TODO: check for conflicts - // install helpers Object.keys(helpers).forEach(function (key) { + if (self[key] !== undefined) { + console.warn('helper ' + key + ' conflicts with some MeteorPromiseChain method'); + } self[key] = helpers[key]; }); } @@ -36,15 +37,26 @@ function MeteorPromiseChain (operand, helpers) { }); -MeteorPromiseChain.methods = [ - 'execute', - 'promise', - 'wait', +var meteorRemoteMethods = [ 'stop', 'start', 'restart', + 'execute', + 'promise', + 'wait', ]; +MeteorPromiseChain.methods = meteorRemoteMethods.concat([ + 'catch', + 'then', + 'always', + 'sleep', + 'expectError', + 'noWait', + 'yet', + 'timeout', +]); + MeteorPromiseChain.prototype.always = function (callback) { "use strict"; @@ -93,7 +105,7 @@ MeteorPromiseChain.prototype.timeout = function () { return this; } -MeteorPromiseChain.methods.forEach(function (name) { +meteorRemoteMethods.forEach(function (name) { "use strict"; /** @@ -106,6 +118,7 @@ MeteorPromiseChain.methods.forEach(function (name) { self._operand, self._promise ]).then(function (all) { return new Promise(function (resolve, reject) { + // TODO: think how we could use value returned by self._promise var operand = all[0]; if (!operand || typeof operand !== 'object') { reject(new Error('MeteorPromiseChain: invalid operand')); diff --git a/tests/specs/chaining.js b/tests/specs/chaining.js new file mode 100644 index 0000000..686de73 --- /dev/null +++ b/tests/specs/chaining.js @@ -0,0 +1,37 @@ + +describe('Chaining', function () { + + var server = meteor(); + var client = browser(server.location); + + it('promise chain should work on server', function () { + return server.execute(function () { + return Meteor.release; + }) + .then(function (value) { + expect(value).not.to.be.empty; + }) + .execute(function () { + return Meteor.release; + }) + .then(function (value) { + expect(value).not.to.be.empty; + }); + }); + + it('promise chain should work on client', function () { + return client.execute(function () { + return Meteor.release; + }) + .then(function (value) { + expect(value).not.to.be.empty; + }) + .execute(function () { + return Meteor.release; + }) + .then(function (value) { + expect(value).not.to.be.empty; + }); + }); + +}); diff --git a/tests/specs/helpers.js b/tests/specs/helpers.js index 7606c94..ad845d6 100644 --- a/tests/specs/helpers.js +++ b/tests/specs/helpers.js @@ -1,18 +1,44 @@ +var Promise = require('es6-promise').Promise; + describe('Helpers', function () { - var server = meteor(); - var client = browser(server.location); + describe('Built in helpers', function () { + + var server = meteor(); + var client = browser(server.location); + + it('should be able to use sendKeys', function () { + return client + .sendKeys('input[type=text]', 'abc') + .expectValueToEqual('input[type=text]', 'abc'); + }); + + it('should be able to use click', function () { + return client + .click('input[type=button]') + .expectTextToContain('p', '1'); + }); - it('should be able to use sendKeys', function () { - return client - .sendKeys('input[type=text]', 'abc') - .expectValueToEqual('input[type=text]', 'abc'); }); - it('should be able to use click', function () { - return client - .click('input[type=button]') - .expectTextToContain('p', '1'); + describe('Custom user-defined helpers', function () { + + var server = meteor({ + helpers: { + sleepForOneSecond: function () { + return this.then(function () { + return new Promise(function (resolve) { + setTimeout(resolve, 1000); + }); + }); + }, + }, + }); + + it('should be able to use a custom helper', function () { + return server.sleepForOneSecond(); + }); + }); }); From 4a4b9f5488e02dbec11a602a1cefbe07b2ba9df9 Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 16:37:43 +0100 Subject: [PATCH 05/13] Make the default value a proper URL --- lib/browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser.js b/lib/browser.js index add08b6..6859ea7 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -10,7 +10,7 @@ function Browser (options) { var self = this; var closure = null; - var driverLocation = options.webdriver || "127.0.0.1:9515"; + var driverLocation = options.webdriver || "http://localhost:9515"; var browser = wd.remote(driverLocation); // default to chromedriver var myLocation = options.location || "http://localhost:3000"; // default to meteor var dontWaitForMeteor = options.dontWaitForMeteor !== undefined ? !!options.dontWaitForMeteor : false; From c4f4868d4d1789d8e8a8648379db47b01c04bff1 Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 16:40:08 +0100 Subject: [PATCH 06/13] Retry on ddp connection error --- lib/ddp.js | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/ddp.js b/lib/ddp.js index 71c1c16..46c378f 100644 --- a/lib/ddp.js +++ b/lib/ddp.js @@ -38,12 +38,31 @@ module.exports = function makeDDPClientFactory (ddpSetupProvider) { ddpVersion : '1' }); - ddpClient.connect(function (err, wasReconnected) { - if (err) { - return reject(err); - } - resolve(ddpClient); - }); + //ddpClient.connect(function (err, wasReconnected) { + // if (err) { + // return reject(err); + // } + // resolve(ddpClient); + //}); + + var retryCount = 5; + + // XXX we need this because the WebApp.httpServer may start with some delay; + // in fact, this should be handled within the app itself + (function tryConnect() { + ddpClient.connect(function (err, wasReconnected) { + console.log('trying to connect'); + if (err) { + if (retryCount <= 0) { + reject(typeof err === 'string' ? new Error(err) : err); + } else { + setTimeout(tryConnect, 500); + } + } else { + resolve(ddpClient); + } + }); + })(); // TODO: re-enable this feature when we make timeout configurable //setTimeout(function () { From 39f97c8fac23cf1e869ea47c7816495af0c17187 Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 16:44:32 +0100 Subject: [PATCH 07/13] Increased mongo debounce to 1000 --- lib/mongo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mongo.js b/lib/mongo.js index 8496abf..dfee8e0 100644 --- a/lib/mongo.js +++ b/lib/mongo.js @@ -56,7 +56,7 @@ module.exports = function MongoServerAsPromise (options) { // use debounce to give the process some time in case it exits prematurely mongoProcess.stdout.on('data', debounce(function (data) { resolve(mongoUrl); - }, 100)); + }, 1000)); // on premature exit, reject the promise mongoProcess.on('exit', function (code) { From 6cc3b3eb5213c63da8c6b2669e43eb7d7be0e9ff Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 16:54:08 +0100 Subject: [PATCH 08/13] Make sure to decrease the retryCount --- lib/ddp.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ddp.js b/lib/ddp.js index 46c378f..b1a56b7 100644 --- a/lib/ddp.js +++ b/lib/ddp.js @@ -56,6 +56,7 @@ module.exports = function makeDDPClientFactory (ddpSetupProvider) { if (retryCount <= 0) { reject(typeof err === 'string' ? new Error(err) : err); } else { + retryCount -= 1; setTimeout(tryConnect, 500); } } else { From 8680f95431914b8b0984cfff60913ba514a98e1c Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 16:55:14 +0100 Subject: [PATCH 09/13] Cleaning up --- lib/ddp.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ddp.js b/lib/ddp.js index b1a56b7..9babd93 100644 --- a/lib/ddp.js +++ b/lib/ddp.js @@ -51,7 +51,6 @@ module.exports = function makeDDPClientFactory (ddpSetupProvider) { // in fact, this should be handled within the app itself (function tryConnect() { ddpClient.connect(function (err, wasReconnected) { - console.log('trying to connect'); if (err) { if (retryCount <= 0) { reject(typeof err === 'string' ? new Error(err) : err); From 99da8dad571af7d98b1cdc26e1bd00e9b0acad38 Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Tue, 23 Dec 2014 17:50:04 +0100 Subject: [PATCH 10/13] Alter ddpClient callback on reconnect --- lib/ddp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ddp.js b/lib/ddp.js index 9babd93..befc930 100644 --- a/lib/ddp.js +++ b/lib/ddp.js @@ -54,7 +54,7 @@ module.exports = function makeDDPClientFactory (ddpSetupProvider) { if (err) { if (retryCount <= 0) { reject(typeof err === 'string' ? new Error(err) : err); - } else { + } else if (!wasReconnected) { retryCount -= 1; setTimeout(tryConnect, 500); } From b435c4a3f47c749508af0aaf8e41fb1d997055ae Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Wed, 24 Dec 2014 10:12:31 +0100 Subject: [PATCH 11/13] Check Gagarin version after the build --- lib/build.js | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/lib/build.js b/lib/build.js index 4f98c8d..bc59266 100644 --- a/lib/build.js +++ b/lib/build.js @@ -19,7 +19,6 @@ module.exports = function BuildAsPromise (options) { var timeout = options.timeout || 60000; var verbose = options.verbose !== undefined ? !!options.verbose : false; - var pathToVersions = path.join(pathToApp, '.meteor', 'versions'); var pathToSmartJson = path.join(pathToApp, 'smart.json'); var pathToMain = path.join(pathToApp, '.meteor', 'local', 'build', 'main.js'); var skipBuild = !!options.skipBuild; @@ -32,19 +31,6 @@ module.exports = function BuildAsPromise (options) { } } - var versions = fs.readFileSync(pathToVersions, 'utf-8'); - var versionMatch = versions.match(/anti:gagarin@(.*)/); - - if (!versionMatch) { - return Promise.reject(new Error('Please add anti:gagarin to your app before running tests.')); - } else if (versionMatch[1] !== version) { - return Promise.reject(new Error( - 'Versions of node package (' + version + - ') and meteor packages (' + versionMatch[1] + - ') are not compatible; please update.' - )); - } - if (myBuildPromises[pathToApp]) return myBuildPromises[pathToApp]; if (fs.existsSync(pathToSmartJson)) { @@ -116,11 +102,17 @@ function BuildPromise(options) { regExp: /App running at:/, action: function () { meteor.once('exit', function () { - if (fs.existsSync(pathToMain)) { - resolve(pathToMain); - } else { - reject(new Error('Meteor build failed.')); + if (!fs.existsSync(pathToMain)) { + reject(new Error('File ' + pathToMain + ' does not exist.')); + return; } + try { + checkIfVersionsMatches(pathToApp); + } catch (err) { + reject(err); + return; + } + resolve(pathToMain); }); meteor.kill('SIGINT'); } @@ -213,3 +205,25 @@ function isLocked(pathToApp) { return fs.existsSync(pathToMongoLock) && fs.readFileSync(pathToMongoLock).toString('utf8'); } +/** + * Verify if Gagarin is instaled and if the version is compatible. + */ +function checkIfVersionsMatches(pathToApp) { + + var pathToVersions = path.join(pathToApp, '.meteor', 'versions'); + var versions = fs.readFileSync(pathToVersions, 'utf-8'); + var versionMatch = versions.match(/anti:gagarin@(.*)/); + + if (!versionMatch) { // looks like gagarin is not even instaled + throw new Error('Please add anti:gagarin to your app before running tests.'); + } else if (versionMatch[1] !== version) { // versions of gagarin are not compatible + throw new Error( + 'Versions of node package (' + version + + ') and meteor package (' + versionMatch[1] + + ') are not compatible; please update.' + ); + } + +} + + From 6e16cc9049a0676c56e71e108bf29fe90390850c Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Wed, 24 Dec 2014 10:32:51 +0100 Subject: [PATCH 12/13] Bumped package version --- package.js | 2 +- package.json | 2 +- tests/build_error/.meteor/versions | 2 +- tests/example/.meteor/versions | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.js b/package.js index 41137fd..eb21c9f 100644 --- a/package.js +++ b/package.js @@ -2,7 +2,7 @@ Package.describe({ summary: "Gagarin, a Meteor testing framework", name: "anti:gagarin", - version: "0.3.0", + version: "0.3.1", git: "https://github.com/anticoders/gagarin.git", }); diff --git a/package.json b/package.json index f3c37fd..9c690c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gagarin", - "version": "0.3.0", + "version": "0.3.1", "description": "another testing framework for your meteor apps", "main": "gagarin.js", "repository": { diff --git a/tests/build_error/.meteor/versions b/tests/build_error/.meteor/versions index 13d1aae..c146985 100644 --- a/tests/build_error/.meteor/versions +++ b/tests/build_error/.meteor/versions @@ -1,4 +1,4 @@ -anti:gagarin@0.3.0 +anti:gagarin@0.3.1 application-configuration@1.0.4 autopublish@1.0.2 autoupdate@1.1.4 diff --git a/tests/example/.meteor/versions b/tests/example/.meteor/versions index 86a0f45..b72159c 100644 --- a/tests/example/.meteor/versions +++ b/tests/example/.meteor/versions @@ -1,6 +1,6 @@ accounts-base@1.1.3 accounts-password@1.0.5 -anti:gagarin@0.3.0 +anti:gagarin@0.3.1 application-configuration@1.0.4 autopublish@1.0.2 autoupdate@1.1.4 From c0f288976bd5c70b372debe1c0efe2b604114041 Mon Sep 17 00:00:00 2001 From: Tomasz Lenarcik Date: Wed, 24 Dec 2014 10:36:33 +0100 Subject: [PATCH 13/13] New version published --- .versions | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .versions diff --git a/.versions b/.versions new file mode 100644 index 0000000..d2e39fa --- /dev/null +++ b/.versions @@ -0,0 +1,18 @@ +anti:gagarin@0.3.1 +base64@1.0.2 +callback-hook@1.0.2 +check@1.0.3 +ddp@1.0.13 +ejson@1.0.5 +geojson-utils@1.0.2 +id-map@1.0.2 +json@1.0.2 +livedata@1.0.12 +logging@1.0.6 +meteor@1.1.4 +minimongo@1.0.6 +ordered-dict@1.0.2 +random@1.0.2 +retry@1.0.2 +tracker@1.0.4 +underscore@1.0.2