open-index/open-npm huggingface dataset:
npm package: @phenax/random-dog-name
Description: Get a new name for that garbage dog
Author: Akshay Nair
Latest version: 0.0.0-test.1


# random-dog-namimizeinator
Get a random dog name. You can name your cat with this too.

### Install

* Add package in project using
`yarn add @phenax/random-dog-name`

* Import
```js
import getRandomDogName from '@phenax/random-dog-name';
```

### API

```js
console.log(`Name: ${getRandomDogName()}`);
```
npm package: @phenax/react-cc-validator
Description: Credit/Debit card number validation library with input formatting
Author: Akshay Nair
Latest version: 0.0.1


# react-cc-validator
Credit/Debit card number validator input written in react.
[Demo](https://phenax.github.io/react-cc-validator)


[![Travis](https://img.shields.io/travis/phenax/react-cc-validator.svg?style=for-the-badge)](https://travis-ci.org/phenax/react-cc-validator)
[![Codecov](https://img.shields.io/codecov/c/github/phenax/react-cc-validator.svg?style=for-the-badge)](https://codecov.io/gh/phenax/react-cc-validator)
<!-- [![npm](https://img.shields.io/npm/v/@phenax/react-cc-validator.svg?style=for-the-badge)] -->



### Install

* Add package in project using
`yarn add @phenax/react-cc-validator`

* Import
```js
import CardNumberValidator from '@phenax/react-cc-validator';
```

### API

#### Usage
You can refer to [/example](https://github.com/phenax/react-cc-validator/tree/master/example/src)

```js
const YourComponent = () => (
  <div>
    <CardNumberValidator>
      {({ isValid, cardType, getInputProps }) => (
        <div>
          <input type="text" {...getInputProps()} />
          <div>{ isValid && cardType }</div>
          {isValid || <div>Card number is invalid</div>}
        </div>
      )}
    </CardNumberValidator>
  </div>
);
```

#### Types
```js
// The props that can be passed to CardNumberValidator compopent
type PropTypes = {
  children: PassedProps => ReactNode,
  validCardTypes: Array<String>,
  format: Boolean,
};

// The props to be passed to the input element
type InputProps = {
  onChange: Function,
  value: String,
};

// The props passed down to the render component
type PassedProps = {
  ...InputProps,
  isValid: Boolean,
  cardType: String,
  getInputProps: () => InputProps,
};
```
npm package: @phenax/react-scripts
Description: Configuration and scripts for Create React App.
Latest version: 0.0.3-alpha

# react-scripts

This package includes scripts and configuration used by [Create React App](https://github.com/facebookincubator/create-react-app).<br>
Please refer to its documentation:

* [Getting Started](https://github.com/facebookincubator/create-react-app/blob/master/README.md#getting-started) – How to create a new app.
* [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md) – How to develop apps bootstrapped with Create React App.
npm package: @phenax/with-experiments
Description: with-experiments HOC for A/B experiments
Author: Shivam Rastogi
Latest version: 0.0.0

# with-experiments

[![Travis][build-badge]][build]
[![npm package][npm-badge]][npm]
[![Coveralls][coveralls-badge]][coveralls]

Describe with-experiments here.

[build-badge]: https://img.shields.io/travis/user/repo/master.png?style=flat-square
[build]: https://travis-ci.org/user/repo

[npm-badge]: https://img.shields.io/npm/v/npm-package.png?style=flat-square
[npm]: https://www.npmjs.org/package/npm-package

[coveralls-badge]: https://img.shields.io/coveralls/user/repo/master.png?style=flat-square
[coveralls]: https://coveralls.io/github/user/repo
npm package: @phence/react-native-magnus
Description: A Utility-First React Native UI Framework
Author: jsartisan
Latest version: 1.1.0

<p align="center">
  <a href="https://magnus-ui.com">
    <img width="80px" style="margin-right: 20px" src="https://magnus-ui.com/images/logo.svg">
  </a>
</p>

<h1 align="center">Magnus UI</h1>

<div align="center">

A Utility-First React Native UI Framework

[![npm package](https://img.shields.io/npm/v/react-native-magnus.svg?style=flat-square)](https://www.npmjs.org/package/react-native-magnus) [![NPM downloads](http://img.shields.io/npm/dm/react-native-magnus.svg?style=flat-square)](http://npmjs.com/react-native-magnus) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)

</div>

<p align="center">
  <a href="https://magnus-ui.com">
    <img width="400px" style="margin-right: 20px" src="https://magnus-ui.com/images/hero.png">
  </a>
</p>

**Build UI in React Native, without the tears**

```jsx
<Text fontSize="md" color="pink500">
  Magnus UI 🚀
</Text>
```

## ✨ Features

- Universal (Android, iOS, Web, & more)
- Works with Expo
- Works with Vanilla React Native
- Full theme support
- Custom theme variants
- TypeScript support
- Super simple API

# Examples

- [Example App]https://expo.io/@pawankumar2901/projects/react-native-magnus-example

## 📦 Installation

```bash
npm install react-native-magnus
```

```bash
yarn add react-native-magnus
```

## 🔨 Usage

```jsx
import { Button } from 'react-native-magnus';

<Button />;
```

## 📦 Components

- [Div](http://magnus-ui.com/docs/div)
- [Text](http://magnus-ui.com/docs/text)
- [Button](http://magnus-ui.com/docs/button)
- [Checkbox](http://magnus-ui.com/docs/checkbox)
- [Drawer](http://magnus-ui.com/docs/drawer)
- [Icon](http://magnus-ui.com/docs/icon)
- [Input](http://magnus-ui.com/docs/input)
- [Avatar](http://magnus-ui.com/docs/avatar)
- [Image](http://magnus-ui.com/docs/image)
- [Modal](http://magnus-ui.com/docs/modal)
- [Radio](http://magnus-ui.com/docs/radio)
- [Skeleton](http://magnus-ui.com/docs/skeleton)
- [Snackbar](http://magnus-ui.com/docs/snackbar)
- [Tag](http://magnus-ui.com/docs/tag)
- [Dropdown](http://magnus-ui.com/docs/dropdown)
- [Fab](http://magnus-ui.com/docs/fab)
- [Select](http://magnus-ui.com/docs/select)
- [Tooltip](http://magnus-ui.com/docs/tooltip)
- [Overlay](http://magnus-ui.com/docs/overlay)

## Examples

- [Components Usage](https://snack.expo.io/@pawankumar2901/magnus-ui)
- [Dribble Login Screen](https://snack.expo.io/@pawankumar2901/dribble-login-page)

## 🤝 Contributing [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
npm package: @phenixs/cli-plugin-babel
Description: babel plugin for phenixs-cli
Author: yangliyang.li@qunar.com
Latest version: 0.0.71

# @vue/cli-plugin-babel

> babel plugin for vue-cli

## Configuration

Uses Babel 7 + `babel-loader` + [@vue/babel-preset-app](https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/babel-preset-app) by default, but can be configured via `babel.config.js` to use any other Babel presets or plugins.

By default, `babel-loader` excludes files inside `node_modules` dependencies. If you wish to explicitly transpile a dependency module, you will need to add it to the `transpileDependencies` option in `vue.config.js`:

``` js
module.exports = {
  transpileDependencies: [
    // can be string or regex
    'my-dep',
    /other-dep/
  ]
}
```

## Caching

[cache-loader](https://github.com/webpack-contrib/cache-loader) is enabled by default and cache is stored in `<projectRoot>/node_modules/.cache/babel-loader`.

## Parallelization

[thread-loader](https://github.com/webpack-contrib/thread-loader) is enabled by default when the machine has more than 1 CPU cores. This can be turned off by setting `parallel: false` in `vue.config.js`.

## Installing in an Already Created Project

``` sh
vue add @vue/babel
```

## Injected webpack-chain Rules

- `config.rule('js')`
- `config.rule('js').use('babel-loader')`
- `config.rule('js').use('cache-loader')`
npm package: @phenixs/cli-plugin-eslint
Description: eslint plugin for phenixs-cli
Author: yangliyang.li@qunar.com
Latest version: 0.0.71

# @vue/cli-plugin-eslint

> eslint plugin for vue-cli

## Injected Commands

- **`vue-cli-service lint`**

  ```
  Usage: vue-cli-service lint [options] [...files]

  Options:

    --format [formatter] specify formatter (default: codeframe)
    --no-fix             do not fix errors
    --max-errors         specify number of errors to make build failed (default: 0)
    --max-warnings       specify number of warnings to make build failed (default: Infinity)
  ```

  Lints and fixes files. If no specific files are given, it lints all files in `src` and `test`.

  Other [ESLint CLI options](https://eslint.org/docs/user-guide/command-line-interface#options) are also supported.

## Configuration

ESLint can be configured via `.eslintrc` or the `eslintConfig` field in `package.json`.

Lint-on-save during development with `eslint-loader` is enabled by default. It can be disabled with the `lintOnSave` option in `vue.config.js`:

``` js
module.exports = {
  lintOnSave: false
}
```

When set to `true`, `eslint-loader` will emit lint errors as warnings. By default, warnings are only logged to the terminal and does not fail the compilation.

To make lint errors show up in the browser overlay, you can use `lintOnSave: 'error'`. This will force `eslint-loader` to always emit errors. this also means lint errors will now cause the compilation to fail.

Alternatively, you can configure the overlay to display both warnings and errors:

``` js
// vue.config.js
module.exports = {
  devServer: {
    overlay: {
      warnings: true,
      errors: true
    }
  }
}
```

When `lintOnSave` is a truthy value, `eslint-loader` will be applied in both development and production. If you want to disable `eslint-loader` during production build, you can use the following config:

``` js
// vue.config.js
module.exports = {
  lintOnSave: process.env.NODE_ENV !== 'production'
}
```

## Installing in an Already Created Project

``` sh
vue add @vue/eslint
```

## Injected webpack-chain Rules

- `config.module.rule('eslint')`
- `config.module.rule('eslint').use('eslint-loader')`
npm package: @phenom.pub/schema-registry-cli
Description: CLI to interact with the Phenom Schema Registry
Author: Hindawi
Latest version: 1.0.6

# `@phenom.pub/schema-registry-cli`

CLI tool to interact with the Phenom Schema Registry

## Usage

```shell
$ schema-registry-cli <command>

Commands:
  schema-registry-cli validate  validate provided schema against the Phenom
                                Schema Registry

Options:
  --help     Show help                                                 [boolean]
  --version  Show version number                                       [boolean]
```

```shell
$ schema-registry-cli validate

validate provided schema against the Phenom Schema Registry

Options:
  --help      Show help                                                [boolean]
  --version   Show version number                                      [boolean]
  --service   Name of the service for which the schema is validated
                                                             [string] [required]
  --path      Path to file exporting the typeDefs (either .js or .graphqls)
                                                             [string] [required]
  --property  Set in case the file provided at path exports an object.   
              The exported object must be a GraphQLSchema type          [string]
```
npm package: @phenomenon/lightning
Description: The extendable TypeScript animation library.
Latest version: 0.4.0

# Lighting

The extendable TypeScript animation library.

```
yarn add @phenomenon/lightning

npm install @phenomenon/lightning
```

## Examples

```js
import { lightning, animate, fromTo, delay, val } from '@phenomenon/lightning'

const frames = animate('#my-element', [
    fromTo({ opacity: val(0, 1) }, 400),
    delay(1000),
    fromTo({ opacity: val(1, 0) }, 400),
])

lightning(frames).play()
```

Using `parallel`, `cascade` or `sequence`.

```js
import {
    lightning,
    animate,
    parallel,
    fromTo,
    delay,
    set,
    val,
    color,
    transform,
} from '@phenomenon/lightning'

const bodyFrames = animate('body', [
    fromTo({ backgroundColor: color('#FF0000', '#00FF00') }, 1500),
])

const elementFrames = animate('#my-element', [
    delay(500),
    set({ display: ['none', 'block'] }),
    fromTo(
        {
            opacity: val(0, 1),
            transform: transform({
                y: val(-200, 0, 'px'),
                scale: val(0.9, 1),
                rotate: val(10, 0, 'deg'),
            }),
        },
        500,
    ),
])

const frames = parallel([bodyFrames, elementFrames])

const animation = lightning(frames, {
    onComplete() {
        console.log('onComplete')
        animation.play() // loop
    },
})

animation.seek(500)
animation.play()
```
npm package: @phenomic/babel-preset
Description: Babel preset, recommended for Phenomic
Latest version: 1.0.0

# @phenomic/babel-preset

> Babel preset, recommended for Phenomic

Basically
[babel-preset-react-app](https://github.com/facebookincubator/create-react-app/tree/master/packages/babel-preset-react-app)
for now

➡ More details at [phenomic.io](https://phenomic.io/)
npm package: @phenomic/markdown-as-json
Description: Transform markdown files as json files
Latest version: 1.0.0

# @phenomic/markdown-as-json

[![Repo on GitHub](https://img.shields.io/badge/repo-GitHub-3D76C2.svg)](https://github.com/phenomic/markdown-as-json)
[![Repo on GitLab](https://img.shields.io/badge/repo-GitLab-6C488A.svg)](https://gitlab.com/MoOx/markdown-as-json)

> Transform markdown content as a JSON

Handles:

- front-matter (via gray-matter)
- auto slug for headings (with anchors)
- code highlight (via highlight.js)
- table of contents (via [remark-toc](https://www.npmjs.com/package/remark-toc))

The idea is to get a markdown like this

````markdown
---
test: a
test2: b
---

## Test

[link](href)

```js
console.log(window);
```
````

like

```json
{
  "test": "a",
  "test2": "b",
  "headings": [
    {
      "id": "test",
      "level": 2,
      "text": "Test",
    },
  ],
  "body": {
    "c": [
      {
        "c": [
          {
            "c": [
              {
                "p": {
                  "class": "icon icon-link",
                },
                "t": "span",
              },
            ],
            "p": {
              "aria-hidden": "true",
              "href": "#test",
            },
            "t": "a",
          },
          "Test",
        ],
        "p": {
          "id": "test",
        },
        "t": "h2",
      },
      "
",
      {
        "c": [
          {
            "c": [
              "link",
            ],
            "p": {
              "href": "href",
            },
            "t": "a",
          },
        ],
        "t": "p",
      },
      "
",
      {
        "c": [
          {
            "c": [
              {
                "c": [
                  "console",
                ],
                "p": {
                  "class": "hljs-built_in",
                },
                "t": "span",
              },
              ".log(",
              {
                "c": [
                  "window",
                ],
                "p": {
                  "class": "hljs-built_in",
                },
                "t": "span",
              },
              ")",
            ],
            "p": {
              "class": "hljs language-js",
            },
            "t": "code",
          },
        ],
        "t": "pre",
      },
    ],
    "t": "div",
  },
}
```

For easy rendering to dom (eg: React etc).

[Check out input](__tests__/index.js) & [output](__tests__/__snapshots__/index.js.snap) to get an idea of what to expect from this package.

[LICENSE](LICENSE)
npm package: @phenomic/preset-react-app
Description: Phenomic React app preset
Latest version: 1.0.0

# @phenomic/preset-react-app

> Phenomic React app preset

- renderer: react (`@phenomic/plugin-renderer-react`)
- bundler: webpack (`@phenomic/plugin-bundler-webpack`)
- collector: files (`@phenomic/plugin-collector-files`)
- transformers: markdown and JSON (`@phenomic/plugin-transform-markdown` +
  `@phenomic/plugin-transform-json`)

---

Check out our
[Getting started with Phenomic and `@phenomic/preset-react-app`](docs/getting-started/README.md)

---

➡ More details at [phenomic.io](https://phenomic.io/)
npm package: @phenomic/reason
Description: Phenomic Reason bindings
Latest version: 1.0.0-alpha.13

# @phenomic/reason

> Phenomic Reason bindings

## Installation

```console
$ npm install --save-dev @phenomic/reason
$ # Add @phenomic/reason to bs-dependencies
$ bsb -clean-world
$ bsb -make-world
```
npm package: @phenomnomnominal/angular-lazy-routes-fix
Description: TSLint rule/fix for Angular lazy-loaded routes
Author: Craig Spence
Latest version: 0.1.5

# angular-lazy-routes-fix

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/angular-lazy-routes-fix.svg)](https://img.shields.io/npm/v/@phenomnomnominal/angular-lazy-routes-fix.svg)
[![Code Climate](https://codeclimate.com/github/phenomnomnominal/angular-lazy-routes-fix/badges/gpa.svg)](https://codeclimate.com/github/phenomnomnominal/angular-lazy-routes-fix)
[![Test Coverage](https://codeclimate.com/github/phenomnomnominal/angular-lazy-routes-fix/coverage.svg)](https://codeclimate.com/github/phenomnomnominal/tsquery/angular-lazy-routes-fix)

## Installation

```sh
npm install @phenomnomnominal/angular-lazy-routes-fix --save-dev
```

Update your tslint.json file to extend this package:

```json
{
  "extends": [
    "@phenomnomnominal/angular-lazy-routes-fix"
  ],
  "rules": {
    "no-lazy-module-paths": [true],
    "//": "or",
    "no-lazy-module-paths": [true, "async"]
  }
}
```
npm package: @phenomnomnominal/commitlint-plugin
Description: commitlint rules for @phenomnomnominal
Author: Craig Spence
Latest version: 1.1.1

# @phenomnomnominal/commitlint-plugin

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/commitlint-plugin.svg)](https://www.npmjs.com/package/@phenomnomnominal/commitlint-plugin)

Custom commitlint rules for some of my open source things!
npm package: @phenomnomnominal/debug
Description: Very lazy tool for adding debug logging
Author: Craig Spence
Latest version: 0.2.5

# [@phenomnomnominal/debug](https://github.com/phenomnomnominal/debug/)

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/debug.svg)](https://www.npmjs.com/package/@phenomnomnominal/debug)

**`debug`** is a super lazy way to add debug logging!

## Usage

```typescript
import { debug } from '@phenomnomnominal/debug';

debug({ enabled: true });
```

## Options

```typescript
export type DebugOptions = {
  enabled: boolean; // Enable debug logging
  time: boolean; // Enable function execution time logging
  values: boolean; // Enable argument and return value logging
  logPath: string; // Disable stdout logging and print to file at this path
  header: string; // Header name for the initial debug log
  include: DebugIncludes; // RegExp to match node_modules paths that should be included in the logs
  ignore: DebugIgnores; // RegExp to match local paths that should be ignored from the logs
  logger: DebugLogger; // Custom logger implementation (Maybe you want to send it via HTTP 🤷‍♂️)
};
```
npm package: @phenomnomnominal/fyi
Description: Do something when a test fails!?
Author: Craig Spence
Latest version: 0.1.1

# FYI

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/fyi.svg)](https://img.shields.io/npm/v/@phenomnomnominal/fyi.svg)
[![Code Climate](https://codeclimate.com/github/phenomnomnominal/fyi/badges/gpa.svg)](https://codeclimate.com/github/phenomnomnominal/fyi)
[![Test Coverage](https://codeclimate.com/github/phenomnomnominal/fyi/coverage.svg)](https://codeclimate.com/github/phenomnomnominal/fyi/coverage)

## Installation

```sh
npm install @phenomnomnominal/fyi --save-dev
```
npm package: @phenomnomnominal/parameterised
Description: Create parameterised tests from Markdown(ish) tables
Author: Craig Spence
Latest version: 0.1.0

# @phenomnomnominal/parameterised

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/parameterised.svg)](https://img.shields.io/npm/v/@phenomnomnominal/parameterised.svg)
[![Code Climate](https://codeclimate.com/github/phenomnomnominal/parameterised/badges/gpa.svg)](https://codeclimate.com/github/phenomnomnominal/parameterised)
[![Test Coverage](https://codeclimate.com/github/phenomnomnominal/parameterised/coverage.svg)](https://codeclimate.com/github/phenomnomnominal/parameterised/coverage)

A little tool to create parameterised tests from [Markdown(ish) tables](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#tables)!

## Installation

```zsh
npm install @phenomnomnominal/parameterised --save-dev
```

## Parameterised testing

When writing unit tests, sometimes it is useful to do something like the following:

```javascript
[
    { a: 1, b: 2, expected: 3 },
    { a: -1, b: 1, expected: 0 },
    { a: 2.5, b: 2.5, expected: 5 }
].forEach(test => {
    const { a, b, expected } = test;
    assert(a + b === expected);
});
```

That works well, but wouldn't it be nice to be able to format that in a slightly more readable way? Enter **`parameterised`**!

```javascript
import { parameterised } from '@phenomnomnominal/parameterised';

parameterised`

    |  a  |  b  | expected |
    |  1  |  2  |    3     |
    |  -1 |  1  |    0     |
    | 2.5 | 2.5 |    5     |

`.forEach(test => {
    const { a, b, expected } = test;
    assert(a + b === expected);
});
```

## Examples:

**`parameterised`** can handle a bunch of different values:

```javascript
parameterised`

    |      param1       |   param2    |   param3  |
    | 1                 | 2           | 3         |
    | "hello"           | a string    | ""        |
    | {"foo":"bar"}     | undefined   | NaN       |
    | ${{ baz: 'qux' }} | Infinity    | [0,1,2]   |
    | ${new Date()}     | ${'string'} | 2e2       |
    | null              | 0.00000001  | ${9**9}   |

`;
```
npm package: @phenomnomnominal/protractor-add-mocha-hook
Description: Attach Mocha hooks 
Author: Craig Spence
Latest version: 0.1.1

# @phenomnomnominal/protractor-add-mocha-hook

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/protractor-add-mocha-hook.svg)](https://img.shields.io/npm/v/@phenomnomnominal/protractor-add-mocha-hook.svg)
[![Code Climate](https://codeclimate.com/github/phenomnomnominal/protractor-add-mocha-hook/badges/gpa.svg)](https://codeclimate.com/github/phenomnomnominal/protractor-add-mocha-hook)
[![Test Coverage](https://codeclimate.com/github/phenomnomnominal/protractor-add-mocha-hook/coverage.svg)](https://codeclimate.com/github/phenomnomnominal/protractor-add-mocha-hook/coverage)

## Installation

```zsh
npm install @phenomnomnominal/protractor-add-mocha-hook --save-dev
```

## Why?

This package is the culmination of a bunch of attempts to get Mocha hooks working well with Protractor, including when running tests in parallel.

This comment from [Tractor](https://github.com/TradeMe/tractor) describes some of the genesis:

```javascript
// HACK:
// This is a bit weird. We want to run some code after each Mocha spec runs,
// so we can add extra data to the test report.
//
// FIRST ATTEMPT: Use Mocha's `afterEach` in a Protractor plugin.
// Tried calling `afterEach in the  `onPrepare` lifecycle took, but
// the global Mocha hooks aren't available yet.
//
// SECOND ATTEMPT: Move hooks to a separate file.
// By moving the hook calls to a separate file, we can push that file into
// the list of specs. This works well when running all the specs in serial,
// but stops working when running them in parallel, as the separate file will
// be run in a separate process.
//
// THIRD ATTEMPT: Use Mocha's `after` hook in a Protractor plugin.
// In the `postTest` part of a Protractor plugin, we have access to the
// `after` hook, so we can use that to attach the hook. Unfortunately,
// the `after` hook happens outside the context of the running test,
// so you can't attach the information to the right test.
//
// FOURTH ATTEMPT: Use Mocha's `afterEach` hook in a Protractor plugin.
// In the `postTest` part of a Protractor plugin, we have access to the
// `afterEach` hook. That's great, and we also have access to the right
// test context. Unfortunately, the hook will be added for *each* test!
// So we have to add a flag and make sure we only add the hook once
// per process.
```

This repo contains the *FIFTH* attempt, adding a setter which allows you to add a hook as soon as Mocha has added it to the global context. It is *definitely* still a hack 😅.
npm package: @phenomnomnominal/protractor-use-mocha-hook
Description: Utility to help attach Mocha hooks to parallel Protractor processes
Author: Craig Spence
Latest version: 0.1.5

# @phenomnomnominal/protractor-use-mocha-hook

[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/protractor-use-mocha-hook.svg)](https://img.shields.io/npm/v/@phenomnomnominal/protractor-use-mocha-hook.svg)
[![Code Climate](https://codeclimate.com/github/phenomnomnominal/protractor-use-mocha-hook/badges/gpa.svg)](https://codeclimate.com/github/phenomnomnominal/protractor-use-mocha-hook)
[![Test Coverage](https://codeclimate.com/github/phenomnomnominal/protractor-use-mocha-hook/coverage.svg)](https://codeclimate.com/github/phenomnomnominal/protractor-use-mocha-hook/coverage)

## Installation

```zsh
npm install @phenomnomnominal/protractor-use-mocha-hook --save-dev
```

## Why

This package is the culmination of a bunch of attempts to get Mocha hooks working well with Protractor, including when running tests in parallel.

This comment from [Tractor](https://github.com/TradeMe/tractor) describes some of the genesis:

```javascript
// HACK:
// This is a bit weird. We want to run some code after each Mocha spec runs,
// so we can add extra data to the test report.
//
// FIRST ATTEMPT: Use Mocha's `afterEach` in a Protractor plugin.
// Tried calling `afterEach in the  `onPrepare` lifecycle took, but
// the global Mocha hooks aren't available yet.
//
// SECOND ATTEMPT: Move hooks to a separate file.
// By moving the hook calls to a separate file, we can push that file into
// the list of specs. This works well when running all the specs in serial,
// but stops working when running them in parallel, as the separate file will
// be run in a separate process.
//
// THIRD ATTEMPT: Use Mocha's `after` hook in a Protractor plugin.
// In the `postTest` part of a Protractor plugin, we have access to the
// `after` hook, so we can use that to attach the hook. Unfortunately,
// the `after` hook happens outside the context of the running test,
// so you can't attach the information to the right test.
//
// FOURTH ATTEMPT: Use Mocha's `afterEach` hook in a Protractor plugin.
// In the `postTest` part of a Protractor plugin, we have access to the
// `afterEach` hook. That's great, and we also have access to the right
// test context. Unfortunately, the hook will be added for *each* test!
// So we have to add a flag and make sure we only add the hook once
// per process.
```

This repo contains the *FIFTH* attempt, adding a setter which allows you to add a hook as soon as Mocha has added it to the global context. It is *definitely* still a hack 😅.

## Usage

It can be used when creating an inline Protractor plugin like this:

```javascript
protractorConfig.plugins.push({
    inline: {
        // use Protractor's setup to get in before Mocha's global `afterEach` hook is created
        setup () {
            // use `function` over `=>` to let Mocha set `this`:
            useMochaHook('afterEach', async function () {
                // do something
            });
        }
    }
});
```