diff --git a/.cz-config.js b/.cz-config.js deleted file mode 100644 index 0f9b0078659..00000000000 --- a/.cz-config.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -module.exports = { - types: [ - {value: 'feat', name: 'feat: A new feature'}, - {value: 'fix', name: 'fix: A bug fix'}, - {value: 'docs', name: 'docs: Documentation only changes'}, - {value: 'style', name: 'style: Changes that deal with code style as opposed to functionality\n (white-space, formatting, missing semi-colons, etc)'}, - {value: 'refactor', name: 'refactor: A code change that neither fixes a bug nor adds a feature'}, - {value: 'perf', name: 'perf: A code change that improves performance'}, - {value: 'test', name: 'test: Adding missing tests'}, - {value: 'chore', name: 'chore: Changes to the build process, auxiliary tools\n or other processes such as documentation generation'}, - {value: 'revert', name: 'revert: Revert to a commit'}, - {value: 'WIP', name: 'WIP: Work in progress'} - ], - scopes: [ - {name: 'auth'}, - {name: 'storage'}, - {name: 'messaging'}, - {name: 'database'}, - {name: 'app'}, - {name: '* (All of the above, or general package concerns)', value: '*'}, - ], - allowCustomScopes: true, - allowBreakingChanges: ['feat', 'fix'] -}; \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 70d1d759ec9..7bd76e61cb1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -4,29 +4,17 @@ # These owners will be the default owners for everything in the repo. * @jshcrowthe -# Order is important. The last matching pattern has the most precedence. -# So if a pull request only touches javascript files, only these owners -# will be requested to review. -*.js @jshcrowthe - -# You can also use email addresses if you prefer. - # Database Code -src/database @mikelehen @schmidt-sebastian -tests/database @mikelehen @schmidt-sebastian +packages/database @mikelehen @schmidt-sebastian # Firestore Code -src/firestore @mikelehen @schmidt-sebastian -tests/firestore @mikelehen @schmidt-sebastian -integration/firestore @mikelehen @schmidt-sebastian +packages/firestore @mikelehen @schmidt-sebastian @wilhuff # Storage Code -src/storage @sphippen -tests/storage @sphippen +packages/storage @sphippen # Messaging Code -src/messaging @gauntface -tests/messaging @gauntface +packages/messaging @gauntface # Auth Code -src/auth.build.js @bojeil-google +packages/auth @bojeil-google @wti806 diff --git a/.gitignore b/.gitignore index 818ee02d43a..97734159a61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,15 @@ +# Build/Dependencies +node_modules +dist +.awcache +/config/project.json + +# Misc +*.log + +# OS Specific Files .DS_Store -node_modules/ -/dist -npm-debug.log -/coverage -/.nyc_output -/tests/config -temp/ -/.vscode -/.ts-node -/.idea -/.awcache + +# Editor Configs +.idea +.vscode \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000000..9ee30628d73 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +# This file is pre-built and need not be formatted +packages/auth/src/auth.js +dist diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000000..dc959d1dacc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + singleQuote: true, + printWidth: 80 +} diff --git a/.travis.yml b/.travis.yml index 12a8aebcd48..0c3ac1a6571 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,20 @@ language: node_js node_js: - - 6 + - stable cache: yarn # Define global C++ compiler version env: global: - CXX=g++-4.8 - matrix: - - TEST_ENV=node - - TEST_ENV=browser before_install: # Yarn defaults to an old version, make sure we # get an up to date version - npm install -g yarn before_script: - - export PATH=$PATH:./node_modules/.bin - - mkdir -p tests/config && echo "$PROJECT_CONFIG" > tests/config/project.json + - npm run test:setup -- --token $FIREBASE_TOKEN --projectId $FIREBASE_PROJECT script: - gulp test --env="$TEST_ENV" - -# Integration Test suite -jobs: - include: - - stage: Integration Tests - script: ./integration/webpack/runner.sh - - script: ./integration/browserify/runner.sh - - script: ./integration/typescript/runner.sh - - script: ./integration/serviceWorker/runner.sh - - script: ./integration/quickstart/runner.sh - - script: ./integration/messaging/runner.sh - - script: ./integration/firestore/runner.sh + - xvfb-run npm test # Misc Addons/Configs dist: trusty diff --git a/.vscode/launch.json b/.vscode/launch.json index e9ab7d0002e..d15ac7773b8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,24 +8,43 @@ "type": "node", "request": "launch", "name": "Firestore Unit Tests (Node)", - "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", - "args": ["test", "--suite=firestore/unit/", "--env=node"], - "port": 9229, + "program": "${workspaceRoot}/packages/firestore/node_modules/.bin/_mocha", + "cwd": "${workspaceRoot}/packages/firestore", + "args": [ + "--compilers", "ts:ts-node/register", + "-r", "src/platform_node/node_init.ts", + "--retries", "5", + "--timeout", "5000", + "test/{,!(integration|browser)/**/}*.test.ts" + ], + "sourceMaps": true, "protocol": "inspector" }, { "type": "node", "request": "launch", "name": "Firestore Unit Tests (Browser)", - "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", - "args": ["test", "--suite=firestore/unit/", "--env=browser", "--debug"] + "program": "${workspaceRoot}/packages/firestore/node_modules/.bin/karma", + "cwd": "${workspaceRoot}/packages/firestore", + "args": [ + "start", + "--auto-watch", + "--testFiles", "test/unit/bootstrap.ts", + "--browsers", "Chrome" + ] }, { "type": "node", "request": "launch", "name": "Firestore Integration Tests (Browser)", - "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", - "args": ["test", "--suite=firestore/integration", "--env=browser", "--debug"] + "program": "${workspaceRoot}/packages/firestore/node_modules/.bin/karma", + "cwd": "${workspaceRoot}/packages/firestore", + "args": [ + "start", + "--auto-watch", + "--testFiles", "test/integration/bootstrap.ts", + "--browsers", "Chrome" + ] } ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6782cf6e64f..15d4e15753b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -102,16 +102,6 @@ Before you start working on a larger contribution, you should get in touch with That's it! Thank you for your contribution! -## Commit Message Guidelines - -This repository follows the commit message format defined by the -[validate-commit-msg](https://npm.im/validate-commit-msg) package on NPM. This is -to make the git history easy to follow, and make it easier to identify which -commits are associated with features, bugfixes, etc. - -We are also Commitizen friendly! If you have the [Commitizen CLI](https://npm.im/commitizen) installed -you can simply use `git cz` to create properly formatted commit messages. - [archive]: https://github.com/firebase/firebase-js-sdk/issues?utf8=%E2%9C%93&q=is%3Aissue [file-an-issue]: https://github.com/firebase/firebase-js-sdk/issues/new [firebase-google-group]: https://groups.google.com/forum/#!forum/firebase-talk @@ -123,4 +113,4 @@ you can simply use `git cz` to create properly formatted commit messages. [jsbin]: http://jsbin.com/rinilu/edit?js,console [slack]: https://firebase-community.appspot.com/ [stackoverflow]: http://stackoverflow.com/questions/tagged/firebase -[support]: https://firebase.google.com/support/ \ No newline at end of file +[support]: https://firebase.google.com/support/ diff --git a/README.md b/README.md index 428972d2bfa..f9cc5303067 100644 --- a/README.md +++ b/README.md @@ -16,150 +16,118 @@ To get started using Firebase, see ### Prerequisites -Before you can start working on the Firebase JS SDK, you need to have Node.js 6.0 or -greater installed on your machine. After doing this, you must also install the -dependencies for this package. +#### Node.js + +Before you can start working on the Firebase JS SDK, you need to have Node.js +`8.0.0` or greater installed on your machine. To download Node.js visit https://nodejs.org/en/download/. -Once you've verified that you are using version 6.0 or later (run `node -v` to see your -current running version of Node.js), you can install the dependencies by running: +_NOTE: You can use a tool like [`NVM`](https://github.com/creationix/nvm) +or [`N`](https://github.com/tj/n) to install and manage multiple node versions_ -```bash -$ npm install -``` +#### Yarn -_NOTE: This package also maintains a `yarn.lock` so you can get faster installs by installing -dependencies with `yarn` instead._ +In addition to Node.js we use `yarn` to facilitate multi package development. -### Pipeline Instructions +To install `yarn` follow the instructions listed on their website: +https://yarnpkg.com/en/docs/install -The Firebase JS SDK is built and tested through a gulp pipeline. You will need to -have the `gulp` command available on your system to run the tasks yourself. +#### Verify Prerequisites -To install `gulp` simply run: +You can verify your setup by running the following commands in your terminal: ```bash -$ npm install -g gulp-cli +$ node -v +$ yarn -v ``` -_NOTE: Installing `gulp-cli` is optional as you can simply leverage the npm commands -for most interactions._ +Your Node.js version should be `8.0.0` or greater and your `yarn` version should +be `1.0.0` or greater. + +_NOTE: We will update the documentation as new versions are required, however +for continuing development on the SDK, staying up to date on the stable versions +of these packages is advised_ -## Gulp Pipeline +### Install Dependencies -Most of the tasks for interacting with the SDK are defined through gulp. If you -installed gulp globally, you can run the following to see all of the available -gulp tasks: +Once you have Node.js and `yarn` installed on your machine and have validated +that you are running the proper version, you can set up the development environment +by running the following at the root of the SDK: ```bash -gulp --tasks +$ yarn ``` ## Testing the SDK -To run all tests for the SDK you must first supply a firebase project config for -your tests. This is done by creating a file called `project.json` and at the -following path: - -``` -tests/config/project.json -``` +### Test Setup -This file should contain a JSON object with your app information (i.e. the same -information you would pass to `firebase.initializeApp`). +A production project is required to test the Firebase JS SDK. You can create a +new project by visiting the [Firebase Console](https://console.firebase.google.com/). -### Project Config +#### Automated Setup -The project supplied in your `project.json` needs to be properly configured to -succesfully run the tests. +Most of the test setup can be done by running the following command at the root +of the package: -#### Database Rules - -_i.e._ - -```json -{ - "rules": { - ".read": "true", - ".write": "true" - } -} +```bash +yarn test:setup ``` -#### Authentiaction Support +#### Authentication Support -Enable the `Anonymous` sign-in provider. +This is the only piece of config that must be done manually. Visit the +authentication config in your project and enable the `Anonymous` sign-in +provider to complete your project config. ### Running the tests -After you have the `project.json` and have properly configured the project, -simply run: `npm test` at the root of this package. - -You can also run the tests by calling `gulp test` if you have gulp installed. - -You can decrease the testing scope by providing the optional `suite`/`env` arguments to `npm/gulp test`. - -_e.g._ +Each of the directories in the `integration` directory as well as the `packages` +directory have their own test suites. These can be run altogether by running the +following command at the root of the package: ```bash -$ gulp test --suite=firestore --env=node +$ yarn test ``` -Any directory path in the tests directory serves as a valid value for the `--suite` flag. - -Valid values for the `--env` flag are `node`/`browser`. - -### Integration Tests - -These tests are functionally different enough from the normal test suite that they have their own README.md. Please view it [here](./integration/README.md): +In addition, you can run any of the tests individually by running `yarn test` in +an individaul package directory. ## Building the SDK ### Introduction -The Javascript SDK is built through a gulp pipeline. - -To build the project run `npm run build` in your CLI. - -This will generate all of the output assets in a `/dist` folder available at the -root of this project. - -Each of the different types of source files are explained more in detail below. +The Firebase JS SDK is built with a series of individual packages that are all +contained in this repository. Development is coordinated via [yarn +workspaces](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/) and +[Lerna](https://lernajs.io/) (a monorepo management tool). -### Source File Handling +Each package in the `packages` directory, constitute a piece of our +implementation. The SDK is built via a combination of all of these packages +which are published under the [`firebase` +scope](https://www.npmjs.com/search?q=scope%3Afirebase) on NPM. -Our source files are all located in the `/src` directory. This currently contains -a variety of different sources (typescript, prebuilt binaries, legacy). We handle -each of these cases in our gulp pipeline. +### Helper Scripts -#### Typescript Source +Each package in the `packages` directory exposes a `dev` script. This script +will set up a watcher for development on the indiviual piece of the SDK. In +addition, there is a top level `dev` script that can be run to start all of the +watch tasks as well as a sandbox server. -This is the planned source language for this repo. As we are able, all components -will be migrated to typescript and processed in the following flow: +You can run the dev script by running the following at the root of the package: -1. TS Files are compiled to ES6 using the Typescript compiler -1. ES6 Files are transpiled to CJS Modules using Babel -1. ES6 Files are processed with webpack to attach to the window global - -#### Prebuilt Binaries - -To allow firebase to build from Github we consume prebuilt binaries of our components -until the source is migrated to this repo. - -These files are processed in the following flow: - -1. Prebuilt browser binaries are ready to consume individually in the browser -however we need to wrap them in a CJS module wrapper for node/webpack/browserify -consumption. -1. The Firebase App binary is generated (from TS) and concatenated with the -browser binaries of each individual module to create `firebase.js`. +```bash +yarn dev +``` -#### Legacy Files +### Prepush Hooks -These files are built in this repo but are being migrated to typescript as we are able. -Once these files are migrated, the associated build process, will be removed. +As part of this repo, we use the NPM package [`husky`](https://npm.im/husky) to +implement git hooks. We leverage the prepush hook to do two things: +- Automated code styling (using [`prettier`](https://npm.im/prettier)) +- Automated LICENSE header insertion ## Contributing diff --git a/config/database.rules.json b/config/database.rules.json new file mode 100644 index 00000000000..b104e9c240e --- /dev/null +++ b/config/database.rules.json @@ -0,0 +1,6 @@ +{ + "rules": { + ".read": true, + ".write": true + } +} \ No newline at end of file diff --git a/config/firebase.json b/config/firebase.json new file mode 100644 index 00000000000..a87d011f65a --- /dev/null +++ b/config/firebase.json @@ -0,0 +1,5 @@ +{ + "database": { + "rules": "database.rules.json" + } +} \ No newline at end of file diff --git a/config/karma.base.js b/config/karma.base.js new file mode 100644 index 00000000000..354bc90f99a --- /dev/null +++ b/config/karma.base.js @@ -0,0 +1,113 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const karma = require('karma'); +const path = require('path'); +const webpackTestConfig = require('./webpack.test'); + +/** + * Custom SauceLabs Launchers + */ +const sauceLabsBrowsers = { + desktop_Safari: { + base: 'SauceLabs', + browserName: 'safari', + platform: 'OS X 10.11', + version: '9.0' + }, + iOS_Safari: { + appiumVersion: '1.6.5', + base: 'SauceLabs', + browserName: 'Safari', + deviceName: 'iPhone Simulator', + deviceOrientation: 'portrait', + platformName: 'iOS', + platformVersion: '9.0' + }, + IE_11: { + base: 'SauceLabs', + browserName: 'internet explorer', + platform: 'Windows 8.1', + version: '11' + } +}; + +const config = { + // disable watcher + autoWatch: false, + + // Doing 65 seconds to allow for the 20 second firestore tests + browserNoActivityTimeout: 65000, + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + 'test/**/*.ts': ['webpack', 'sourcemap'] + }, + + mime: { + 'text/x-typescript': ['ts', 'tsx'] + }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['spec' /*, 'saucelabs' */], + + // web server port + port: 8080, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: karma.constants.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + customLaunchers: sauceLabsBrowsers, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['ChromeHeadless'], + + webpack: webpackTestConfig, + + webpackMiddleware: { + quiet: true, + stats: { + colors: true + } + }, + + sauceLabs: { + tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER, + username: process.env.SAUCE_USERNAME, + accessKey: process.env.SAUCE_ACCESS_KEY, + startConnect: false + }, + + singleRun: false +}; + +// In CI environment, use saucelabs to test +if (false /* process.env.TRAVIS */) { + config.browsers = [...config.browsers, ...Object.keys(sauceLabsBrowsers)]; +} + +module.exports = config; diff --git a/integration/quickstart/tsconfig.json b/config/tsconfig.base.json similarity index 55% rename from integration/quickstart/tsconfig.json rename to config/tsconfig.base.json index 6fe0bc0cfa1..99e890f5944 100644 --- a/integration/quickstart/tsconfig.json +++ b/config/tsconfig.base.json @@ -1,24 +1,20 @@ { "compileOnSave": false, "compilerOptions": { + "declaration": true, "lib": [ "es5", "es2015", "es2015.promise", "dom" ], - "allowJs": true, "module": "commonjs", "moduleResolution": "node", - "noImplicitAny": true, - "outDir": "tmp", - "target": "ES5", + "noImplicitAny": false, "sourceMap": true, - "typeRoots" : [ - "node_modules/@types" + "target": "es5", + "typeRoots": [ + "../node_modules/@types" ] - }, - "exclude": [ - "node_modules" - ] -} \ No newline at end of file + } +} diff --git a/config/webpack.test.js b/config/webpack.test.js new file mode 100644 index 00000000000..ed5d7974f6b --- /dev/null +++ b/config/webpack.test.js @@ -0,0 +1,40 @@ +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const path = require('path'); +const webpack = require('webpack'); + +module.exports = { + devtool: 'eval-source-map', + module: { + rules: [ + { + test: /\.tsx?$/, + exclude: /node_modules/, + use: 'ts-loader' + }, + { + test: /\.js$/, + use: ['source-map-loader'], + enforce: 'pre' + } + ] + }, + resolve: { + modules: ['node_modules', path.resolve(__dirname, '../../node_modules')], + extensions: ['.js', '.ts'] + } +}; diff --git a/gulp/config.js b/gulp/config.js deleted file mode 100644 index 771d0c56c5a..00000000000 --- a/gulp/config.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const path = require('path'); -const cwd = process.cwd(); -const karma = require('karma'); - -const configObj = { - root: path.resolve(cwd), - pkg: require(path.resolve(cwd, 'package.json')), - testConfig: { - timeout: 5000, - retries: 5 - }, - tsconfig: require(path.resolve(cwd, 'tsconfig.json')), - tsconfigTest: require(path.resolve(cwd, 'tsconfig.test.json')), - paths: { - outDir: path.resolve(cwd, 'dist'), - tempDir: path.resolve(cwd, 'temp'), - }, - babel: { - plugins: [ - 'add-module-exports', - ], - presets: [ - ['env', { - "targets": { - "browsers": [ - "ie >= 9" - ] - }, - }] - ] - }, - babelWebpack: { - presets: [ - ["env", { - "modules": false, - "targets": { - "browsers": [ - "ie >= 9" - ] - }, - }] - ] - }, - karma: { - autoWatch: false, - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - browserNoActivityTimeout: 30000, - - customHeaders: [{ - match: '.*', - name: 'Service-Worker-Allowed', - value: '/' - }], - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: [ - 'mocha', - 'karma-typescript' - ], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - '**/*.ts': ['karma-typescript'] - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['spec'], - - // web server port - port: 8080, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: karma.constants.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['ChromeHeadless'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - // karma-typescript config - karmaTypescriptConfig: { - tsconfig: `./tsconfig.test.json` - }, - - // Stub for client config - client: { - mocha: {} - } - } -}; - -configObj.karma.client.mocha.timeout = configObj.testConfig.timeout; -configObj.karma.client.mocha.retries = configObj.testConfig.retries; - -module.exports = configObj; diff --git a/gulp/tasks/build.js b/gulp/tasks/build.js deleted file mode 100644 index 2740e89bb01..00000000000 --- a/gulp/tasks/build.js +++ /dev/null @@ -1,440 +0,0 @@ -/** - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const gulp = require('gulp'); -const merge = require('merge2'); -const config = require('../config'); -const ts = require("gulp-typescript"); -const tsProject = ts.createProject('tsconfig.json'); -const babel = require('gulp-babel'); -const rename = require('gulp-rename'); -const through = require('through2'); -const path = require('path'); -const clone = require('gulp-clone'); -const webpack = require('webpack'); -const webpackStream = require('webpack-stream'); -const sourcemaps = require('gulp-sourcemaps'); -const concat = require('gulp-concat'); -const replace = require('gulp-replace'); -const gulpFile = require('gulp-file'); -const rimraf = require('rimraf'); -const header = require('gulp-header'); -const gitRev = require('git-rev-sync'); -const gulpIf = require('gulp-if'); -const stripComments = require('gulp-strip-comments'); -const filesize = require('filesize'); -const glob = require('glob'); -const fs = require('fs'); -const gzipSize = require('gzip-size'); -const WrapperPlugin = require('wrapper-webpack-plugin'); -const { CheckerPlugin } = require('awesome-typescript-loader'); - -function cleanDist(dir) { - return function cleanDistDirectory(done) { - rimraf(`${config.paths.outDir}${ dir ? `/${dir}` : ''}`, done); - } -} - -function compileTypescriptToES2015() { - const stream = tsProject.src() - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(tsProject()); - return merge([ - stream.dts - .pipe(gulp.dest(`${config.paths.outDir}/es2015`)), - stream.js - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest(`${config.paths.outDir}/es2015`)) - ]); -}; - -function compileES2015ToCJS() { - return gulp.src('dist/es2015/**/*.js') - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(babel(config.babel)) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest(`${config.paths.outDir}/cjs`)) -}; - -function processPrebuiltFilesForBrowser() { - return gulp.src([ - 'src/**/*.build.js', - ]) - .pipe(stripComments()) - .pipe(rename(_path => { - _path.basename = `firebase-${_path.basename.replace('.build', '')}`; - return _path; - })) - .pipe(gulp.dest(`${config.paths.outDir}/browser`)); -} - -function processPrebuiltFilesForCJS() { - return gulp.src([ - 'src/**/*.build.js', - ]) - .pipe(stripComments()) - .pipe(rename(_path => { - _path.basename = `${_path.basename.replace('.build', '')}`; - return _path; - })) - .pipe(through.obj(function(file, encoding, cb) { - const _path = path.parse(file.path); - const moduleName = _path.name.replace('.build', '').replace('-node', ''); - - file.contents = Buffer.concat([ - new Buffer(`var firebase = require('./app'); -(function(){`), - file.contents, - new Buffer(`}).call(typeof global !== undefined ? global : typeof self !== undefined ? self : typeof window !== undefined ? window : {});`) - ]); - - this.push(file); - return cb(); - })) - .pipe(gulp.dest(`${config.paths.outDir}/cjs`)); -} - -function compileIndvES2015ModulesToBrowser() { - const isFirebaseApp = fileName => { - const pathObj = path.parse(fileName); - return pathObj.name === 'firebase-app'; - }; - - const webpackConfig = { - devtool: 'source-map', - entry: { - 'firebase-app': './src/app.ts', - 'firebase-storage': './src/storage.ts', - 'firebase-messaging': './src/messaging.ts', - 'firebase-database': './src/database.ts', - 'firebase-firestore': './src/firestore.ts', - }, - output: { - filename: '[name].js', - jsonpFunction: 'webpackJsonpFirebase', - path: path.resolve(__dirname, './dist/browser'), - }, - module: { - rules: [{ - test: /\.tsx?$/, - exclude: /node_modules/, - loader: 'awesome-typescript-loader', - options: { - useCache: true, - useBabel: true, - babelOptions: config.babelWebpack - } - }] - }, - plugins: [ - new CheckerPlugin(), - new webpack.optimize.ModuleConcatenationPlugin(), - new webpack.optimize.CommonsChunkPlugin({ - name: 'firebase-app' - }), - new WrapperPlugin({ - header: fileName => { - return isFirebaseApp(fileName) ? `var firebase = (function() { - var window = typeof window === 'undefined' ? self : window; - return ` : `try { - `; - }, - footer: fileName => { - // Note: '.default' needed because of https://github.com/babel/babel/issues/2212 - return isFirebaseApp(fileName) ? ` - })().default;` : ` - } catch(error) { - throw new Error( - 'Cannot instantiate ${fileName} - ' + - 'be sure to load firebase-app.js first.' - ) - }` - } - }), - new webpack.optimize.UglifyJsPlugin({ - sourceMap: true, - mangle: { - props: { - ignore_quoted: true, - // NOTE: Firestore uses __foo__ variables that must not be mangled. - regex: /^_[^_]|[^_]_$/ - } - }, - compress: { - passes: 3, - unsafe: true, - warnings: false, - } - }) - ], - resolve: { - extensions: ['.ts', '.tsx', '.js'] - }, - }; - - return gulp.src('src/**/*.ts') - .pipe(webpackStream(webpackConfig, webpack)) - .pipe(gulp.dest(`${config.paths.outDir}/browser`)); -} - -function buildBrowserFirebaseJs() { - // Exclude firebase-firestore from combined firebase.js - return gulp.src([ - './dist/browser/*.js', - '!./dist/browser/firebase-firestore.js' - ]) - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(concat('firebase.js')) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest(`${config.paths.outDir}/browser`)); -} - -function buildAltEnvFirebaseJs() { - const babelConfig = Object.assign({}, config.babel, { - plugins: config.babel.plugins - }); - return gulp.src([ - './dist/es2015/firebase-browser.js', - './dist/es2015/firebase-node.js', - './dist/es2015/firebase-react-native.js', - ]) - .pipe(sourcemaps.init({ loadMaps: true })) - .pipe(babel(babelConfig)) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest(`${config.paths.outDir}/cjs`)); -} - -function copyPackageContents() { - const copyBrowserCode = gulp.src('./dist/browser/**/*') - .pipe(gulp.dest(`${config.paths.outDir}/package`)); - - const copyCJSCode = gulp.src([ - './dist/cjs/**/*', - '!./dist/cjs/firebase.js*' - ]) - .pipe(gulp.dest(`${config.paths.outDir}/package`)); - - return merge([ - copyBrowserCode, - copyCJSCode - ]); -} - -function compileMetaFiles() { - const outPkg = (_pkg => { - // Format the new package.json - let obj = Object.assign({}, _pkg, { - scripts: null, - devDependencies: null, - main: 'firebase-node.js', - browser: 'firebase-browser.js', - 'react-native': 'firebase-react-native.js', - types: 'firebase.d.ts', - nyc: null, - babel: null, - }); - - // Delete all props that are falsy - for (let key in obj) { - if (!obj[key]) delete obj[key]; - } - - // Return formatted JSON string - return JSON.stringify(obj, null, 2); - })(config.pkg); - - const pkgJson = gulpFile('package.json', outPkg, {src: true }) - - const copyFiles = gulp.src([ - 'LICENSE', - './dist/global/*', - './typings/**/*' - ]); - - const copyReadme = gulp.src('README.public.md') - .pipe(rename({ - basename: 'README' - })) - .pipe(gulp.dest(`${config.paths.outDir}/package/`)); - - const copyExterns = gulp.src('./externs/**/*') - .pipe(gulp.dest(`${config.paths.outDir}/package/externs`)); - - return merge([ - merge([copyFiles,pkgJson]) - .pipe(gulp.dest(`${config.paths.outDir}/package`)), - copyExterns, - copyReadme - ]); -} - -function injectSDKVersion() { - return gulp.src('./dist/package/**/*', {base: '.'}) - .pipe(replace(/\${JSCORE_VERSION}/g, config.pkg.version)) - .pipe(gulp.dest('.')); -} - -function cleanComments() { - return gulp.src([ - './dist/package/**/*.js', - '!./dist/package/externs/*' - ], {base: '.'}) - .pipe(stripComments({ - // TODO: Remove this comment in 3.8.0 release - ignore: /\/\/# sourceMappingURL=.+\.map/g - })) - .pipe(gulp.dest('.')); -} - -function injectLicenseInfo() { - const rev = gitRev.short(); - - const licenseHeader = `/*! @license Firebase v${config.pkg.version} -Build: rev-${rev} -Terms: https://firebase.google.com/terms/ */ - -`; - - const bigLicenseHeader = `/*! @license Firebase v${config.pkg.version} -Build: rev-${rev} -Terms: https://firebase.google.com/terms/ - ---- - -typedarray.js -Copyright (c) 2010, Linden Research, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. */ - -`; - - return gulp.src('./dist/package/**/*.js', {base: '.'}) - .pipe(gulpIf(file => { - const _path = path.parse(file.path); - return _path.base !== 'firebase.js' && !~_path.base.indexOf('database'); - },header(licenseHeader), header(bigLicenseHeader))) - .pipe(gulp.dest('.')); -} - -function logFileSize(done) { - console.log('\r\n| File | Parsed Size | Gzip Size'); - console.log('|----------|-------------|------|'); - - const filePaths = glob.sync('./dist/browser/*.js'); - filePaths - .map(filePath => { - const _path = path.parse(filePath); - return path.resolve(_path.dir, `../package/${_path.base}`); - }) - .map(filePath => { - const _path = path.parse(filePath); - const fileContents = fs.readFileSync(filePath, 'utf8'); - const rawSize = fs.statSync(filePath).size; - const size = filesize(rawSize); - const gzip = filesize(gzipSize.sync(fileContents)); - return { - file: _path.base, - size, - gzip - }; - }) - .forEach(obj => console.log(`| ${obj.file} | ${obj.size} | ${obj.gzip} |`)); - - console.log('\r\n'); - done(); -} - -/** - * GULP TASKS - * - * Gulp tasks in Gulp 4.0 are a description of a series of functions. - * The functions are all above and are easier to maintain individually - * - * Each "task" is then responsible for wiring up the dep trees itself, - * because of this you have a finer degree of control of the ordering - * of your tasks **and** you can optimize the parallelization of each - * task. - */ - -gulp.task('build:es2015', gulp.series([ - compileTypescriptToES2015, -])); - -gulp.task('build:cjs', gulp.parallel([ - gulp.series([ - compileTypescriptToES2015, - gulp.parallel(compileES2015ToCJS, buildAltEnvFirebaseJs) - ]), - processPrebuiltFilesForCJS, -])); - -gulp.task('process:prebuilt', gulp.parallel([ - processPrebuiltFilesForBrowser, - processPrebuiltFilesForCJS -])); - -// This is the optimized build path, we reuse this in -// a couple places so capturing it here -const compileSourceAssets = gulp.series([ - compileTypescriptToES2015, - gulp.parallel([ - compileIndvES2015ModulesToBrowser, - compileES2015ToCJS, - ]) -]); - -gulp.task('build:browser', gulp.series([ - // Build the src assets and prebuilt assets in - // parallel - gulp.parallel([ - compileSourceAssets, - processPrebuiltFilesForBrowser, - ]), - buildBrowserFirebaseJs -])); - -const buildSDK = exports.buildSDK = gulp.series([ - cleanDist(), - gulp.parallel([ - compileSourceAssets, - processPrebuiltFilesForBrowser, - processPrebuiltFilesForCJS, - compileMetaFiles - ]), - gulp.parallel(buildBrowserFirebaseJs, buildAltEnvFirebaseJs), - copyPackageContents, - injectLicenseInfo, - injectSDKVersion, - logFileSize -]); - -gulp.task('build', buildSDK); diff --git a/gulp/tasks/test.js b/gulp/tasks/test.js deleted file mode 100644 index 554753ce16c..00000000000 --- a/gulp/tasks/test.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright 2017 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const gulp = require('gulp'); -const mocha = require('gulp-mocha'); -const setEnv = require('gulp-env').set; -const karma = require('karma'); -const config = require('../config'); -const buildTasks = require('./build'); -const argv = require('yargs').argv; - -function runNodeTest(suite = '**') { - /** - * Custom error handler for "No test files found" errors - */ - return gulp.src([ - `tests/**/${suite}/**/*.test.ts`, - 'src/firestore/platform_node/node_init.ts', - // TODO(b/66918026): Re-enable Firestore integration tests on node. - '!tests/firestore/integration/**/*.test.ts', - '!tests/**/browser/**/*.test.ts', - '!tests/**/binary/**/*.test.ts', - '!src/firebase-*.ts', - ], { read: false }) - .pipe(setEnv({ - TS_NODE_PROJECT: 'tsconfig.test.json' - })) - .pipe(mocha({ - reporter: 'spec', - compilers: 'ts:ts-node/register', - timeout: config.testConfig.timeout, - retries: config.testConfig.retries, - inspect: true - })) - .on('error', err => { - if (err && err.message && ~err.message.indexOf('No test files found')) return; - throw err; - }); -} - -function runBrowserTest(suite = '.*', debug) { - return new Promise((resolve, reject) => { - let karmaConfig = Object.assign({}, config.karma, { - // list of files / patterns to load in the browser - files: [ - `./src/**/*.ts`, - `./tests/**/*.ts`, - { pattern: `./tests/config/**/*`, included: false, served: true } - ], - - // list of files to exclude from the included globs above - exclude: [ - // we don't want this file as it references files that only exist once compiled - `./src/firebase-*.ts`, - - // We don't want to load the node env - `./src/utils/nodePatches.ts`, - - // Don't include node test files - './tests/**/node/**/*.test.ts', - - // Don't include binary test files - './tests/**/binary/**/*.test.ts', - ], - }); - - Object.assign(karmaConfig.karmaTypescriptConfig, { - bundlerOptions: { - entrypoints: new RegExp(`^.*tests/${suite}.*\.test\.ts$|^.*src/firestore/platform_browser/browser_init.ts$`) - } - }); - - if (debug) { - karmaConfig = Object.assign({}, karmaConfig, { - autoWatch: true, - singleRun: false, - browsers: ['Chrome'] - }); - - Object.assign(karmaConfig.karmaTypescriptConfig, { - coverageOptions: { - instrumentation: false - } - }); - } - - new karma.Server(karmaConfig, exitcode => { - if (exitcode) return reject(exitcode); - resolve(); - }).start(); - }); -} - -function runTests(devMode) { - const suite = argv.suite || ''; - const env = argv.env || '*'; - const debug = !!argv.debug || false; - console.log('debug:', debug); - console.log(`Values: ${suite}:${env}`); - - switch(env) { - case 'node': return runNodeTest(suite); - case 'browser': return runBrowserTest(suite, debug); - default: - // Incidentally this works returning a stream and promise value - return Promise.all([ - runNodeTest(suite), - runBrowserTest(suite, debug), - ]); - } -} - -exports.runTests = runTests; - -gulp.task('test', runTests); diff --git a/index.html b/index.html deleted file mode 100644 index 71587230182..00000000000 --- a/index.html +++ /dev/null @@ -1,5 +0,0 @@ - -
- - - \ No newline at end of file diff --git a/integration/README.md b/integration/README.md deleted file mode 100644 index 910f0ec3bc5..00000000000 --- a/integration/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Integration Test Suites - -These test suites are high level validation suites that are largely coupled to an environment. They will test things like: - -- Service Worker Integration -- Compatability with Webpack/Browserify/Typescript etc -- High level UI testing -- Others with same kinds of environmental restriction - -Each test suite is expected to be fully isolated so some small duplication of config files and such is expected. - -Each suite also contains a `runner.sh` file that contains the logic to actually test the module. **Make no assumptions** as you write these tests as nothing is provided by default (e.g. the current codebase hasn't built yet, test config files may not exist, etc). - -## `shared` Directory - -The `shared` directory in this folder currently contains two files: - - - `namespaceDefinition.json` - - `validator.js` - -These two files can be used to validate the firebase namespace and currently serves as the base for many of our integration tests. - -_NOTE: `validator.js` should only be used **after** initializing a test firebase app (i.e. make a call to `firebase.initializeApp` before validating the namespace)_ - -## Authoring an Integration Test - -The point of the integration tests is to be as flexible as possible. The only convention that I would recommend is supplying a `runner.sh` file to do the actual work of the test. - -That said, if you are looking for a pattern to follow, the process that was followed for several of the tests, is outlined below: - -- Copy the test files to a temporary working directory -- Setup an `EXIT` trap to cleanup the temporary directory at the end of the script -- Ensure that the SDK gets built if it doesn't already exist -- `npm install` the folder `dist/package`, this allows the test to function as if the SDK was installed from NPM -- (For tests that are only validating the firebase namespace) copy the `shared` directory above into the working directory - -The tests are then ran with karma/mocha/webdriver.io/selenium or whatever else you need to accomplish the purpose of your test. Each of these runners requires their own config (and sometimes their own dependencies), supply these config files directly in the test directory (e.g. many of the suites have their own package.json) as the tests are meant to be isolated from each other as much as possible. \ No newline at end of file diff --git a/integration/browserify/karma.conf.js b/integration/browserify/karma.conf.js index ca22b87178a..665d026581f 100644 --- a/integration/browserify/karma.conf.js +++ b/integration/browserify/karma.conf.js @@ -14,49 +14,18 @@ * limitations under the License. */ -// Karma configuration -module.exports = function(config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', +const karma = require('karma'); +const path = require('path'); +const karmaBase = require('../../config/karma.base'); +module.exports = function(config) { + const karmaConfig = Object.assign({}, karmaBase, { + // files to load into karma + files: [{ pattern: `dist/**/*` }], // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha'], - - // list of files / patterns to load in the browser - files: [ - 'build/**/*' - ], - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['spec'], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['ChromeHeadless'], - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, + frameworks: ['mocha'] + }); - // Concurrency level - // how many browser should be started simultaneous - concurrency: Infinity - }) -} + config.set(karmaConfig); +}; diff --git a/integration/browserify/package.json b/integration/browserify/package.json index b12ebfd2de8..491bba16f8d 100644 --- a/integration/browserify/package.json +++ b/integration/browserify/package.json @@ -1,14 +1,23 @@ { "name": "firebase-browserify-test", - "version": "1.0.0", - "main": "runner.sh", + "private": true, + "version": "0.1.0", + "scripts": { + "pretest": "mkdirp dist && browserify src/namespace.test.js -o dist/namespace.test.js", + "test": "karma start --single-run" + }, + "dependencies": { + "firebase": "^4.3.3" + }, "devDependencies": { - "browserify": "^14.4.0", - "chai": "^3.5.0", + "browserify": "^14.4.0", + "chai": "^4.1.1", "karma": "^1.7.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0", + "karma-sauce-launcher": "^1.2.0", "karma-spec-reporter": "0.0.31", - "mocha": "^3.5.0" + "mkdirp": "^0.5.1", + "mocha": "^3.5.0" } } diff --git a/integration/browserify/runner.sh b/integration/browserify/runner.sh deleted file mode 100755 index af47ca46db0..00000000000 --- a/integration/browserify/runner.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -# Copyright 2017 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Variables -ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" -GULP_CLI="$ROOT/node_modules/.bin/gulp" -BROWSERIFY_CLI="$ROOT/node_modules/.bin/browserify" -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -WORK_DIR=`mktemp -d` - -# check if tmp dir was created -if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then - echo "Could not create temp dir" - exit 1 -fi - -# deletes the temp directory -function cleanup { - rm -rf "$WORK_DIR" - echo "Deleted temp working directory $WORK_DIR" -} - -# register the cleanup function to be called on the EXIT signal -trap cleanup EXIT - -# Enter work dir -pushd "$WORK_DIR" - -if [ ! -d "$ROOT/dist/package" ]; then - pushd $ROOT - $GULP_CLI build - popd -fi - -# Simulate env -cp $DIR/* . -cp $DIR/../shared/* . -npm install -npm install "$ROOT/dist/package" - -# Build the new env -mkdir -p build -./node_modules/.bin/browserify namespace.test.js -o build/bundle.js - -# Run the tests -./node_modules/.bin/karma start diff --git a/integration/browserify/namespace.test.js b/integration/browserify/src/namespace.test.js similarity index 83% rename from integration/browserify/namespace.test.js rename to integration/browserify/src/namespace.test.js index ae821bfbc59..af48e959412 100644 --- a/integration/browserify/namespace.test.js +++ b/integration/browserify/src/namespace.test.js @@ -15,8 +15,8 @@ */ const firebase = require('firebase'); -const namespaceDefinition = require('./namespaceDefinition'); -const validateNamespace = require('./validator'); +const namespaceDefinition = require('../../shared/namespaceDefinition'); +const validateNamespace = require('../../shared/validator'); firebase.initializeApp({ apiKey: 'test-api-key', @@ -27,6 +27,6 @@ firebase.initializeApp({ messagingSenderId: '012345678910' }); -describe("Firebase Namespace Validation", function() { +describe('Firebase Namespace Validation', function() { validateNamespace(namespaceDefinition, firebase); -}); \ No newline at end of file +}); diff --git a/integration/firestore/README.md b/integration/firestore/README.md new file mode 100644 index 00000000000..a057f484bd3 --- /dev/null +++ b/integration/firestore/README.md @@ -0,0 +1,6 @@ +These tests are intended to be run against the minified compiled version of the +firebase binary (i.e. `firebase.js` and `firebase-firestore.js` of the `firebase` +package). + +They are currently just rerunning tests against the uncompiled version and we +need to address that. diff --git a/integration/firestore/karma.conf.js b/integration/firestore/karma.conf.js index 592775c14d1..4b83216dcd3 100644 --- a/integration/firestore/karma.conf.js +++ b/integration/firestore/karma.conf.js @@ -21,14 +21,10 @@ module.exports = function(config) { config.set({ // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: [ - 'mocha', - ], + frameworks: ['mocha'], // list of files / patterns to load in the browser - files: [ - { pattern: 'tests/**/*.test.ts' } - ], + files: [{ pattern: 'tests/**/*.test.ts' }], client: { mocha: { @@ -43,7 +39,7 @@ module.exports = function(config) { }, mime: { - 'text/x-typescript': ['ts','tsx'] + 'text/x-typescript': ['ts', 'tsx'] }, // test results reporter to use @@ -70,5 +66,5 @@ module.exports = function(config) { singleRun: true, webpack: webpackConfig - }) -} + }); +}; diff --git a/integration/firestore/webpack.config.js b/integration/firestore/webpack.config.js index df19056cc41..fce6705dc78 100644 --- a/integration/firestore/webpack.config.js +++ b/integration/firestore/webpack.config.js @@ -19,13 +19,15 @@ const webpack = require('webpack'); module.exports = { module: { - rules: [{ - test: /\.tsx?$/, - exclude: /node_modules/, - loader: 'ts-loader' - }] + rules: [ + { + test: /\.tsx?$/, + exclude: /node_modules/, + loader: 'ts-loader' + } + ] }, resolve: { extensions: ['.js', '.ts'] } -} \ No newline at end of file +}; diff --git a/integration/messaging/README.md b/integration/messaging/README.md deleted file mode 100644 index 1d26afe5bc2..00000000000 --- a/integration/messaging/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Currently `firebase-js-sdk` does not have any selenium support so these -tests need to be run manually until such a time that support is made available -and tests are ported over. diff --git a/integration/messaging/download-browsers.js b/integration/messaging/download-browsers.js index bdac0b3e9e0..90f1318a392 100644 --- a/integration/messaging/download-browsers.js +++ b/integration/messaging/download-browsers.js @@ -23,11 +23,11 @@ Promise.all([ seleniumAssistant.downloadLocalBrowser('chrome', 'unstable', 48), seleniumAssistant.downloadLocalBrowser('firefox', 'stable', 48), seleniumAssistant.downloadLocalBrowser('firefox', 'beta', 48), - seleniumAssistant.downloadLocalBrowser('firefox', 'unstable', 48), + seleniumAssistant.downloadLocalBrowser('firefox', 'unstable', 48) ]) -.then(() => { - console.log('Browser download complete.'); -}) -.catch((err) => { - console.error('Browser download failed.'); -}); + .then(() => { + console.log('Browser download complete.'); + }) + .catch(err => { + console.error('Browser download failed.'); + }); diff --git a/integration/messaging/package-lock.json b/integration/messaging/package-lock.json deleted file mode 100644 index b55ce1c6f97..00000000000 --- a/integration/messaging/package-lock.json +++ /dev/null @@ -1,1908 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "accepts": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", - "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=", - "dev": true, - "requires": { - "mime-types": "2.1.16", - "negotiator": "0.6.1" - } - }, - "adm-zip": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz", - "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=", - "dev": true - }, - "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", - "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", - "dev": true, - "requires": { - "extend": "3.0.1", - "semver": "5.0.3" - }, - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "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" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "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 - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", - "dev": true - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "bluebird": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz", - "integrity": "sha1-AdqNgh2HgT0ViWfnQ9X+bGLPjA8=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "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=", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chai": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.1.tgz", - "integrity": "sha1-ZuISeebzxkFf+CMYeCJ5AOIXGzk=", - "dev": true, - "requires": { - "assertion-error": "1.0.2", - "check-error": "1.0.2", - "deep-eql": "2.0.2", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "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" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chromedriver": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-2.31.0.tgz", - "integrity": "sha1-gsdY7kAVqogPRQCLujRkM8+dsUo=", - "dev": true, - "requires": { - "extract-zip": "1.6.5", - "kew": "0.7.0", - "mkdirp": "0.5.1", - "request": "2.81.0", - "rimraf": "2.6.1" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "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" - } - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "content-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "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=", - "dev": true - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "1.0.0" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-eql": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-2.0.2.tgz", - "integrity": "sha1-sbrAblbwp2d3aG1Qyf63XC7XZ5o=", - "dev": true, - "requires": { - "type-detect": "3.0.0" - }, - "dependencies": { - "type-detect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-3.0.0.tgz", - "integrity": "sha1-RtDMhVOrt7E6NSsNbeov1Y8tm1U=", - "dev": true - } - } - }, - "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "globby": "6.1.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "p-map": "1.1.1", - "pify": "3.0.0", - "rimraf": "2.6.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "dmg": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dmg/-/dmg-0.1.0.tgz", - "integrity": "sha1-s46iEH9vCwcEQrv3mb/E8q7apfg=", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "encodeurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=", - "dev": true - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, - "requires": { - "iconv-lite": "0.4.18" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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=", - "dev": true - }, - "etag": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", - "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=", - "dev": true - }, - "express": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz", - "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=", - "dev": true, - "requires": { - "accepts": "1.3.3", - "array-flatten": "1.1.1", - "content-disposition": "0.5.2", - "content-type": "1.0.2", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.8", - "depd": "1.1.1", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.0", - "finalhandler": "1.0.4", - "fresh": "0.5.0", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.1", - "path-to-regexp": "0.1.7", - "proxy-addr": "1.1.5", - "qs": "6.5.0", - "range-parser": "1.2.0", - "send": "0.15.4", - "serve-static": "1.12.4", - "setprototypeof": "1.0.3", - "statuses": "1.3.1", - "type-is": "1.6.15", - "utils-merge": "1.0.0", - "vary": "1.1.1" - }, - "dependencies": { - "qs": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", - "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extract-zip": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz", - "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=", - "dev": true, - "requires": { - "concat-stream": "1.6.0", - "debug": "2.2.0", - "mkdirp": "0.5.0", - "yauzl": "2.4.1" - }, - "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" - } - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "1.0.1" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "1.2.0" - } - }, - "finalhandler": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz", - "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==", - "dev": true, - "requires": { - "debug": "2.6.8", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.1", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.16" - } - }, - "forwarded": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=", - "dev": true - }, - "fresh": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", - "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=", - "dev": true - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "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=", - "dev": true - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "geckodriver": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-1.8.0.tgz", - "integrity": "sha1-ef7fk3B3w0uu5ZGim7zxtgLS1hk=", - "dev": true, - "requires": { - "adm-zip": "0.4.7", - "bluebird": "3.4.6", - "got": "5.6.0", - "tar.gz": "1.0.5" - } - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "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" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "got": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz", - "integrity": "sha1-ux1+4WO3gIK7yOuDbz85UATqb78=", - "dev": true, - "requires": { - "create-error-class": "3.0.2", - "duplexer2": "0.1.4", - "is-plain-obj": "1.1.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "node-status-codes": "1.0.0", - "object-assign": "4.1.1", - "parse-json": "2.2.0", - "pinkie-promise": "2.0.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.3", - "timed-out": "2.0.0", - "unzip-response": "1.0.2", - "url-parse-lax": "1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "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=", - "dev": true - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", - "dev": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.8", - "extend": "3.0.1" - } - }, - "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", - "dev": true - }, - "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=", - "dev": true, - "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=", - "dev": true - }, - "ipaddr.js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", - "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "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-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "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=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "kew": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", - "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", - "dev": true - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "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=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "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=", - "dev": true, - "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=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", - "dev": true - }, - "mime-db": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", - "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=", - "dev": true - }, - "mime-types": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", - "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", - "dev": true, - "requires": { - "mime-db": "1.29.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "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=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", - "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==", - "dev": true, - "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", - "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=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "dev": true, - "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" - } - }, - "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - } - } - }, - "mout": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", - "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "node-fetch": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.2.tgz", - "integrity": "sha512-xZZUq2yDhKMIn/UgG5q//IZSNLJIwW2QxS14CNH5spuiXkITM2pUitjdq58yLSaU7m4M0wBNaM2Gh/ggY4YJig==", - "dev": true, - "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" - } - }, - "node-localstorage": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.0.tgz", - "integrity": "sha1-LkNqro3Mms6XtDxlwWwNV3vgpVw=", - "dev": true, - "requires": { - "write-file-atomic": "1.3.4" - } - }, - "node-status-codes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", - "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "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=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "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=", - "dev": true - }, - "p-map": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", - "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", - "dev": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "parseurl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=", - "dev": true - }, - "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=", - "dev": true - }, - "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-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=", - "dev": true - }, - "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "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=", - "dev": true - }, - "proxy-addr": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", - "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", - "dev": true, - "requires": { - "forwarded": "0.1.0", - "ipaddr.js": "1.4.0" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1", - "readable-stream": "2.3.3" - } - }, - "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" - } - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "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.16", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "sauce-connect-launcher": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.2.tgz", - "integrity": "sha1-c0bMj73EQxkTI0ObBzNFH181IfI=", - "dev": true, - "requires": { - "adm-zip": "0.4.7", - "async": "2.5.0", - "https-proxy-agent": "1.0.0", - "lodash": "4.17.4", - "rimraf": "2.6.1" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "selenium-assistant": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/selenium-assistant/-/selenium-assistant-5.1.0.tgz", - "integrity": "sha512-p9FSg0jTG4PPqTS5I+UNiZScYPzHFzSt8LXicvuqlsgFbZAxXDZgTlFtoDCS8TzscgCqz4slIgLg7f+oaMr4qA==", - "dev": true, - "requires": { - "chalk": "1.1.3", - "del": "3.0.0", - "dmg": "0.1.0", - "fs-extra": "3.0.1", - "mkdirp": "0.5.1", - "node-localstorage": "1.3.0", - "request": "2.81.0", - "sauce-connect-launcher": "1.2.2", - "selenium-webdriver": "3.4.0", - "semver": "5.4.1", - "which": "1.3.0", - "yauzl": "2.8.0" - } - }, - "selenium-webdriver": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.4.0.tgz", - "integrity": "sha1-FR90RSlNpqZsScwwB0eioX5TxSo=", - "dev": true, - "requires": { - "adm-zip": "0.4.7", - "rimraf": "2.6.1", - "tmp": "0.0.30", - "xml2js": "0.4.17" - } - }, - "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 - }, - "send": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz", - "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=", - "dev": true, - "requires": { - "debug": "2.6.8", - "depd": "1.1.1", - "destroy": "1.0.4", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.0", - "fresh": "0.5.0", - "http-errors": "1.6.2", - "mime": "1.3.4", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.3.1" - } - }, - "serve-static": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz", - "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=", - "dev": true, - "requires": { - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "parseurl": "1.3.1", - "send": "0.15.4" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "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" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "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" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar.gz": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.5.tgz", - "integrity": "sha1-4a2n5F7yJBtLHuWBI8j0C108G8Q=", - "dev": true, - "requires": { - "bluebird": "2.11.0", - "commander": "2.11.0", - "fstream": "1.0.11", - "mout": "0.11.1", - "tar": "2.2.1" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "dev": true - } - } - }, - "timed-out": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", - "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=", - "dev": true - }, - "tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "dev": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-detect": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", - "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", - "dev": true - }, - "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.16" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "1.0.4" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", - "dev": true - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", - "dev": true - }, - "vary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", - "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "xml2js": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", - "dev": true, - "requires": { - "sax": "1.2.4", - "xmlbuilder": "4.2.1" - } - }, - "xmlbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", - "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "yauzl": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", - "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", - "dev": true, - "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" - } - } - } -} diff --git a/integration/messaging/package.json b/integration/messaging/package.json index a05b21da8ac..9c11c4eb7ea 100644 --- a/integration/messaging/package.json +++ b/integration/messaging/package.json @@ -1,7 +1,13 @@ { + "name": "firebase-messaging-selenium-test", + "private": true, + "version": "0.1.0", "scripts": { "test": "node ./download-browsers.js && mocha" }, + "dependencies": { + "firebase": "^4.3.3" + }, "devDependencies": { "chai": "^4.1.1", "chromedriver": "^2.31.0", diff --git a/integration/messaging/runner.sh b/integration/messaging/runner.sh deleted file mode 100755 index 1575a6ddcde..00000000000 --- a/integration/messaging/runner.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash - -# Copyright 2017 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -ev - -# Variables -ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" -GULP_CLI="$ROOT/node_modules/.bin/gulp" -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -WORK_DIR=`mktemp -d` - -# check if tmp dir was created -if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then - echo "Could not create temp dir" - exit 1 -fi - -# deletes the temp directory -function cleanup { - rm -rf "$WORK_DIR" - echo "Deleted temp working directory $WORK_DIR" -} - -# register the cleanup function to be called on the EXIT signal -# trap cleanup EXIT - -# Enter work dir -pushd "$WORK_DIR" - -if [ ! -d "$ROOT/dist/package" ]; then - pushd $ROOT - $GULP_CLI build - popd -fi - -# Simulate env -cp -r $DIR/* . -npm install - -echo "$ROOT/dist/package" -npm install "$ROOT/dist/package" - -if hash xvfb-run 2>/dev/null; then - xvfb-run npm run test -else - npm run test -fi diff --git a/integration/messaging/test/send-receive-msg.js b/integration/messaging/test/send-receive-msg.js index c21ec37dd9a..66caa4edc27 100644 --- a/integration/messaging/test/send-receive-msg.js +++ b/integration/messaging/test/send-receive-msg.js @@ -33,7 +33,7 @@ describe('Firebase Messaging Integration Tests', () => { return testServer.stop(); }); - const performTestInBrowser = (seleniumBrowser) => { + const performTestInBrowser = seleniumBrowser => { // Mocha must have functions in describe and it functions due to its // binding behavior describe(`Test Messaging in ${seleniumBrowser.getPrettyName()}`, function() { @@ -47,11 +47,14 @@ describe('Firebase Messaging Integration Tests', () => { this.timeout(10 * 1000); // Configure the notification permissions - switch(seleniumBrowser.getId()) { + switch (seleniumBrowser.getId()) { case 'firefox': { const ffProfile = new seleniumFirefox.Profile(); - ffProfile.setPreference('security.turn_off_all_security_so_that_' + - 'viruses_can_take_over_this_computer', true); + ffProfile.setPreference( + 'security.turn_off_all_security_so_that_' + + 'viruses_can_take_over_this_computer', + true + ); ffProfile.setPreference('dom.push.testing.ignorePermission', true); ffProfile.setPreference('notification.prompt.testing', true); ffProfile.setPreference('notification.prompt.testing.allow', true); @@ -64,23 +67,25 @@ describe('Firebase Messaging Integration Tests', () => { profile: { content_settings: { exceptions: { - notifications: {}, - }, - }, - }, + notifications: {} + } + } + } }; - chromePreferences.profile.content_settings. - exceptions.notifications[testServer.serverAddress + ',*'] = { - setting: 1, + chromePreferences.profile.content_settings.exceptions.notifications[ + testServer.serverAddress + ',*' + ] = { + setting: 1 }; - seleniumBrowser.getSeleniumOptions().setUserPreferences(chromePreferences); + seleniumBrowser + .getSeleniumOptions() + .setUserPreferences(chromePreferences); /* eslint-enable camelcase */ break; } } - return seleniumBrowser.getSeleniumDriver() - .then((driver) => { + return seleniumBrowser.getSeleniumDriver().then(driver => { currentWebDriver = driver; }); }); @@ -94,16 +99,17 @@ describe('Firebase Messaging Integration Tests', () => { }); const getInPageToken = () => { - return currentWebDriver.wait(() => { - return currentWebDriver.executeScript(() => { - return document.querySelector('.js-token').textContent.length > 0; + return currentWebDriver + .wait(() => { + return currentWebDriver.executeScript(() => { + return document.querySelector('.js-token').textContent.length > 0; + }); + }) + .then(() => { + return currentWebDriver.executeScript(() => { + return document.querySelector('.js-token').textContent; + }); }); - }) - .then(() => { - return currentWebDriver.executeScript(() => { - return document.querySelector('.js-token').textContent; - }); - }); }; const sendFCMMessage = (endpoint, apiBody) => { @@ -111,116 +117,144 @@ describe('Firebase Messaging Integration Tests', () => { method: 'POST', body: JSON.stringify(apiBody), headers: { - 'Authorization': 'key=AIzaSyCqJkOa5awRsZ-1EyuAwU4loC3YXDBouIo', + Authorization: 'key=AIzaSyCqJkOa5awRsZ-1EyuAwU4loC3YXDBouIo', 'Content-Type': 'application/json' } }) - .then((response) => { - // FCM will return HTML is there is an error so we can't parse - // the response as JSON, instead have to read as text, then parse - // then handle the possible error. - return response.text() - .then((responseText) => { - try { - return JSON.parse(responseText); - } catch (err) { - throw new Error(`Unexpected response: '${responseText}'`); + .then(response => { + // FCM will return HTML is there is an error so we can't parse + // the response as JSON, instead have to read as text, then parse + // then handle the possible error. + return response.text().then(responseText => { + try { + return JSON.parse(responseText); + } catch (err) { + throw new Error(`Unexpected response: '${responseText}'`); + } + }); + }) + .then(responseObj => { + if (responseObj.success !== 1) { + throw new Error( + 'Unexpected response: ' + JSON.stringify(responseObj) + ); } }); - }) - .then((responseObj) => { - if (responseObj.success !== 1) { - throw new Error('Unexpected response: ' +JSON.stringify(responseObj)); - } - }); }; const getInPageMessage = () => { - return currentWebDriver.wait(() => { - return currentWebDriver.executeScript(() => { - return document.querySelectorAll('.js-message-list > li').length > 0; + return currentWebDriver + .wait(() => { + return currentWebDriver.executeScript(() => { + return ( + document.querySelectorAll('.js-message-list > li').length > 0 + ); + }); + }) + .then(() => { + return currentWebDriver.executeScript(() => { + return document.querySelector('.js-message-list > li:first-child') + .textContent; + }); }); - }) - .then(() => { - return currentWebDriver.executeScript(() => { - return document.querySelector('.js-message-list > li:first-child').textContent; - }); - }); }; - const performTest = (dataPayload, notificationPayload) => { - return currentWebDriver.get(`${testServer.serverAddress}/demo-valid/`) - .then(() => getInPageToken()) - .then((fcmToken) => { - const fcmAPIPayload = {}; - fcmAPIPayload.to = fcmToken; + const performTest = (dataPayload, notificationPayload, context) => { + return currentWebDriver + .get(`${testServer.serverAddress}/demo-valid/`) + .then(() => getInPageToken()) + .then(fcmToken => { + const fcmAPIPayload = {}; + fcmAPIPayload.to = fcmToken; - if (dataPayload != null) { - fcmAPIPayload.data = dataPayload; - } + if (dataPayload != null) { + fcmAPIPayload.data = dataPayload; + } - if (notificationPayload != null) { - fcmAPIPayload.notification = notificationPayload; - } + if (notificationPayload != null) { + fcmAPIPayload.notification = notificationPayload; + } - return sendFCMMessage(PROD_ENDPOINT, fcmAPIPayload); - }) - .then(() => { - return getInPageMessage(); - }) - .then((inPageMessage) => { - const inPageObj = JSON.parse(inPageMessage); - if (dataPayload) { - expect(inPageObj.data).to.deep.equal(dataPayload); - } else { - expect(typeof inPageObj.data).to.equal('undefined'); - } - if (notificationPayload) { - expect(inPageObj.notification).to.deep.equal(notificationPayload); - } else { - expect(typeof inPageObj.notification).to.equal('undefined'); - } - }) - .then(() => { - return new Promise((resolve) => setTimeout(resolve, 4000)); - }); + return sendFCMMessage(PROD_ENDPOINT, fcmAPIPayload); + }) + .then(() => { + return getInPageMessage(); + }) + .then(inPageMessage => { + const inPageObj = JSON.parse(inPageMessage); + if (dataPayload) { + expect(inPageObj.data).to.deep.equal(dataPayload); + } else { + expect(typeof inPageObj.data).to.equal('undefined'); + } + if (notificationPayload) { + expect(inPageObj.notification).to.deep.equal(notificationPayload); + } else { + expect(typeof inPageObj.notification).to.equal('undefined'); + } + }) + .then(() => { + return new Promise(resolve => setTimeout(resolve, 4000)); + }) + .catch(err => { + if (seleniumBrowser.getReleaseName() === 'unstable') { + console.warn( + chalk`{yellow WARNING: Test failed in unstable browser, skipping}` + ); + console.warn(err); + if (context) { + return context.skip(); + } + } + throw err; + }); }; it('should send and receive messages with no payload', function() { - return performTest(null, null); + return performTest(null, null, this); }); it('should send and receive messages with data payload', function() { - return performTest({hello: 'world'}, null); + return performTest({ hello: 'world' }, null, this); }); it('should send and receive messages with notification payload', function() { - return performTest(null, { - title: 'Test Title', - body: 'Test Body', - icon: '/test/icon.png', - click_action: '/', - tag: 'test-tag', - }); + return performTest( + null, + { + title: 'Test Title', + body: 'Test Body', + icon: '/test/icon.png', + click_action: '/', + tag: 'test-tag' + }, + this + ); }); it('should send and receive messages with data & notification payload', function() { - return performTest({hello: 'world'}, { - title: 'Test Title', - body: 'Test Body', - icon: '/test/icon.png', - click_action: '/', - tag: 'test-tag', - }); + return performTest( + { hello: 'world' }, + { + title: 'Test Title', + body: 'Test Body', + icon: '/test/icon.png', + click_action: '/', + tag: 'test-tag' + }, + this + ); }); }); }; const availableBrowsers = seleniumAssistant.getLocalBrowsers(); - availableBrowsers.forEach((assistantBrowser) => { + availableBrowsers.forEach(assistantBrowser => { // Only test on Chrome and Firefox - if (assistantBrowser.getId() !== 'chrome' && - assistantBrowser.getId() !== 'firefox') { + if ( + assistantBrowser.getId() !== 'chrome' && + assistantBrowser.getId() !== 'firefox' + ) { return; } diff --git a/integration/messaging/test/static/demo-valid/index.html b/integration/messaging/test/static/demo-valid/index.html index 5dd4d9b632c..2f87d8edf83 100644 --- a/integration/messaging/test/static/demo-valid/index.html +++ b/integration/messaging/test/static/demo-valid/index.html @@ -27,8 +27,8 @@