UNPKG

protractor

Version:

Webdriver E2E test wrapper for Angular.

200 lines (186 loc) 5.82 kB
var q = require('q'), fs = require('fs'), _ = require('lodash'), ngHintNames = { ngHintControllers: 'Controllers', ngHintDirectives: 'Directives', ngHintDom: 'DOM', ngHintEvents: 'Events', ngHintInterpolation: 'Interpolation', ngHintModules: 'Modules', ngHintScopes: 'Scopes', ngHintGeneral: 'General' }; /** * You enable this plugin in your config file: * * exports.config = { * plugins: [{ * path: 'node_modules/protractor/plugins/ngHint', * * asTests: {Boolean}, * excludeURLs: {(String|RegExp)[]} * }] * }; * * asTests specifies if the plugin should generate passed/failed test results * based on the ngHint output or instead log the results to the console. * Defaults to true. * * excludeURLs specifies a list of URLs for which ngHint results should be * ignored. Defaults to [] */ /* * The strategy for this plugin is as follows: * * During setup, install the ngHint code and listeners to capture its output. * Store the output in the following format: * {page URL} -> {module} -> {message} -> {message type} * * So, for instance, you might have: * { * 'google.com': { * 'Controllers': { * {'It is against Angular best practices to...': warning} * }, * 'Modules: { * {'Module "Search" was loaded but does not exist': error} * } * } * } * * We store the messages as keys in objects in order to avoid duplicates. */ /** * Configures the plugin to grab the output of ngHint * * @see docs/plugins.md * @public */ function setup() { // Intercept ngHint output browser.addMockModule('protractorNgHintCaptureModule_', function() { angular.module('protractorNgHintCaptureModule_', []); var hintInstalled = true; if (!angular.hint) { hintInstalled = false; angular.hint = {}; } /** override */ angular.hint.onMessage = function(module, message, type) { var ngHintLog = JSON.parse(localStorage.getItem( 'ngHintLog_protractor') || '{}'); var pageLog = ngHintLog[location] || {}; var moduleLog = pageLog[module] || {}; moduleLog[message] = type; pageLog[module] = moduleLog; ngHintLog[location] = pageLog; localStorage.setItem('ngHintLog_protractor', JSON.stringify(ngHintLog)); }; if (!hintInstalled) { angular.hint.onMessage('General', 'ngHint plugin cannot be run as ' + 'ngHint code was never included into the page', 'warning'); } }); } /** * Checks if a URL should not be examined by the ngHint plugin * * @param {String} url The URL to check for exclusion * @param {Object} config The configuration file for the ngHint plugin * @return {Boolean} true if the URL should not be examined by the ngHint plugin * @private */ function isExcluded(url, config) { var excludeURLs = config.excludeURLs || []; for (var i = 0; i < excludeURLs.length; i++) { if (typeof excludeURLs[i] == typeof '') { if (url == excludeURLs[i]) { return true; } } else { if (excludeURLs[i].test(url)) { return true; } } } return false; } /** * Checks if a warning message should be ignored by the ngHint plugin * * @param {String} message The message to check * @return {Boolean} true if the message should be ignored * @private */ function isMessageToIgnore(message) { if (message == 'It is against Angular best practices to instantiate a ' + 'controller on the window. This behavior is deprecated in Angular ' + '1.3.0') { return true; // An ngHint bug, see http://git.io/S3yySQ } var module = /^Module "(\w*)" was created but never loaded\.$/.exec( message); if (module != null) { module = module[1]; if (ngHintNames[module] != null) { return true; // An ngHint module } if ((module == 'protractorBaseModule_') || (module == 'protractorNgHintCaptureModule_')) { return true; // A protractor module } } return false; } /** * Checks the information which has been stored by the ngHint plugin and * generates passed/failed tests and/or console output * * @see docs/plugins.md * @return {q.Promise} A promise which resolves to the results of any passed or * failed tests * @public */ function teardown() { var self = this; // Get logged data return browser.executeScript_(function() { return localStorage.getItem('ngHintLog_protractor') || '{}'; }, 'get ngHintLog').then(function(ngHintLog) { ngHintLog = JSON.parse(ngHintLog); // Get a list of all the modules we tested against var modulesUsed = _.union.apply(_, [_.values(ngHintNames)].concat( _.values(ngHintLog).map(Object.keys))); // Check log var testOut = {failedCount: 0, specResults: []}; for (url in ngHintLog) { if (!isExcluded(url, self.config)) { for (var i = 0; i < modulesUsed.length; i++) { var resultInfo = {specName: 'Angular Hint Test: ' + modulesUsed[i] + ' (' + url + ')'}; var passed = true; // Fill in the test details var messages = ngHintLog[url][modulesUsed[i]]; if (messages) { for (var message in messages) { if (!isMessageToIgnore(message)) { (self.config.asTests !== false ? self.addFailure : self.addWarning)(messages[message] + ' -- ' + message, resultInfo); passed = false; } } } if (passed) { self.addSuccess(resultInfo); } } } } }); } // Export exports.setup = setup; exports.teardown = teardown;