From c1cdb630403fc95d16dc04d5e1f06c6d04646923 Mon Sep 17 00:00:00 2001 From: Matt Edelman Date: Sat, 6 Jan 2018 17:42:25 -0800 Subject: [PATCH] first commit of "new" nemo (nee nemo-runner) --- .eslintignore | 1 + .eslintrc.js | 217 ++++ .gitignore | 4 + CHANGELOG.md | 50 + README.md | 256 ++++ bin/_nemo | 55 + bin/nemo | 54 + lib/flow.js | 167 +++ lib/instance.js | 211 +++ lib/prefontaine.js | 36 + lib/reporter.js | 40 + lib/server.js | 62 + lib/starter.js | 92 ++ package-lock.json | 2642 ++++++++++++++++++++++++++++++++++++++ package.json | 68 + static/report-output.png | Bin 0 -> 68129 bytes test/config/config.json | 95 ++ test/config/useme.js | 25 + test/form.js | 16 + test/locator/form.json | 7 + test/nested.js | 31 + test/nested2.js | 19 + test/pay.js | 10 + test/search.js | 12 + 24 files changed, 4170 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 README.md create mode 100755 bin/_nemo create mode 100755 bin/nemo create mode 100644 lib/flow.js create mode 100644 lib/instance.js create mode 100644 lib/prefontaine.js create mode 100644 lib/reporter.js create mode 100644 lib/server.js create mode 100644 lib/starter.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 static/report-output.png create mode 100644 test/config/config.json create mode 100644 test/config/useme.js create mode 100644 test/form.js create mode 100644 test/locator/form.json create mode 100644 test/nested.js create mode 100644 test/nested2.js create mode 100644 test/pay.js create mode 100644 test/search.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..759c70f --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,217 @@ +module.exports = { + "env": { + "node": true, + "es6": true + }, + + "plugins": ["es6-recommended"], + + "ecmaFeatures": { + "arrowFunctions": true, + "binaryLiterals": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": true, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": true, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "octalLiterals": true, + "regexUFlag": true, + "regexYFlag": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "unicodeCodePointEscapes": true, + "globalReturn": true, + "jsx": true + }, + + "rules": { + + // + //Possible Errors + // + // The following rules point out areas where you might have made mistakes. + // + "comma-dangle": 2, // disallow or enforce trailing commas + "no-cond-assign": 2, // disallow assignment in conditional expressions + "no-console": 1, // disallow use of console (off by default in the node environment) + "no-constant-condition": 2, // disallow use of constant expressions in conditions + "no-control-regex": 2, // disallow control characters in regular expressions + "no-debugger": 2, // disallow use of debugger + "no-dupe-args": 2, // disallow duplicate arguments in functions + "no-dupe-keys": 2, // disallow duplicate keys when creating object literals + "no-duplicate-case": 2, // disallow a duplicate case label. + "no-empty": 2, // disallow empty statements + "no-empty-character-class": 2, // disallow the use of empty character classes in regular expressions + "no-ex-assign": 2, // disallow assigning to the exception in a catch block + "no-extra-boolean-cast": 2, // disallow double-negation boolean casts in a boolean context + "no-extra-parens": 0, // disallow unnecessary parentheses (off by default) + "no-extra-semi": 2, // disallow unnecessary semicolons + "no-func-assign": 2, // disallow overwriting functions written as function declarations + "no-inner-declarations": 2, // disallow function or variable declarations in nested blocks + "no-invalid-regexp": 2, // disallow invalid regular expression strings in the RegExp constructor + "no-irregular-whitespace": 2, // disallow irregular whitespace outside of strings and comments + "no-negated-in-lhs": 2, // disallow negation of the left operand of an in expression + "no-obj-calls": 2, // disallow the use of object properties of the global object (Math and JSON) as functions + "no-regex-spaces": 2, // disallow multiple spaces in a regular expression literal + "no-sparse-arrays": 2, // disallow sparse arrays + "no-unreachable": 2, // disallow unreachable statements after a return, throw, continue, or break statement + "use-isnan": 2, // disallow comparisons with the value NaN + "valid-jsdoc": 2, // Ensure JSDoc comments are valid (off by default) + "valid-typeof": 2, // Ensure that the results of typeof are compared against a valid string + + // + // Best Practices + // + // These are rules designed to prevent you from making mistakes. + // They either prescribe a better way of doing something or help you avoid footguns. + // + "block-scoped-var": 0, // treat var statements as if they were block scoped (off by default). 0: deep destructuring is not compatible https://github.com/eslint/eslint/issues/1863 + "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default) + // "consistent-return": 2, // require return statements to either always or never specify values + "curly": 2, // specify curly brace conventions for all control statements + "default-case": 2, // require default case in switch statements (off by default) + "dot-notation": 2, // encourages use of dot notation whenever possible + "eqeqeq": 2, // require the use of === and !== + "guard-for-in": 2, // make sure for-in loops have an if statement (off by default) + "no-alert": 2, // disallow the use of alert, confirm, and prompt + "no-caller": 2, // disallow use of arguments.caller or arguments.callee + "no-div-regex": 2, // disallow division operators explicitly at beginning of regular expression (off by default) + "no-else-return": 2, // disallow else after a return in an if (off by default) + "no-labels": 2, // disallow use of labels for anything other then loops, switches and labeled statements + "no-eq-null": 2, // disallow comparisons to null without a type-checking operator (off by default) + "no-eval": 2, // disallow use of eval() + "no-extend-native": 2, // disallow adding to native types + "no-extra-bind": 2, // disallow unnecessary function binding + "no-fallthrough": 2, // disallow fallthrough of case statements + "no-floating-decimal": 2, // disallow the use of leading or trailing decimal points in numeric literals (off by default) + "no-implied-eval": 2, // disallow use of eval()-like methods + "no-iterator": 2, // disallow usage of __iterator__ property + "no-lone-blocks": 2, // disallow unnecessary nested blocks + "no-loop-func": 2, // disallow creation of functions within loops + "no-multi-spaces": 2, // disallow use of multiple spaces + "no-multi-str": 2, // disallow use of multiline strings + "no-native-reassign": 2, // disallow reassignments of native objects + "no-new": 2, // disallow use of new operator when not part of the assignment or comparison + "no-new-func": 2, // disallow use of new operator for Function object + "no-new-wrappers": 2, // disallows creating new instances of String,Number, and Boolean + "no-octal": 2, // disallow use of octal literals + "no-octal-escape": 2, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251"; + "no-param-reassign": 2, // disallow reassignment of function parameters (off by default) + // "no-process-env": 2, // disallow use of process.env (off by default) + "no-proto": 2, // disallow usage of __proto__ property + "no-redeclare": 2, // disallow declaring the same variable more then once + "no-return-assign": 2, // disallow use of assignment in return statement + "no-script-url": 2, // disallow use of javascript: urls. + "no-self-compare": 2, // disallow comparisons where both sides are exactly the same (off by default) + "no-sequences": 2, // disallow use of comma operator + "no-throw-literal": 2, // restrict what can be thrown as an exception (off by default) + "no-unused-expressions": 2, // disallow usage of expressions in statement position + "no-void": 2, // disallow use of void operator (off by default) + "no-warning-comments": [0, {"terms": ["todo", "fixme"], "location": "start"}], // disallow usage of configurable warning terms in comments": 2, // e.g. TODO or FIXME (off by default) + "no-with": 2, // disallow use of the with statement + "radix": 2, // require use of the second argument for parseInt() (off by default) + "vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default) + "wrap-iife": 2, // require immediate function invocation to be wrapped in parentheses (off by default) + "yoda": 2, // require or disallow Yoda conditions + + // + // Strict Mode + // + // These rules relate to using strict mode. + // + "strict": 0, // controls location of Use Strict Directives. 0: required by `babel-eslint` + + // + // Variables + // + // These rules have to do with variable declarations. + // + "no-catch-shadow": 2, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment) + "no-delete-var": 2, // disallow deletion of variables + "no-label-var": 2, // disallow labels that share a name with a variable + "no-shadow": 2, // disallow declaration of variables already declared in the outer scope + "no-shadow-restricted-names": 2, // disallow shadowing of names such as arguments + "no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block + "no-undef-init": 2, // disallow use of undefined when initializing variables + "no-undefined": 2, // disallow use of undefined variable (off by default) + "no-unused-vars": 2, // disallow declaration of variables that are not used in the code + "no-use-before-define": 2, // disallow use of variables before they are defined + + // + //Stylistic Issues + // + // These rules are purely matters of style and are quite subjective. + // + "indent": ["error", 2], // this option sets a specific tab width for your code (off by default) + "brace-style": 1, // enforce one true brace style (off by default) + "camelcase": 1, // require camel case names + "comma-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after comma + "comma-style": [1, "last"], // enforce one true comma style (off by default) + "consistent-this": [1, "_this"], // enforces consistent naming when capturing the current execution context (off by default) + "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines + "func-names": 0, // require function expressions to have a name (off by default) + "func-style": 0, // enforces use of function declarations or expressions (off by default) + "key-spacing": [1, {"beforeColon": false, "afterColon": true}], // enforces spacing between keys and values in object literal properties + "max-nested-callbacks": [1, 3], // specify the maximum depth callbacks can be nested (off by default) + "new-cap": [1, {newIsCap: true, capIsNew: false}], // require a capital letter for constructors + "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments + "newline-after-var": 0, // allow/disallow an empty newline after var statement (off by default) + "no-array-constructor": 1, // disallow use of the Array constructor + "no-inline-comments": 1, // disallow comments inline after code (off by default) + "no-lonely-if": 1, // disallow if as the only statement in an else block (off by default) + "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation + "no-multiple-empty-lines": [1, {"max": 2}], // disallow multiple empty lines (off by default) + "no-nested-ternary": 1, // disallow nested ternary expressions (off by default) + "no-new-object": 1, // disallow use of the Object constructor + "no-spaced-func": 1, // disallow space between function identifier and application + "no-ternary": 0, // disallow the use of ternary operators (off by default) + "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines + // "no-underscore-dangle": 1, // disallow dangling underscores in identifiers + "one-var": [1, "never"], // allow just one var statement per function (off by default) + "operator-assignment": [1, "never"], // require assignment operator shorthand where possible or prohibit it entirely (off by default) + "padded-blocks": [1, "never"], // enforce padding within blocks (off by default) + "quote-props": [1, "as-needed"], // require quotes around object literal property names (off by default) + "quotes": [1, "single"], // specify whether double or single quotes should be used + "semi": [1, "always"], // require or disallow use of semicolons instead of ASI + "semi-spacing": [1, {"before": false, "after": true}], // enforce spacing before and after semicolons + "sort-vars": 0, // sort variables within the same declaration block (off by default) + "keyword-spacing": [1], // require a space after certain keywords (off by default) + "space-before-blocks": [1, "always"], // require or disallow space before blocks (off by default) + "space-before-function-paren": [1, {"anonymous": "always", "named": "never"}], // require or disallow space before function opening parenthesis (off by default) + "object-curly-spacing": [1, "never"], // require or disallow spaces inside brackets (off by default) + "space-in-parens": [1, "never"], // require or disallow spaces inside parentheses (off by default) + "space-infix-ops": ["error"], // require spaces around operators + "space-unary-ops": [1, {"words": true, "nonwords": false}], // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default) + "spaced-comment": [2, "always"], // Requires or disallows a whitespace (space or tab) beginning a comment (spaced-comment) + "wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default) + + // + // ECMAScript 6 + // + // These rules are only relevant to ES6 environments and are off by default. + // + // "no-var": 2, // require let or const instead of var (off by default) + "generator-star-spacing": [2, "before"], // enforce the spacing around the * in generator functions (off by default) + + // + // Legacy + // + // The following rules are included for compatibility with JSHint and JSLint. + // While the names of the rules may not match up with the JSHint/JSLint counterpart, + // the functionality is the same. + // + "max-depth": [2, 3], // specify the maximum depth that blocks can be nested (off by default) + // "max-len": [2, 100, 2], // specify the maximum length of a line in your program (off by default) + "max-params": [2, 5], // limits the number of parameters that can be used in the function declaration. (off by default) + "max-statements": 0, // specify the maximum number of statement allowed in a function (off by default) + "no-bitwise": 0, // disallow use of bitwise operators (off by default) + "no-plusplus": 2 // disallow use of unary operators, ++ and -- (off by default) + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2c0533 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +*.log +.idea +test/report \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..d4a4d8e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,50 @@ +## v4.0.0-alpha.1 + +- rename from nemo-runner to nemo + +## v1.5.0-alpha + +- works for xunit and mochawesome reporters: + - group nemo instance reports under directory [MMDDYYYY]/[HHMMSS] + - add main report.json for set of parallel instances +- add "afterEach" screenshot (for mochawesome, adds image directly to report) +- add "nemo.runner.snap" method to take a screenshot +- fix for #25 (data parallel feature doesn't use specific profile data object) + +## v1.4.0 + +- modify driver kill logic (again) to exit nemo when the `root` mocha Suite ends +- add current mocha test's context to the `nemo.mocha` property + +## v1.3.1 + +- modify driver kill logic to count total suites (fixes nested suites) +- add nested suites to tests +- add couple more scripts to package.json + +## v1.3.0 + +- kill child processes when they error +- add parallel test +- enable the `data` parallel feature + +## v1.2.0 + +- allow setting concurrency limit in config with `maxConcurrent` for parallel testing + +## v1.1.1 + +- prevent mocha from running against 0 matches in "parallel": "file" mode + +## v1.1.0 + +- append profile name to report filename + +## v1.0.1 + +- fix file name appending +- add basic testing + +## v1.0.0-alpha.3 + +- implement parallel by file feature diff --git a/README.md b/README.md new file mode 100644 index 0000000..2358a85 --- /dev/null +++ b/README.md @@ -0,0 +1,256 @@ +# nemo + +Node.js solution for running mocha-based selenium-webdriver tests. + +## Getting started + +Install nemo + +```sh +npm install --save-dev nemo +``` + +Install chromedriver and GeckoDriver to your $PATH + +Add tests directory structure + +``` +test + functional + config + config.json + spec + spec.js +``` + +`config.json` + +```js +{ + "driver": { + "browser": "phantomjs" + }, + "data": { + "baseUrl": "http://localhost:8000" + }, + "profiles": { + "base": { + "tests": "path:spec/*.js", + "env": { + "DEBUG": "nemo*" + }, + "mocha": { + "timeout": 180000, + "retries": 0, + "require": "babel-register", + "grep": "argv:grep" + } + }, + "chrome": { + "driver": { + "browser": "chrome" + } + }, + "firefox": { + "driver": { + "browser": "firefox" + } + } + } +} +``` + +`spec.js` + +```js +describe('@foo@', function () { + it('should @success@fully load a URL', async function () { + let nemo = this.nemo; + await nemo.driver.get(nemo.data.baseUrl); + await nemo.driver.sleep(3000); + }); +}); +describe('@bar@', function () { + it('should @fail@ to load a URL', async function () { + let nemo = this.nemo; + await nemo.driver.get('http://localhost/does/not/exist'); + await nemo.driver.sleep(3000); + }); +}); +``` + +Add run script(s) to package.json (you can also just run the full command directly but this is cleaner) + +```js +"scripts": { + "start": "node index.js", + "nemo": "nemo -B test/functional -P firefox,chrome -G @foo@,@bar@", + "nemo:debug": "nemo --inspect --debug-brk -B test/functional -P firefox -G @foo@" +}, +``` + +Give it a try + +```sh +npm run nemo +``` + +You should have seen two Firefox and two Chrome browser instances open and execute the scripts. + +## CLI arguments + +```sh + Usage: _nemo [options] + + Options: + + -h, --help output usage information + -V, --version output the version number + -B, --base-directory parent directory for config/ and spec/ (or other test file) directories. relative to cwd + -P, --profile [profile] which profile(s) to run, out of the configuration + -G, --grep only run tests matching + -F, --file run parallel by file + -D, --data run parallel by data + --debug-brk enable node's debugger breaking on the first line + --inspect activate devtools in chrome + --no-timeouts remove timeouts in debug/inspect use case + +``` + +## Profile options + +### `base` + +is the main profile configuration that others will merge into + +### `base.tests` + +is an absolute path based glob pattern. (e.g. `"tests": "path:spec/!(wdb)*.js",`) + +### `base.parallel` + +only valid for 'base'. + +- if set to 'file' it will create a child process for each mocha file (alternative to `-F` CLI arg) +- if set to 'data' it will create a child process for each object key under `base.data` (alternative to the `-D` CLI arg) + +### `base.reports` + +Recommended to set this as `path:report`, which will create a `report` directory beneath your base directory. See `Reporting` below. + +### `base.mocha` + +mocha options. described elsewhere + +### `base.env` + +any environment variables you want in the test process. + +NOTES: +- currently `base.env` is only honored if nemo is launching parallel nemo instances (each as its own process). +If nemo launches a single nemo instance in the main process, these are ignored. +- any env variables in your nemo process will be merged into the env for the parallel processes +(along with whatever is set under `base.env`) + +### `base.maxConcurrent` + +a number which represents the max limit of concurrent suites nemo will execute in parallel - if not provided there is no limit + +## Reporting + +Recommended reporters are `mochawesome` or `xunit`. If you use either of these, `nemo` will generate timestamped directories for each run. + The reports will be further separated based on the parallel options. E.g. + +![50%](static/report-output.png) + +In the above example, parallel options were "profile", "file", and "data". + +A summary for all parallel instances can be found at `summary.json` + +### Screenshots + +`nemo` will take a screenshot automatically after each test execution (pass or fail). The screenshots will be +named based on the respective test name. E.g. `my awesome test.after.png`. + +You can use `nemo.runner.snap()` at any point in a test, to grab a screenshot. These screenshots will be named based on +the respective test name, and number of screenshots taken using `nemo.runner.snap()`. E.g. +- `my awesome test.1.png` +- `my awesome test.2.png` +- `my awesome test.3.png` + +If you use the `mochawesome` reporter, you will see these screeshots in the `Additional Context` section of the html report. + +## Adding Nemo into the mocha context and vice versa + +nemo injects a `nemo` instance into the Mocha context (for it, before, after, etc functions) which can be accessed by +`this.nemo` within the test suites. + +nemo also adds the current test's context to `nemo.mocha`. That can be useful if you want to access or modify the test's context from within a nemo plugin. +### Parallel functionality + +nemo will execute in parallel `-P (profile)` x `-G (grep)` mocha instances. The example above uses "browser" as the +profile dimension and suite name as the "grep" dimension. Giving 2x2=4 parallel executions. + +In addition to `profile` and `grep`, are the dimensions `file` and `data`. + +#### Parallel by `file` + +`file` will multiply the existing # of instances by the # of files selected by your configuration. + +#### Parallel by `data` + +`data` will multiply the existing # of instances by the # of keys found under `profiles.base.data`. It can also be overriden per-profile. It will also replace + `nemo.data` with the value of each keyed object. In other words, you can use this to do parallel, data-driven testing. + +If you have the following base profile configuration: + +```js + "profiles": { + "base": { + "data": { + "US": {"url": "http://www.paypal.com"}, + "FR": {"url": "http://www.paypal.fr"} + }, + "parallel": "data", + "tests": "path:spec/test-spec.js", + "mocha": { + //... + } + } + } +``` + +Then the following test will run twice (in parallel) with corresponding values of `nemo.data.url`: + +```js +it('@loadHome@', function () { + var nemo = this.nemo; + return nemo.driver.get(nemo.data.url);//runs once with paypal.com, once with paypal.fr +}); +``` + +#### Parallel reporting + +Using a reporter which gives file output will be the most beneficial. `nemo` comes out of the box, ready to use `mochawesome` or `xunit` for outputting a report per parallel instance. + + +### Mocha options + +The properties passed in to the `"mocha"` property of `config.json` will be applied to the `mocha` instances that are created. In general, these properties correlate with the `mocha` command line arguments. E.g. if you want this: + +```sh +mocha --timeout 180000 +``` + +You should add this to the `"mocha"` property within `"profiles"` of `config.json`: + +```json +"profile": { + ...other stuff, + "mocha": { + "timeout": 180000 + } +} +``` + +`nemo` creates `mocha` instances programmatically. Unfortunately, not all `mocha` command line options are available when instantiating it this way. One of the arguments that is **not** supported is the `--require` flag, which useful if you want to `require` a module, e.g. `babel-register` for transpilation. Thus, we added a `"require"` property in `config.json`, which takes a string of a single npm module name, or an array of npm module names. If it is an array, `nemo` will `require` each one before instantiating the `mocha` instances. diff --git a/bin/_nemo b/bin/_nemo new file mode 100755 index 0000000..5d6d17b --- /dev/null +++ b/bin/_nemo @@ -0,0 +1,55 @@ +#!/usr/bin/env node +'use strict'; + + +/** + * Module dependencies. + */ + +var program = require('commander'); +var path = require('path'); +var fs = require('fs'); +var cwd = process.cwd(); +var server = require('../lib/server'); +var debug = require('debug'); +var log = debug('nemo:log'); +var error = debug('nemo:error'); +var prefontaine = require('../lib/prefontaine'); + +function list(val) { + return val.split(','); +} + +function cwdPath(rel) { + return path.resolve(cwd, rel); +} + +program + .version(JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')).version) + .usage('[options]') + .option('-B, --base-directory ', 'parent directory for config/ and spec/ (or other test file) directories. relative to cwd', cwdPath) + .option('-P, --profile [profile]', 'which profile(s) to run, out of the configuration', list) + .option('-G, --grep ', 'only run tests matching ', list) + .option('-F, --file ', 'run parallel by file') + .option('-D, --data ', 'run parallel by data') + .option('-S, --server ', 'run the nemo web server') + .option('--debug-brk', 'enable node\'s debugger breaking on the first line') + .option('--inspect', 'activate devtools in chrome') + .option('--no-timeouts', 'remove timeouts in debug/inspect use case') + .parse(process.argv); + +program._name = 'nemo'; + +// are we launching the server? +if (program.server) { + log('CLI launching server'); + return server(program); +} +log('CLI launching runner'); +prefontaine(program) + .then(function (pre) { + return prefontaine.start(pre); + }) + .catch(function (err) { + error('problem with start %O', err); + }); diff --git a/bin/nemo b/bin/nemo new file mode 100755 index 0000000..4e2d3f8 --- /dev/null +++ b/bin/nemo @@ -0,0 +1,54 @@ +#!/usr/bin/env node + +'use strict'; + +var spawn = require('child_process').spawn; +var path = require('path'); +var args = [path.join(__dirname, '_nemo')]; +var proc; + +process.argv.slice(2).forEach(function (arg) { + var flag = arg.split('=')[0]; + + switch (flag) { + case 'debug': + case '--debug': + case '--debug-brk': + case '--inspect': + case '--inspect-brk': + args.unshift(arg); + break; + default: + if (arg.indexOf('--harmony') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--trace') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--icu-data-dir') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--max-old-space-size') === 0) { + args.unshift(arg); + } else if (arg.indexOf('--preserve-symlinks') === 0) { + args.unshift(arg); + } else { + args.push(arg); + } + break; + } +}); + +proc = spawn(process.execPath, args, {stdio: 'inherit'}); +proc.on('exit', function (code, signal) { + process.on('exit', function () { + if (signal) { + process.kill(process.pid, signal); + } else { + process.exit(code); + } + }); +}); + +// terminate children. +process.on('SIGINT', function () { + proc.kill('SIGINT'); + proc.kill('SIGTERM'); +}); diff --git a/lib/flow.js b/lib/flow.js new file mode 100644 index 0000000..f611b83 --- /dev/null +++ b/lib/flow.js @@ -0,0 +1,167 @@ +'use strict'; + +var merge = require('lodash.merge'); +var debug = require('debug'); +var log = debug('nemo:log'); +var error = debug('nemo:error'); +var filenamify = require('filenamify'); +var reporter = require('../lib/reporter'); +var Glob = require('glob'); +var path = require('path'); +var moment = require('moment'); + + +let profile = function profile(cb) { + var base = this.config.get('profiles:base'); + var profiles = this.program.profile; + profiles = profiles || 'base'; + profiles = (profiles instanceof Array) ? profiles : [profiles]; + this.instances = []; + profiles.forEach(function (profil) { + var conf; + var instance; + var profileObj = this.config.get(`profiles:${profil}`); + log('flow:profile %s', profil); + if (!profileObj) { + error('flow:profile, profile %s is undefined', profil); + return; + } + conf = merge({}, base, profileObj || {}); + instance = { + tags: {profile: profil}, + conf: conf + }; + this.instances.push(instance); + }.bind(this)); + cb(null, this); +}; + +let reportDir = function reportDir(cb) { + let tsDirName = moment().format("MM-DD-YYYY/HH-mm-ss"); + let fullReportPath = `${this.config.get('profiles:base:reports')}/${tsDirName}`; + this.config.set('profiles:base:reports', fullReportPath); + log(`flow:reportDir: ${fullReportPath}`); + this.instances.forEach(function (instance) { + instance.conf.reports = fullReportPath; + log(`flow:reportDir: instance.conf.reports ${instance.conf.reports}`) + }); + cb(null, this); +}; + +let grep = function grep(cb) { + var instances = []; + var greps = this.program.grep || ''; + greps = (greps instanceof Array) ? greps : [greps]; + log('flow:grep, greps: %s', greps); + this.instances.forEach(function (instance) { + greps.forEach(function (gerp) { + var _instance = merge({}, instance); + if (gerp !== '') { + _instance.conf.mocha.grep = gerp; + _instance.tags.grep = gerp; + } + instances.push(_instance); + }); + }); + this.instances = instances; + log('flow:grep, #instances: %d', this.instances.length); + cb(null, this); +}; + +let glob = function glob(cb) { + var instances = []; + this.instances.forEach(function (instance, index, arr) { + var testFileGlob = path.resolve(this.program.baseDirectory, instance.conf.tests); + Glob(testFileGlob, {}, function (err, files) { + var _instance = merge({}, instance); + log('flow:glob, #files %d', files.length); + if (err) { + return cb(err); + } + _instance.conf.tests = files; + instances.push(_instance); + if (index === arr.length - 1) { + this.instances = instances; + log('flow:glob, #instances: %d', this.instances.length); + cb(null, this); + } + }.bind(this)); + }.bind(this)); +}; + +let pfile = function pfile(cb) { + var base = this.config.get('profiles:base'); + var instances = []; + if (this.program.file || base.parallel && base.parallel.indexOf('file') !== -1) { + log('flow:pfile, parallel by file'); + this.instances.forEach(function (instance) { + var files = instance.conf.tests; + files.forEach(function (file) { + var _instance; + var justFile = file.split(this.program.baseDirectory)[1]; + justFile = filenamify(justFile); + // remove file ext + justFile = (justFile.endsWith('.js')) ? justFile.substr(0, justFile.length - 3) : justFile; + log('flow:pfile, file %s', justFile); + _instance = merge({}, instance); + _instance.conf.tests = [file]; + _instance.tags.file = justFile; + instances.push(_instance); + }.bind(this)); + }.bind(this)); + this.instances = instances; + } + log('flow:pfile, #instances: %d', this.instances.length); + cb(null, this); +}; + +let pdata = function pdata(cb) { + var instances = []; + var datas = this.config.get('profiles:base:data'); + // var base = this.config.get('profiles:base'); + + // if (this.program.data || base.parallel && base.parallel.indexOf('data') !== -1) { + datas = (typeof datas !== 'object') ? {} : datas; + log('flow:pdata, parallel by data'); + this.instances.forEach(function (instance) { + // check for local data + if (instance.conf.parallel && instance.conf.parallel === 'data') { + datas = instance.conf.data || datas; + for (let key in datas) { + if (Object.prototype.hasOwnProperty.call(datas, key)) { + let _instance; + _instance = merge({}, instance); + _instance.tags.key = key; + _instance.conf.data = datas[key]; + instances.push(_instance); + } + } + } + else { + instances.push(instance); + } + }); + this.instances = instances; + // } + log('flow:pfile, #instances: %d', this.instances.length); + cb(null, this); +}; + +let reportFiles = function reportFiles(cb) { + log('flow:reportFiles:start'); + let instances = []; + // let reporterFromConfig = this.config.get('profiles:base:mocha:reporter'); + this.instances.forEach(function (instance) { + let reporterFromConfig = instance.conf.mocha.reporter; + // set up reporter options + if (reporter.hasOwnProperty(reporterFromConfig)) { + log(`flow:reportFiles: we have a handler for ${reporterFromConfig}`); + reporter[reporterFromConfig](instance); + } + instances.push(instance); + }); + this.instances = instances; + cb(null, this); +}; + +module.exports = [profile, reportDir, grep, glob, pfile, pdata, reportFiles]; diff --git a/lib/instance.js b/lib/instance.js new file mode 100644 index 0000000..6d97afc --- /dev/null +++ b/lib/instance.js @@ -0,0 +1,211 @@ +'use strict'; + +module.exports = function instance(input, done) { + var Nemo = require('nemo'); + var Mocha = require('mocha'); + var debug = require('debug'); + var path = require('path'); + var filenamify = require('filenamify'); + var addContext = require('mochawesome/addContext'); + var mkdirp = require('mkdirp'); + var uuidv4 = require('uuid/v4'); + var fs = require('fs'); + var log = debug('nemo:log'); + var error = debug('nemo:error'); + var mocha; + var anyTests = false; + var baseDirectory = input.basedir; + input.profile.tags.uid = uuidv4(); + var profileConf = input.profile.conf; + var profileData = profileConf.data; + var result = {tags: input.profile.tags, total: 0, pass: 0, fail: 0}; + var driverConfig; + var runner; + + var exitInstance = function (failures, summary) { + // only attach this listener if we aren't running in parallel + if (!done && process) { + process.on('exit', function () { + // exit with non-zero status if there were failures + console.log('exit handler'); + process.exit(failures); + }); + } + // attempted to run with no matching suites/tests + if (!anyTests && done) { + done(summary); + } + }; + + var defineSuite = function (config) { + var nemo; + var requireFromConfig = profileConf.mocha.require; + var modulesToRequire = []; + + // if an array was already declared, use it + if (requireFromConfig && Array.isArray(requireFromConfig)) { + modulesToRequire = requireFromConfig; + + // else if it was a single module declared, format to array + } else if (requireFromConfig && typeof requireFromConfig === 'string') { + modulesToRequire = [requireFromConfig]; + } + + modulesToRequire.forEach(function (module) { + try { + require(module); + } catch (err) { + throw new Error(err); + } + }); + + // make a Mocha + mocha = new Mocha(profileConf.mocha); + // add files + profileConf.tests.forEach(function (file) { + log('%s: add file %s', input.profile.tags.uid, file); + mocha.addFile(file); + }); + // calculate driver configuration + driverConfig = profileConf.driver; + config.set('driver', Object.assign({}, config.get('driver'), driverConfig)); + config.set('data', Object.assign({}, profileData || config.get('data'))); + + if (profileConf.parallel === 'file' && mocha.options.grep) { + // if we're running parallel by file, make sure we really need to run() + mocha.loadFiles(); + const throwawayRunner = new Mocha.Runner(mocha.suite); + const matchingTests = throwawayRunner.grep(mocha.options.grep).total; + if (!matchingTests) { + // don't run the suite, just exit the process + return exitInstance(); + } + } + runner = mocha.run(function (failures) { + exitInstance(failures, result); + }); + // runner.on('start', function (Arg) { + // // never called. filed https://github.com/mochajs/mocha/issues/2753 + // }); + runner.on('test', function (Test) { + Test.ctx.nemo = nemo; + nemo.mocha = Test.ctx; + }); + // runner.on('test end', function (Test) { + // // not using this currently + // }); + runner.on('pass', function () { + result.total = result.total + 1; + result.pass = result.pass + 1; + }); + runner.on('fail', function () { + result.total = result.total + 1; + result.fail = result.fail + 1; + }); + // runner.on('hook end', function (Evt) { + // // not using this currently + // }); + runner.on('hook', function (Evt) { + Evt.ctx.nemo = nemo; + // not using this currently + }); + + + runner.on('suite', function (Suite) { + if (input.profile.reportFile) { + result.reportFile = input.profile.reportFile; + } + log('suite event, suite %s, root: %s', Suite.title, Suite.root); + anyTests = true; + if (!(nemo && nemo.driver)) { + + Suite.beforeAll(function checkNemo(_done) { + Nemo(config).then(function (_nemo) { + nemo = _nemo; + nemo.runner = { + snap: function () { + var imagePath = arguments[0]; + if (!imagePath) { + log(`nemo.runner.snap for test ${nemo.mocha.test.title}`); + nemo.mocha.test.__screenshot = (nemo.mocha.test.__screenshot) ? (nemo.mocha.test.__screenshot + 1) : 1; + + var screenshotName = `${filenamify(nemo.mocha.test.title)}.${nemo.mocha.test.__screenshot}.png`; + imagePath = `${profileConf.reports}/${screenshotName}`; + + // below only applicable for mochawesome reports + addContext(nemo.mocha, screenshotName); + } + return nemo.driver.takeScreenshot() + .then(function (img) { + let pFunk; + let p = new Promise((resolve, reject) => { + pFunk = {resolve, reject}; + }); + log(`afterEach: got the screenshot, ${imagePath}`); + mkdirp.sync(path.dirname(imagePath)); + + // save screen image + fs.writeFile(imagePath, img, { + 'encoding': 'base64' + }, function (err) { + if (err) { + pFunk.reject(err); + } else { + pFunk.resolve(true); + } + }); + return p; + }) + .catch(function (err) { + console.log(`nemo.runner.snap: triggered error block: ${err}`); + }); + } + } + _done(); + }).catch(function (err) { + error(err); + _done(err); + if (done) { + done(result); + } + }); + }); + Suite._beforeAll.unshift(Suite._beforeAll.pop()); + } + Suite.afterEach(function capture() { + if (this.currentTest.gotScreenshot) { + return Promise.resolve(); + } + this.currentTest.gotScreenshot = true; + log(`afterEach: start`); + var screenshotName = `${filenamify(this.currentTest.title)}.after.png`; + var imagePath = `${profileConf.reports}/${screenshotName}`; + + // below only applicable for mochawesome reports + addContext(this, screenshotName); + return this.nemo.runner.snap(imagePath); + }); + Suite._afterEach.unshift(Suite._afterEach.pop()); + }); + runner.on('suite end', function (Evt) { + log('suite end called for %s which is root: %s', Evt.title, Evt.root); + if (Evt.root && nemo && nemo.driver) { + nemo.driver.quit() + .then(function () { + log('Suite is ended. Quit driver and call done'); + if (done) { + done(result); + } + }); + } + }); + }; + Nemo.Configure(baseDirectory, {}).then(defineSuite) + .catch(function (err) { + error('error in defineSuite chain'); + error(err); + if (done) { + done(result); + } + }); +}; diff --git a/lib/prefontaine.js b/lib/prefontaine.js new file mode 100644 index 0000000..85ddbed --- /dev/null +++ b/lib/prefontaine.js @@ -0,0 +1,36 @@ +var Nemo = require('nemo'); +var starter = require('../lib/starter'); +var flow = require('../lib/flow'); +var async = require('async'); +var debug = require('debug'); +var log = debug('nemo:log'); +var error = debug('nemo:error'); + +module.exports = function prefontaine(program) { + return Nemo.Configure(program.baseDirectory, {}).then(function (config) { + let prefontaine = {program: program, config: config}; + return Promise.resolve(prefontaine); + }).catch(function (err) { + error('problem with main configuration %O', err); + }); +}; + +module.exports.start = function start(prefontaine) { + let pFunk; + let p = new Promise((resolve, reject) => { + pFunk = {resolve, reject}; + }); + let _flow = flow.map(function (fn) { + return fn.bind(prefontaine); + }); + log('flow length %d', _flow.length); + async.series(_flow, function (err) { + if (err) { + return pFunk.reject(err); + } + log('assembled %d instances', prefontaine.instances.length); + starter.apply(prefontaine); + pFunk.resolve(prefontaine); + }); + return p; +}; \ No newline at end of file diff --git a/lib/reporter.js b/lib/reporter.js new file mode 100644 index 0000000..b0e6109 --- /dev/null +++ b/lib/reporter.js @@ -0,0 +1,40 @@ +var debug = require('debug'); +var log = debug('nemo:log'); +var filenamify = require('filenamify'); + +// var error = debug('nemo:error'); + +module.exports.mochawesome = function mochawesome(instance) { + log(`reporter:mochawesome: start: %O`, instance.conf.mocha); + let instanceLabel = ''; + for (let tag in instance.tags) { + if (instance.tags.hasOwnProperty(tag)) { + instanceLabel += `:${tag}:${instance.tags[tag]}:`; + } + } + instance.conf.reports = `${instance.conf.reports}/${filenamify(instanceLabel)}`; + let reporterOptions = { + reportDir: instance.conf.reports, + reportFilename: 'nemo-report' + }; + instance.reportFile = `${instance.conf.reports}/nemo-report.html`; + instance.conf.mocha.reporterOptions = Object.assign({}, instance.conf.mocha.reporterOptions, reporterOptions); +}; + +module.exports.xunit = function (instance) { + log(`reporter:xunit: start: %O`, instance.conf.mocha); + let instanceLabel = ''; + for (let tag in instance.tags) { + if (instance.tags.hasOwnProperty(tag)) { + instanceLabel += `:${tag}:${instance.tags[tag]}:`; + } + } + instance.conf.reports = filenamify.path(`${instance.conf.reports}/${instanceLabel}`); + if (instance.conf.mocha.reporterOptions && instance.conf.mocha.reporterOptions.output) { + let reporterOptions = { + output: `${instance.conf.reports}/nemo-report.xml` + }; + instance.reportFile = `${instance.conf.reports}/nemo-report.xml`; + instance.conf.mocha.reporterOptions = Object.assign({}, instance.conf.mocha.reporterOptions, reporterOptions); + } +}; \ No newline at end of file diff --git a/lib/server.js b/lib/server.js new file mode 100644 index 0000000..14254c9 --- /dev/null +++ b/lib/server.js @@ -0,0 +1,62 @@ +const express = require('express') +const prefontaine = require('./prefontaine'); +var graphqlHTTP = require('express-graphql'); +var { buildSchema } = require('graphql'); + +var schema = buildSchema(` + type Query { + hello: String, + balls: String + } +`); + +var root = { hello: () => 'Hello world!', + balls: () => 'balls' +}; + +module.exports = (program) => { + + const app = express() + + app.get('/profiles', (req, res) => { + // debugger; + // console.log(prefontaine.config.get('profiles')) + + // res.json(prefontaine.config.get('profiles')) + prefontaine(program) + .then(function (pre) { + res.json(pre.config.get('profiles')) + }); + }); + app.post('/profiles/run/:profile', (req, res) => { + let prog = Object.assign({}, program, {profile: req.params.profile, fromServer: true}) + prefontaine(prog) + .then(function (pre) { + // console.log(pre); + return prefontaine.start(pre); + }) + .then(function (pre) { + //quick hack + let reportUrl = `http://localhost:3000/report/${pre.config.get('profiles:base:reports').split('test/report/')[1]}/summary.json` + res.json({launched: true, + summary: reportUrl + }); + }) + .catch(function (err) { + res.json({launched: false}); + }); + }); + prefontaine(program) + .then(function (pre) { + app.use('/report', express.static(pre.config.get('profiles:base:reports'), {index:false})); + app.use('/graphql', graphqlHTTP({ + schema: schema, + rootValue: root, + graphiql: true, + })); + app.listen(3000, () => console.log('Nemo-Runner listening on port 3000!')) + + }); + + +} \ No newline at end of file diff --git a/lib/starter.js b/lib/starter.js new file mode 100644 index 0000000..2dbd9ae --- /dev/null +++ b/lib/starter.js @@ -0,0 +1,92 @@ +'use strict'; + +var spawn = require('threads').spawn; +var instance = require('../lib/instance'); +var debug = require('debug'); +var parallelLimit = require('async/parallelLimit'); +var log = debug('nemo:log'); +var error = debug('nemo:error'); +var fs = require('fs'); +var table = require('cli-table'); + +module.exports = function pistol() { + var results = []; + var complete = 0; + var iconfig; + var tasks; + var maxConcurrent; + + if (this.instances.length === 1 && !this.program.fromServer) { + iconfig = this.instances[0]; + log('single kickoff with instance %O', iconfig.tags); + // TODO: below doesn't impact debuglogs of modules already loaded + process.env = Object.assign({}, process.env, iconfig.conf.env || {}); + return instance({basedir: this.program.baseDirectory, profile: iconfig}); + } + // parallel use case + tasks = this.instances.map(function (iconf) { + return function (done) { + var thread = spawn(instance, {env: Object.assign({}, process.env, iconf.conf.env || {})}); + log('multi kickoff with instance %O', iconf.tags); + thread + .send({basedir: this.program.baseDirectory, profile: iconf}) + // The handlers come here: (none of them is mandatory) + .on('message', function (summary) { + log('Thread complete', summary); + if (summary) { + results.push(summary); + } + thread.kill(); + }) + .on('error', function (er) { + error(er); + thread.kill(); + }) + .on('exit', function () { + var totals; + complete = complete + 1; + log(`Thread exited. ${complete}/${this.instances.length}`); + thread.removeAllListeners('message'); + thread.removeAllListeners('error'); + thread.removeAllListeners('exit'); + if (complete === this.instances.length) { + totals = {total: 0, pass: 0, fail: 0}; + log('Everything done, shutting down the thread pool.'); + results.forEach(function (result) { + totals.total = totals.total + result.total; + totals.pass = totals.pass + result.pass; + totals.fail = totals.fail + result.fail; + }); + + let summary = JSON.stringify({ + iterations: results, + summary: totals + }, null, '\t') + /* eslint-disable */ + // console.log(summary); + let tabl = new table({ + head: ['tags', 'pass', 'fail', 'total', 'report'] + }); + results.forEach(function (iter) { + let tags = ''; + Object.keys(iter.tags).forEach(function (key) { + if (key === 'uid') { + return; + } + tags += `${key}: ${iter.tags[key]}\n` + }); + tabl.push([tags, iter.pass, iter.fail, iter.total, iter.reportFile || '']); + }); + tabl.push(['TOTALS', totals.pass, totals.fail, totals.total]); + console.log(tabl.toString()); + fs.writeFileSync(`${this.config.get('profiles:base:reports')}/summary.json`, summary); + /* eslint-enable */ + } + done(); + }.bind(this)); + }.bind(this); + }.bind(this)); + + maxConcurrent = this.config.get('profiles:base:maxConcurrent') || Infinity; + parallelLimit(tasks, maxConcurrent); +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..543dfb9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2642 @@ +{ + "name": "nemo", + "version": "4.0.0-alpha.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "ajv": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", + "dev": true, + "requires": { + "co": "4.6.0", + "json-stable-stringify": "1.0.1" + } + }, + "ajv-keywords": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", + "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "dev": true + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "1.0.3" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "1.0.3" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "requires": { + "lodash": "4.17.4" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "caller": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/caller/-/caller-1.0.1.tgz", + "integrity": "sha1-uFGGD3Dhlds9J3OVqhp+I+ow7PU=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "0.2.0" + } + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "dev": true, + "requires": { + "restore-cursor": "1.0.1" + } + }, + "cli-table": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", + "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "requires": { + "colors": "1.0.3" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "coa": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/coa/-/coa-0.3.9.tgz", + "integrity": "sha1-fj0g0wr3C4CGLpXU1JtxUYO+lgQ=", + "requires": { + "q": "0.8.12" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" + }, + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "typedarray": "0.0.6" + } + }, + "confit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/confit/-/confit-2.2.1.tgz", + "integrity": "sha1-VvU2H4HKTKegsuQ5lKzEoXRUyjU=", + "requires": { + "async": "0.9.2", + "babel-runtime": "4.7.3", + "caller": "1.0.1", + "core-util-is": "1.0.2", + "debuglog": "1.0.1", + "load-jsonic-sync": "1.0.1", + "minimist": "1.2.0", + "shortstop": "1.0.3", + "shortstop-handlers": "1.0.1" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "babel-runtime": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-4.7.3.tgz", + "integrity": "sha1-rMC2GU3m4MqO/tC5e2OTZuZJUDE=" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-react-class": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz", + "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "0.10.37" + } + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=" + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-equal": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.1.2.tgz", + "integrity": "sha1-skbCuApXCkfBG+HZvRBw7IeLh84=" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defined": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", + "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=" + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "5.0.0", + "is-path-cwd": "1.0.0", + "is-path-in-cwd": "1.0.0", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "rimraf": "2.6.2" + } + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" + }, + "doctrine": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", + "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, + "requires": { + "esutils": "2.0.2" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "0.4.19" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "dev": true, + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-symbol": "3.1.1" + } + }, + "es6-map": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", + "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-set": "0.1.5", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-promise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" + }, + "es6-set": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", + "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1", + "event-emitter": "0.3.5" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escope": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", + "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", + "dev": true, + "requires": { + "es6-map": "0.1.5", + "es6-weak-map": "2.0.2", + "esrecurse": "4.2.0", + "estraverse": "4.2.0" + } + }, + "eslint": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", + "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "chalk": "1.1.3", + "concat-stream": "1.6.0", + "debug": "2.6.9", + "doctrine": "2.0.2", + "escope": "3.6.0", + "espree": "3.5.2", + "esquery": "1.0.0", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "file-entry-cache": "2.0.0", + "glob": "7.1.2", + "globals": "9.18.0", + "ignore": "3.3.7", + "imurmurhash": "0.1.4", + "inquirer": "0.12.0", + "is-my-json-valid": "2.16.1", + "is-resolvable": "1.0.0", + "js-yaml": "3.10.0", + "json-stable-stringify": "1.0.1", + "levn": "0.3.0", + "lodash": "4.17.4", + "mkdirp": "0.5.1", + "natural-compare": "1.4.0", + "optionator": "0.8.2", + "path-is-inside": "1.0.2", + "pluralize": "1.2.1", + "progress": "1.1.8", + "require-uncached": "1.0.3", + "shelljs": "0.7.8", + "strip-bom": "3.0.0", + "strip-json-comments": "2.0.1", + "table": "3.8.3", + "text-table": "0.2.0", + "user-home": "2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-plugin-es6-recommended": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-es6-recommended/-/eslint-plugin-es6-recommended-0.1.2.tgz", + "integrity": "sha1-QXqSBwUvvT0liKhwmkEuS9llH94=", + "dev": true + }, + "espree": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", + "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, + "requires": { + "acorn": "5.2.1", + "acorn-jsx": "3.0.1" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", + "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, + "requires": { + "estraverse": "4.2.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "4.2.0", + "object-assign": "4.1.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "dev": true, + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.37" + } + }, + "eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + } + }, + "express-graphql": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/express-graphql/-/express-graphql-0.6.11.tgz", + "integrity": "sha512-dC/FAun5rqcRxhDe78047hqc048mo3xZpBDS0Z7RZOw9UleO9mZE0rHMS9yrVSaYzsLiz+q4PldKu6Oaqop+CA==", + "requires": { + "accepts": "1.3.4", + "content-type": "1.0.4", + "http-errors": "1.6.2", + "raw-body": "2.3.2" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fbjs": { + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", + "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", + "requires": { + "core-js": "1.2.7", + "isomorphic-fetch": "2.2.1", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "promise": "7.3.1", + "setimmediate": "1.0.5", + "ua-parser-js": "0.7.17" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + } + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "1.3.0", + "object-assign": "4.1.1" + } + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=" + }, + "filenamify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.0.0.tgz", + "integrity": "sha1-vRYiYsC26Uv7zc8Zo7uzdk94VpU=", + "requires": { + "filename-reserved-regex": "2.0.0", + "strip-outer": "1.0.0", + "trim-repeated": "1.0.0" + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "0.3.3", + "del": "2.2.2", + "graceful-fs": "4.1.11", + "write": "0.2.1" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "3.0.1", + "universalify": "0.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fsu/-/fsu-1.0.4.tgz", + "integrity": "sha512-T8DGjqL3DNJsA/uHWUTIZhJ/VuEqi3QdNsQBAWpKtoIPS/8rK4HWG79ae2+HEw+Cz9e5lIsWghpoXCcNsrDPFA==" + }, + "generate-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", + "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "dev": true + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dev": true, + "requires": { + "is-property": "1.0.2" + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "arrify": "1.0.1", + "glob": "7.1.2", + "object-assign": "4.1.1", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "graphql": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.12.3.tgz", + "integrity": "sha512-Hn9rdu4zacplKXNrLCvR8YFiTGnbM4Zw/UH8FDmzBDsH7ou40lSNH4tIlsxcYnz2TGNVJCpu1WxCM23yd6kzhA==", + "requires": { + "iterall": "1.1.3" + } + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.3.1" + }, + "dependencies": { + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + } + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "inquirer": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", + "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", + "dev": true, + "requires": { + "ansi-escapes": "1.4.0", + "ansi-regex": "2.1.1", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "figures": "1.7.0", + "lodash": "4.17.4", + "readline2": "1.0.1", + "run-async": "0.1.0", + "rx-lite": "3.1.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-my-json-valid": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", + "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "dev": true, + "requires": { + "generate-function": "2.0.0", + "generate-object-property": "1.2.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", + "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, + "requires": { + "is-path-inside": "1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", + "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "dev": true, + "requires": { + "path-is-inside": "1.0.2" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "dev": true + }, + "is-resolvable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", + "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "dev": true, + "requires": { + "tryit": "1.0.3" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "1.7.3", + "whatwg-fetch": "2.0.3" + } + }, + "iterall": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.1.3.tgz", + "integrity": "sha512-Cu/kb+4HiNSejAPhSaN1VukdNTTi/r4/e+yykqjlG/IW+1gZH5b4+Bq3whDX4tvbYugta3r8KTMUiqT3fIGxuQ==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "1.0.9", + "esprima": "4.0.0" + } + }, + "json-ometajs": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-ometajs/-/json-ometajs-3.0.2.tgz", + "integrity": "sha1-EO86ysJ1bWWJt/zg3542/BVbRPs=", + "requires": { + "ometajs": "4.0.0" + } + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsonic-ometajs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonic-ometajs/-/jsonic-ometajs-3.0.1.tgz", + "integrity": "sha1-nKhQw48TYa8ORX43g2BIXoEJ09U=", + "requires": { + "json-ometajs": "3.0.2", + "ometajs": "4.0.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, + "jszip": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", + "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", + "requires": { + "core-js": "2.3.0", + "es6-promise": "3.0.2", + "lie": "3.1.1", + "pako": "1.0.6", + "readable-stream": "2.0.6" + }, + "dependencies": { + "core-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "1.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "requires": { + "immediate": "3.0.6" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "load-jsonic-sync": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/load-jsonic-sync/-/load-jsonic-sync-1.0.1.tgz", + "integrity": "sha1-isfhvG4TBzd2zYftOHkuGssoUHg=", + "requires": { + "jsonic-ometajs": "3.0.1", + "verror": "1.10.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "requires": { + "lodash._basecopy": "3.0.1", + "lodash.keys": "3.1.2" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=" + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "requires": { + "lodash._baseassign": "3.2.0", + "lodash._basecreate": "3.0.3", + "lodash._isiterateecall": "3.0.9" + } + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.isfunction": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.8.tgz", + "integrity": "sha1-TbcJ/IG8So/XEnpFilNGxc3OLGs=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "3.9.1", + "lodash.isarguments": "3.1.0", + "lodash.isarray": "3.0.4" + } + }, + "lodash.merge": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", + "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=" + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "requires": { + "js-tokens": "3.0.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "requires": { + "graceful-readlink": "1.0.1" + } + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + } + } + }, + "mochawesome": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mochawesome/-/mochawesome-2.3.1.tgz", + "integrity": "sha512-amkBeQZz/IUTm2o1VLHiih30RHdt4uMAAhyvd5oJ5FMq5gCmqzFS29pobVyGajqzPvC+na8U+nzO8DtftQoLLw==", + "requires": { + "babel-runtime": "6.26.0", + "chalk": "1.1.3", + "diff": "3.2.0", + "json-stringify-safe": "5.0.1", + "lodash": "4.17.4", + "mochawesome-report-generator": "2.3.2", + "strip-ansi": "4.0.0", + "uuid": "3.1.0" + } + }, + "mochawesome-report-generator": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/mochawesome-report-generator/-/mochawesome-report-generator-2.3.2.tgz", + "integrity": "sha512-T2bY3ezsZuKmM9DyZff/F7WlhHVfEq2Y2dZb9PdfT+ZclFz/b7iIqXBThi6j5Y+xUSOV1LY4rg072Fc0xdmiRQ==", + "requires": { + "chalk": "1.1.3", + "dateformat": "2.2.0", + "fs-extra": "3.0.1", + "fsu": "1.0.4", + "lodash.isfunction": "3.0.8", + "opener": "1.4.3", + "prop-types": "15.6.0", + "react": "15.6.2", + "react-dom": "15.6.2", + "tcomb": "3.2.24", + "tcomb-validation": "3.4.1", + "validator": "7.2.0", + "yargs": "7.1.0" + } + }, + "moment": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz", + "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "dev": true + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "nemo-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nemo-core/-/nemo-core-1.0.0.tgz", + "integrity": "sha512-FKnXRJX4qVGJMns0WE3LjroUqkFZ7iIK73frYgz+1f6GtRcaHE6JypQSXyohF+cTCADT3a+48aaudJALt85Bcg==", + "requires": { + "async": "2.6.0", + "confit": "2.2.1", + "debug": "3.1.0", + "lodash": "4.17.4", + "selenium-webdriver": "3.6.0", + "shortstop-handlers": "1.0.1", + "yargs": "7.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "nemo-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nemo-view/-/nemo-view-3.1.0.tgz", + "integrity": "sha512-eQYLDmZzq+uFNfAlsiPgnBuw9oDyh0hHl50tOQyR8KNHQINKI5jSwrdauI09IUoawWzYoc+pxSWlzklzwuIw7g==", + "requires": { + "debug": "2.6.9", + "glob": "7.1.2", + "lodash": "4.17.4", + "selenium-drivex": "2.0.1", + "shush": "1.0.0" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "5.4.1", + "validate-npm-package-license": "3.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "ometajs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ometajs/-/ometajs-4.0.0.tgz", + "integrity": "sha1-e/vSeO8O9c76XQUGLdeHus7VbLU=", + "requires": { + "coa": "0.3.9", + "q": "0.8.12", + "uglify-js": "1.3.5" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=" + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "pako": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", + "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "2.0.4" + } + }, + "pluralize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", + "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "2.0.6" + } + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1" + } + }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, + "q": { + "version": "0.8.12", + "resolved": "https://registry.npmjs.org/q/-/q-0.8.12.tgz", + "integrity": "sha1-kWKpHhGBnEvNp9oVz1/vqtB3iCM=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "react": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz", + "integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=", + "requires": { + "create-react-class": "15.6.2", + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "react-dom": { + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz", + "integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=", + "requires": { + "fbjs": "0.8.16", + "loose-envify": "1.3.1", + "object-assign": "4.1.1", + "prop-types": "15.6.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "readline2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "mute-stream": "0.0.5" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "1.5.0" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "0.1.0", + "resolve-from": "1.0.1" + } + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dev": true, + "requires": { + "exit-hook": "1.1.1", + "onetime": "1.1.0" + } + }, + "resumer": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", + "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", + "requires": { + "through": "2.3.8" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, + "run-async": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "rx-lite": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", + "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "selenium-drivex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/selenium-drivex/-/selenium-drivex-2.0.1.tgz", + "integrity": "sha512-Yc+l+R6/SUXj0fotg43thvd9Uq5g2yrW8B08scgF7g4N9nFZlh+3kP91yvoCtQWw/FMefuRiD4dd/lqkJPc2OQ==", + "requires": { + "async": "0.9.2", + "debug": "2.6.9" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + } + } + }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "requires": { + "jszip": "3.1.5", + "rimraf": "2.6.2", + "tmp": "0.0.30", + "xml2js": "0.4.19" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, + "shortstop": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/shortstop/-/shortstop-1.0.3.tgz", + "integrity": "sha1-1Ddpw2/ufiCjub/S0IeJNf+G58Y=", + "requires": { + "async": "0.2.10", + "core-util-is": "1.0.2" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + } + } + }, + "shortstop-handlers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/shortstop-handlers/-/shortstop-handlers-1.0.1.tgz", + "integrity": "sha1-B1WstmBMdsnA52qelD+TeQurHcQ=", + "requires": { + "caller": "1.0.1", + "core-util-is": "1.0.2", + "glob": "7.1.2" + } + }, + "shush": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shush/-/shush-1.0.0.tgz", + "integrity": "sha1-wnQVqeRY8v7TmyfPjrN8ADeCtDE=", + "requires": { + "caller": "0.0.1", + "strip-json-comments": "0.1.3" + }, + "dependencies": { + "caller": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/caller/-/caller-0.0.1.tgz", + "integrity": "sha1-83odbqEOgp2UchrimpC7T7Uqt2c=", + "requires": { + "tape": "2.3.3" + } + }, + "strip-json-comments": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", + "integrity": "sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ=" + } + } + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + } + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "strip-outer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.0.tgz", + "integrity": "sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "requires": { + "has-flag": "1.0.0" + } + }, + "table": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", + "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", + "dev": true, + "requires": { + "ajv": "4.11.8", + "ajv-keywords": "1.5.1", + "chalk": "1.1.3", + "lodash": "4.17.4", + "slice-ansi": "0.0.4", + "string-width": "2.1.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + } + } + }, + "tape": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tape/-/tape-2.3.3.tgz", + "integrity": "sha1-Lnzgox3wn41oUWZKcYQuDKUFevc=", + "requires": { + "deep-equal": "0.1.2", + "defined": "0.0.0", + "inherits": "2.0.3", + "jsonify": "0.0.0", + "resumer": "0.0.0", + "through": "2.3.8" + } + }, + "tcomb": { + "version": "3.2.24", + "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.24.tgz", + "integrity": "sha512-N9IrL2iIyS/f4+WHYZaMh04ZqDL8yEit9cVdnn+fOuL6jbKo1fusNswHOjSo/kbYwLUKRS1OlQmAkyeNxyEUhA==" + }, + "tcomb-validation": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tcomb-validation/-/tcomb-validation-3.4.1.tgz", + "integrity": "sha512-urVVMQOma4RXwiVCa2nM2eqrAomHROHvWPuj6UkDGz/eb5kcy0x6P0dVt6kzpUZtYMNoAqJLWmz1BPtxrtjtrA==", + "requires": { + "tcomb": "3.2.24" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "threads": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/threads/-/threads-0.7.3.tgz", + "integrity": "sha1-69Awk6PtgwGFuRZgb6RvkyJJsk0=", + "requires": { + "eventemitter3": "2.0.3", + "native-promise-only": "0.8.1" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "requires": { + "os-tmpdir": "1.0.2" + } + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "requires": { + "escape-string-regexp": "1.0.5" + } + }, + "tryit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", + "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" + }, + "uglify-js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", + "integrity": "sha1-S1v/+Rhu/7qoiOTJ6UvZ/EyUkp0=" + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "dev": true, + "requires": { + "os-homedir": "1.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, + "validator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-7.2.0.tgz", + "integrity": "sha512-c8NGTUYeBEcUIGeMppmNVKHE7wwfm3mYbNZxV+c5mlv9fDHI7Ad3p07qfNrn/CvpdkK2k61fOLRO2sTEhgQXmg==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "whatwg-fetch": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", + "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=" + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "0.5.1" + } + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": "1.2.4", + "xmlbuilder": "9.0.4" + } + }, + "xmlbuilder": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", + "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "requires": { + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "3.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..daf83ab --- /dev/null +++ b/package.json @@ -0,0 +1,68 @@ +{ + "name": "nemo", + "version": "4.0.0-alpha.1", + "description": "Wrapper to run mocha suites with injected selenium-webdriver instance", + "main": "index.js", + "scripts": { + "test": "npm run lint && npm run nemo", + "nemo": "DEBUG=nemo*,mocha:runner ./bin/nemo -B test -G @suite1", + "nemo:no:selenium:promises": "SELENIUM_PROMISE_MANAGER=0 DEBUG=nemo* ./bin/nemo -B test -P pay -D", + "nemo:debug": "DEBUG=nemo ./bin/nemo -B test -G @suite1 --debug-brk --inspect", + "nemo:parallel": "DEBUG=nemo* ./bin/nemo -B test -G @suite1,@suite2,@suite3,@suite4 -F", + "nemo:parallel:data": "DEBUG=nemo* ./bin/nemo -B test -P search,pay -D", + "nemo:search": "SELENIUM_PROMISE_MANAGER=0 DEBUG=nemo* ./bin/nemo -B test -P search -D", + "nemo:pay": "SELENIUM_PROMISE_MANAGER=0 DEBUG=nemo* ./bin/nemo -B test -P pay -D", + "nemo:form": "SELENIUM_PROMISE_MANAGER=0 DEBUG=nemo* ./bin/nemo -B test -P form", + "nemo:xunit": "DEBUG=nemo* ./bin/nemo -B test -G @suite1 -P xunit", + "nemo:server": "DEBUG=nemo* ./bin/nemo -B test -S", + "lint": "eslint ./bin/* ./lib/*" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/paypal/nemo.git" + }, + "bin": { + "nemo": "./bin/nemo", + "_nemo": "./bin/_nemo" + }, + "keywords": [ + "nemo", + "mocha", + "selenium", + "parallel" + ], + "author": "grawk ", + "contributors": [ + "grawk ", + "Kurt Weiberth ", + "Ethan Godt " + ], + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/krakenjs/nemo/issues" + }, + "homepage": "https://github.com/krakenjs/nemo#readme", + "dependencies": { + "async": "^2.5.0", + "cli-table": "^0.3.1", + "commander": "^2.9.0", + "debug": "^2.6.3", + "express": "^4.16.2", + "express-graphql": "^0.6.11", + "filenamify": "^2.0.0", + "glob": "^7.1.1", + "graphql": "^0.12.3", + "lodash.merge": "^4.6.0", + "mocha": "^3.2.0", + "mochawesome": "^2.3.1", + "moment": "^2.19.2", + "nemo-core": "^1.0.0", + "nemo-view": "^3.1.0", + "threads": "^0.7.2", + "uuid": "^3.1.0" + }, + "devDependencies": { + "eslint": "^3.19.0", + "eslint-plugin-es6-recommended": "^0.1.2" + } +} diff --git a/static/report-output.png b/static/report-output.png new file mode 100644 index 0000000000000000000000000000000000000000..78da73146b80356564ba1c0a4421f00634bc5a44 GIT binary patch literal 68129 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 F|1WPwm*D^a literal 0 HcmV?d00001 diff --git a/test/config/config.json b/test/config/config.json new file mode 100644 index 0000000..7b87876 --- /dev/null +++ b/test/config/config.json @@ -0,0 +1,95 @@ +{ + "driver": { + "browser": "phantomjs" + }, + "plugins": { + "view": { + "module": "nemo-view", + "arguments": ["path:locator"] + } + }, + "data": { + "baseUrl": "https://www.google.com" + }, + "profiles": { + "base": { + "tests": "path:./nested*.js", + "reports": "path:report", + "env": { // these only get set when running in parallel (child processes from main process) + "DEBUG": "nemo*" + }, + "driver": { + "browser": "chrome" + }, + "mocha": { + "timeout": 180000, + "reporter": "mochawesome" + } + }, + "xunit": { + "mocha": { + "reporter": "xunit", + "reporterOptions": { + "output": "this just tells nemo we want to output files" + } + } + }, + "search": { + "tests": "path:./search.js", + "parallel": "data", + "data": { + "google": { + "baseUrl": "https://www.google.com", + "input": "input[name=q]", + "button": "input[type=submit][name=btnK]", + "result": "#search" + }, + "yahoo": { + "baseUrl": "http://www.yahoo.com", + "input": "input[name=p]", + "button": "#uh-search-button", + "result": "#results" + }, + "bing": { + "baseUrl": "http://www.bing.com", + "input": "input[name=q]", + "button": "input[name=go]", + "result": "#b_results" + } + } + }, + "pay": { + "tests": "path:./pay.js", + "parallel": "data", + "data": { + "paypal": { + "baseUrl": "https://www.paypal.com", + "signupButton": "#signup-button",// + "signupForm": "#cta-btn" + }, + "square": { + "baseUrl": "http://www.squareup.com", + "signupButton": "a.button[href*=signup]",//Sign up with Square + "signupForm": "body.signup-page"// + } + } + }, + "form": { + "tests": "path:./form.js", + "data": { + "useme": "require:./config/useme", + "baseUrl": "https://mdn.github.io/learning-area/html/forms/your-first-HTML-form/first-form-styled.html" + } + }, + "chrome": { + "driver": { + "browser": "phantomjs"//just pretending this is another browser :) + } + }, + "firefox": { + "driver": { + "browser": "phantomjs"//just pretending this is another browser :) + } + } + } +} diff --git a/test/config/useme.js b/test/config/useme.js new file mode 100644 index 0000000..92956bb --- /dev/null +++ b/test/config/useme.js @@ -0,0 +1,25 @@ +module.exports = `My friends feel it's their appointed duty +They keep trying to tell me all you want to do is use me +But my answer yeah to all that use me stuff +Is I want to spread the news that if it feels this good getting used +Oh you just keep on using me until you use me up +Until you use me up + +My brother sit me right down and he talked to me +He told me that I ought not to let you just walk on me +And I'm sure he meant well yeah but when our talk was through +I said brother if you only knew you'd wish that you were in my shoes +You just keep on using me until you use me up +Until you use me up + +Oh sometimes yeah it's true you really do abuse me +You get in a crowd of high class people and then you act real rude to me +But oh baby baby baby baby when you love me I can't get enough +I and I want to spread the news that if it feels this good getting used +Oh you just keep on using me until you use me up +Until you use me up + +Talking about you using me but it all depends on what you do +It ain't too bad the way you're using me +'Cause I sure am using you to do the things you do +Ah ha to do the things you do`; \ No newline at end of file diff --git a/test/form.js b/test/form.js new file mode 100644 index 0000000..ed5a9ca --- /dev/null +++ b/test/form.js @@ -0,0 +1,16 @@ + +describe('@form@', function () { + it('should fill in a simple form', async function () { + let nemo = this.nemo; + + let {name, email, message, sendButton, result} = nemo.view.form; + await nemo.driver.get(nemo.data.baseUrl); + await name().sendKeys('Bill Withers'); + await email().sendKeys('bwithers@soul.singer'); + await message().sendKeys(nemo.data.useme); + await nemo.runner.snap(); + await sendButton().click(); + await result.waitVisible(); + await result.textEquals('405 Not Allowed'); + }); +}); diff --git a/test/locator/form.json b/test/locator/form.json new file mode 100644 index 0000000..cb9a65f --- /dev/null +++ b/test/locator/form.json @@ -0,0 +1,7 @@ +{ + "name": "#name", + "email": "#mail", + "message": "#msg", + "sendButton": "button[type=submit]", + "result": "center h1" +} \ No newline at end of file diff --git a/test/nested.js b/test/nested.js new file mode 100644 index 0000000..0a8f60e --- /dev/null +++ b/test/nested.js @@ -0,0 +1,31 @@ + +describe('@suite1@suite2@suite3@suite4@', function () { + it('may fail a few times1', function () { + let nemo = this.nemo; + //verify nemo.mocha property + if (!nemo.mocha === this) { + return Promise.reject(new Error('didnt find mocha context at nemo.mocha')); + } + return nemo.driver.get(nemo.data.baseUrl) + .then(function () { + return nemo.runner.snap() + }) + .then(function () { + return nemo.runner.snap() + }) + }); + describe('@inner@', function () { + it('may fail a few times2', function () { + let nemo = this.nemo; + //verify nemo.mocha property + if (!nemo.mocha === this) { + return Promise.reject(new Error('didnt find mocha context at nemo.mocha')); + } + return nemo.driver.get(nemo.data.baseUrl) + .then(function () { + return nemo.driver.sleep(500); + }); + }); + }); + +}); diff --git a/test/nested2.js b/test/nested2.js new file mode 100644 index 0000000..82c4386 --- /dev/null +++ b/test/nested2.js @@ -0,0 +1,19 @@ + +describe('@suite1.2@suite2.2@suite3.2@suite4.2@', function () { + it('may fail a few times3', function () { + let nemo = this.nemo; + return nemo.driver.get(nemo.data.baseUrl) + .then(function () { + return nemo.driver.sleep(500); + }); + }); + describe('@inner@', function () { + it('may fail a few times4', function () { + let nemo = this.nemo; + return nemo.driver.get(nemo.data.baseUrl) + .then(function () { + return nemo.driver.sleep(500); + }); + }); + }); +}); diff --git a/test/pay.js b/test/pay.js new file mode 100644 index 0000000..063517d --- /dev/null +++ b/test/pay.js @@ -0,0 +1,10 @@ + +describe('@pay@', function () { + it('should show a signup form for payment processor', async function () { + let nemo = this.nemo; + let {baseUrl, signupButton, signupForm} = nemo.data; + await nemo.driver.get(baseUrl); + await nemo.view._find(signupButton).click(); + await nemo.view._waitVisible(signupForm); + }); +}); diff --git a/test/search.js b/test/search.js new file mode 100644 index 0000000..65caa8f --- /dev/null +++ b/test/search.js @@ -0,0 +1,12 @@ + +describe('@search@', function () { + it('should execute a web search', async function () { + let nemo = this.nemo; + let {baseUrl, input, button, result} = nemo.data; + await nemo.driver.get(baseUrl); + await nemo.view._find(input).sendKeys('nemo selenium'); + await nemo.view._find(input).sendKeys(nemo.wd.Key.TAB); // close any modal overlay (like google has) + await nemo.view._find(button).click(); + await nemo.view._waitVisible(result); + }); +});