diff --git a/.babelrc b/.babelrc index a3b237f0..adae42de 100644 --- a/.babelrc +++ b/.babelrc @@ -1,4 +1,13 @@ { "presets": ["env", "react"], - "plugins": ["transform-object-rest-spread", "transform-class-properties"] + "plugins": ["transform-object-rest-spread", "transform-class-properties"], + "env": { + "test": { + "plugins": [ + ["istanbul", { + exclude: ["node_modules/**", "test/**"] + }] + ] + } + } } diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..f78c4ee5 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,27 @@ +version: 2 +jobs: + build: + docker: + # specify the version you desire here + - image: node:8 + - image: selenium/standalone-chrome:3.1.0 + working_directory: ~/repo + steps: + - checkout + - run: + name: "Create artifacts directory" + command: mkdir /tmp/artifacts + - restore_cache: + key: v1-dependencies-{{ checksum "package.json" }} + + - run: npm install + + - save_cache: + paths: + - node_modules + key: v1-dependencies-{{ checksum "package.json" }} + + - run: mkdir -p /tmp/artifacts/logs + - run: DOCKER_HOST=localhost npm test + - run: npm run build + - run: ./node_modules/.bin/istanbul report --include /tmp/artifacts/coverage/coverage.json --dir /tmp/artifacts/coverage html lcov diff --git a/.gitignore b/.gitignore index 99105f43..83a8308f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ node_modules # Ignore build files public +/errorShots +/old diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 5e66cd33..00000000 --- a/circle.yml +++ /dev/null @@ -1,6 +0,0 @@ -machine: - node: - version: 6 -test: - post: - - npm run build diff --git a/config/wdio.conf.js b/config/wdio.conf.js index f0d33317..41fe910d 100644 --- a/config/wdio.conf.js +++ b/config/wdio.conf.js @@ -2,36 +2,36 @@ var webpack = require("webpack"); var WebpackDevServer = require("webpack-dev-server"); var webpackConfig = require("./webpack.production.config"); var testConfig = require("../test/config/specs"); +var artifacts = require("../test/artifacts"); +var isDocker = require("is-docker"); var server; +var SCREENSHOT_PATH = artifacts.pathSync("screenshots"); exports.config = { specs: [ - './test/specs/**/*.js' + './test/functional/advanced.js' ], exclude: [ ], maxInstances: 10, capabilities: [{ maxInstances: 5, - browserName: 'firefox' + browserName: 'chrome' }], sync: true, logLevel: 'verbose', coloredLogs: true, bail: 0, - screenshotPath: './errorShots/', + screenshotPath: SCREENSHOT_PATH, + host: (isDocker() ? process.env.DOCKER_HOST : "127.0.0.1"), baseUrl: 'http://localhost', waitforTimeout: 10000, connectionRetryTimeout: 90000, connectionRetryCount: 3, - services: ['phantomjs'], framework: 'mocha', reporters: ['spec'], - phantomjsOpts: { - webdriverLogfile: 'phantomjs.log' - }, mochaOpts: { ui: 'bdd', // Because we don't know how long the initial build will take... @@ -43,6 +43,6 @@ exports.config = { server.listen(testConfig.port); }, onComplete: function(exitCode) { - server.close(); + server.close() } } diff --git a/config/webpack.production.config.js b/config/webpack.production.config.js index 01a5c4e9..383bb7d5 100644 --- a/config/webpack.production.config.js +++ b/config/webpack.production.config.js @@ -1,4 +1,3 @@ - var webpack = require('webpack'); var path = require('path'); var loaders = require('./webpack.loaders'); @@ -7,14 +6,9 @@ var HtmlWebpackPlugin = require('html-webpack-plugin'); var WebpackCleanupPlugin = require('webpack-cleanup-plugin'); var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; var CopyWebpackPlugin = require('copy-webpack-plugin'); +var artifacts = require("../test/artifacts"); -var OUTPATH; -if(process.env.CIRCLE_ARTIFACTS) { - OUTPATH = path.join(process.env.CIRCLE_ARTIFACTS, "build"); -} -else { - OUTPATH = path.join(__dirname, '..', 'public'); -} +var OUTPATH = artifacts.pathSync("/build"); module.exports = { entry: { diff --git a/package-lock.json b/package-lock.json index f539a8f1..51652f84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -908,6 +908,17 @@ "babel-runtime": "6.26.0" } }, + "babel-plugin-istanbul": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.5.tgz", + "integrity": "sha1-Z2DN2Xf0EdPhdbsGTyvDJ9mbK24=", + "dev": true, + "requires": { + "find-up": "2.1.0", + "istanbul-lib-instrument": "1.9.1", + "test-exclude": "4.1.1" + } + }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", @@ -1879,6 +1890,45 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "cacache": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.1.tgz", + "integrity": "sha512-dRHYcs9LvG9cHgdPzjiI+/eS7e1xRhULrcyOx04RZQsszNJXU2SL9CyG60yLnge282Qq5nwTv+ieK2fH+WPZmA==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "chownr": "1.0.1", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lru-cache": "4.1.1", + "mississippi": "1.3.0", + "mkdirp": "0.5.1", + "move-concurrently": "1.0.1", + "promise-inflight": "1.0.1", + "rimraf": "2.6.2", + "ssri": "5.0.0", + "unique-filename": "1.1.0", + "y18n": "3.2.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, "call-matcher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", @@ -2069,6 +2119,12 @@ "readdirp": "2.1.0" } }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2238,9 +2294,9 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "codemirror": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.32.0.tgz", - "integrity": "sha512-95OxAlYiigW0g4n4ixFdavG07clJGILp3MvHh2pKR3FvyrTuHHvqtKSVbrV3/Jz6o0YqGvyCDLDTbH4h6ciaSw==" + "version": "5.33.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.33.0.tgz", + "integrity": "sha512-HT6PKVqkwpzwB3jl5hXFoQteEWXbSWMzG3Z8RVYlx8hZwCOLCy4NU7vkSB3dYX3e6ORwRfGw4uFOXaw4rn/a9Q==" }, "color": { "version": "2.0.1", @@ -2355,15 +2411,6 @@ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, "combined-stream": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", @@ -2536,6 +2583,20 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "1.2.0", + "fs-write-stream-atomic": "1.0.10", + "iferr": "0.1.5", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "run-queue": "1.0.3" + } + }, "copy-to-clipboard": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz", @@ -2545,19 +2606,37 @@ } }, "copy-webpack-plugin": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.2.3.tgz", - "integrity": "sha512-cL/Wl3Y1QmmKThl/mWeGB+HH3YH+25tn8nhqEGsZda4Yn7GqGnDZ+TbeKJ7A6zvrxyNhhuviYAxn/tCyyAqh8Q==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.3.1.tgz", + "integrity": "sha512-xlcFiW/U7KrpS6dFuWq3r8Wb7koJx7QVc7LDFCosqkikaVSxkaYOnwDLwilbjrszZ0LYZXThDAJKcQCSrvdShQ==", "dev": true, "requires": { - "bluebird": "3.5.1", - "glob": "7.1.2", + "cacache": "10.0.1", + "find-cache-dir": "1.0.0", + "globby": "7.1.1", "is-glob": "4.0.0", "loader-utils": "0.2.17", "lodash": "4.17.4", - "minimatch": "3.0.4" + "minimatch": "3.0.4", + "p-limit": "1.1.0", + "pify": "3.0.0", + "serialize-javascript": "1.4.0" }, "dependencies": { + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "1.0.2", + "dir-glob": "2.0.0", + "glob": "7.1.2", + "ignore": "3.3.7", + "pify": "3.0.0", + "slash": "1.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2597,6 +2676,16 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "dev": true, + "requires": { + "object-assign": "4.1.1", + "vary": "1.1.2" + } + }, "cosmiconfig": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", @@ -2672,6 +2761,16 @@ "sha.js": "2.4.9" } }, + "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" + } + }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", @@ -2992,6 +3091,12 @@ "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=" }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -3194,6 +3299,27 @@ "randombytes": "2.0.5" } }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "path-type": "3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + } + } + }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -3446,6 +3572,18 @@ } } }, + "duplexify": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "dev": true, + "requires": { + "end-of-stream": "1.4.0", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + } + }, "earcut": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.2.tgz", @@ -4543,6 +4681,16 @@ "vlq": "0.2.3" } }, + "flush-write-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz", + "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, "follow-redirects": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", @@ -4605,13 +4753,14 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=" }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { - "null-check": "1.0.0" + "inherits": "2.0.3", + "readable-stream": "2.3.3" } }, "fs-extra": { @@ -4624,6 +4773,18 @@ "universalify": "0.1.1" } }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "iferr": "0.1.5", + "imurmurhash": "0.1.4", + "readable-stream": "2.3.3" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4681,6 +4842,21 @@ "globule": "1.2.0" } }, + "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" + } + }, "geojson-area": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/geojson-area/-/geojson-area-0.1.0.tgz", @@ -5433,6 +5609,12 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", @@ -5676,6 +5858,12 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, + "is-docker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", + "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -5738,6 +5926,18 @@ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=" }, + "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-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", @@ -5809,6 +6009,12 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "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-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -5923,6 +6129,146 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.10", + "js-yaml": "3.7.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-coverage": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.9.1.tgz", + "integrity": "sha512-RQmXeQ7sphar7k7O1wTNzVczF9igKpaeGQAG9qR2L+BS4DCJNTI9nytRmIVYevwO0bbq+2CXvJmYDuz0gMrywA==", + "dev": true, + "requires": { + "babel-generator": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "istanbul-lib-coverage": "1.1.1", + "semver": "5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + } + } + }, "js-base64": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz", @@ -6134,6 +6480,12 @@ "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", "dev": true }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "dev": true + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -6166,325 +6518,6 @@ "resolved": "https://registry.npmjs.org/junk/-/junk-2.1.0.tgz", "integrity": "sha1-9DG0t/By3FAKXxDOf07HGTDnATQ=" }, - "karma": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz", - "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "body-parser": "1.18.2", - "chokidar": "1.7.0", - "colors": "1.1.2", - "combine-lists": "1.0.1", - "connect": "3.6.5", - "core-js": "2.5.1", - "di": "0.0.1", - "dom-serialize": "2.2.1", - "expand-braces": "0.1.2", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "http-proxy": "1.16.2", - "isbinaryfile": "3.0.2", - "lodash": "3.10.1", - "log4js": "0.6.38", - "mime": "1.3.4", - "minimatch": "3.0.4", - "optimist": "0.6.1", - "qjobs": "1.1.5", - "range-parser": "1.2.0", - "rimraf": "2.6.2", - "safe-buffer": "5.1.1", - "socket.io": "1.7.3", - "source-map": "0.5.7", - "tmp": "0.0.31", - "useragent": "2.2.1" - }, - "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "engine.io": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz", - "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "ws": "1.1.2" - } - }, - "engine.io-client": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz", - "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - }, - "socket.io": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz", - "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=", - "dev": true, - "requires": { - "debug": "2.3.3", - "engine.io": "1.8.3", - "has-binary": "0.1.7", - "object-assign": "4.1.0", - "socket.io-adapter": "0.5.0", - "socket.io-client": "1.7.3", - "socket.io-parser": "2.3.1" - } - }, - "socket.io-adapter": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz", - "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=", - "dev": true, - "requires": { - "debug": "2.3.3", - "socket.io-parser": "2.3.1" - } - }, - "socket.io-client": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz", - "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.3", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "dev": true, - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" - }, - "dependencies": { - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": "0.0.6", - "ultron": "1.0.2" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - } - } - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", - "dev": true, - "requires": { - "fs-access": "1.0.1", - "which": "1.3.0" - } - }, - "karma-firefox-launcher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.0.1.tgz", - "integrity": "sha1-zlj0fCATqIFW1VpdYTN8CZz1u1E=", - "dev": true - }, - "karma-mocha": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", - "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", - "dev": true, - "requires": { - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "karma-webpack": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.6.tgz", - "integrity": "sha512-dcKvtiW00caWrceCKwIvlKwHQu8zI+e3zWZYDLk7kr7nl1lYSp8uP+8fQoBvRCnZiPUGuwU5Psm20NbEIn7KlA==", - "dev": true, - "requires": { - "async": "0.9.2", - "loader-utils": "0.2.17", - "lodash": "3.10.1", - "source-map": "0.5.7", - "webpack-dev-middleware": "1.12.0" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, "kdbush": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz", @@ -6692,16 +6725,6 @@ "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" }, - "lodash._createcompounder": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz", - "integrity": "sha1-XdLLVTctbnDg4jkvsjBNZjEJEHU=", - "dev": true, - "requires": { - "lodash.deburr": "3.2.0", - "lodash.words": "3.2.0" - } - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", @@ -6713,12 +6736,6 @@ "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", "dev": true }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -6752,15 +6769,6 @@ "lodash._isiterateecall": "3.0.9" } }, - "lodash.deburr": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-3.2.0.tgz", - "integrity": "sha1-baj1QzSjZqfPTEx2742Aqhs2XtU=", - "dev": true, - "requires": { - "lodash._root": "3.0.1" - } - }, "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", @@ -6826,15 +6834,6 @@ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, - "lodash.words": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.words/-/lodash.words-3.2.0.tgz", - "integrity": "sha1-TiqGSbwIdFsXxpWxo86P7llmI7M=", - "dev": true, - "requires": { - "lodash._root": "3.0.1" - } - }, "log-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", @@ -7244,6 +7243,24 @@ "minipass": "2.2.1" } }, + "mississippi": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-1.3.0.tgz", + "integrity": "sha1-0gFYPrEjJ+PFwWQqQEqcrPlONPU=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "duplexify": "3.5.1", + "end-of-stream": "1.4.0", + "flush-write-stream": "1.0.2", + "from2": "2.3.0", + "parallel-transform": "1.1.0", + "pump": "1.0.3", + "pumpify": "1.3.5", + "stream-each": "1.2.2", + "through2": "2.0.3" + } + }, "mixin-object": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", @@ -7313,87 +7330,6 @@ } } }, - "mocha-loader": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/mocha-loader/-/mocha-loader-1.1.1.tgz", - "integrity": "sha1-Ocm3jErWmrxTPtAuLas5gkTKM6s=", - "dev": true, - "requires": { - "css-loader": "0.23.1", - "loader-utils": "1.1.0", - "script-loader": "0.7.2", - "style-loader": "0.13.2" - }, - "dependencies": { - "css-loader": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.23.1.tgz", - "integrity": "sha1-n6I/K1wJZSNZEK1ezvO4o2OQ/lA=", - "dev": true, - "requires": { - "css-selector-tokenizer": "0.5.4", - "cssnano": "3.10.0", - "loader-utils": "0.2.17", - "lodash.camelcase": "3.0.1", - "object-assign": "4.1.1", - "postcss": "5.2.18", - "postcss-modules-extract-imports": "1.1.0", - "postcss-modules-local-by-default": "1.2.0", - "postcss-modules-scope": "1.1.0", - "postcss-modules-values": "1.3.0", - "source-list-map": "0.1.8" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } - } - }, - "css-selector-tokenizer": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.5.4.tgz", - "integrity": "sha1-E5uv00o1/QwUKEhwSeBpnm9qLCE=", - "dev": true, - "requires": { - "cssesc": "0.1.0", - "fastparse": "1.1.1" - } - }, - "lodash.camelcase": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz", - "integrity": "sha1-kyyLh/ikN3iXxnGXUzKC+Xrqwpg=", - "dev": true, - "requires": { - "lodash._createcompounder": "3.0.0" - } - }, - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true - }, - "style-loader": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.13.2.tgz", - "integrity": "sha1-dFMzhM9pjHEEx5URULSXF63C87s=", - "dev": true, - "requires": { - "loader-utils": "1.1.0" - } - } - } - }, "mousetrap": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.1.tgz", @@ -7404,6 +7340,20 @@ "resolved": "https://registry.npmjs.org/mout/-/mout-1.0.0.tgz", "integrity": "sha1-m98dSvV9ZtR8s1OmM1oygQmOFQE=" }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "1.2.0", + "copy-concurrently": "1.0.5", + "fs-write-stream-atomic": "1.0.10", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "run-queue": "1.0.3" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7758,12 +7708,6 @@ "boolbase": "1.0.0" } }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", @@ -8079,6 +8023,17 @@ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "dev": true }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "0.2.2", + "inherits": "2.0.3", + "readable-stream": "2.3.3" + } + }, "param-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", @@ -9064,6 +9019,12 @@ "asap": "2.0.6" } }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, "prop-types": { "version": "15.6.0", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", @@ -9114,6 +9075,27 @@ "randombytes": "2.0.5" } }, + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "requires": { + "end-of-stream": "1.4.0", + "once": "1.4.0" + } + }, + "pumpify": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz", + "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=", + "dev": true, + "requires": { + "duplexify": "3.5.1", + "inherits": "2.0.3", + "pump": "1.0.3" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -9124,12 +9106,6 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" }, - "qjobs": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.1.5.tgz", - "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=", - "dev": true - }, "qs": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", @@ -9276,12 +9252,6 @@ "unpipe": "1.0.0" } }, - "raw-loader": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true - }, "rbush": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.1.tgz", @@ -9291,10 +9261,11 @@ } }, "react": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz", - "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=", + "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", @@ -9360,9 +9331,9 @@ "dev": true }, "react-dom": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.0.tgz", - "integrity": "sha1-nMMHnD3NcNTG4BuEqrKn40wwP1g=", + "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", @@ -10329,6 +10300,15 @@ "is-promise": "2.1.0" } }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "1.2.0" + } + }, "rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", @@ -10448,15 +10428,6 @@ } } }, - "script-loader": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/script-loader/-/script-loader-0.7.2.tgz", - "integrity": "sha512-UMNLEvgOAQuzK8ji8qIscM3GIrRCWN6MmMXGD4SD5l6cSycgGsCo0tX5xRnfQcoghqct0tjHjcykgI1PyBE2aA==", - "dev": true, - "requires": { - "raw-loader": "0.5.1" - } - }, "scss-tokenizer": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", @@ -10489,6 +10460,111 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, + "selenium-standalone": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/selenium-standalone/-/selenium-standalone-6.11.0.tgz", + "integrity": "sha512-MedSwbiyLkv/nxr7JpI9zFNSAmSDpcz+bCaVSJC1krXYeIzFuj6tKMMss57xwu4VHgfInTy3IIMM2HdjN87xXQ==", + "dev": true, + "requires": { + "async": "2.5.0", + "commander": "2.11.0", + "cross-spawn": "5.1.0", + "debug": "2.6.9", + "lodash": "4.17.4", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "progress": "1.1.8", + "request": "2.79.0", + "tar-stream": "1.5.2", + "urijs": "1.19.0", + "which": "1.3.0", + "yauzl": "2.9.1" + }, + "dependencies": { + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.16.1", + "pinkie-promise": "2.0.1" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.6.0", + "caseless": "0.11.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "qs": "6.3.2", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.4.3", + "uuid": "3.1.0" + } + }, + "tar-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.2.tgz", + "integrity": "sha1-+8bG6DwaGdTLSMfZYXH8JI7/x78=", + "dev": true, + "requires": { + "bl": "1.2.1", + "end-of-stream": "1.4.0", + "readable-stream": "2.3.3", + "xtend": "4.0.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + } + } + }, "selfsigned": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz", @@ -10543,6 +10619,12 @@ "upper-case-first": "1.1.2" } }, + "serialize-javascript": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz", + "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=", + "dev": true + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -11099,6 +11181,15 @@ } } }, + "ssri": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.0.0.tgz", + "integrity": "sha512-728D4yoQcQm1ooZvSbywLkV1RjfITZXh0oWrhM/lnsx3nAHx7LsRGJWB/YyvoceAYRq98xqbstiN4JBv1/wNHg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "stackframe": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", @@ -11241,6 +11332,16 @@ "through": "2.3.8" } }, + "stream-each": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", + "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "dev": true, + "requires": { + "end-of-stream": "1.4.0", + "stream-shift": "1.0.0" + } + }, "stream-http": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", @@ -11254,6 +11355,12 @@ "xtend": "4.0.1" } }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -11745,6 +11852,19 @@ } } }, + "test-exclude": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "2.3.11", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12126,6 +12246,24 @@ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", "dev": true }, + "unique-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", + "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "dev": true, + "requires": { + "unique-slug": "2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", + "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, + "requires": { + "imurmurhash": "0.1.4" + } + }, "universalify": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", @@ -12151,6 +12289,12 @@ "upper-case": "1.1.3" } }, + "urijs": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.0.tgz", + "integrity": "sha512-Qs2odXn0hST5VSPVjpi73CMqtbAoanahaqWBujGU+IyMrMqpWcIhDewxQRhCkmqYxuyvICDcSuLdv2O7ncWBGw==", + "dev": true + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -12459,6 +12603,49 @@ "phantomjs-prebuilt": "2.1.16" } }, + "wdio-selenium-standalone-service": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/wdio-selenium-standalone-service/-/wdio-selenium-standalone-service-0.0.9.tgz", + "integrity": "sha1-yA1P9Il0TVoLkdUYl2SRbUwMhWQ=", + "dev": true, + "requires": { + "fs-extra": "0.30.0", + "selenium-standalone": "6.11.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + } + } + }, "wdio-spec-reporter": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/wdio-spec-reporter/-/wdio-spec-reporter-0.1.2.tgz", @@ -13170,6 +13357,16 @@ } } }, + "yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + }, "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", diff --git a/package.json b/package.json index c358b4b7..ba5d9e03 100644 --- a/package.json +++ b/package.json @@ -39,14 +39,14 @@ "ol-mapbox-style": "^1.0.1", "openlayers": "^4.4.2", "prop-types": "^15.6.0", - "react": "16.0.0", + "react": "^15.6.2", "react-addons-pure-render-mixin": "^15.6.2", "react-autocomplete": "^1.7.2", "react-codemirror2": "^3.0.7", "react-collapse": "^4.0.3", "react-color": "^2.13.8", "react-copy-to-clipboard": "^5.0.1", - "react-dom": "16.0.0", + "react-dom": "^15.6.2", "react-file-reader-input": "^1.1.4", "react-height": "^3.0.0", "react-icon-base": "^2.1.1", @@ -90,6 +90,7 @@ "babel-core": "^6.26.0", "babel-eslint": "^8.0.2", "babel-loader": "7.1.1", + "babel-plugin-istanbul": "^4.1.5", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-flow-strip-types": "^6.22.0", @@ -97,34 +98,38 @@ "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.24.1", + "babel-register": "^6.26.0", "babel-runtime": "^6.26.0", "base64-loader": "^1.0.0", "copy-webpack-plugin": "^4.2.0", + "cors": "^2.8.4", "css-loader": "^0.28.7", "eslint": "^4.10.0", "eslint-plugin-react": "^7.4.0", + "express": "^4.16.2", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", + "is-docker": "^1.1.0", + "istanbul": "^0.4.5", + "istanbul-lib-coverage": "^1.1.1", "json-loader": "^0.5.7", - "karma": "^1.7.1", - "karma-chrome-launcher": "^2.2.0", - "karma-firefox-launcher": "^1.0.1", - "karma-mocha": "^1.3.0", - "karma-webpack": "^2.0.5", + "mkdirp": "^0.5.1", "mocha": "^4.0.1", - "mocha-loader": "^1.1.1", "node-sass": "^4.6.0", "react-hot-loader": "^3.1.1", "sass-loader": "^6.0.6", + "selenium-standalone": "^6.11.0", "style-loader": "^0.19.0", "stylelint": "^7.13.0", "stylelint-config-standard": "^15.0.1", "transform-loader": "^0.2.4", + "uuid": "^3.1.0", "wdio-mocha-framework": "^0.5.11", "wdio-phantomjs-service": "^0.2.2", + "wdio-selenium-standalone-service": "0.0.9", "wdio-spec-reporter": "^0.1.2", - "webdriverio": "^4.8.0", + "webdriverio": "^4.9.8", "webpack": "^3.8.1", "webpack-bundle-analyzer": "^2.9.0", "webpack-cleanup-plugin": "^0.5.1", diff --git a/src/components/App.jsx b/src/components/App.jsx index d51f7248..cd74f747 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -20,6 +20,7 @@ import { RevisionStore } from '../libs/revisions' import LayerWatcher from '../libs/layerwatcher' import tokens from '../config/tokens.json' import isEqual from 'lodash.isequal' +import Debug from '../libs/debug' function updateRootSpec(spec, fieldName, newValues) { return { @@ -53,9 +54,19 @@ export default class App extends React.Component { this.styleStore = new StyleStore() } this.styleStore.latestStyle(mapStyle => this.onStyleChanged(mapStyle)) + + if(Debug.enabled()) { + Debug.set("maputnik", "styleStore", this.styleStore); + Debug.set("maputnik", "revisionStore", this.revisionStore); + } }) } + if(Debug.enabled()) { + Debug.set("maputnik", "revisionStore", this.revisionStore); + Debug.set("maputnik", "styleStore", this.styleStore); + } + this.state = { errors: [], infos: [], @@ -70,22 +81,28 @@ export default class App extends React.Component { this.layerWatcher = new LayerWatcher({ onVectorLayersChange: v => this.setState({ vectorLayers: v }) }) + + this.onKeyDown = this.onKeyDown.bind(this); + } + + onKeyDown(e) { + console.log("??? keyCode ctrlKey="+e.ctrlKey+", keyCode="+e.keyCode) + // Control + Z + if(e.ctrlKey && e.keyCode === 90) { + this.onUndo(e); + } + else if(e.ctrlKey && e.keyCode === 89) { + this.onRedo(e); + } } componentDidMount() { this.fetchSources(); - Mousetrap.bind(['ctrl+z'], this.onUndo.bind(this)); - Mousetrap.bind(['ctrl+y'], this.onRedo.bind(this)); + document.addEventListener("keydown", this.onKeyDown); } componentWillUnmount() { - Mousetrap.unbind(['ctrl+z'], this.onUndo.bind(this)); - Mousetrap.unbind(['ctrl+y'], this.onRedo.bind(this)); - } - - onReset() { - this.styleStore.purge() - loadDefaultStyle(mapStyle => this.onStyleOpen(mapStyle)) + document.removeEventListener("keydown", this.onKeyDown); } saveStyle(snapshotStyle) { diff --git a/src/components/Button.jsx b/src/components/Button.jsx index d87b8517..b1189c17 100644 --- a/src/components/Button.jsx +++ b/src/components/Button.jsx @@ -4,6 +4,7 @@ import classnames from 'classnames' class Button extends React.Component { static propTypes = { + "data-wd-key": PropTypes.string, onClick: PropTypes.func, style: PropTypes.object, className: PropTypes.string, @@ -14,6 +15,7 @@ class Button extends React.Component { return {this.props.children} diff --git a/src/components/Toolbar.jsx b/src/components/Toolbar.jsx index 6b30fb51..14fa0d13 100644 --- a/src/components/Toolbar.jsx +++ b/src/components/Toolbar.jsx @@ -63,6 +63,7 @@ class ToolbarAction extends React.Component { render() { return {this.props.children} @@ -139,23 +140,23 @@ export default class Toolbar extends React.Component {

Maputnik

- + Open - + Export - + Sources - + Style Settings - + { this.props.inspectModeEnabled && Map Mode } diff --git a/src/components/fields/FunctionSpecField.jsx b/src/components/fields/FunctionSpecField.jsx index 9772a33d..981bb1c9 100644 --- a/src/components/fields/FunctionSpecField.jsx +++ b/src/components/fields/FunctionSpecField.jsx @@ -131,8 +131,7 @@ export default class FunctionSpecProperty extends React.Component { /> ) } - - return
+ return
{specField}
} diff --git a/src/components/fields/SpecField.jsx b/src/components/fields/SpecField.jsx index 00796ef4..38c5675f 100644 --- a/src/components/fields/SpecField.jsx +++ b/src/components/fields/SpecField.jsx @@ -58,70 +58,79 @@ export default class SpecField extends React.Component { name: this.props.fieldName, onChange: newValue => this.props.onChange(this.props.fieldName, newValue) } - switch(this.props.fieldSpec.type) { - case 'number': return ( - - ) - case 'enum': - const options = Object.keys(this.props.fieldSpec.values).map(v => [v, capitalize(v)]) - if(options.length <= 3 && optionsLabelLength(options) <= 20) { - return - } else { - return - } - case 'string': - if(iconProperties.indexOf(this.props.fieldName) >= 0) { - return - } else { - return - } - case 'color': return ( - - ) - case 'boolean': return ( - - ) - case 'array': - if(this.props.fieldName === 'text-font') { - return - } else { - if (this.props.fieldSpec.length) { - return [v, capitalize(v)]) + + if(options.length <= 3 && optionsLabelLength(options) <= 20) { + return } else { - return } - } - default: return null + case 'string': + if(iconProperties.indexOf(this.props.fieldName) >= 0) { + return + } else { + return + } + case 'color': return ( + + ) + case 'boolean': return ( + + ) + case 'array': + if(this.props.fieldName === 'text-font') { + return + } else { + if (this.props.fieldSpec.length) { + return + } else { + return + } + } + default: return null + } } + + return ( +
+ {childNodes.call(this)} +
+ ); } } diff --git a/src/components/filter/FilterEditor.jsx b/src/components/filter/FilterEditor.jsx index 73cb2f13..02ee2a40 100644 --- a/src/components/filter/FilterEditor.jsx +++ b/src/components/filter/FilterEditor.jsx @@ -89,7 +89,7 @@ export default class CombiningFilterEditor extends React.Component { } return
-
+
diff --git a/src/components/modals/ExportModal.jsx b/src/components/modals/ExportModal.jsx index 13718357..d8b2a742 100644 --- a/src/components/modals/ExportModal.jsx +++ b/src/components/modals/ExportModal.jsx @@ -5,7 +5,6 @@ import { saveAs } from 'file-saver' import styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec' import InputBlock from '../inputs/InputBlock' import StringInput from '../inputs/StringInput' -import SelectInput from '../inputs/SelectInput' import CheckboxInput from '../inputs/CheckboxInput' import Button from '../Button' import Modal from './Modal' @@ -215,6 +214,7 @@ class ExportModal extends React.Component { render() { return -
+

{this.props.title}

this.props.onOpenToggle(false)} + data-wd-key={this.props["data-wd-key"]+".close-modal"} > diff --git a/src/components/modals/OpenModal.jsx b/src/components/modals/OpenModal.jsx index bcd1ba8a..4ce76f56 100644 --- a/src/components/modals/OpenModal.jsx +++ b/src/components/modals/OpenModal.jsx @@ -133,6 +133,7 @@ class OpenModal extends React.Component { } return this.onOpenToggle()} title={'Open Style'} @@ -151,9 +152,9 @@ class OpenModal extends React.Component {

Load from a URL. Note that the URL must have CORS enabled.

- this.styleUrlElement = input} className="maputnik-input" placeholder="Enter URL..."/> + this.styleUrlElement = input} className="maputnik-input" placeholder="Enter URL..."/>
- +
diff --git a/src/components/modals/SettingsModal.jsx b/src/components/modals/SettingsModal.jsx index ef50ad26..941a8189 100644 --- a/src/components/modals/SettingsModal.jsx +++ b/src/components/modals/SettingsModal.jsx @@ -42,6 +42,7 @@ class SettingsModal extends React.Component { const metadata = this.props.mapStyle.metadata || {} const inputProps = { } return @@ -68,6 +72,7 @@ class SettingsModal extends React.Component { @@ -75,6 +80,7 @@ class SettingsModal extends React.Component { @@ -82,6 +88,7 @@ class SettingsModal extends React.Component { @@ -89,6 +96,7 @@ class SettingsModal extends React.Component { + */ +try { +browser.addCommand('setValueSafe', function(selector, text) { + for(var i=0; i<10; i++) { + console.log(">>>> waiting for visible"); + browser.waitForVisible(selector); + + var elements = browser.elements(selector); + if(elements.length > 1) { + console.error(">>> Too many elements found"); + throw "Too many elements found"; + } + + console.log(">>>> setting value"); + browser.setValue(selector, text); + var browserText = browser.getValue(selector); + + console.log("browserText='%s' test='%s'", browserText, text); + + if(browserText == text) { + return; + } + else { + console.error("Warning: setValue failed, trying again"); + } + } + + // Wait for change events to fire and state updated + browser.flushReactUpdates(); +}) + +browser.addCommand('takeScreenShot', function(filepath) { + var data = browser.screenshot(); + fs.writeFileSync(path.join(SCREENSHOTS_PATH, filepath), data.value, 'base64'); +}); + +browser.addCommand('flushReactUpdates', function() { + browser.executeAsync(function(done) { + // For any events to propogate + setImmediate(function() { + // For the DOM to be updated. + setImmediate(done); + }) + }) +}) + +} catch(err) { + console.error(err); +} + +describe('maputnik', function() { + var geoserver; + + before(function(done) { + // Start style server + geoserver = geoServer.listen(9002, done); + }); + + function getStyleStore(browser) { + var result = browser.executeAsync(function(done) { + window.debug.get("maputnik", "styleStore").latestStyle(done); + }) + return result.value; + } + + function getRevisionStore(browser) { + var result = browser.execute(function(done) { + var rs = window.debug.get("maputnik", "revisionStore") + + return { + currentIdx: rs.currentIdx, + revisions: rs.revisions + }; + }) + return result.value; + } + + function getStyleUrl(styles) { + var port = geoserver.address().port; + return "http://localhost:"+port+"/styles/empty/"+styles.join(","); + } + + function getGeoServerUrl(urlPath) { + var port = geoserver.address().port; + return "http://localhost:"+port+"/"+urlPath; + } + + beforeEach(function() { + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example", + "raster:raster" + ])); + browser.waitForExist(".maputnik-toolbar-link"); + browser.flushReactUpdates(); + }); + + it('check logo exists', function () { + var src = browser.getAttribute(".maputnik-toolbar-link img", "src"); + assert.equal(src, config.baseUrl+'/img/logo-color.svg'); + }); + + function closeModal(wdKey) { + console.log(">> A"); + browser.waitUntil(function() { + return browser.isVisibleWithinViewport(wd.$(wdKey)); + }); + + console.log(">> B"); + var closeBtnSelector = wd.$(wdKey+".close-modal"); + browser.click(closeBtnSelector); + + console.log(">> C"); + browser.waitUntil(function() { + return !browser.isVisibleWithinViewport(wd.$(wdKey)); + }); + } + + describe("modal", function() { + describe("open", function() { + var styleFilePath = __dirname+"/../example-style.json"; + var styleFileData = JSON.parse(fs.readFileSync(styleFilePath)); + + beforeEach(function() { + browser.url(config.baseUrl+"?debug"); + + browser.waitForExist(".maputnik-toolbar-link"); + browser.flushReactUpdates(); + + browser.click(wd.$("nav:open")) + browser.flushReactUpdates(); + }); + + it("close", function() { + closeModal("open-modal"); + }); + + it("upload", function() { + browser.waitForExist("*[type='file']") + browser.chooseFile("*[type='file']", styleFilePath); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.deepEqual(styleFileData, styleObj); + }); + + it("load from url", function() { + var styleFileUrl = getGeoServerUrl("example-style.json"); + + browser.setValueSafe(wd.$("open-modal.url.input"), styleFileUrl); + + var selector = wd.$("open-modal.url.button"); + console.log("selector", selector); + browser.click(selector); + + // Allow the network request to happen + // NOTE: Its localhost so this should be fast. + browser.pause(300); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + console.log("styleFileData", styleFileData); + assert.deepEqual(styleFileData, styleObj); + }); + + // TODO: Need to work out how to mock out the end points + it("gallery") + }) + + describe("export", function() { + + beforeEach(function() { + browser.url(config.baseUrl+"?debug"); + + browser.waitForExist(".maputnik-toolbar-link"); + browser.flushReactUpdates(); + + browser.click(wd.$("nav:export")) + browser.flushReactUpdates(); + }); + + it("close", function() { + closeModal("export-modal"); + }); + + // TODO: Work out how to download a file and check the contents + it("download") + // TODO: Work out how to mock the end git points + it("save to gist") + }) + + describe("sources", function() { + it("active sources") + it("public source") + it("add new source") + }) + + describe("inspect", function() { + it("toggle", function() { + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example" + ])); + + browser.click(wd.$("nav:inspect")); + }) + }) + + describe("style settings", function() { + beforeEach(function() { + browser.url(config.baseUrl+"?debug"); + + browser.waitForExist(".maputnik-toolbar-link"); + browser.flushReactUpdates(); + + browser.click(wd.$("nav:settings")) + browser.flushReactUpdates(); + }); + + it("name", function() { + browser.setValueSafe(wd.$("modal-settings.name"), "foobar") + browser.click(wd.$("modal-settings.owner")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.name, "foobar"); + }) + it("owner", function() { + browser.setValueSafe(wd.$("modal-settings.owner"), "foobar") + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.owner, "foobar"); + }) + it("sprite url", function() { + browser.setValueSafe(wd.$("modal-settings.sprite"), "http://example.com") + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.sprite, "http://example.com"); + }) + it("glyphs url", function() { + var glyphsUrl = "http://example.com/{fontstack}/{range}.pbf" + browser.setValueSafe(wd.$("modal-settings.glyphs"), glyphsUrl) + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.glyphs, glyphsUrl); + }) + + it("mapbox access token", function() { + var apiKey = "testing123"; + browser.setValueSafe(wd.$("modal-settings.maputnik:mapbox_access_token"), apiKey); + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + browser.waitUntil(function() { + return styleObj.metadata["maputnik:mapbox_access_token"] == apiKey; + }) + }) + + it("open map tiles access token", function() { + var apiKey = "testing123"; + browser.setValueSafe(wd.$("modal-settings.maputnik:openmaptiles_access_token"), apiKey); + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.metadata["maputnik:openmaptiles_access_token"], apiKey); + }) + + it("style renderer", function() { + var selector = wd.$("modal-settings.maputnik:renderer"); + browser.selectByValue(selector, "ol3"); + browser.click(wd.$("modal-settings.name")) + browser.flushReactUpdates(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.equal(styleObj.metadata["maputnik:renderer"], "ol3"); + }) + }) + + describe("sources", function() { + it("toggle") + }) + }) + + describe.skip("zoom level", function() { + it("via url", function() { + var zoomLevel = "12.37" + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example" + ])+"#"+zoomLevel+"/41.3805/2.1635"); + + browser.waitUntil(function () { + return ( + browser.isVisible(".mapboxgl-ctrl-zoom") + && browser.getText(".mapboxgl-ctrl-zoom") === "Zoom level: "+(zoomLevel) + ); + }, 10*1000) + }) + it("via map controls", function() { + var zoomLevel = 12.37; + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example" + ])+"#"+zoomLevel+"/41.3805/2.1635"); + + browser.click(".mapboxgl-ctrl-zoom-in") + browser.waitUntil(function () { + var text = browser.getText(".mapboxgl-ctrl-zoom") + return text === "Zoom level: "+(zoomLevel+1); + }, 10*1000) + }) + }) + + describe.skip("groups", function() { + it("simple", function() { + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example" + ])); + + modelCommands.addLayer.open(); + var aId = modelCommands.addLayer.fill({ + id: "foo", + type: "background" + }) + + modelCommands.addLayer.open(); + var bId = modelCommands.addLayer.fill({ + id: "foo_bar", + type: "background" + }) + + modelCommands.addLayer.open(); + var bId = modelCommands.addLayer.fill({ + id: "foo_baz", + type: "background" + }) + + browser.waitForExist(wd.$("layer-list-group:foo-0")); + + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo")), false); + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo_bar")), false); + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo_baz")), false); + + browser.click(wd.$("layer-list-group:foo-0")); + + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo")), true); + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo_bar")), true); + assert.equal(browser.isVisibleWithinViewport(wd.$("layer-list-item:foo_baz")), true); + }) + }) + + describe.skip("history", function() { + /** + * See + */ + it("undo/redo", function() { + var styleObj; + + browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + "geojson:example" + ])); + + modelCommands.addLayer.open(); + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, []); + + modelCommands.addLayer.fill({ + id: "step 1", + type: "background" + }) + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": "step 1", + "type": 'background' + } + ]); + + modelCommands.addLayer.open(); + modelCommands.addLayer.fill({ + id: "step 2", + type: "background" + }) + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": "step 1", + "type": 'background' + }, + { + "id": "step 2", + "type": 'background' + } + ]); + + console.log(">>> LOGS", JSON.stringify(browser.log("browser"), null, 2)) + + browser + .keys(['Control', 'z']) + .keys(['Control']); + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": "step 1", + "type": 'background' + } + ]); + + console.log(">>> LOGS", JSON.stringify(browser.log("browser"), null, 2)) + + browser + .keys(['Control', 'z']) + .keys(['Control']); + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + ]); + + console.log(">>> LOGS", JSON.stringify(browser.log("browser"), null, 2)) + + browser + .keys(['Control', 'y']) + .keys(['Control']); + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": "step 1", + "type": 'background' + } + ]); + + console.log(">>> LOGS", JSON.stringify(browser.log("browser"), null, 2)) + + browser + .keys(['Control', 'y']) + .keys(['Control']); + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": "step 1", + "type": 'background' + }, + { + "id": "step 2", + "type": 'background' + } + ]); + + console.log(">>> LOGS", JSON.stringify(browser.log("browser"), null, 2)) + }); + }) + + describe("layers", function() { + beforeEach(function() { + modelCommands.addLayer.open(); + }); + + describe("ops", function() { + it("delete", function() { + var styleObj; + var id = modelCommands.addLayer.fill({ + type: "background" + }) + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'background' + }, + ]); + + browser.click(wd.$("layer-list-item:"+id+":delete", "")); + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + ]); + }); + + it("duplicate", function() { + var styleObj; + var id = modelCommands.addLayer.fill({ + type: "background" + }) + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'background' + }, + ]); + + browser.click(wd.$("layer-list-item:"+id+":copy", "")); + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id+"-copy", + "type": "background" + }, + { + "id": id, + "type": "background" + }, + ]); + }); + + it("hide", function() { + var styleObj; + var id = modelCommands.addLayer.fill({ + type: "background" + }) + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'background' + }, + ]); + + browser.click(wd.$("layer-list-item:"+id+":toggle-visibility", "")); + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "background", + "layout": { + "visibility": "none" + } + }, + ]); + + browser.click(wd.$("layer-list-item:"+id+":toggle-visibility", "")); + + styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "background", + "layout": { + "visibility": "visible" + } + }, + ]); + }) + }) + + describe("grouped", function() { + it("with underscore") + it("no without underscore") + it("double underscore only grouped once") + }) + + describe("tooltips", function() { + }) + + describe("help", function() { + }) + + + describe('background', function () { + + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "background" + }) + + browser.waitUntil(function() { + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'background' + } + ]); + }); + }); + + describe("modify", function() { + function createBackground() { + // Setup + var id = uuid(); + + browser.selectByValue(wd.$("add-layer.layer-type", "select"), "background"); + browser.flushReactUpdates(); + browser.setValueSafe(wd.$("add-layer.layer-id", "input"), "background:"+id); + + browser.click(wd.$("add-layer")); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": 'background:'+id, + "type": 'background' + } + ]); + return id; + } + + // ====> THESE SHOULD BE FROM THE SPEC + describe("layer", function() { + it("expand/collapse"); + it("id", function() { + var bgId = createBackground(); + + browser.click(wd.$("layer-list-item:background:"+bgId)) + + var id = uuid(); + browser.setValueSafe(wd.$("layer-editor.layer-id", "input"), "foobar:"+id) + browser.click(wd.$("min-zoom")) + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": 'foobar:'+id, + "type": 'background' + } + ]); + }); + + // NOTE: This needs to be removed from the code + it("type"); + + it("min-zoom", function() { + var bgId = createBackground(); + + browser.click(wd.$("layer-list-item:background:"+bgId)) + browser.setValueSafe(wd.$("min-zoom", "input"), 1) + browser.click(wd.$("layer-editor.layer-id", "input")); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.deepEqual(styleObj.layers, [ + { + "id": 'background:'+bgId, + "type": 'background', + "minzoom": 1 + } + ]); + + // AND RESET! + // browser.setValueSafe(wd.$("min-zoom", "input"), "") + // browser.click(wd.$("max-zoom", "input")); + + // var styleObj = getStyleStore(browser); + // console.log("styleObj", styleObj); + + // assert.deepEqual(styleObj.layers, [ + // { + // "id": 'background:'+bgId, + // "type": 'background' + // } + // ]); + }); + + it("max-zoom", function() { + var bgId = createBackground(); + + browser.click(wd.$("layer-list-item:background:"+bgId)) + browser.setValueSafe(wd.$("max-zoom", "input"), 1) + browser.click(wd.$("layer-editor.layer-id", "input")); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.deepEqual(styleObj.layers, [ + { + "id": 'background:'+bgId, + "type": 'background', + "maxzoom": 1 + } + ]); + }); + + it("comments", function() { + var bgId = createBackground(); + var id = uuid(); + + browser.click(wd.$("layer-list-item:background:"+bgId)); + browser.setValueSafe(wd.$("layer-comment", "textarea"), id); + browser.click(wd.$("layer-editor.layer-id", "input")); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.deepEqual(styleObj.layers, [ + { + "id": 'background:'+bgId, + "type": 'background', + metadata: { + 'maputnik:comment': id + } + } + ]); + + // Unset it again. + // TODO: This fails + // browser.setValueSafe(wd.$("layer-comment", "textarea"), ""); + // browser.click(wd.$("min-zoom", "input")); + // browser.flushReactUpdates(); + + // var styleObj = getStyleStore(browser); + // console.log("styleObj", styleObj); + // assert.deepEqual(styleObj.layers, [ + // { + // "id": 'background:'+bgId, + // "type": 'background' + // } + // ]); + }); + + it("color", null, function() { + var bgId = createBackground(); + var id = uuid(); + + browser.click(wd.$("layer-list-item:background:"+bgId)); + + browser.click(wd.$("spec-field:background-color", "input")) + // browser.debug(); + + var styleObj = getStyleStore(browser); + console.log("styleObj", styleObj); + assert.deepEqual(styleObj.layers, [ + { + "id": 'background:'+bgId, + "type": 'background' + } + ]); + + }) + }) + + describe("filter", function() { + it("expand/collapse"); + it("compound filter"); + }) + + describe("paint", function() { + it("expand/collapse"); + it("color"); + it("pattern"); + it("opacity"); + }) + // <===== + + describe("json-editor", function() { + it("expand/collapse"); + it("modify"); + + // TODO + it.skip("parse error", function() { + var bgId = createBackground(); + var id = uuid(); + + browser.click(wd.$("layer-list-item:background:"+bgId)); + + var errorSelector = ".CodeMirror-lint-marker-error"; + assert.equal(browser.isExisting(errorSelector), false); + + browser.click(".CodeMirror") + browser.keys("\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013\uE013 {"); + browser.waitForExist(errorSelector) + + browser.click(wd.$("layer-editor.layer-id")); + }); + }); + }) + }); + + describe('fill', function () { + it.skip("add", function() { + // browser.debug(); + + var id = modelCommands.addLayer.fill({ + type: "fill", + layer: "example" + }); + + var styleObj = getStyleStore(browser); + console.log("STYLEOBJ", styleObj); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'fill', + "source": "example" + } + ]); + }) + + // TODO: Change source + it("change source") + }); + + describe('line', function () { + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "line", + layer: "example" + }); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "line", + "source": "example", + } + ]); + }); + + it("groups", null, function() { + // TODO + // Click each of the layer groups. + }) + }); + + describe('symbol', function () { + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "symbol", + layer: "example" + }); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "symbol", + "source": "example", + } + ]); + }); + }); + + describe('raster', function () { + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "raster", + layer: "raster" + }); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "raster", + "source": "raster", + } + ]); + }); + }); + + describe('circle', function () { + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "circle", + layer: "example" + }); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": "circle", + "source": "example", + } + ]); + }); + + }); + + describe('fill extrusion', function () { + it.skip("add", function() { + var id = modelCommands.addLayer.fill({ + type: "fill-extrusion", + layer: "example" + }); + + var styleObj = getStyleStore(browser); + assert.deepEqual(styleObj.layers, [ + { + "id": id, + "type": 'fill-extrusion', + "source": "example" + } + ]); + }); + }); + + // These get used in the marketing material. They are also useful to do a quick manual check of the styling across browsers + // NOTE: These duplicate some of the tests, however this is indended becuase it's likely these will change for aesthetic reasons over time + }); + + // describe('screenshots', function() { + + // beforeEach(function() { + // browser.windowHandleSize({ + // width: 1280, + // height: 800 + // }); + // }) + + // it("front_page", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/front_page.png") + // }) + + // it("open", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.click(wd.$("nav:open")) + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/open.png") + // }) + + // it("export", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.click(wd.$("nav:export")) + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/export.png") + // }) + + // it("sources", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.click(wd.$("nav:sources")) + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/sources.png") + // }) + + // it("style settings", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.click(wd.$("nav:settings")) + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/settings.png") + // }) + + // it("inspect", function() { + // browser.url(config.baseUrl+"?debug&style="+getStyleUrl([ + // "geojson:example" + // ])); + // browser.waitForExist(".maputnik-toolbar-link"); + // browser.flushReactUpdates(); + + // browser.click(wd.$("nav:inspect")) + // browser.flushReactUpdates(); + + // browser.takeScreenShot("/inspect.png") + // }) + // }) + + var coverage = istanbulCov.createCoverageMap({}); + + afterEach(function() { + // Code coverage + var results = browser.execute(function() { + return window.__coverage__; + }); + + coverage.merge(results.value); + }) + + after(function() { + var jsonStr = JSON.stringify(coverage, null, 2); + fs.writeFileSync(COVERAGE_PATH+"/coverage.json", jsonStr); + }) + +}); + diff --git a/test/geojson-server.js b/test/geojson-server.js new file mode 100644 index 00000000..cac65e11 --- /dev/null +++ b/test/geojson-server.js @@ -0,0 +1,93 @@ +const cors = require("cors"); +const express = require("express"); +const fs = require("fs"); +const sourceData = require("./sources"); + + +var app = express(); + +app.use(cors()); + + +function buildStyle(opts) { + opts = opts || {}; + opts = Object.assign({ + sources: {} + }, opts); + + return { + "id": "test-style", + "version": 8, + "name": "Test Style", + "metadata": { + "maputnik:renderer": "mbgljs" + }, + "sources": opts.sources, + "glyphs": "https://demo.tileserver.org/fonts/{fontstack}/{range}.pbf", + "sprites": "https://demo.tileserver.org/fonts/{fontstack}/{range}.pbf", + "layers": [] + } +} + +function buildGeoJSONSource(data) { + return { + type: "vector", + data: data + }; +} + +function buildResterSource(req, key) { + return { + "tileSize": 256, + "tiles": [ + req.protocol + '://' + req.get('host') + "/" + key + "/{x}/{y}/{z}" + ], + "type": "raster" + }; +} + + +app.get("/sources/raster/{x}/{y}/{z}", function(req, res) { + res.status(404).end(); +}) + +app.get("/styles/empty/:sources", function(req, res) { + var reqSources = req.params.sources.split(","); + + var sources = {}; + // reqSources.forEach(function(key) { + // sources[key] = buildGeoJSONSource(sourceData[key]); + // }); + reqSources.forEach(function(key) { + var parts = key.split(":"); + var type = parts[0]; + var key = parts[1]; + + if(type === "geojson") { + sources[key] = buildGeoJSONSource(sourceData[key]); + } + else if(type === "raster") { + sources[key] = buildResterSource(req, key); + } + else { + console.error("ERR: Invalid type: %s", type); + throw "Invalid type" + } + }); + + var json = buildStyle({ + sources: sources + }); + res.send(json); +}) + +app.get("/example-style.json", function(req, res) { + res.json( + JSON.parse( + fs.readFileSync(__dirname+"/example-style.json").toString() + ) + ); +}) + + +module.exports = app; diff --git a/test/sources/example.json b/test/sources/example.json new file mode 100644 index 00000000..43246f9b --- /dev/null +++ b/test/sources/example.json @@ -0,0 +1,15 @@ +{ + "type":"FeatureCollection", + "features":[ + { + "type":"Feature", + "properties": { + "name": "Dinagat Islands" + }, + "geometry":{ + "type": "Point", + "coordinates": [125.6, 10.1] + } + } + ] +} diff --git a/test/sources/index.js b/test/sources/index.js new file mode 100644 index 00000000..894cce78 --- /dev/null +++ b/test/sources/index.js @@ -0,0 +1,3 @@ +module.exports = { + example: require("./example") +}; diff --git a/test/specs/simple.js b/test/specs/simple.js deleted file mode 100644 index fb6ca499..00000000 --- a/test/specs/simple.js +++ /dev/null @@ -1,15 +0,0 @@ -var assert = require('assert'); -var config = require("../config/specs"); - - -describe('maputnik', function() { - - it('check logo exists', function () { - browser.url(config.baseUrl); - browser.waitForExist(".maputnik-toolbar-link"); - - var src = browser.getAttribute(".maputnik-toolbar-link img", "src"); - assert.equal(src, config.baseUrl+'/img/logo-color.svg'); - }); - -}); diff --git a/test/wd-helper.js b/test/wd-helper.js new file mode 100644 index 00000000..c1691295 --- /dev/null +++ b/test/wd-helper.js @@ -0,0 +1,6 @@ +module.exports = { + "$": function(key, selector) { + selector = selector || ""; + return "*[data-wd-key='"+key+"'] "+selector; + } +}