# react-component-isolator
A simple module that spins up a react app where the only component is the react component you pass in.

## Set up:

### Install `react-component-isolator`

```
npm install react-component-isolator --save-dev
```

### Install `react-app-rewired` in the client

```
cd <REACT_SUBDIR>
npm install --save-dev react-app-rewired
```

### Add an `npm run isolate` command

Inside your `package.json` in your React client, add a new script:

```json
{
    "scripts": {
        "isolate": "react-app-rewired start"
    }
}
```

### Ignore test files

Ignore the following folder:

```
<REACT_SUBDIR>/src/_isolator_generated_files_
```

Ignore the following file:

```
<REACT_SUBDIR>/config-overrides.js
```

## Customization:

### Project Subdirectory

If your React project is not in the `/client` folder, add a `REACT_SUBDIR` environment variable when running tests. If the top-level folder is the React project, use `.` as the subdirectory.

## Writing Tests

We will assume that you are using `dce-selenium` to write your tests.

### Import at the top of every test file:

```js
const isolate = require('react-component-isolator');
```

### Test an individual component:

Call the `isolate` function with an arguments object that has the following properties:

- `component` – the relative path of the component to test from _within the /src folder_
- `test` – an _asynchronous_ function containing the tests to run on the component. Called with a url argument (the url to visit to view the component
- `[props]` – an object containing all the properties of the component in the form `{ prop: value }` where the values must either be functions or JSONifiable values

From within a prop that is a function, you can use `this.get(key)` and `this.set(key, val)` to read from/write to the embeddedMetadata.

Using `dce-selenium`, you can get the embeddedMetadata using:

```js
const data = await driver.getEmbeddedMetadata();
```

### Example test:

```js
it('Works', async function () {
    await isolate({
        component: 'Buttons/OkayButton',
        props: {
            title: 'Click Me',
            onClick: () => {
                this.set('buttonClicked', true);
            },
        },
        test: async (url) => {
            await driver.visit(url);
            await driver.clickByContents('Click Me');
            const data = await driver.getEmbeddedMetadata();
            assert(data.buttonClicked);
        },
    });
});
```
