diff --git a/Makefile b/Makefile index 5c3d664..b386afc 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ test: karma start test-all: + standard mocha karma start --single-run --browsers browserstack-osx-chrome karma start --single-run --browsers browserstack-osx-firefox diff --git a/actions.js b/actions.js index 9b5dfc2..e4b70ba 100644 --- a/actions.js +++ b/actions.js @@ -1,181 +1,182 @@ -var debug = require('debug')('browser-monkey'); -var sendkeys = require('./sendkeys'); -var errorHandler = require('./errorHandler'); -function notSillyBlankIEObject(element){ - return Object.keys(element).length > 0; +var debug = require('debug')('browser-monkey') +var sendkeys = require('./sendkeys') +var errorHandler = require('./errorHandler') +function notSillyBlankIEObject (element) { + return Object.keys(element).length > 0 } module.exports = { - focus: function(element, options) { - var focus = typeof options == 'object' && options.hasOwnProperty('focus')? options.focus: true; + focus: function (element, options) { + var focus = typeof options === 'object' && options.hasOwnProperty('focus') ? options.focus : true if (focus) { - var $ = this.get('$'); - var document = this.get('document'); + var $ = this.get('$') + var document = this.get('document') if (element && element.length > 0) { - element = element[0]; + element = element[0] } - var activeElement = document.activeElement; + var activeElement = document.activeElement if (activeElement && !$(activeElement).is(':focus') && notSillyBlankIEObject(activeElement)) { - $(activeElement).trigger('blur'); + $(activeElement).trigger('blur') } - if (['[object Document]', '[object HTMLDocument]'].indexOf(document.toString()) === -1){ - document.activeElement = element; + if (['[object Document]', '[object HTMLDocument]'].indexOf(document.toString()) === -1) { + document.activeElement = element } - $(element).focus(); + $(element).focus() } }, - click: function(options) { - var self = this; + click: function (options) { + var self = this if (typeof options === 'string') { - self = this.linkOrButton(options); + self = this.linkOrButton(options) } - return self.enabled().element(options).then(function(element) { - debug('click', element); - self.handleEvent({type: 'click', element: element}); - self.focus(element, options); - element.trigger('mousedown'); - element.trigger('mouseup'); - element.trigger('click'); - }).catch(errorHandler(new Error())); + return self.enabled().element(options).then(function (element) { + debug('click', element) + self.handleEvent({type: 'click', element: element}) + self.focus(element, options) + element.trigger('mousedown') + element.trigger('mouseup') + element.trigger('click') + }).catch(errorHandler(new Error())) }, - select: function(options) { - if (typeof options == 'string') { - var o = arguments[1] || {}; - o.text = options; - return this.select(o); + select: function (options) { + if (typeof options === 'string') { + var o = arguments[1] || {} + o.text = options + return this.select(o) } - var $ = this.get('$'); - var self = this; - - return this.is('select').find('option', options).elements(options).then(function(optionElements) { - var optionElement = $(optionElements[0]); - var selectElement = optionElement.parent(); - self.focus(selectElement, options); - optionElement.prop('selected', true); - optionElement.attr('selected', 'selected'); - selectElement.val(optionElement.val()); - - debug('select', selectElement); + var $ = this.get('$') + var self = this + + return this.is('select').find('option', options).elements(options).then(function (optionElements) { + var optionElement = $(optionElements[0]) + var selectElement = optionElement.parent() + self.focus(selectElement, options) + optionElement.prop('selected', true) + optionElement.attr('selected', 'selected') + selectElement.val(optionElement.val()) + + debug('select', selectElement) self.handleEvent({ type: 'select option', value: selectElement.val(), element: selectElement, optionElement: optionElement - }); + }) - selectElement.trigger('change'); - }).catch(errorHandler(new Error())); + selectElement.trigger('change') + }).catch(errorHandler(new Error())) }, - typeIn: function(text, options) { - if (typeof text === 'object'){ - text = text.text; + typeIn: function (text, options) { + if (typeof text === 'object') { + text = text.text } - var self = this; - - return this.element(options).then(function(element) { - debug('typeIn', element, text); - assertCanTypeIntoElement(element); - self.focus(element, options); - self.handleEvent({type: 'typing', text: text, element: element}); - return sendkeys(element, text); - }).catch(errorHandler(new Error())); + var self = this + + return this.element(options).then(function (element) { + debug('typeIn', element, text) + assertCanTypeIntoElement(element) + self.focus(element, options) + self.handleEvent({type: 'typing', text: text, element: element}) + return sendkeys(element, text) + }).catch(errorHandler(new Error())) }, - submit: function(options) { - var self = this; + submit: function (options) { + var self = this - return this.element(options).then(function(element) { - debug('submit', element); - self.focus(element, options); - self.handleEvent({type: 'submit', element: element}); - return element.trigger('submit'); - }).catch(errorHandler(new Error())); + return this.element(options).then(function (element) { + debug('submit', element) + self.focus(element, options) + self.handleEvent({type: 'submit', element: element}) + return element.trigger('submit') + }).catch(errorHandler(new Error())) }, - typeInHtml: function(html, options) { - var self = this; + typeInHtml: function (html, options) { + var self = this - return this.element(options).then(function(element) { - self.focus(element, options); - debug('typeInHtml', element, html); - self.handleEvent({type: 'typing html', html: html, element: element}); - return sendkeys.html(element, html); - }).catch(errorHandler(new Error())); + return this.element(options).then(function (element) { + self.focus(element, options) + debug('typeInHtml', element, html) + self.handleEvent({type: 'typing html', html: html, element: element}) + return sendkeys.html(element, html) + }).catch(errorHandler(new Error())) }, - - fill: function(field){ - var isArray = Object.prototype.toString.call(field) === '[object Array]'; - var component = this; + fill: function (field) { + var isArray = Object.prototype.toString.call(field) === '[object Array]' + var component = this var Promise = this.promise() - return new Promise(function(success, failure){ + return new Promise(function (resolve, reject) { if (isArray) { - var fields = field; - function fillField(){ - var field = fields.shift(); - if (field) { - return component.fill(field).then(fillField).catch(failure); - } else { - success(); - } - } - - fillField(); + fillField(component, field) + .then(resolve) + .catch(reject) } else { if (!field.name) { try { - field = inferField(component, field); - } catch(e) { - failure(e.message); - return; + field = inferField(component, field) + } catch (e) { + reject(e) + return } } if (typeof component[field.name] === 'function') { - var finder = component[field.name]() - success(component[field.name]()[field.action](field.options)); + resolve(component[field.name]()[field.action](field.options)) } else { - failure("No field '"+field.name+"' exists on this component"); + reject(new Error("No field '" + field.name + "' exists on this component")) } } - }); + }) } -}; +} -function inferField(component, field){ - var ignoreActions = {constructor: true, _options: true}; +function fillField (component, fields) { + var field = fields.shift() + if (field) { + return component.fill(field).then(function () { + return fillField(component, fields) + }) + } else { + return Promise.resolve() + } +} + +function inferField (component, field) { + var ignoreActions = {constructor: true, _options: true} for (var action in component) { - if (field[action] && !ignoreActions[action]){ + if (field[action] && !ignoreActions[action]) { var newField = { name: field[action], action: action, options: field - }; - delete field[action]; + } + delete field[action] if (field.options) { - newField.options = field.options; + newField.options = field.options } - if (typeof component[newField.name] !== 'function'){ - throw new Error("Field '"+newField.name+"' does not exist"); + if (typeof component[newField.name] !== 'function') { + throw new Error("Field '" + newField.name + "' does not exist") } - return newField; + return newField } }; if (!field.name) { - throw new Error('No action found for field: '+JSON.stringify(field)); + throw new Error('No action found for field: ' + JSON.stringify(field)) } } -function canTypeIntoElement(element) { +function canTypeIntoElement (element) { return element.is('input:not([type]), ' + 'input[type=text], ' + 'input[type=email], ' + @@ -184,11 +185,11 @@ function canTypeIntoElement(element) { 'input[type=tel], ' + 'input[type=url], ' + 'input[type=number],' + - 'textarea'); + 'textarea') } -function assertCanTypeIntoElement(element) { +function assertCanTypeIntoElement (element) { if (!canTypeIntoElement(element)) { - throw new Error('Cannot type into ' + element.prop('tagName')); + throw new Error('Cannot type into ' + element.prop('tagName')) } } diff --git a/angular.js b/angular.js index 60164f8..9178b20 100644 --- a/angular.js +++ b/angular.js @@ -1,18 +1,19 @@ var debug = require('debug')('browser-monkey:angular') -var Mount = require('./mount'); -var createMonkey = require('./create'); -var createTestDiv = require('./createTestDiv'); +var Mount = require('./mount') +var createMonkey = require('./create') +var createTestDiv = require('./createTestDiv') +var angular = require('angular') -module.exports = function(app) { +module.exports = function (app) { return new Mount(app, { - stopApp: function(){}, - startApp: function(){ + stopApp: function () {}, + startApp: function () { debug('Mounting angular app ' + app.moduleName) - var div = createTestDiv(); - div.setAttribute(app.directiveName, ''); - angular.bootstrap(div, [app.moduleName]); + var div = createTestDiv() + div.setAttribute(app.directiveName, '') + angular.bootstrap(div, [app.moduleName]) - return createMonkey(document.body); + return createMonkey(document.body) } - }).start(); + }).start() } diff --git a/assertions.js b/assertions.js index 7b90e60..1203f54 100644 --- a/assertions.js +++ b/assertions.js @@ -1,20 +1,19 @@ -var Options = require('./options'); -var expectOneElement = require('./expectOneElement'); -var errorHandler = require('./errorHandler'); +var Options = require('./options') +var expectOneElement = require('./expectOneElement') +var errorHandler = require('./errorHandler') module.exports = { is: function (css) { - var $ = this.get('$'); - return this.addFinder(this.createElementTester({css: css})); + return this.addFinder(this.createElementTester({css: css})) }, exists: function (options) { - return this.shouldExist(options); + return this.shouldExist(options) }, shouldExist: function (options) { return this.resolve(options) - .catch(errorHandler(new Error())); + .catch(errorHandler(new Error())) }, shouldFind: function (selector, findOptions, existOptions) { @@ -24,68 +23,66 @@ module.exports = { shouldNotExist: function (options) { return this.notResolve(options) - .catch(errorHandler(new Error())); + .catch(errorHandler(new Error())) }, - has: function(options) { - return this.shouldHave(options); + has: function (options) { + return this.shouldHave(options) }, - shouldHave: function(options) { - var $ = this.get('$'); - var self = this; + shouldHave: function (options) { + var self = this - var resolveOptions = Options.remove(options, ['timeout', 'interval']); - resolveOptions.allowMultiple = true; + var resolveOptions = Options.remove(options, ['timeout', 'interval']) + resolveOptions.allowMultiple = true - var additionalAssertions = Object.keys(options).filter(function(finderMethodName){ - return options[finderMethodName] && options[finderMethodName].constructor === Object && typeof self[finderMethodName] === 'function'; - }); + var additionalAssertions = Object.keys(options).filter(function (finderMethodName) { + return options[finderMethodName] && options[finderMethodName].constructor === Object && typeof self[finderMethodName] === 'function' + }) - var additionalOptions = Options.remove(options, additionalAssertions); + var additionalOptions = Options.remove(options, additionalAssertions) - var assertions = additionalAssertions.map(function(finderMethodName){ + var assertions = additionalAssertions.map(function (finderMethodName) { if (typeof self[finderMethodName] === 'function') { - return self[finderMethodName]().shouldHave(additionalOptions[finderMethodName]); + return self[finderMethodName]().shouldHave(additionalOptions[finderMethodName]) } - }); + }) - assertions.push(this.addFinder(this.createElementTester(options)).shouldExist(resolveOptions)); + assertions.push(this.addFinder(this.createElementTester(options)).shouldExist(resolveOptions)) return Promise.all(assertions) - .catch(errorHandler(new Error())); + .catch(errorHandler(new Error())) }, - shouldHaveElement: function(fn, options) { - var $ = this.get('$'); - var self = this; + shouldHaveElement: function (fn, options) { + var $ = this.get('$') + var self = this return this.addFinder({ find: function (elements) { - expectOneElement(self, elements); - elements.toArray().forEach(function(element){ - fn($(element)); - }); - return elements; + expectOneElement(self, elements) + elements.toArray().forEach(function (element) { + fn($(element)) + }) + return elements } - }).shouldExist(options); + }).shouldExist(options) }, - shouldHaveElements: function(fn, options) { - options = Options.default(options, {allowMultiple: true, trace: false}); + shouldHaveElements: function (fn, options) { + options = Options.default(options, {allowMultiple: true, trace: false}) return this.addFinder({ find: function (elements) { - fn(elements.toArray()); - return elements; + fn(elements.toArray()) + return elements } - }).shouldExist(options); + }).shouldExist(options) }, - shouldNotHave: function(options) { - var $ = this.get('$'); - var resolveOptions = Options.remove(options, ['timeout', 'interval']); - resolveOptions.allowMultiple = true; + shouldNotHave: function (options) { + var resolveOptions = Options.remove(options, ['timeout', 'interval']) + resolveOptions.allowMultiple = true - return this.addFinder(this.createElementTester(options)).shouldNotExist(resolveOptions); + return this.addFinder(this.createElementTester(options)).shouldNotExist(resolveOptions) } -}; +} diff --git a/create.js b/create.js index 4f84893..468fb2c 100644 --- a/create.js +++ b/create.js @@ -1,13 +1,13 @@ -var Selector = require('./selector'); -var finders = require('./finders'); -var actions = require('./actions'); -var assertions = require('./assertions'); -var promise = require('./promise'); +var Selector = require('./selector') +var finders = require('./finders') +var actions = require('./actions') +var assertions = require('./assertions') +var promise = require('./promise') -module.exports = function(rootSelector) { +module.exports = function (rootSelector) { return new Selector(rootSelector) .component(promise) .component(finders) .component(actions) - .component(assertions); + .component(assertions) } diff --git a/createTestDiv.js b/createTestDiv.js index 9beb4d4..8b0ea21 100644 --- a/createTestDiv.js +++ b/createTestDiv.js @@ -1,12 +1,12 @@ var div -module.exports = function() { +module.exports = function () { if (div && div.parentNode) { - div.parentNode.removeChild(div); + div.parentNode.removeChild(div) } div = window.document.createElement('div') window.document.body.appendChild(div) - return div; + return div } diff --git a/elementTester.js b/elementTester.js index 43898ed..66ba8ef 100644 --- a/elementTester.js +++ b/elementTester.js @@ -1,35 +1,34 @@ -var chai = require('chai'); -var expect = chai.expect; -var elementsToString = require('./elementsToString'); -require('array.prototype.find').shim(); +var chai = require('chai') +var expect = chai.expect +var elementsToString = require('./elementsToString') +require('array.prototype.find').shim() -function assertElementProperties($, elements, expected, getProperty, exact) { - function assertion(actual, expected) { +function assertElementProperties ($, elements, expected, getProperty, exact) { + function assertion (actual, expected) { if (exact) { - expect(actual, 'expected element to have exact text ' + JSON.stringify(expected) + ' but contained ' + JSON.stringify(actual)).to.equal(expected.toString()); + expect(actual, 'expected element to have exact text ' + JSON.stringify(expected) + ' but contained ' + JSON.stringify(actual)).to.equal(expected.toString()) } else { - expect(actual, 'expected element to contain ' + JSON.stringify(expected) + ' but contained ' + JSON.stringify(actual)).to.contain(expected); + expect(actual, 'expected element to contain ' + JSON.stringify(expected) + ' but contained ' + JSON.stringify(actual)).to.contain(expected) } } if (expected instanceof Array) { var actualTexts = elements.toArray().map(function (item) { - return getProperty($(item)); - }); - - expect(actualTexts.length, 'expected ' + JSON.stringify(actualTexts) + ' to respectively contain ' + JSON.stringify(expected)).to.eql(expected.length); + return getProperty($(item)) + }) + expect(actualTexts.length, 'expected ' + JSON.stringify(actualTexts) + ' to respectively contain ' + JSON.stringify(expected)).to.eql(expected.length) - var comparer = exact == true ? - function(a, b) { return a == b; } : - function(a, b) { return a.indexOf(b) != -1} + var comparer = exact === true + ? function (a, b) { return a === b } + : function (a, b) { return a.indexOf(b) !== -1 } - var found = []; - expected.forEach(function(value) { - var foundValue = actualTexts.find(function(actual) { + var found = [] + expected.forEach(function (value) { + var foundValue = actualTexts.find(function (actual) { return comparer(actual, value) }) - if (foundValue != undefined) { + if (foundValue !== undefined) { actualTexts.splice(actualTexts.indexOf(foundValue), 1) found.push(value) } @@ -37,126 +36,125 @@ function assertElementProperties($, elements, expected, getProperty, exact) { try { expect(found).to.eql(expected) - } catch(e) { - if (found.slice().sort().toString() == expected.slice().sort().toString()) { - e.message += '\nThe text was found but in a different order than specified - maybe you need some sorting?'; + } catch (e) { + if (found.slice().sort().toString() === expected.slice().sort().toString()) { + e.message += '\nThe text was found but in a different order than specified - maybe you need some sorting?' } - throw e; + throw e } } else { - var elementText = getProperty($(elements)); - assertion(elementText, expected); + var elementText = getProperty($(elements)) + assertion(elementText, expected) } } -function getNormalisedText(el) { - return (el.innerText() || '').replace(/ +/g,' ').replace(/ *\r?\n */g,"\n"); +function getNormalisedText (el) { + return (el.innerText() || '').replace(/ +/g, ' ').replace(/ *\r?\n */g, '\n') } -function getValue(e, property) { - var val = e.val(); +function getValue (e, property) { + var val = e.val() // Fails with missing value attribute in VDOM without 'string' test (returns SoftSetHook{value: ''}) - return (typeof val === "string" && val) || ''; + return (typeof val === 'string' && val) || '' } module.exports = { - css: function($el, message, css) { + css: function ($el, message, css) { if (!$el.is(css)) { - throw new Error(message || ('expected elements ' + elementsToString($el) + ' to have css ' + css)); + throw new Error(message || ('expected elements ' + elementsToString($el) + ' to have css ' + css)) } }, - elements: function($el, message, predicate){ + elements: function ($el, message, predicate) { if (!predicate($el.toArray())) { - throw new Error(message || 'expected elements to pass predicate'); + throw new Error(message || 'expected elements to pass predicate') } }, - text: function($el, message, text) { - assertElementProperties(this.get('$'), $el, text, function (e) { return getNormalisedText(e)}, text === ''); + text: function ($el, message, text) { + assertElementProperties(this.get('$'), $el, text, function (e) { return getNormalisedText(e) }, text === '') }, - length: function($el, message, length) { + length: function ($el, message, length) { if ($el.length !== length) { - throw new Error(message || ('expected ' + elementsToString($el) + ' to have ' + length + ' elements')); + throw new Error(message || ('expected ' + elementsToString($el) + ' to have ' + length + ' elements')) } }, - html: function($el, message, html) { - assertElementProperties(this.get('$'), $el, html, function (e) { return e.html(); }); + html: function ($el, message, html) { + assertElementProperties(this.get('$'), $el, html, function (e) { return e.html() }) }, - checked: function($el, message, checked) { - var $ = this.get('$'); - var elements = $el.toArray(); + checked: function ($el, message, checked) { + var $ = this.get('$') + var elements = $el.toArray() if (checked instanceof Array) { var elementsChecked = elements.map(function (element) { - return !!$(element).prop('checked'); - }); - expect(elementsChecked, 'expected ' + elementsToString($el) + ' to have checked states ' + JSON.stringify(checked)).to.eql(checked); + return !!$(element).prop('checked') + }) + expect(elementsChecked, 'expected ' + elementsToString($el) + ' to have checked states ' + JSON.stringify(checked)).to.eql(checked) } else { var elementsNotMatching = elements.filter(function (element) { - return $(element).prop('checked') !== checked; - }); - expect(elementsNotMatching.length, 'expected ' + elementsToString($el) + ' to be ' + (checked? 'checked': 'unchecked')).to.equal(0); + return $(element).prop('checked') !== checked + }) + expect(elementsNotMatching.length, 'expected ' + elementsToString($el) + ' to be ' + (checked ? 'checked' : 'unchecked')).to.equal(0) } }, - exactText: function($el, message, exactText) { - assertElementProperties(this.get('$'), $el, exactText, function (e) { return getNormalisedText(e); }, true); + exactText: function ($el, message, exactText) { + assertElementProperties(this.get('$'), $el, exactText, function (e) { return getNormalisedText(e) }, true) }, - value: function($el, message, value) { - assertElementProperties(this.get('$'), $el, value, getValue, value === ''); + value: function ($el, message, value) { + assertElementProperties(this.get('$'), $el, value, getValue, value === '') }, - exactValue: function($el, message, exactValue) { - assertElementProperties(this.get('$'), $el, exactValue, getValue, true); + exactValue: function ($el, message, exactValue) { + assertElementProperties(this.get('$'), $el, exactValue, getValue, true) }, - attributes: function($el, message, attributes) { - var $ = this.get('$'); - var elements = $el.toArray(); + attributes: function ($el, message, attributes) { + var $ = this.get('$') + var elements = $el.toArray() if (attributes instanceof Array) { expect(elements.length).to.equal(attributes.length, 'expected the matched elements to be the same length as the expected attributes') - elements.forEach(function(el, index){ - var attributesForElement = attributes[index]; - Object.keys(attributesForElement).forEach(function(attributeKey){ - expect($(el).attr(attributeKey)).to.equal(attributesForElement[attributeKey]); - }); - }); - + elements.forEach(function (el, index) { + var attributesForElement = attributes[index] + Object.keys(attributesForElement).forEach(function (attributeKey) { + expect($(el).attr(attributeKey)).to.equal(attributesForElement[attributeKey]) + }) + }) } else { - elements.forEach(function(el){ - Object.keys(attributes).forEach(function(attributeKey){ - expect($(el).attr(attributeKey)).to.equal(attributes[attributeKey]); - }); - }); + elements.forEach(function (el) { + Object.keys(attributes).forEach(function (attributeKey) { + expect($(el).attr(attributeKey)).to.equal(attributes[attributeKey]) + }) + }) } }, - label: function($el, message, label) { - var $ = this.get('$'); - var links = $el.toArray().filter(function(el) { + label: function ($el, message, label) { + var $ = this.get('$') + var links = $el.toArray().filter(function (el) { if ($(el).is('a')) { - var anchor = $(el); - var href = anchor.attr('href'); + var anchor = $(el) + var href = anchor.attr('href') return typeof href !== typeof undefined && href !== false && ( - anchor.text() == label || - anchor.attr('id') == label || - anchor.attr('title') == label || - anchor.find("img").toArray().filter(function(img) { - return $(img).attr('alt') == label; + anchor.text() === label || + anchor.attr('id') === label || + anchor.attr('title') === label || + anchor.find('img').toArray().filter(function (img) { + return $(img).attr('alt') === label }).length > 0 - ); + ) } if ($(el).is('button, input[type=submit], input[type=button], input[type=reset]')) { - var button = $(el); - return button.attr('id') == label || - button.text() == label || - (typeof button.attr('value') == 'string' && button.attr('value').indexOf(label) > -1) || - (typeof button.attr('title') == 'string' && button.attr('title').indexOf(label) > -1) || - button.find("img").toArray().filter(function(img) { - return typeof $(img).attr('alt') == 'string' && $(img).attr('alt').indexOf(label) > -1; + var button = $(el) + return button.attr('id') === label || + button.text() === label || + (typeof button.attr('value') === 'string' && button.attr('value').indexOf(label) > -1) || + (typeof button.attr('title') === 'string' && button.attr('title').indexOf(label) > -1) || + button.find('img').toArray().filter(function (img) { + return typeof $(img).attr('alt') === 'string' && $(img).attr('alt').indexOf(label) > -1 }).length > 0 } - }); + }) - expect(links.length).to.equal(1, message); + expect(links.length).to.equal(1, message) } -}; +} diff --git a/elementsToString.js b/elementsToString.js index b5f3928..d07bd46 100644 --- a/elementsToString.js +++ b/elementsToString.js @@ -1,6 +1,5 @@ -module.exports = function elementsToString(els) { +module.exports = function elementsToString (els) { return els.toArray().map(function (el) { - if (el && el.outerHTML) - return el.outerHTML.replace(el.innerHTML, ''); - }).join(', '); + if (el && el.outerHTML) { return el.outerHTML.replace(el.innerHTML, '') } + }).join(', ') } diff --git a/errorHandler.js b/errorHandler.js index 5ff27ee..598e77e 100644 --- a/errorHandler.js +++ b/errorHandler.js @@ -1,15 +1,15 @@ -function BrowserMonkeyError(message, stack) { - this.name = 'BrowserMonkeyError'; - this.message = message; - this.stack = stack; +function BrowserMonkeyError (message, stack) { + this.name = 'BrowserMonkeyError' + this.message = message + this.stack = stack } -BrowserMonkeyError.prototype = Object.create(Error.prototype); -BrowserMonkeyError.prototype.constructor = BrowserMonkeyError; +BrowserMonkeyError.prototype = Object.create(Error.prototype) +BrowserMonkeyError.prototype.constructor = BrowserMonkeyError -module.exports = function(error) { - return function(e) { - var bmError = new BrowserMonkeyError(e.message, error.stack); - //bmError.internalError = e; - throw bmError; +module.exports = function (error) { + return function (e) { + var bmError = new BrowserMonkeyError(e.message, error.stack) + // bmError.internalError = e; + throw bmError } } diff --git a/expectOneElement.js b/expectOneElement.js index df434ba..0ca1f53 100644 --- a/expectOneElement.js +++ b/expectOneElement.js @@ -1,8 +1,8 @@ -var chai = require('chai'); -var expect = chai.expect; -var elementsToString = require('./elementsToString'); +var chai = require('chai') +var expect = chai.expect +var elementsToString = require('./elementsToString') -module.exports = function expectOneElement(scope, elements) { - var msg = "expected to find exactly one element: " + scope.printFinders(scope._finders) + ', but found :' + elementsToString(elements); - expect(elements.length, msg).to.equal(1); +module.exports = function expectOneElement (scope, elements) { + var msg = 'expected to find exactly one element: ' + scope.printFinders(scope._finders) + ', but found :' + elementsToString(elements) + expect(elements.length, msg).to.equal(1) } diff --git a/finders.js b/finders.js index ce9f698..7a53a7f 100644 --- a/finders.js +++ b/finders.js @@ -1,283 +1,283 @@ -var Options = require('./options'); -var expectOneElement = require('./expectOneElement'); +var Options = require('./options') +var expectOneElement = require('./expectOneElement') +var window = require('global') module.exports = { - elementFinder: function(css) { - var $ = this.get('$'); - var self = this; + elementFinder: function (css) { + var $ = this.get('$') + var self = this return { - find: function(element) { - var els = $(element).find(css); + find: function (element) { + var els = $(element).find(css) if (self.get('visibleOnly')) { - els = els.filter(function(index){ - var el = this[index] || this; - var ignoreVisibilityOfTags = ['OPTION']; + els = els.filter(function (index) { + var el = this[index] || this + var ignoreVisibilityOfTags = ['OPTION'] if (el && ignoreVisibilityOfTags.indexOf(el.tagName) !== -1) { - el = el.parentNode; + el = el.parentNode } - return $(el).is(':visible'); - }); + return $(el).is(':visible') + }) } if (els.length > 0) { - return els; + return els } }, - toString: function() { - return css; + toString: function () { + return css } - }; + } }, addFinder: function (finder) { - var finders = this._finders && this._finders.slice() || []; - finders.push(finder); - return this.clone({_finders: finders}); + var finders = this._finders && (this._finders.slice() || []) + finders.push(finder) + return this.clone({_finders: finders}) }, - createElementTester: function(criteria) { - var self = this; + createElementTester: function (criteria) { + var self = this if (typeof criteria === 'string') { - criteria = { css: criteria }; + criteria = { css: criteria } } if (typeof criteria === 'function') { - criteria = { predicate: criteria }; + criteria = { predicate: criteria } } return { - find: function($el) { - var message = criteria.message; - Object.keys(criteria).forEach(function(key){ - var value = criteria[key]; - var tester = self._elementTesters[key]; + find: function ($el) { + var message = criteria.message + Object.keys(criteria).forEach(function (key) { + var value = criteria[key] + var tester = self._elementTesters[key] if (value !== undefined && tester !== undefined) { - tester.call(self, $el, message, value); + tester.call(self, $el, message, value) } - }); - return $el; + }) + return $el }, - toString: function(){ - return criteria.message || criteria.css || criteria.text; + toString: function () { + return criteria.message || criteria.css || criteria.text } - }; + } }, find: function (selector, options) { - var $ = this.get('$'); - var message = JSON.stringify(options); - var scope = this.addFinder(this.elementFinder(selector)); + var message = JSON.stringify(options) + var scope = this.addFinder(this.elementFinder(selector)) if (options) { - var tester = this.createElementTester(options); + var tester = this.createElementTester(options) return scope.filter(function (element) { try { - return tester.find(element); + return tester.find(element) } catch (error) { - return false; + return false } - }, message); + }, message) } else { - return scope; + return scope } }, containing: function (selector, options) { - var $ = this.get('$'); - var message = options && JSON.stringify(options); - var findElements = this.elementFinder(selector); - var finder; + var $ = this.get('$') + var message = options && JSON.stringify(options) + var findElements = this.elementFinder(selector) + var finder if (options) { - var tester = this.createElementTester(options); + var tester = this.createElementTester(options) finder = { find: function (elements) { - var found = findElements.find(elements); + var found = findElements.find(elements) var tested = found.toArray().filter(function (element) { try { - tester.find(element); - return true; + tester.find(element) + return true } catch (error) { - return false; + return false } - }); + }) if (tested.length > 0) { - return tested; + return tested } }, toString: function () { - return selector + (message? ' ' + message: ''); + return selector + (message ? ' ' + message : '') } } } else { - finder = findElements; + finder = findElements } return this.addFinder({ - find: function(elements) { - var els = Array.prototype.filter.call(elements, function(el) { + find: function (elements) { + var els = Array.prototype.filter.call(elements, function (el) { try { - return finder.find(el); + return finder.find(el) } catch (e) { - return false; + return false } - }); + }) if (els.length > 0) { - return $(els); + return $(els) } }, - toString: function() { - return ':has(' + finder.toString() + ')'; + toString: function () { + return ':has(' + finder.toString() + ')' } - }); + }) }, - linkOrButton: function(label) { + linkOrButton: function (label) { return this.find( 'a, button, input[type=submit], input[type=button], input[type=reset]', {label: label}, - "[linkOrButton: " + label + "]" - ); + '[linkOrButton: ' + label + ']' + ) }, - button: function(label) { + button: function (label) { return this.find( 'button, input[type=submit], input[type=button], input[type=reset]', {label: label}, - "[button: " + label + "]" - ); + '[button: ' + label + ']' + ) }, - link: function(label) { - return this.find('a', {label: label}, "[link: " + label + "]"); + link: function (label) { + return this.find('a', {label: label}, '[link: ' + label + ']') }, elements: function (options) { - options = Options.default(options, {allowMultiple: true}); - return this.resolve(options); + options = Options.default(options, {allowMultiple: true}) + return this.resolve(options) }, element: function (options) { - var $ = this.get('$'); + var $ = this.get('$') return this.resolve(options).then(function (elements) { - return $(elements[0]); - }); + return $(elements[0]) + }) }, printFinders: function (finders) { - return finders.map(function (f) { return f.toString(); }).join(' ').replace(/\s+\:/g,':'); + return finders.map(function (f) { return f.toString() }).join(' ').replace(/\s+:/g, ':') }, findElements: function (options) { - var $ = this.get('$'); - var self = this; - var allowMultiple = Options.get(options, 'allowMultiple'); + var $ = this.get('$') + var self = this + var allowMultiple = Options.get(options, 'allowMultiple') - function findWithFinder(el, finderIndex) { - var finder = self._finders[finderIndex]; + function findWithFinder (el, finderIndex) { + var finder = self._finders[finderIndex] if (finder) { - var found = finder.find(el); + var found = finder.find(el) if (!found) { - throw new Error("expected to find: " + self.printFinders(self._finders)); + throw new Error('expected to find: ' + self.printFinders(self._finders)) } - return findWithFinder(found, finderIndex + 1); + return findWithFinder(found, finderIndex + 1) } else { - return el; + return el } }; - function selector() { - var selector = self._selector; + function selector () { + var selector = self._selector if ( selector && - typeof Element !== 'undefined' && - selector instanceof Element && - selector.tagName == 'IFRAME' + typeof window.Element !== 'undefined' && + selector instanceof window.Element && + selector.tagName === 'IFRAME' ) { - return selector.contentDocument; + return selector.contentDocument } else if ( selector && typeof selector.prop === 'function' && selector.prop('tagName') === 'IFRAME' ) { - return selector[0].contentDocument; + return selector[0].contentDocument } else { - return selector || 'html'; + return selector || 'html' } } - var elements = findWithFinder($(selector()), 0); + var elements = findWithFinder($(selector()), 0) if (!allowMultiple) { - expectOneElement(self, elements); + expectOneElement(self, elements) } - return elements.toArray(); + return elements.toArray() }, - resolve: function(options) { - var self = this; - var defaultTimeout = this.get('timeout') || 1000; - var retryOptions = Options.remove(options, ['timeout', 'interval']); - retryOptions.timeout = retryOptions.timeout || defaultTimeout; + resolve: function (options) { + var self = this + var defaultTimeout = this.get('timeout') || 1000 + var retryOptions = Options.remove(options, ['timeout', 'interval']) + retryOptions.timeout = retryOptions.timeout || defaultTimeout - var result = this.retry(retryOptions, function() { - return self.findElements(options); - }); + var result = this.retry(retryOptions, function () { + return self.findElements(options) + }) - return result; + return result }, - notResolve: function(options) { - var self = this; + notResolve: function (options) { + var self = this - return this.retry(options, function() { - var found = false; + return this.retry(options, function () { + var found = false try { - self.findElements({allowMultiple: true}); - found = true; + self.findElements({allowMultiple: true}) + found = true } catch (e) { } if (found) { - throw new Error("didn't expect to find element: " + self.printFinders(self._finders)); + throw new Error("didn't expect to find element: " + self.printFinders(self._finders)) } - }); + }) }, filter: function (filter, message) { - var $ = this.get('$'); + var $ = this.get('$') return this.addFinder({ find: function (elements) { - var filteredElements = elements.toArray().filter(function(element){ + var filteredElements = elements.toArray().filter(function (element) { return filter($(element)) - }); + }) if (filteredElements && filteredElements.length > 0) { - return $(filteredElements); + return $(filteredElements) } }, toString: function () { - return message || '[filter]'; + return message || '[filter]' } - }); + }) }, enabled: function () { return this.filter(function (element) { - var tagName = element.prop('tagName'); - return !((tagName == 'BUTTON' || tagName == 'INPUT') && element.prop('disabled')); - }, '[disabled=false]'); + var tagName = element.prop('tagName') + return !((tagName === 'BUTTON' || tagName === 'INPUT') && element.prop('disabled')) + }, '[disabled=false]') } -}; +} diff --git a/hyperdom.js b/hyperdom.js index 916073e..77c71fd 100644 --- a/hyperdom.js +++ b/hyperdom.js @@ -1,41 +1,41 @@ -var Mount = require('./mount'); -var hyperdom = require('hyperdom'); -var createMonkey = require('./create'); -var window = require('global'); +var Mount = require('./mount') +var hyperdom = require('hyperdom') +var createMonkey = require('./create') +var window = require('global') var createTestDiv = require('./createTestDiv') var extend = require('lowscore/extend') -module.exports = function(app, options) { +module.exports = function (app, options) { return new Mount(app, { - stopApp: function(){ + stopApp: function () { }, - startApp: function(){ + startApp: function () { if (options && options.router) { options.router.reset() } - var app = this.app; + var app = this.app if (Mount.runningInNode) { try { - var vquery = require('vdom-query'); + var vquery = require('vdom-query') } catch (e) { - throw new Error('you must `npm install vdom-query --save-dev` to run tests in node'); + throw new Error('you must `npm install vdom-query --save-dev` to run tests in node') } - var vdom = hyperdom.html('body'); + var vdom = hyperdom.html('body') - var monkey = createMonkey(vdom); - monkey.set({$: vquery, visibleOnly: false, document: {}}); + var monkey = createMonkey(vdom) + monkey.set({$: vquery, visibleOnly: false, document: {}}) - hyperdom.appendVDom(vdom, app, extend({ requestRender: setTimeout, window: window }, options)); - return monkey; + hyperdom.appendVDom(vdom, app, extend({ requestRender: setTimeout, window: window }, options)) + return monkey } else { var testDiv = createTestDiv() if (options && (options.hash || options.url) && options.router) { options.router.push(options.url || options.hash) } - hyperdom.append(testDiv, app, extend({ requestRender: setTimeout }, options)); - return createMonkey(testDiv); + hyperdom.append(testDiv, app, extend({ requestRender: setTimeout }, options)) + return createMonkey(testDiv) } } - }).start(); + }).start() } diff --git a/iframe.js b/iframe.js index a708cd5..dadbbf9 100644 --- a/iframe.js +++ b/iframe.js @@ -1,46 +1,45 @@ var debug = require('debug')('browser-monkey:angular') -var Mount = require('./mount'); -var createMonkey = require('./create'); -var hobostyle = require('hobostyle'); -var createTestDiv = require('./createTestDiv'); -var addressBarInterval; +var Mount = require('./mount') +var createMonkey = require('./create') +var hobostyle = require('hobostyle') +var createTestDiv = require('./createTestDiv') +var addressBarInterval -module.exports = function(url) { +module.exports = function (url) { return new Mount(url, { - stopApp: function(){}, - startApp: function(){ + stopApp: function () {}, + startApp: function () { debug('Mounting iframe: ' + url) - var div = createTestDiv(); - var addressBar = document.createElement('div'); - addressBar.innerText = url; - addressBar.className = 'address-bar'; - div.appendChild(addressBar); + var div = createTestDiv() + var addressBar = document.createElement('div') + addressBar.innerText = url + addressBar.className = 'address-bar' + div.appendChild(addressBar) - var iframe = document.createElement('iframe'); - iframe.src = url; + var iframe = document.createElement('iframe') + iframe.src = url iframe.onload = function () { - addressBar.innerText = iframe.contentWindow.location.href; - }; - iframe.height = window.innerHeight - addressBar.clientHeight - 10; - div.appendChild(iframe); + addressBar.innerText = iframe.contentWindow.location.href + } + iframe.height = window.innerHeight - addressBar.clientHeight - 10 + div.appendChild(iframe) if (addressBarInterval) { - clearInterval(addressBarInterval); + clearInterval(addressBarInterval) } addressBarInterval = setInterval(function () { if (iframe.contentWindow) { - addressBar.innerText = iframe.contentWindow.location.href; + addressBar.innerText = iframe.contentWindow.location.href } else { - clearInterval(addressBarInterval); + clearInterval(addressBarInterval) } - }, 300); + }, 300) - hobostyle.style('html,body { margin: 0; height: 100%; }'); - hobostyle.style('iframe { border: none; width: 100%; }'); + hobostyle.style('html,body { margin: 0; height: 100%; }') + hobostyle.style('iframe { border: none; width: 100%; }') hobostyle.style('.address-bar { padding: 5px; font-family: arial; font-size: 20px; border-bottom: 1px solid gray; }') - return createMonkey(iframe); + return createMonkey(iframe) } - }).start(); + }).start() } - diff --git a/index.js b/index.js index b385d8a..9838084 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -module.exports = require('./create')(); +module.exports = require('./create')() diff --git a/jquery.js b/jquery.js index 94f58de..deb61f9 100644 --- a/jquery.js +++ b/jquery.js @@ -1,63 +1,62 @@ -var jquery = require('jquery'); -function dispatchEvent(element, eventType){ - var event; +var jquery = require('jquery') +function dispatchEvent (element, eventType) { + var event if (eventType === 'click') { - element.click(); + element.click() } else { if (document.createEvent) { - event = document.createEvent("Event"); - event.initEvent(eventType, true, true); - element.dispatchEvent(event); + event = document.createEvent('Event') + event.initEvent(eventType, true, true) + element.dispatchEvent(event) } else { - event = document.createEventObject(); - event.eventType = eventType; - event.eventName = eventType; - element.fireEvent("on" + event.eventType, event); + event = document.createEventObject() + event.eventType = eventType + event.eventName = eventType + element.fireEvent('on' + event.eventType, event) } } } if (jquery.fn) { jquery.fn.extend({ - innerText: function(){ - var el = this[0].body || this[0]; - return el.innerText || el.textContent; + innerText: function () { + var el = this[0].body || this[0] + return el.innerText || el.textContent }, - trigger: function(eventType){ - for (var i=0; i 0) { - throw new Error('properties ' + keys.join(', ') + ' not recognised, try ' + this.validOptions.join(', ')); + throw new Error('properties ' + keys.join(', ') + ' not recognised, try ' + this.validOptions.join(', ')) } } } diff --git a/package.json b/package.json index 72b34c8..40084eb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "reliable dom testing", "main": "index.js", "scripts": { - "test": "mocha && karma start --single-run" + "test": "standard && mocha && karma start --single-run" }, "engines": { "node": "7.6.0" @@ -42,6 +42,7 @@ "react": "^15.4.1", "react-dom": "^15.4.1", "server-destroy": "^1.0.1", + "standard": "^10.0.0", "vdom-query": "https://github.com/featurist/vdom-query", "virtual-dom": "^2.1.1", "watchify": "^3.7.0" @@ -59,6 +60,9 @@ "lowscore": "^1.12.1", "trytryagain": "1.2.0" }, + "standard": { + "env": ["mocha"] + }, "browserify": { "transform": [ "browserify-optional" diff --git a/promise.js b/promise.js index f54b94e..04ef42b 100644 --- a/promise.js +++ b/promise.js @@ -1,16 +1,16 @@ -var FinishedPromise = require('finished-promise'); -var trytryagain = require('trytryagain'); +var FinishedPromise = require('finished-promise') +var trytryagain = require('trytryagain') -function immediately(retryOptions, fn) { - return FinishedPromise.resolve().then(fn); +function immediately (retryOptions, fn) { + return FinishedPromise.resolve().then(fn) } module.exports = { promise: function () { - return this.get('immediate') ? FinishedPromise : Promise; + return this.get('immediate') ? FinishedPromise : Promise }, retry: function (options, fn) { - return this.get('immediate') ? immediately(options, fn) : trytryagain(options, fn); + return this.get('immediate') ? immediately(options, fn) : trytryagain(options, fn) } } diff --git a/react.js b/react.js index 7e859b8..602556e 100644 --- a/react.js +++ b/react.js @@ -1,18 +1,18 @@ -var Mount = require('./mount'); +var Mount = require('./mount') var React = require('react') var ReactDOM = require('react-dom') -var createMonkey = require('./create'); -var createTestDiv = require('./createTestDiv'); +var createMonkey = require('./create') +var createTestDiv = require('./createTestDiv') -module.exports = function(app) { +module.exports = function (app) { return new Mount(app, { - stopApp: function() { + stopApp: function () { }, - startApp: function() { + startApp: function () { var div = createTestDiv() ReactDOM.render(React.createElement(this.app.constructor, null), div) - return createMonkey(document.body); + return createMonkey(document.body) } }).start() } diff --git a/reloadButton.js b/reloadButton.js index 6c8b2ac..f997621 100644 --- a/reloadButton.js +++ b/reloadButton.js @@ -2,7 +2,7 @@ var href = window.location.href var hobostyle = require('hobostyle') var extend = require('lowscore/extend') -module.exports = function refreshButton(_options) { +module.exports = function refreshButton (_options) { var options = extend({ style: true, class: 'browser-monkey-reload' @@ -10,21 +10,21 @@ module.exports = function refreshButton(_options) { if (options.style) { hobostyle.style( - '.' + options['class'] + ' {' - + 'z-index: 1000;' - + 'position: fixed;' - + 'right: 5px;' - + 'bottom: 5px;' - + 'background-color: rgba(255, 255, 255, 0.85);' - + 'padding: 5px 10px;' - + 'text-decoration: none;' - + 'color: #444444;' - + 'font-family: "Open Sans", sans-serif;' - + '}' - + '.' + options['class'] + ':hover {' - + 'color: black;' - + 'box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 5px;' - + '}') + '.' + options['class'] + ' {' + + 'z-index: 1000;' + + 'position: fixed;' + + 'right: 5px;' + + 'bottom: 5px;' + + 'background-color: rgba(255, 255, 255, 0.85);' + + 'padding: 5px 10px;' + + 'text-decoration: none;' + + 'color: #444444;' + + 'font-family: "Open Sans", sans-serif;' + + '}' + + '.' + options['class'] + ':hover {' + + 'color: black;' + + 'box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 5px;' + + '}') } var link = document.createElement('a') diff --git a/removeStrictFromSend.js b/removeStrictFromSend.js index 0e38b28..b1571d3 100644 --- a/removeStrictFromSend.js +++ b/removeStrictFromSend.js @@ -1,6 +1,5 @@ -var util = require('util'); -var through = require('through'); -var path = require('path'); +var through = require('through') +var path = require('path') // in pre safari 10 send causes a strict mode bug to occur in safari // and so can't load vinehill/express apps at all @@ -9,35 +8,35 @@ var path = require('path'); // in any browser anymore. will be able to remove this once // older versions of safari are less used -function unstrictifySend(file, opts) { - opts = opts || {}; - opts.exclude = ['json'].concat(opts.exclude||[]); +function unstrictifySend (file, opts) { + opts = opts || {} + opts.exclude = ['json'].concat(opts.exclude || []) - var stream = through(write, end); - var applied = false; + var stream = through(write, end) + var applied = false - var filetype = path.extname(file).replace('.', ''); + var filetype = path.extname(file).replace('.', '') var excluded = (opts.exclude).some(function (excludedExt) { - return filetype == excludedExt.replace('.', ''); - }); + return filetype === excludedExt.replace('.', '') + }) - return stream; + return stream - function write(buf) { + function write (buf) { if (!applied && !excluded) { - applied = true; + applied = true } - if (file.indexOf('send/index.js') != -1) { + if (file.indexOf('send/index.js') !== -1) { var output = buf.toString().replace(/'use strict'/, '') stream.queue(output) } else { - stream.queue(buf); + stream.queue(buf) } } - function end() { - stream.queue(null); + function end () { + stream.queue(null) } } -module.exports = unstrictifySend; +module.exports = unstrictifySend diff --git a/selector.js b/selector.js index 49d13d1..62334ab 100644 --- a/selector.js +++ b/selector.js @@ -1,78 +1,78 @@ -var elementTester = require('./elementTester'); -var global = require('global'); - -function Selector(selector, finders, options) { - this._selector = selector; - this._finders = finders || []; - this._options = options || { visibleOnly: true, $: require('./jquery'), document: global.document, immediate: false, timeout: 1000 }; - this._handlers = []; - this._elementTesters = elementTester; +var elementTester = require('./elementTester') +var global = require('global') + +function Selector (selector, finders, options) { + this._selector = selector + this._finders = finders || [] + this._options = options || { visibleOnly: true, $: require('./jquery'), document: global.document, immediate: false, timeout: 1000 } + this._handlers = [] + this._elementTesters = elementTester } -Selector.prototype.set = function(options){ - var self = this; - Object.keys(options).forEach(function(key){ - self._options[key] = options[key]; - }); - return this; +Selector.prototype.set = function (options) { + var self = this + Object.keys(options).forEach(function (key) { + self._options[key] = options[key] + }) + return this } -Selector.prototype.get = function(key){ - return this._options[key]; +Selector.prototype.get = function (key) { + return this._options[key] } Selector.prototype.clone = function (extension) { - var clone = new this.constructor(); - var self = this; + var clone = new this.constructor() + var self = this Object.keys(self).forEach(function (key) { - clone[key] = self[key]; - }); + clone[key] = self[key] + }) Object.keys(extension).forEach(function (key) { - clone[key] = extension[key]; - }); + clone[key] = extension[key] + }) - return clone; -}; + return clone +} Selector.prototype.on = function (handler) { - this._handlers.push(handler); - return this; -}; + this._handlers.push(handler) + return this +} Selector.prototype.handleEvent = function () { - var args = arguments; + var args = arguments this._handlers.forEach(function (handler) { - handler.apply(undefined, args); - }); -}; + handler.apply(undefined, args) + }) +} Selector.prototype.scope = function (scope) { if (scope instanceof Selector) { - return this.clone(scope); + return this.clone(scope) } else { - return this.clone({_selector: scope}); + return this.clone({_selector: scope}) } -}; +} Selector.prototype.extend = function (methods) { - return this.component(methods); -}; + return this.component(methods) +} Selector.prototype.component = function (methods) { - function Component() { - Selector.apply(this, arguments); + function Component () { + Selector.apply(this, arguments) } - Component.prototype = new this.constructor(); + Component.prototype = new this.constructor() Object.keys(methods).forEach(function (method) { - Component.prototype[method] = methods[method]; - }); - Component.prototype.constructor = Component; + Component.prototype[method] = methods[method] + }) + Component.prototype.constructor = Component - return new Component().scope(this); -}; + return new Component().scope(this) +} -module.exports = Selector; +module.exports = Selector diff --git a/sendkeys.js b/sendkeys.js index 44cec2f..fa41405 100644 --- a/sendkeys.js +++ b/sendkeys.js @@ -1,37 +1,37 @@ -function dispatchEvent(el, type, char) { - el.trigger(type, {charCode: char}); +function dispatchEvent (el, type, char) { + el.trigger(type, {charCode: char}) } -function sendkey(el, char) { - dispatchEvent(el, "keydown", char); - dispatchEvent(el, "keypress", char); - dispatchEvent(el, "input"); - dispatchEvent(el, "keyup", char); +function sendkey (el, char) { + dispatchEvent(el, 'keydown', char) + dispatchEvent(el, 'keypress', char) + dispatchEvent(el, 'input') + dispatchEvent(el, 'keyup', char) } -function sendkeys(el, text) { - var originalValue = el.val(); +function sendkeys (el, text) { + var originalValue = el.val() if (text.length === 0) { - el.val(''); - sendkey(el, ''); + el.val('') + sendkey(el, '') } else { for (var n = 0; n < text.length; ++n) { - var char = text[n]; - var value = text.substring(0, n + 1); - el.val(value); - sendkey(el, char); + var char = text[n] + var value = text.substring(0, n + 1) + el.val(value) + sendkey(el, char) } } - if (originalValue !== text){ - dispatchEvent(el, 'change'); + if (originalValue !== text) { + dispatchEvent(el, 'change') } }; -sendkeys.html = function(el, html) { - el.innerHTML = html; - dispatchEvent(el, "input"); -}; +sendkeys.html = function (el, html) { + el.innerHTML = html + dispatchEvent(el, 'input') +} -module.exports = sendkeys; +module.exports = sendkeys diff --git a/setTestUrl.js b/setTestUrl.js index e9331fc..8f8a6d2 100644 --- a/setTestUrl.js +++ b/setTestUrl.js @@ -1,4 +1,4 @@ -module.exports = function(options) { +module.exports = function (options) { if (options) { if (options.hash !== undefined) { window.location.hash = options.hash diff --git a/stubBrowser.js b/stubBrowser.js index 1f4ee8b..706322b 100644 --- a/stubBrowser.js +++ b/stubBrowser.js @@ -1,26 +1,28 @@ -var window = require('global'); +var window = require('global') -var registeredEvents = {}; -var pushState, replaceState; +var registeredEvents = {} +var pushState, replaceState -pushState = replaceState = function(state, title, url) { +pushState = replaceState = function (state, title, url) { window.location.pathname = url; - (registeredEvents['onpopstate'] || []).forEach(function(cb) { cb({}); }); -}; + (registeredEvents['onpopstate'] || []).forEach(function (cb) { + cb() + }) +} -window.location = window.location || {}; -window.location.pathname = window.location.pathname || '/'; -window.location.origin = window.location.origin || ''; -window.location.search = window.location.search || ''; +window.location = window.location || {} +window.location.pathname = window.location.pathname || '/' +window.location.origin = window.location.origin || '' +window.location.search = window.location.search || '' window.history = { pushState: pushState, - replaceState: replaceState, -}; + replaceState: replaceState +} -window.addEventListener = function(eventName, cb) { - eventName = 'on'+eventName; +window.addEventListener = function (eventName, cb) { + eventName = 'on' + eventName if (!registeredEvents[eventName]) { - registeredEvents[eventName] = []; + registeredEvents[eventName] = [] } - registeredEvents[eventName].push(cb); -}; + registeredEvents[eventName].push(cb) +} diff --git a/test/actionsSpec.js b/test/actionsSpec.js index f287d3e..f466473 100644 --- a/test/actionsSpec.js +++ b/test/actionsSpec.js @@ -1,317 +1,313 @@ -var AssertionError = require('assert').AssertionError var demand = require('must') -var domTest = require('./domTest'); -var retry = require('trytryagain'); +var domTest = require('./domTest') +var retry = require('trytryagain') -describe('actions', function(){ +describe('actions', function () { describe('clicking', function () { - domTest('stack trace', function(browser, dom){ + domTest('stack trace', function (browser, dom) { return browser.find('div') .click() - .assertStackTrace(__filename); + .assertStackTrace(__filename) }, { mochaOnly: true - }); + }) domTest('should eventually click an element', function (browser, dom, $) { - var promise = browser.find('.element').click(); - var clicked = false; + var promise = browser.find('.element').click() + var clicked = false dom.eventuallyInsert( $('
').on('click', function () { - clicked = true; + clicked = true }) - ); + ) return promise.then(function () { - demand(clicked).to.equal(true); - }); - }); + demand(clicked).to.equal(true) + }) + }) domTest('sends mousedown mouseup and click events', function (browser, dom) { - var events = []; + var events = [] dom.insert('
').on('mousedown', function () { - events.push('mousedown'); + events.push('mousedown') }).on('mouseup', function () { - events.push('mouseup'); + events.push('mouseup') }).on('click', function () { - events.push('click'); - }); + events.push('click') + }) return browser.find('.element').click().then(function () { - demand(events).to.eql(['mousedown', 'mouseup', 'click']); - }); - }); + demand(events).to.eql(['mousedown', 'mouseup', 'click']) + }) + }) domTest('mousedown mouseup and click events bubble up to parent', function (browser, dom) { - var events = []; + var events = [] dom.insert('
inner
').on('mousedown', function () { - events.push('mousedown'); + events.push('mousedown') }).on('mouseup', function () { - events.push('mouseup'); + events.push('mouseup') }).on('click', function () { - events.push('click'); - }); + events.push('click') + }) return browser.find('.inner-element').click().then(function () { - demand(events).to.eql(['mousedown', 'mouseup', 'click']); - }); - }, {vdom: false}); + demand(events).to.eql(['mousedown', 'mouseup', 'click']) + }) + }, {vdom: false}) domTest('waits until checkbox is enabled before clicking', function (browser, dom) { - var promise = browser.find('input[type=checkbox]').click(); - var clicked; - var buttonState = 'disabled'; + var promise = browser.find('input[type=checkbox]').click() + var clicked + var buttonState = 'disabled' - var button = dom.insert(''); + var button = dom.insert('') button.on('click', function () { - clicked = buttonState; - }); + clicked = buttonState + }) setTimeout(function () { - button.prop('disabled', false); + button.prop('disabled', false) buttonState = 'enabled' - }, 10); + }, 10) return promise.then(function () { - demand(clicked).to.equal('enabled'); - }); - }); + demand(clicked).to.equal('enabled') + }) + }) domTest('waits until button is enabled before clicking', function (browser, dom) { - var promise = browser.find('button', {text: 'a button'}).click(); - var clicked; - var buttonState = 'disabled'; + var promise = browser.find('button', {text: 'a button'}).click() + var clicked + var buttonState = 'disabled' - var button = dom.insert(''); + var button = dom.insert('') button.on('click', function () { - clicked = buttonState; - }); + clicked = buttonState + }) setTimeout(function () { - button.prop('disabled', false); + button.prop('disabled', false) buttonState = 'enabled' - }, 10); + }, 10) return promise.then(function () { - demand(clicked).to.equal('enabled'); - }); - }); - }); + demand(clicked).to.equal('enabled') + }) + }) + }) - describe('select', function(){ - domTest('stack trace', function(browser, dom){ + describe('select', function () { + domTest('stack trace', function (browser, dom) { return browser.find('div') .select({text: 'Text'}) - .assertStackTrace(__filename); + .assertStackTrace(__filename) }, { mochaOnly: true - }); + }) - describe('text', function(){ - domTest('respects timeout option', function(browser, dom, $){ - var promise = browser.find('.element').select({text: 'Second', timeout: 3 }); + describe('text', function () { + domTest('respects timeout option', function (browser, dom, $) { + var promise = browser.find('.element').select({text: 'Second', timeout: 3}) dom.eventuallyInsert( $('') - , 6); + , 6) return demand(promise).reject.with.error() - }); + }) - domTest('respects timeout option, when passed separately from text', function(browser, dom, $){ - var promise = browser.find('.element').select('Second', {timeout: 3 }); + domTest('respects timeout option, when passed separately from text', function (browser, dom, $) { + var promise = browser.find('.element').select('Second', {timeout: 3}) dom.eventuallyInsert( $('') - , 6); + , 6) - return demand(promise).reject.with.error('expected to find: .element select option {"timeout":3,"text":"Second"}'); - }); + return demand(promise).reject.with.error('expected to find: .element select option {"timeout":3,"text":"Second"}') + }) - domTest('eventually selects an option element using the text', function(browser, dom, $){ - var promise = browser.find('.element').select({text: 'Second'}); - var selectedItem = undefined; + domTest('eventually selects an option element using the text', function (browser, dom, $) { + var promise = browser.find('.element').select({text: 'Second'}) + var selectedItem dom.eventuallyInsert( $('').on('change', function () { - selectedItem = $(this).find('option[selected]').text(); + selectedItem = $(this).find('option[selected]').text() }) - ); + ) return promise.then(function () { - demand(selectedItem).to.equal('Second'); - }); - }); + demand(selectedItem).to.equal('Second') + }) + }) - domTest('eventually selects an option element using the text, when text is passed as a string', function(browser, dom, $){ - var promise = browser.find('.element').select('Second'); - var selectedItem = undefined; + domTest('eventually selects an option element using the text, when text is passed as a string', function (browser, dom, $) { + var promise = browser.find('.element').select('Second') + var selectedItem dom.eventuallyInsert( $('').on('change', function () { - selectedItem = $(this).find('option[selected]').text(); + selectedItem = $(this).find('option[selected]').text() }) - ); + ) return promise.then(function () { - demand(selectedItem).to.equal('Second'); - }); - }); + demand(selectedItem).to.equal('Second') + }) + }) - domTest('should eventually select an option element using a partial match', function(browser, dom, $){ - var promise = browser.find('.element').select({text: 'Seco'}); - var selectedItem = undefined; + domTest('should eventually select an option element using a partial match', function (browser, dom, $) { + var promise = browser.find('.element').select({text: 'Seco'}) + var selectedItem dom.eventuallyInsert( $('').on('change', function (e) { - selectedItem = $(this).find('option[selected]').text(); + selectedItem = $(this).find('option[selected]').text() }) - ); + ) return promise.then(function () { - demand(selectedItem).to.equal('Second'); - }); - }); + demand(selectedItem).to.equal('Second') + }) + }) - domTest('selects the first match if multiple available', function(browser, dom, $){ - var selectedItem = undefined; + domTest('selects the first match if multiple available', function (browser, dom, $) { + var selectedItem var select = dom.insert('').on('change', function (e) { - selectedItem = select.val(); - }); + selectedItem = select.val() + }) - return browser.find('select').select({text: 'Item'}).then(function(){ - demand(selectedItem).to.equal('1'); - }); - }); + return browser.find('select').select({text: 'Item'}).then(function () { + demand(selectedItem).to.equal('1') + }) + }) - domTest('selects an option that eventually appears', function(browser, dom, $){ - var promise = browser.find('.element').select({text: 'Second'}); - var selectedItem = undefined; + domTest('selects an option that eventually appears', function (browser, dom, $) { + var promise = browser.find('.element').select({text: 'Second'}) + var selectedItem var select = dom.insert('').on('change', function (e) { - selectedItem = $(this).find('option[selected]').text(); - }); + selectedItem = $(this).find('option[selected]').text() + }) setTimeout(function () { - select.append(''); - }, 20); + select.append('') + }, 20) return promise.then(function () { - demand(selectedItem).to.equal('Second'); - }); - }); + demand(selectedItem).to.equal('Second') + }) + }) - domTest('errors when the specified option does not exist', function(browser, dom){ - var promise = browser.find('.element').select({text: 'Does not exist'}); + domTest('errors when the specified option does not exist', function (browser, dom) { + var promise = browser.find('.element').select({text: 'Does not exist'}) - dom.eventuallyInsert(''); + dom.eventuallyInsert('') return demand(promise).reject.with.error() - }); - - domTest('errors when the input is not a select', function(browser, dom){ - var promise = browser.find('.element').select({text: 'Whatevs'}); - dom.eventuallyInsert('
'); - return demand(promise).reject.with.error(/to have css select/); - }); + }) - domTest('selects an option using text that is falsy', function(browser, dom, $){ - var promise = browser.find('.element').select({text: 0}); - var selectedItem = undefined; + domTest('errors when the input is not a select', function (browser, dom) { + var promise = browser.find('.element').select({text: 'Whatevs'}) + dom.eventuallyInsert('
') + return demand(promise).reject.with.error(/to have css select/) + }) - var select = dom.insert('').on('change', function (e) { - selectedItem = $(this).find('option[selected]').text(); - }); + domTest('selects an option using text that is falsy', function (browser, dom, $) { + var promise = browser.find('.element').select({text: 0}) + var selectedItem + dom.insert('').on('change', function (e) { + selectedItem = $(this).find('option[selected]').text() + }) return promise.then(function () { - demand(selectedItem).to.equal('0'); - }); - }); - }); - - describe('exactText', function(){ - domTest('should select an option using exact text that would otherwise match multiple options', function(browser, dom, $){ - var promise = browser.find('.element').select({exactText: 'Mr'}); - var selectedItem = undefined; + demand(selectedItem).to.equal('0') + }) + }) + }) - var select = dom.insert('').on('change', function (e) { - selectedItem = $(this).find('option[selected]').text(); - }); + describe('exactText', function () { + domTest('should select an option using exact text that would otherwise match multiple options', function (browser, dom, $) { + var promise = browser.find('.element').select({exactText: 'Mr'}) + var selectedItem + dom.insert('').on('change', function (e) { + selectedItem = $(this).find('option[selected]').text() + }) return promise.then(function () { - demand(selectedItem).to.equal('Mr'); - }); - }); - - domTest('should select an option using exact text that is falsy', function(browser, dom, $){ - var promise = browser.find('.element').select({exactText: 0}); - var selectedItem = undefined; + demand(selectedItem).to.equal('Mr') + }) + }) - var select = dom.insert('').on('change', function (e) { - selectedItem = $(this).find('option[selected]').text(); - }); + domTest('should select an option using exact text that is falsy', function (browser, dom, $) { + var promise = browser.find('.element').select({exactText: 0}) + var selectedItem + dom.insert('').on('change', function (e) { + selectedItem = $(this).find('option[selected]').text() + }) return promise.then(function () { - demand(selectedItem).to.equal('0'); - }); - }); - }); - }); + demand(selectedItem).to.equal('0') + }) + }) + }) + }) describe('submit', function () { - domTest('stack trace', function(browser, dom){ + domTest('stack trace', function (browser, dom) { return browser.find('div') .submit() - .assertStackTrace(__filename); + .assertStackTrace(__filename) }, { mochaOnly: true - }); + }) domTest('should submit the form', function (browser, dom) { - var submitted = false; - var promise = browser.find('input').submit(); + var submitted = false + var promise = browser.find('input').submit() dom.insert('
').on('submit', function (ev) { - submitted = true; - }); + submitted = true + }) return promise.then(function () { - demand(submitted).to.equal(true); - }); - }); + demand(submitted).to.equal(true) + }) + }) domTest('should submit the form when submit button is clicked', function (browser, dom) { - var submitted = false; - var promise = browser.find('input').click(); + var submitted = false + var promise = browser.find('input').click() dom.insert('
submit
').on('submit', function (ev) { - ev.preventDefault(); - submitted = true; - }); + ev.preventDefault() + submitted = true + }) return promise.then(function () { - demand(submitted).to.be.true; - }); - }, {vdom: false}); - }); + demand(submitted).to.equal(true) + }) + }, {vdom: false}) + }) - describe('typeIn', function(){ - domTest('stack trace', function(browser, dom){ + describe('typeIn', function () { + domTest('stack trace', function (browser, dom) { return browser.find('input') .typeIn('hello') - .assertStackTrace(__filename); + .assertStackTrace(__filename) }, { mochaOnly: true - }); + }) - [ + var allowedToTypeInto = [ '', '', '', @@ -321,201 +317,203 @@ describe('actions', function(){ '', '', '