├── .npmignore ├── .gitignore ├── README.md ├── LICENSE ├── package.json └── index.js /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | _* 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | _* 3 | !.gitignore 4 | !.npmignore 5 | node_modules 6 | env.json 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # karma-customelements 2 | An extension of [@author.io/karma-base](https://github.com/author/karma-base), specifically for simplifying the scaffolding for web component tests. 3 | 4 | ## Installation 5 | 6 | Install as a development dependency. 7 | 8 | `npm install @author.io/karma-customelements -D` 9 | 10 | ## Usage 11 | 12 | Make sure you've reviewed the [@author.io/karma-base](https://github.com/author/karma-base) README, since it does the bulk of the work. This module makes it simpler to identify which files are tested in which environment (i.e. ES5 vs ES6). 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Author.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@author.io/karma-base", 3 | "version": "1.1.13", 4 | "description": "A base configuration for running Karma browser tests locally and on Sauce Labs.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo no test available" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/author-components/karma-base.git" 12 | }, 13 | "keywords": [ 14 | "karma", 15 | "author.io", 16 | "base", 17 | "web", 18 | "components" 19 | ], 20 | "author": "Author.io", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/author-components/karma-base/issues" 24 | }, 25 | "homepage": "https://github.com/author-components/karma-base#readme", 26 | "dependencies": { 27 | "browserify": "^16.2.3", 28 | "browserslist": "^4.4.1", 29 | "chalk": "^2.4.2", 30 | "karma": "^4.0.0", 31 | "karma-browserify": "^6.0.0", 32 | "karma-browserstack-launcher": "^1.4.0", 33 | "karma-chrome-launcher": "^2.2.0", 34 | "karma-edge-launcher": "^0.4.2", 35 | "karma-firefox-launcher": "^1.1.0", 36 | "karma-html2js-preprocessor": "^1.1.0", 37 | "karma-ie-launcher": "^1.0.0", 38 | "karma-safari-launcher": "^1.0.0", 39 | "karma-sauce-launcher": "^2.0.2", 40 | "karma-source-map-support": "^1.3.0", 41 | "karma-sourcemap-loader": "^0.3.7", 42 | "karma-spec-reporter": "0.0.32", 43 | "karma-tap": "^4.1.4", 44 | "karma-tap-pretty-reporter": "^4.1.0", 45 | "leaked-handles": "^5.2.0", 46 | "localenvironment": "^1.0.2", 47 | "macos-release": "^2.0.0", 48 | "table": "^5.2.1", 49 | "tap": "^12.1.2", 50 | "tap-diff": "^0.1.1", 51 | "tape": "^4.9.2", 52 | "watchify": "^3.11.0" 53 | }, 54 | "publishConfig": { 55 | "access": "public" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | require('localenvironment') 3 | let path = require('path') 4 | 5 | module.exports = testService => { 6 | if (!testService) { 7 | return module.exports('local') 8 | } 9 | 10 | let modernBrowsersOnly = process.argv.indexOf('--modern_browsers_only') > 0 ? true : false 11 | let CI = (testService !== 'local' && (process.argv.indexOf('--local') < 0)) 12 | let browserslist = require('browserslist') 13 | let pkg = require(path.join(process.cwd(),'./package.json')) 14 | 15 | let b = {} 16 | Object.keys(browserslist.data).filter(browser => { 17 | return /op_|opera|ie_mob|samsung/i.exec(browser) === null 18 | }).map(browserName => { 19 | var browser = browserslist.data[browserName] 20 | return `${browser.name} ${browser.released.pop()}` 21 | }).forEach(function (item, index, arr) { 22 | item = item.split(' ') 23 | var attr = (item[0] === 'edge' ? 'microsoft' : '') + item[0].toLowerCase() 24 | 25 | if (attr === 'ie') { 26 | attr = 'internet explorer' 27 | } 28 | 29 | b[attr] = item[1] 30 | }) 31 | 32 | // Construct Browser Testing List 33 | let browsers = {} 34 | let keys = Object.keys(b) 35 | 36 | for (let i = 0; i < keys.length; i++) { 37 | let brwsr = keys[i].replace(/\.|\s/, '_') 38 | 39 | if (brwsr.indexOf('and_') < 0 && brwsr.indexOf('bb') < 0 && brwsr.indexOf('ios') < 0 && brwsr.indexOf('baidu') < 0 && brwsr.indexOf('android') < 0 && brwsr.indexOf('explorer') < 0 && brwsr.toLowerCase().indexOf('edge') < 0 && brwsr.indexOf('safari') < 0) { 40 | let cfg = { 41 | base: testService, 42 | browserName: keys[i], 43 | version: b[keys[i]] + (brwsr.indexOf('.') < 0 ? '.0' : ''), 44 | platform: brwsr.indexOf(/safari/i) >= 0 ? 'macOS 10.14' : 'Windows 10' 45 | } 46 | 47 | browsers['BROWSER_' + brwsr + '_' + b[keys[i]].replace(/\.|\s/, '_')] = cfg 48 | } 49 | } 50 | 51 | browsers['BROWSER_Chrome_45'] = { 52 | base: testService, 53 | browserName: 'chrome', 54 | version: '45.0', 55 | platform: 'Windows 10' 56 | } 57 | 58 | browsers['BROWSER_Firefox_50'] = { 59 | base: testService, 60 | browserName: 'firefox', 61 | version: '50.0', 62 | platform: 'Windows 10' 63 | } 64 | 65 | browsers['BROWSER_InternetExplorer'] = { 66 | base: testService, 67 | browserName: 'internet explorer', 68 | version: '11.0', 69 | platform: 'Windows 8.1' 70 | } 71 | 72 | browsers['BROWSER_Safari_10'] = { 73 | base: testService, 74 | browserName: 'safari', 75 | platform: 'OS X 16.0', 76 | version: '10.1' 77 | } 78 | 79 | browsers['BROWSER_Safari_12'] = { 80 | base: testService, 81 | browserName: 'safari', 82 | platform: 'OS X 18.0', 83 | version: '12.0' 84 | } 85 | 86 | browsers['BROWSER_MicrosoftEdge'] = { 87 | base: testService, 88 | browserName: 'microsoftedge', 89 | version: '18.17763', 90 | platform: 'Windows 10' 91 | } 92 | 93 | // Convert to BrowserStack format if applicable 94 | if (testService.toLowerCase().indexOf('browserstack') >= 0) { 95 | Object.keys(browsers).forEach(browser => { 96 | browsers[browser].browser = browsers[browser].browserName 97 | browsers[browser].browser_version = browsers[browser].version.trim() 98 | 99 | if (browsers[browser].browser === 'internet explorer') { 100 | browsers[browser].browser = 'IE' 101 | } 102 | 103 | if (browsers[browser].browser.toLowerCase().indexOf('edge') >= 0) { 104 | browsers[browser].browser = 'Edge' 105 | browsers[browser].browser_version = browsers[browser].browser_version.split('.')[0] + '.0' 106 | } 107 | 108 | if (!browsers[browser].platform) { 109 | browsers[browser].platform = 'Windows 10' 110 | } 111 | 112 | browsers[browser].os = browsers[browser].platform.split(/\s+/)[0].trim() 113 | browsers[browser].os_version = (browsers[browser].platform.split(/\s+/).pop() || '').trim() 114 | 115 | if (browsers[browser].os === 'OS' || browsers[browser].os.toLowerCase().indexOf('mac') >= 0) { 116 | browsers[browser].os = 'OS X' 117 | try { 118 | browsers[browser].os_version = ((require('macos-release')(browsers[browser].os_version)).name || 'Mojave').replace('OS X', '').trim() 119 | } catch (e) {} 120 | } 121 | 122 | delete browsers[browser].browserName 123 | delete browsers[browser].version 124 | delete browsers[browser].platform 125 | }) 126 | } 127 | 128 | // console.log(JSON.stringify(browsers, null, 2)) 129 | const chalk = require('chalk') 130 | const tablemaker = require('table').table 131 | const displayBrowserList = BrowserList => { 132 | let rows = [[chalk.bold('Browser'), chalk.bold('Version'), chalk.bold('Platform')]] 133 | 134 | Object.keys(BrowserList).sort().forEach(slbrowser => { 135 | rows.push( 136 | [ 137 | (BrowserList[slbrowser].browserName || BrowserList[slbrowser].browser).trim(), 138 | (BrowserList[slbrowser].version || BrowserList[slbrowser].browser_version).trim(), 139 | (BrowserList[slbrowser].platform || BrowserList[slbrowser].os + ' ' + BrowserList[slbrowser].os_version).trim() 140 | ] 141 | ) 142 | }) 143 | 144 | console.log(tablemaker(rows, { 145 | columns: { 146 | 1: { 147 | alignment: 'right' 148 | } 149 | } 150 | })) 151 | } 152 | 153 | let karmaconfig = { 154 | get configuration () { 155 | let cfg = { 156 | basePath: '', 157 | frameworks: ['tap', 'browserify', 'source-map-support'], 158 | reporters: ['tap-pretty'], 159 | tapReporter: { 160 | prettify: require('tap-diff'), 161 | separator: '****************************' 162 | }, 163 | files: karmaconfig.getFiles(), 164 | port: 9876, 165 | colors: true, 166 | browserDisconnectTolerance: 2, 167 | browsers: ['Chrome'], 168 | singleRun: true, 169 | flags: [ 170 | '--no-sandbox', 171 | '--disable-gpu', 172 | '--no-default-browser-check', 173 | '--no-first-run', 174 | '--disable-default-apps', 175 | '--disable-popup-blocking', 176 | '--disable-translate', 177 | '--disable-background-timer-throttling', 178 | '--disable-renderer-backgrounding', 179 | '--disable-device-discovery-notifications', 180 | '--disable-web-security' 181 | ] 182 | } 183 | 184 | if (CI) { 185 | if (testService.toLowerCase() === 'saucelabs') { 186 | cfg.reporters.push('saucelabs') 187 | cfg.sauceLabs = { // eslint-disable-line no-unused-vars 188 | testName: `${pkg.name} v${pkg.version}`, 189 | build: process.env.TRAVIS_BUILD_NUMBER || process.env.CI_BUILD_TAG || process.env.CI_BUILD_NUMBER || process.env.BUILD_NUMBER || (new Date()).toISOString(), 190 | recordVideo: false, 191 | recordScreenshots: false 192 | } 193 | 194 | if (process.env.hasOwnProperty('TRAVIS_JOB_NUMBER')) { 195 | cfg.sauceLabs.startConnect = false 196 | cfg.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER 197 | cfg.sauceLabs.connectOptions = { 198 | port: 5757, 199 | logfile: 'sauce_connect.log' 200 | } 201 | } 202 | } else if (testService.toLowerCase() === 'browserstack') { 203 | cfg.browserStack = { 204 | username: process.env.BROWSERSTACK_USERNAME, 205 | accessKey: process.env.BROWSERSTACK_SECRET 206 | } 207 | } 208 | 209 | if (modernBrowsersOnly) { 210 | Object.keys(browsers).forEach(br => { 211 | if (['BROWSER_Chrome_45', 'BROWSER_InternetExplorer', 'BROWSER_Firefox_50'].indexOf(br) >= 0) { 212 | delete browsers[br] 213 | } 214 | }) 215 | } 216 | 217 | cfg.customLaunchers = browsers 218 | cfg.browsers = Object.keys(browsers) 219 | 220 | displayBrowserList(browsers) 221 | } else { 222 | cfg.plugins = [ 223 | require('karma-browserify'), 224 | require('tape'), 225 | require('karma-tap'), 226 | require('karma-tap-pretty-reporter'), 227 | require('karma-spec-reporter'), 228 | require('karma-chrome-launcher'), 229 | require('karma-firefox-launcher'), 230 | require('karma-safari-launcher'), 231 | require('karma-ie-launcher'), 232 | require('karma-edge-launcher'), 233 | require('karma-source-map-support'), 234 | require('karma-html2js-preprocessor'), 235 | require('karma-sauce-launcher'), 236 | require('karma-browserstack-launcher') 237 | ] 238 | 239 | var localBrowsers = {} 240 | Object.keys(cfg.browsers).forEach(br => { 241 | localBrowsers[cfg.browsers[br]] = { 242 | browserName: cfg.browsers[br], 243 | version: 'Local Copy', 244 | platform: (process.platform === 'win32' ? 'Windows' : (process.platform === 'debian' ? 'macOS' : process.platform)) + ' ' + require('os').release() 245 | } 246 | }) 247 | 248 | displayBrowserList(localBrowsers) 249 | } 250 | 251 | return cfg 252 | }, 253 | 254 | modernOnly () { 255 | modernBrowsersOnly = true 256 | }, 257 | 258 | displayFiles () { 259 | console.log(tablemaker([[chalk.bold('Included Files')]].concat(karmaconfig.getFiles().map(file => { return [file.pattern || file] })))) 260 | }, 261 | 262 | getFiles () { 263 | return ['./test/*.js', '/test/test.html'] 264 | } 265 | } 266 | 267 | return karmaconfig 268 | } 269 | --------------------------------------------------------------------------------