This example shows various examples of testing Cocoon nodes and definitions, as well as using Cocoon itself for end-to-end testing.
npx github-download-directory aengl/cocoon examples/testing
cd examples/testing
npm install
npm run editor
To run the tests in this example:
npm run test
Since Cocoon nodes are essentially just functions, they are particularly easy to test. The @cocoon/testing package provides a test helper that automatically creates a dummy context to make unit testing of nodes a trivial matter. Here is an example that uses AVA:
// MyNode.test.js
import { snapshotNode } from '@cocoon/testing';
import test from 'ava';
import { MyNode } from './MyNode';
test('produces correct output', async t => {
t.snapshot(await snapshotNode(MyNode, { data: 'foo' }));
});
For a complete example, check Assert.test.js.
When integration testing definitions we don't need the @cocoon/testing
helper library, since we're running the definition with Cocoon itself, albeit headlessly without the editor:
// test.js
import { testDefinition } from '@cocoon/cocoon';
import test from 'ava';
test('runs cocoon.yml', async t => {
t.snapshot(await testDefinition('cocoon.yml'));
});
Cocoon itself can be used as a test runner for complex integration and end-to-end tests. In this example, we create an automated test for a website using puppeteer.
The idea is straightforward: create a browser and page object and pass them through a series of nodes that execute simple Puppeteer snippets. The main advantage is that it breaks complicated, long tests into re-usable chunks and allows us to write them bit by bit, without having to re-run the entire test from the start.
As an added bonus, Cocoon can take a screenshot of each step and show it in the editor, produces a nice visual history of the test for free.
Using another custom node (Assert.js) we can check properties through the context.
This example also demonstrates that in Cocoon it's not always necessary to create isomorphic nodes and avoid mutation of port data. While it limits some of its capabilities (persisting and inspecting port data is not possible with non-serialisable data), there are compelling use-cases to do so anyway.
We're certainly not advocating to replace your entire end-to-end test suite with Cocoon, that would most certainly be a questionable move. But Cocoon can help make development of complex tests easier, and the resulting scripts can ultimately just be called like a traditional JS generator function, outside of Cocoon.