# WooCommerce End-to-End Test Packages

There are two limitations which significantly impact the architecture of E2E test packages:

- Referencing the `jest` functions `describe`, `it`, `beforeAll`, etc. throws a fatal error outside the `jest` environment.
- `jest` will not scan for tests in any path containing `node_mdules`.

## Creating a tests package

The way to create a tests package with the above limitations is

- **In the tests package**, wrap each test in a function

```js
/**
 * Require the necessary jest functions to prevent the package build from referencing them
 * `import` references imported functions during package build
 */

const { describe, it, beforeAll } = require( '@jest/globals' );

const testMyCriticalFlow = () => {
    describe( 'My Critical Flow', () => {
        beforeAll( async () => {
            // Test setup
        } );
        it( 'can complete first step', async () => {
            // Do stuff
          expect( someValue ).toBeTruthy();
        } );
    } );
};

modules.exports = testMyFlow;
```

- **In the `tests/e2e/specs` folder**, create a test spec that calls the test function

```js
import { testMyCriticalFlow } from 'MyTestsPackage';

testMyCriticalFlow();
```

## Adding the scaffolds for the test installer

To work with the limitations outlined above, the test installer needs to access the test scaffolding information without accessing the package index. As a result, the `installFiles` is a required path in the steps below

- Create an `installFiles` folder in the root of the package
- Add an `index.js` to the folder which exports an object with some or all of three properties
```js
module.exports = {
	defaultJson: 'installFiles/default-test-config.json',
	initializeSh: 'installFiles/initialize.sh.default',
	testSpecs: 'installFiles/scaffold-tests.json',
};
```
- The value of each of the properties should be a relative path from the package `index.js`. The test installer will remove `dist`, `build`, and `build-modules` from the end of the package index path.
- `defaultJson`: Path to a JSON file containing all `default.json` entries needed for the tests in the package. 
- `initializeSh`: Path to a bash script containing the WP CLI commands needed to initialize the `e2e-environment` test container.
- `testSpecs`: Path to a JSON file containing a nested object
```json
{
  "active": [
    {
      "name": "first-folder-name",
      "description": "First tests",
      "testFiles": [
        {
          "name": "test-name-a",
          "functions": [
            "testMyCriticalFlow"
          ]
        },
        {
          "name": "test-name-b",
          "functions": [
            "testSecondCriticalFlow",
            "testThirdCriticalFlow"
          ]
        }
      ]
    },
    {
      "name": "second-folder-name",
      "description": "Second tests",
      "testFiles": [
        ....
      ]
    }
  ]
}
```

The test installer uses the `testSpecs` nested object to create test specs. Using the example above, create `tests/e2e/specs/first-folder-name/test-name-b.test.js`:

```js
/* This file was auto-generated by the command `npx wc-e2e install your-package-name`. */
import { testSecondCriticalFlow, testThirdCriticalFlow } from 'your-package-name';

testSecondCriticalFlow();
testThirdCriticalFlow();
```

