From 77b3c43945af1520b0839e214bc5d7592db0ecca Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Sun, 23 Apr 2017 17:57:57 +0300 Subject: [PATCH 01/13] add support for redirects inside iframe for performing the handshake again --- src/courier/PostMessageChannel.js | 24 +++++++++++---- src/courier/PostMessageUtilities.js | 48 ++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/src/courier/PostMessageChannel.js b/src/courier/PostMessageChannel.js index 9787c32..ae32806 100644 --- a/src/courier/PostMessageChannel.js +++ b/src/courier/PostMessageChannel.js @@ -317,7 +317,8 @@ this.targetOrigin = options.targetOrigin; this.maxConcurrency = PostMessageUtilities.parseNumber(options.maxConcurrency, DEFAULT_CONCURRENCY); this.handshakeInterval = PostMessageUtilities.parseNumber(options.handshakeInterval, DEFAULT_HANDSHAKE_RETRY_INTERVAL); - this.handshakeAttempts = PostMessageUtilities.parseNumber(options.handshakeAttempts, DEFAULT_HANDSHAKE_RETRY_ATTEMPTS); + this.handshakeAttemptsOrig = PostMessageUtilities.parseNumber(options.handshakeAttempts, DEFAULT_HANDSHAKE_RETRY_ATTEMPTS); + this.handshakeAttempts = this.handshakeAttemptsOrig; this.hostParam = options.hostParam; this.channel = "undefined" !== typeof options.channel ? options.channel : _getChannelUrlIndicator(); this.useObjects = options.useObjects; @@ -564,6 +565,10 @@ if (!this.disposed && !this.ready) { this.ready = true; + // Handshake was successful, Channel is ready for messages + // Set the counter back to original value for dealing with iframe reloads + this.handshakeAttempts = this.handshakeAttemptsOrig; + // Process queued messages if any if (this.messageQueue && this.messageQueue.length) { PostMessageUtilities.delay(function() { @@ -638,7 +643,9 @@ * @private */ function _createIFrame(options, container) { + var frame = document.createElement("IFRAME"); var name = PostMessageUtilities.createUniqueSequence(IFRAME_PREFIX + PostMessageUtilities.SEQUENCE_FORMAT); + var delay = options.delayLoad; var defaultAttributes = { "id": name, "name" :name, @@ -647,23 +654,22 @@ "title": "", // Adding an empty title for accessibility "role": "presentation", // Adding a presentation role http://yahoodevelopers.tumblr.com/post/59489724815/easy-fixes-to-common-accessibility-problems "allowTransparency":"true" - }, - defaultStyle = { + }; + var defaultStyle = { width :"0px", height : "0px", position :"absolute", top : "-1000px", left : "-1000px" }; - var frame = document.createElement("IFRAME"); - var delay = options.delayLoad; options.attributes = options.attributes || defaultAttributes; - for(var key in options.attributes){ + for (var key in options.attributes){ if (options.attributes.hasOwnProperty(key)) { frame.setAttribute(key, options.attributes[key]); } } + options.style = options.style || defaultStyle; if (options.style) { for (var attr in options.style) { @@ -696,6 +702,12 @@ var load = function() { this.loading = false; + if (this.handshakeAttempts === this.handshakeAttemptsOrig) { + // Probably a first try for handshake or a reload of the iframe, + // Either way, we'll need to perform handshake, so ready flag should be set to false (if not already) + this.ready = false; + } + _handshake.call(this, this.handshakeInterval); }.bind(this); diff --git a/src/courier/PostMessageUtilities.js b/src/courier/PostMessageUtilities.js index a1a040a..2816f87 100644 --- a/src/courier/PostMessageUtilities.js +++ b/src/courier/PostMessageUtilities.js @@ -70,7 +70,7 @@ } }, "*"); } - catch(ex) { + catch (ex) { // Browsers which has postMessage Objects support sends messages using // the structured clone algorithm - https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm // In which Error and Function objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a DATA_CLONE_ERR exception. @@ -145,16 +145,38 @@ return domain; } + /** + * Method to resolve the needed origin parameters from url + * @param {String} [hostParam] - string to represent the name of the host parameter in querystring + * @param {String} [url] - string to represent the url to resolve parameters from + * @returns {String} the parameter from the url + */ + function resolveParameters(hostParam, url) { + var param; + var value = getURLParameter("lpHost", url); + + if (!value) { + param = getURLParameter("hostParam", url) || hostParam; + + if (param) { + value = getURLParameter(param, url); + } + } + + return value; + } + /** * Method to resolve the needed origin * @param {Object} [target] - the target to resolve the host for * @param {Boolean} [top] - boolean indication for using helper of the top window if needed + * @param {String} [hostParam] - string to represent the name of the host parameter in querystring * @returns {String} the origin for the target */ - function resolveOrigin(target, top) { + function resolveOrigin(target, top, hostParam) { var origin; var url; - var param; + var ref; try { url = target && target.contentWindow && "undefined" !== typeof Window && !(target instanceof Window) && target.getAttribute && target.getAttribute("src"); @@ -163,23 +185,20 @@ try { if (!url) { - url = getURLParameter("lpHost"); - - if (!url) { - param = getURLParameter("hostParam"); - - if (param) { - url = getURLParameter(param); - } - } + url = resolveParameters(hostParam); } if (!url) { url = document.referrer; + ref = true; } if (url) { url = decodeURIComponent(url); + + if (ref) { + url = resolveParameters(hostParam, url); + } } origin = getHost(url, target, top); @@ -194,10 +213,11 @@ /** * Method to retrieve a url parameter from querystring by name * @param {String} name - the name of the parameter + * @param {String} [url] - optional url to parse * @returns {String} the url parameter value */ - function getURLParameter(name) { - return decodeURIComponent((new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(document.location.search) || [void 0, ""])[1].replace(/\+/g, "%20")) || null; + function getURLParameter(name, url) { + return decodeURIComponent((new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(url || document.location.search) || [void 0, ""])[1].replace(/\+/g, "%20")) || null; } /** From dbd86198ada8f1f29581a41106393ebc024dc26e Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Sun, 23 Apr 2017 17:58:39 +0300 Subject: [PATCH 02/13] Fix API spec in source --- src/courier/PostMessageCourier.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/courier/PostMessageCourier.js b/src/courier/PostMessageCourier.js index 1344511..d0552b7 100644 --- a/src/courier/PostMessageCourier.js +++ b/src/courier/PostMessageCourier.js @@ -4,13 +4,13 @@ * 2) IE9-, FF & Opera Mini does not support MessageChannel and therefore we fallback to using basic postMessage. * This makes the communication opened to any handler registered for messages on the same origin. * 3) All passDataByRef flags (in LPEventChannel) are obviously ignored - * 4) In case the browser does not support passing object using postMessage (IE8+, Opera Mini), and no special serialize/deserialize methods are supplied to LPPostMessageCourier, + * 4) In case the browser does not support passing object using postMessage (IE8+, Opera Mini), and no special serialize/deserialize methods are supplied to PostMessageCourier, * All data is serialized using JSON.stringify/JSON.parse which means that Object data is limited to JSON which supports types like: * strings, numbers, null, arrays, and objects (and does not allow circular references). * Trying to serialize other types, will result in conversion to null (like Infinity or NaN) or to a string (Dates) * that must be manually deserialized on the other side - * 5) When Iframe is managed outside of LPPostMessageCourier (passed by reference to the constructor), - * a targetOrigin option is expected to be passed to the constructor, and a query parameter with the name "lphost" is expected on the iframe url (unless the LPPostMessageCourier + * 5) When Iframe is managed outside of PostMessageCourier (passed by reference to the constructor), + * a targetOrigin option is expected to be passed to the constructor, and a query parameter with the name "lpHost" is expected on the iframe url (unless the PostMessageCourier * at the iframe side, had also been initialized with a valid targetOrigin option) */ // TODO: Add Support for target management when there is a problem that requires re-initialization of the target @@ -198,10 +198,10 @@ * @param eventChannel * @private */ - function _registerProxy(eventChannel){ - if(eventChannel && eventChannel.registerProxy){ + function _registerProxy(eventChannel) { + if (eventChannel && "function" === typeof eventChannel.registerProxy) { eventChannel.registerProxy({ - trigger: function(){ + trigger: function () { _postMessage.call(this, Array.prototype.slice.apply(arguments), ACTION_TYPE.TRIGGER); }, context: this @@ -550,7 +550,7 @@ /** * Method for checking two way communication for action - * @param {LPPostMessageCourier.ACTION_TYPE} action - the action type name + * @param {PostMessageCourier.ACTION_TYPE} action - the action type name * @returns {Boolean} flag to indicate whether the action is two way (had return call) * @private */ From 8303fe36e3d6937b50820f93a7dc67354713068c Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Sun, 23 Apr 2017 17:58:58 +0300 Subject: [PATCH 03/13] improve proxy feature --- src/Channels.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/Channels.js b/src/Channels.js index a59469c..5c14c1e 100644 --- a/src/Channels.js +++ b/src/Channels.js @@ -31,23 +31,18 @@ } }(typeof ChronosRoot === "undefined" ? this : ChronosRoot, function (root, exports, Events, Commands, ReqRes, hide) { function Channels(options) { - options = options || {}; + var externalAPIS = []; var events = options.events || new Events(options.config && options.config.events); var commands = options.commands || new Commands(options.config && options.config.commands); var reqres = options.reqres || new ReqRes(options.config && options.config.reqres); - this.once = events.once; this.hasFiredEvents = events.hasFired; - this.trigger = _wrapCalls({ - func: events.trigger, - context: events, - triggerType: "trigger" - }); - this.publish = this.trigger; + this.trigger = events.trigger; + this.publish = events.publish; this.bind = events.bind; this.register = events.register; this.unbind = events.unbind; @@ -60,9 +55,16 @@ this.request = reqres.request; this.reply = reqres.reply; this.stopReplying = reqres.stopReplying; + if (options.externalProxy === true) { + this.trigger = _wrapCalls({ + func: events.trigger, + context: events, + triggerType: "trigger" + }); + this.publish = this.trigger; this.registerProxy = registerProxy; - } + } /** * Wraps API calls to trigger other registered functions @@ -76,12 +78,13 @@ options.func.apply(options.context, Array.prototype.slice.call(arguments, 0)); - for(var i = 0; i < externalAPIS.length; i++){ + for (var i = 0; i < externalAPIS.length; i++) { api = externalAPIS[i]; - if(api[options.triggerType]){ - try{ + if (api[options.triggerType]) { + try { api[options.triggerType].apply(api.context,Array.prototype.slice.call(arguments, 0)); - }catch (exc){} + } + catch (exc) {} } } }; @@ -92,7 +95,7 @@ * @param external */ function registerProxy(external){ - if(typeof external === 'object' && external.trigger){ + if (typeof external === 'object' && external.trigger) { externalAPIS.push(external); } } From 43e4d4799e466cfa8c2113741752d76cc119d2dc Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Sun, 23 Apr 2017 17:59:15 +0300 Subject: [PATCH 04/13] add tests for iframe redirects --- test/js/courier_sanity_no_iframe_test.js | 38 ++++++++++++++++++++-- test/js/courier_sanity_test.js | 36 ++++++++++++++++++++- test/resources/courier_test_frame.html | 40 ++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/test/js/courier_sanity_no_iframe_test.js b/test/js/courier_sanity_no_iframe_test.js index cae35d8..5acbcc1 100644 --- a/test/js/courier_sanity_no_iframe_test.js +++ b/test/js/courier_sanity_no_iframe_test.js @@ -33,6 +33,7 @@ describe("PostMessageCourier Sanity Tests with iFrame creation from the outside" // create a sandbox sandbox = sinon.sandbox.create(); + var completed = false; var target = { url: url + (0 < url.indexOf("?") ? "&" : "?") + "_d=" + buster++, callback: function() { @@ -43,7 +44,11 @@ describe("PostMessageCourier Sanity Tests with iFrame creation from the outside" }); msgChannel = courierLocal.getMessageChannel(); evChannel = courierLocal.getEventChannel(); - done(); + + if (!completed) { + completed = true; + done(); + } } }; var frame = createIFrame({ target: target }); @@ -259,6 +264,35 @@ describe("PostMessageCourier Sanity Tests with iFrame creation from the outside" expect(request).to.be.undefined; }); }); + + describe("check can run request on iframe and get async response after an iframe redirect", function () { + + it("run request on iframe and get async response after an iframe redirect", function (done) { + var request = courierLocal.request({ + appName: "host", + reqName: "Redirect" + }, function (err, data) { + expect(err).to.be.null; + expect(data).to.be.equal("Going to Redirect..."); + + setTimeout(function() { + var request2 = courierLocal.request({ + appName: "host", + reqName: "Async Ma Shlomha?", + data: { + text: "TODA!" + } + }, function (err, data) { + expect(err).to.be.null; + expect(data).to.be.equal("TODA!"); + done(); + }); + }, 300); + }); + + expect(request).to.be.undefined; + }); + }); }); function addElementEventListener(element, event, callback) { @@ -309,7 +343,7 @@ function createIFrame(options) { if (options && options.target && options.target.url) { var src = options.target.url + (0 < options.target.url.indexOf("?") ? "&bust=" : "?bust="); src += (new Date()).getTime(); - src += ("&host=" + document.location.protocol + "//" + document.location.host); + src += ("&lpHost=" + document.location.protocol + "//" + document.location.host); frame.setAttribute("src", src); } diff --git a/test/js/courier_sanity_test.js b/test/js/courier_sanity_test.js index 8a3f9b1..6f66f32 100644 --- a/test/js/courier_sanity_test.js +++ b/test/js/courier_sanity_test.js @@ -33,6 +33,7 @@ describe("PostMessageCourier Sanity Tests", function () { }); } }; + var completed = false; var target2 = { url: target.url, bust: false, @@ -48,7 +49,10 @@ describe("PostMessageCourier Sanity Tests", function () { appName: "host", eventName: "Hello" }); - done(); + if (!completed) { + completed = true; + done(); + } }, channel: withChannel }; @@ -805,6 +809,7 @@ describe("PostMessageCourier Sanity Tests", function () { cmdName: "command", data: {success: true} }, function (err, callback) { + err = err || void 0; expect(err).to.be.undefined; counting(); callback(); @@ -824,4 +829,33 @@ describe("PostMessageCourier Sanity Tests", function () { expect(res).to.be.undefined; }); }); + + describe("check can run request on iframe and get async response after an iframe redirect", function () { + + it("run request on iframe and get async response after an iframe redirect", function (done) { + var request = courierGlobal.request({ + appName: "host", + reqName: "Redirect" + }, function (err, data) { + expect(err).to.be.null; + expect(data).to.be.equal("Going to Redirect..."); + + setTimeout(function() { + var request2 = courierGlobal.request({ + appName: "host", + reqName: "Async Ma Shlomha?", + data: { + text: "TODA!" + } + }, function (err, data) { + expect(err).to.be.null; + expect(data).to.be.equal("TODA!"); + done(); + }); + }, 300); + }); + + expect(request).to.be.undefined; + }); + }); }); diff --git a/test/resources/courier_test_frame.html b/test/resources/courier_test_frame.html index f9621d4..5732810 100644 --- a/test/resources/courier_test_frame.html +++ b/test/resources/courier_test_frame.html @@ -98,6 +98,20 @@ } }); + courier.reply({ + appName: "host", + reqName: "Redirect", + func: function(data, callback) { + setTimeout(function() { + callback(null, "Going to Redirect..."); + + setTimeout(function() { + redirect(); + }, 100); + }, 0); + } + }); + ///// ---- TRIGGERS ------ //// function multiply(data) { courier.trigger({ @@ -148,6 +162,32 @@ } } + function redirect() { + var page = document.location.pathname.split("/").pop(); + var lpHost = getQueryVariable('lpHost'); + var bust = getQueryVariable('bust'); + var polyfill = getQueryVariable('lpPMCPolyfill'); + + if (bust) { + bust = (new Date()).getTime(); + } + + var redirect = page + ((bust || lpHost || polyfill) ? "?" : "") + (bust ? "bust=" + bust : "") + (lpHost ? (bust ? "&" : "") + "lpHost=" + lpHost : "") + (polyfill ? (bust || lpHost ? "&" : "") + "lpPMCPolyfill=" + polyfill : ""); + document.location.href = redirect; + } + + function getQueryVariable(variable) { + var query = window.location.search.substring(1); + var vars = query.split('&'); + for (var i = 0; i < vars.length; i++) { + var pair = vars[i].split('='); + if (decodeURIComponent(pair[0]) === variable) { + return decodeURIComponent(pair[1]); + } + } + console.log('Query variable ' + variable + ' not found'); + } + if ("true" === Chronos.PostMessageUtilities.getURLParameter("syncTrigger")) { courier.trigger({ appName: "frame", From 7c62c61dbdb445ee094ba93a37ca1c2b709cf0c6 Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Thu, 18 May 2017 10:23:20 +0300 Subject: [PATCH 05/13] make channels tests run --- test/js/channels_sanity_test.js | 16 ++++++++++------ test/lib/conf.js | 1 + test/resources/events_test_base.html | 1 - 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/js/channels_sanity_test.js b/test/js/channels_sanity_test.js index 050fadd..9f2b919 100644 --- a/test/js/channels_sanity_test.js +++ b/test/js/channels_sanity_test.js @@ -4,8 +4,8 @@ describe('Channels Sanity Tests', function () { before(function (done) { if ("undefined" !== typeof define) { - require(["Chronos.Channels"], function(Channels) { - Channels = Channels; + require(["Chronos.Channels"], function(_Channels) { + Channels = _Channels; done(); }); } @@ -46,18 +46,22 @@ describe('Channels Sanity Tests', function () { describe("check response on named channels", function () { var res; - var namedChannels = new Channels({ appName: "NamedReqRes" }); + var namedChannels; + + before(function() { + namedChannels = new Channels({ appName: "NamedChannels" }); + }); it("should respond with 1", function () { - var reqId = namedChannels.reply({ - reqName: "get", + var reqId = namedChannels.comply({ + cmdName: "get", func: function () { return 1; } }); res = namedChannels.command({ - reqName: "get", + cmdName: "get", data: {} }); expect(reqId).not.to.be.null; diff --git a/test/lib/conf.js b/test/lib/conf.js index fa9a0b7..7a3ecd7 100644 --- a/test/lib/conf.js +++ b/test/lib/conf.js @@ -32,6 +32,7 @@ define("conf", function() { "../js/events_sanity_test.js", "../js/commands_sanity_test.js", "../js/reqres_sanity_test.js", + "../js/channels_sanity_test.js", "../js/courier_sanity_test.js", "../js/courier_sanity_no_iframe_test.js" ] diff --git a/test/resources/events_test_base.html b/test/resources/events_test_base.html index 4f9f9be..4ad55bd 100644 --- a/test/resources/events_test_base.html +++ b/test/resources/events_test_base.html @@ -17,7 +17,6 @@ element.attachEvent("on" + event, callback); } } - From 6cababe6339eb490c4676f9613a7e045c842b7f7 Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Thu, 18 May 2017 12:11:38 +0300 Subject: [PATCH 06/13] be more explicit and and do not create dependency between trigger and publish apis --- src/Channels.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Channels.js b/src/Channels.js index 5c14c1e..d72c20e 100644 --- a/src/Channels.js +++ b/src/Channels.js @@ -62,7 +62,11 @@ context: events, triggerType: "trigger" }); - this.publish = this.trigger; + this.publish = _wrapCalls({ + func: events.publish, + context: events, + triggerType: "trigger" + }); this.registerProxy = registerProxy; } From a94ff3d6cdab60120d200bae2ec1fe7f3432b2d1 Mon Sep 17 00:00:00 2001 From: eliranm Date: Sun, 21 May 2017 11:40:22 +0300 Subject: [PATCH 07/13] remove obsolete grunt step --- build/aliases.js | 1 - 1 file changed, 1 deletion(-) diff --git a/build/aliases.js b/build/aliases.js index 9940ae7..9048670 100644 --- a/build/aliases.js +++ b/build/aliases.js @@ -6,7 +6,6 @@ module.exports = function (grunt, options) { 'default': tasks, 'test': [ 'node_version', - 'mochaTest', 'env', 'instrument', 'connect', From eaa0b590788831200e68253e66b7d179140c59d7 Mon Sep 17 00:00:00 2001 From: eliranm Date: Sun, 21 May 2017 11:44:29 +0300 Subject: [PATCH 08/13] refactor: DRY --- build/aliases.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/build/aliases.js b/build/aliases.js index 9048670..50ed788 100644 --- a/build/aliases.js +++ b/build/aliases.js @@ -1,15 +1,10 @@ module.exports = function (grunt, options) { - var tasks = ['node_version', 'jshint', 'env', 'instrument', 'connect', 'mocha', 'makeReport', 'concat', 'concat_in_order', 'uglify']; + var testTasks = ['env', 'instrument', 'connect', 'mocha', 'makeReport']; + var tasks = [].concat(['node_version', 'jshint'], testTasks, ['concat', 'concat_in_order', 'uglify']); return { 'tasks': ['availabletasks'], 'default': tasks, - 'test': [ - 'node_version', - 'env', - 'instrument', - 'connect', - 'mocha' - ] + 'test': testTasks }; }; From d4b5c6ca87171dd08fc975fe09ea6783054e4b97 Mon Sep 17 00:00:00 2001 From: eliranm Date: Sun, 21 May 2017 17:01:37 +0300 Subject: [PATCH 09/13] fix source paths for require calls --- src/Commands.js | 2 +- src/Events.js | 2 +- src/Reqres.js | 2 +- src/util/CommandsUtil.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Commands.js b/src/Commands.js index 931f1cc..e6269ba 100644 --- a/src/Commands.js +++ b/src/Commands.js @@ -14,7 +14,7 @@ /* istanbul ignore next */ if ("object" === typeof exports) { // CommonJS - factory(root, exports, require("util/EventsUtil").EventsUtil, require("util/CommandsUtil").CommandsUtil); + factory(root, exports, require("./util/EventsUtil").EventsUtil, require("./util/CommandsUtil").CommandsUtil); } /* istanbul ignore next */ else { diff --git a/src/Events.js b/src/Events.js index a72bae7..5638a0f 100644 --- a/src/Events.js +++ b/src/Events.js @@ -14,7 +14,7 @@ /* istanbul ignore next */ if ("object" === typeof exports) { // CommonJS - factory(root, exports, require("util/EventsUtil").EventsUtil); + factory(root, exports, require("./util/EventsUtil").EventsUtil); } /* istanbul ignore next */ else { diff --git a/src/Reqres.js b/src/Reqres.js index b1dede7..8864411 100644 --- a/src/Reqres.js +++ b/src/Reqres.js @@ -14,7 +14,7 @@ /* istanbul ignore next */ if ("object" === typeof exports) { // CommonJS - factory(root, exports, require("util/EventsUtil").EventsUtil, require("util/CommandsUtil").CommandsUtil); + factory(root, exports, require("./util/EventsUtil").EventsUtil, require("./util/CommandsUtil").CommandsUtil); } /* istanbul ignore next */ else { diff --git a/src/util/CommandsUtil.js b/src/util/CommandsUtil.js index fd93e3c..a14d6c0 100644 --- a/src/util/CommandsUtil.js +++ b/src/util/CommandsUtil.js @@ -15,7 +15,7 @@ /* istanbul ignore next */ if ("object" === typeof exports) { // CommonJS - factory(root, exports, require("util/EventsUtil").EventsUtil); + factory(root, exports, require("./EventsUtil").EventsUtil); } /* istanbul ignore next */ else { From 1a271780a964040442541a34cbaf828571a28031 Mon Sep 17 00:00:00 2001 From: eliranm Date: Sun, 21 May 2017 17:05:10 +0300 Subject: [PATCH 10/13] add unit-tests for commonjs module loading --- build/aliases.js | 10 +++++-- build/mocha.json | 2 +- build/simplemocha.json | 7 +++++ package.json | 1 + unittest/module_loading_test.js | 49 +++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 build/simplemocha.json create mode 100644 unittest/module_loading_test.js diff --git a/build/aliases.js b/build/aliases.js index 50ed788..00dbd2e 100644 --- a/build/aliases.js +++ b/build/aliases.js @@ -1,10 +1,14 @@ module.exports = function (grunt, options) { - var testTasks = ['env', 'instrument', 'connect', 'mocha', 'makeReport']; - var tasks = [].concat(['node_version', 'jshint'], testTasks, ['concat', 'concat_in_order', 'uglify']); + var validate = ['node_version', 'jshint']; + var test = ['env', 'instrument', 'connect', 'mocha:test', 'makeReport']; + var unitTest = ['simplemocha:unittest']; + var pack = ['concat', 'concat_in_order', 'uglify']; + var tasks = [].concat(validate, unitTest, test, pack); return { 'tasks': ['availabletasks'], 'default': tasks, - 'test': testTasks + 'test': test, + 'unittest': unitTest }; }; diff --git a/build/mocha.json b/build/mocha.json index 5f33dbd..1ea5f24 100755 --- a/build/mocha.json +++ b/build/mocha.json @@ -8,7 +8,7 @@ "threshold": 80, "globalThreshold": 84, "timeout": 60000, - "--web-security" : false, + "--web-security": false, "urls": [ "http://localhost:8001/test/resources/events_test_base.html" ] diff --git a/build/simplemocha.json b/build/simplemocha.json new file mode 100644 index 0000000..0b710cd --- /dev/null +++ b/build/simplemocha.json @@ -0,0 +1,7 @@ +{ + "unittest": { + "src": [ + "./unittest/**/*_test.js" + ] + } +} diff --git a/package.json b/package.json index b5f84a1..2a09095 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "grunt-mocha": "~1.0.4", "grunt-node-version": "~1.0.2", "grunt-replace": "~1.0.1", + "grunt-simple-mocha": "^0.4.1", "load-grunt-config": "~0.19.2", "mkdirp": "~0.5.1", "mocha": "~3.2.0", diff --git a/unittest/module_loading_test.js b/unittest/module_loading_test.js new file mode 100644 index 0000000..65ece36 --- /dev/null +++ b/unittest/module_loading_test.js @@ -0,0 +1,49 @@ +'use strict'; + +const assert = require('assert'); +const path = require('path'); + +describe('chronosjs', function () { + + describe('module', function () { + + const MODULE_ERROR_PATTERN = /Cannot find module/; + + let moduleLoader = (modulePath) => { + return () => { + require(modulePath); + }; + }; + + let errorAssertionHandler = (errorPattern) => { + return (err) => { + if ((err instanceof Error) && errorPattern.test(err)) { + return err; + } + }; + }; + + let moduleLoadingTest = (modulePath) => { + let moduleName = path.basename(modulePath); + it(`'${moduleName}' should be consumable in a commonjs environment`, () => { + assert.doesNotThrow(moduleLoader(modulePath), errorAssertionHandler(MODULE_ERROR_PATTERN)); + }); + }; + + moduleLoadingTest('../src/Channels'); + moduleLoadingTest('../src/Commands'); + moduleLoadingTest('../src/Events'); + moduleLoadingTest('../src/Reqres'); + + moduleLoadingTest('../src/util/CommandsUtil'); + moduleLoadingTest('../src/util/EventsUtil'); + + moduleLoadingTest('../src/courier/PostMessageChannel'); + moduleLoadingTest('../src/courier/PostMessageChannelPolyfill'); + moduleLoadingTest('../src/courier/PostMessageCourier'); + moduleLoadingTest('../src/courier/PostMessageMapper'); + moduleLoadingTest('../src/courier/PostMessagePromise'); + moduleLoadingTest('../src/courier/PostMessageUtilities'); + + }); +}); From 4a0b7415fe4a767093f9694d6331634e81573bfd Mon Sep 17 00:00:00 2001 From: eliranm Date: Sun, 21 May 2017 17:12:25 +0300 Subject: [PATCH 11/13] add unit-tests for commonjs module loading --- unittest/module_loading_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/module_loading_test.js b/unittest/module_loading_test.js index 65ece36..a8d10cf 100644 --- a/unittest/module_loading_test.js +++ b/unittest/module_loading_test.js @@ -1,7 +1,7 @@ 'use strict'; -const assert = require('assert'); const path = require('path'); +const assert = require('assert'); describe('chronosjs', function () { From 264f3aa2379086646074129d56808d769ad140ba Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Sun, 28 May 2017 13:55:08 +0300 Subject: [PATCH 12/13] remove double append in external iframe courier tests --- test/js/courier_sanity_no_iframe_test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/js/courier_sanity_no_iframe_test.js b/test/js/courier_sanity_no_iframe_test.js index 5acbcc1..3b623cb 100644 --- a/test/js/courier_sanity_no_iframe_test.js +++ b/test/js/courier_sanity_no_iframe_test.js @@ -338,8 +338,6 @@ function createIFrame(options) { } }.bind(this)); - document.body.appendChild(frame); - if (options && options.target && options.target.url) { var src = options.target.url + (0 < options.target.url.indexOf("?") ? "&bust=" : "?bust="); src += (new Date()).getTime(); From c00b7294c420d454f3bcaa4fa31c67864b1e99d7 Mon Sep 17 00:00:00 2001 From: Itai Koren Date: Thu, 1 Jun 2017 08:39:25 +0300 Subject: [PATCH 13/13] Bump minor version + upgrade deps --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 2a09095..6b82bc3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "chronosjs", "description": "JS Channels Mechanism", - "version": "0.0.23", + "version": "0.1.0", "author": { "name": "LivePersonInc", "email": "fe-infra-lp@liveperson.com" @@ -21,26 +21,26 @@ "circuit-breakerjs": "~0.0.5" }, "devDependencies": { - "body-parser": "^1.17.1", - "chai": "~3.5.0", + "body-parser": "~1.17.2", + "chai": "~4.0.1", "grunt": "~1.0.1", "grunt-available-tasks": "~0.6.3", "grunt-concat-in-order": "~0.2.6", "grunt-contrib-concat": "~1.0.1", "grunt-contrib-connect": "~1.0.2", "grunt-contrib-jshint": "~1.1.0", - "grunt-contrib-uglify": "^2.2.1", + "grunt-contrib-uglify": "^3.0.1", "grunt-env": "~0.4.4", "grunt-istanbul": "~0.7.2", "grunt-mocha": "~1.0.4", "grunt-node-version": "~1.0.2", "grunt-replace": "~1.0.1", - "grunt-simple-mocha": "^0.4.1", + "grunt-simple-mocha": "~0.4.1", "load-grunt-config": "~0.19.2", "mkdirp": "~0.5.1", - "mocha": "~3.2.0", + "mocha": "~3.4.2", "requirejs": "~2.3.3", - "sinon": "~2.1.0", + "sinon": "~2.3.2", "time-grunt": "~1.4.0" }, "repository": {