Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Jest circus support & RootCauseJestEnv #55

Merged
merged 7 commits into from Oct 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 26 additions & 27 deletions docs/integration-guide.md
@@ -1,4 +1,4 @@
# [Draft][WIP] Testim Root Cause integration guide
# [Draft][wip] Testim Root Cause integration guide

To read about the benefits of using Root Cause, see: XXX

Expand All @@ -7,10 +7,11 @@ To read about the benefits of using Root Cause, see: XXX
Testim Root Cause can work with playwright and puppeteer in a similar manner. -->

## Jest and Puppeteer

[Example project](https://github.com/testimio/root-cause/tree/master/integration-examples/jest-and-puppeteer)

Root Cause assume you already have global browser page available in your jest setup.
The following example assume you are using the popular [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) package.
The following example assume you are using the popular [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) package.

### Install the `@testim/root-cause-jest` package.

Expand All @@ -19,31 +20,30 @@ npm install testim/root-cause-jest
```

### Update your jest.config.js

```js
const puppeteerPreset = require('jest-puppeteer-preset/jest-preset.json');

const runId = Date.now().toString();

module.exports = {
...puppeteerPreset,
reporters: [
['@testim/root-cause-jest/lib/reporter/default', { runId }],
],
setupFilesAfterEnv: [
...puppeteerPreset.setupFilesAfterEnv,
'@testim/root-cause-jest/lib/forSetupFilesAfterEnv'
],
globals: {
runId,
},
...puppeteerPreset,
testEnvironment: '@testim/root-cause-jest/lib/RootCauseJestEnv',
reporters: [['@testim/root-cause-jest/lib/reporter/default', { runId }]],
globals: {
runId,
},
};

```

### Run your test

After the config change, you can run jest as usual.

```sh
npx jest
```

If there are no failing tests, Root Cause will inject the command to run to view the failing test analysis (See the following screenshot)

<img src="./images/jest-puppeteer-reporter-output.png" border="1">
Expand All @@ -53,40 +53,39 @@ npx root-cause show a3427a48ff8c45c2ee6e574d60fad119
```

### View results

To view the full test list, and open the viewer for passing tests, read the Root Cause CLI section ahead.

## Jest and Playwright

[Example project](https://github.com/testimio/root-cause/tree/master/integration-examples/jest-and-playwright)

The instructions are the same as with Puppeteer, but the jest config change.
Assuming you are using the popular jest-playwright package, your jest config should look like:

```js
const playwrightPreset = require('jest-playwright-preset/jest-preset.json');

const runId = Date.now().toString();

module.exports = {
...playwrightPreset,
testRunner: 'jasmine2',
reporters: [
['@testim/root-cause-jest/lib/reporter/default', { runId }],
],
setupFilesAfterEnv: [
...playwrightPreset.setupFilesAfterEnv,
'@testim/root-cause-jest/lib/forSetupFilesAfterEnv'
],
globals: {
runId,
},
...playwrightPreset,
testEnvironment: '@testim/root-cause-jest/lib/RootCauseJestEnv',
reporters: [['@testim/root-cause-jest/lib/reporter/default', { runId }]],
globals: {
runId,
},
};

```

The rest of the steps are the same.

## Mocha

[Example project](https://github.com/testimio/root-cause/tree/master/integration-examples/mocha-and-puppeteer)

## launch api

[Example project](https://github.com/testimio/root-cause/tree/master/integration-examples/launch-api)

## Root Cause CLI
Expand Down
@@ -0,0 +1,16 @@
// @ts-nocheck

// Avoid registering ts-node twice
if (!process[Symbol.for('ts-node.register.instance')]) {
const tsNode = require('ts-node');

tsNode.register({
transpileOnly: true,
compilerOptions: require('@testim/root-cause-jest/tsconfig').compilerOptions,
// skipIgnore: true,
// ignore: [],
});
}
const Env = require('@testim/root-cause-jest/lib/RootCauseJestEnv');

module.exports = Env;
@@ -1,22 +1,24 @@
const { navigateToBaseUrl, sendSpecialCharacter } = require("../helpers");
const { navigateToBaseUrl, sendSpecialCharacter } = require('../helpers');

it("Should add 4 todos", async function () {
await navigateToBaseUrl(page);
describe('Some describe', () => {
it('Should add 4 todos', async function () {
await navigateToBaseUrl(page);

await page.type(".new-todo", "Buy milk");
await sendSpecialCharacter(page, ".new-todo", "Enter");
await page.type('.new-todo', 'Buy milk');
await sendSpecialCharacter(page, '.new-todo', 'Enter');

await page.type(".new-todo", "Order Pizza");
await sendSpecialCharacter(page, ".new-todo", "Enter");
await page.type('.new-todo', 'Order Pizza');
await sendSpecialCharacter(page, '.new-todo', 'Enter');

await page.type(".new-todo", "Wash the dishes");
await sendSpecialCharacter(page, ".new-todo", "Enter");
await page.type('.new-todo', 'Wash the dishes');
await sendSpecialCharacter(page, '.new-todo', 'Enter');

await page.type(".new-todo", "Talk to Ben");
await sendSpecialCharacter(page, ".new-todo", "Enter");
await page.type('.new-todo', 'Talk to Ben');
await sendSpecialCharacter(page, '.new-todo', 'Enter');

await expect(page).toEqualText(".todo-list > :nth-child(1) label", "Buy milk");
await expect(page).toEqualText(".todo-list > :nth-child(2) label", "Order Pizza");
await expect(page).toEqualText(".todo-list > :nth-child(3) label", "Wash the dishes");
await expect(page).toEqualText(".todo-list > :nth-child(4) label", "Talk to Ben");
await expect(page).toEqualText('.todo-list > :nth-child(1) label', 'Buy milk');
await expect(page).toEqualText('.todo-list > :nth-child(2) label', 'Order Pizza');
await expect(page).toEqualText('.todo-list > :nth-child(3) label', 'Wash the dishes');
await expect(page).toEqualText('.todo-list > :nth-child(4) label', 'Talk to Ben');
});
});

This file was deleted.

15 changes: 8 additions & 7 deletions integration-examples/todomvc-jest-playwright/jest.config.js
Expand Up @@ -6,17 +6,18 @@ const playwrightPreset = require('jest-playwright-preset/jest-preset.json');
// The run id should be unique across runs
const runId = Date.now().toString();

module.exports = {
const config = {
...playwrightPreset,
testRunner: 'jasmine2',
reporters: [['./reporter', { runId }]],
setupFilesAfterEnv: [
...playwrightPreset.setupFilesAfterEnv,
'./setupFilesAfterEnv',
...(process.env.NO_RC ? [] : ['./forSetupFilesAfterEnv']),
],
setupFilesAfterEnv: [...playwrightPreset.setupFilesAfterEnv, './setViewportSizeBeforeEach'],
globals: {
runId,
},
maxWorkers: '50%',
};

if (!process.env.NO_RC) {
config.testEnvironment = './RootCauseJestEnvTranspile';
}

module.exports = config;
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -26,8 +26,8 @@
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-no-only-tests": "^2.4.0",
"husky": "^4.2.5",
"jest": "^26",
"jest-jasmine2": "^26",
"jest": "^26.5.3",
"jest-jasmine2": "^26.5.3",
"lerna": "^3.22.1",
"prettier": "^2.1.1",
"typescript": "^3.9.2",
Expand Down
24 changes: 24 additions & 0 deletions packages/internal-self-tests-helpers/testHelpers.ts
Expand Up @@ -55,6 +55,30 @@ export function getMochaTestTimeZeroPrettyFormatPlugin(): jest.SnapshotSerialize
return plugin;
}

export function trimTrailingSpacesPrettyFormatPlugin(): jest.SnapshotSerializerPlugin {
const plugin: Plugin = {
test(val) {
if (typeof val === 'string' && val.match(/ +?\n/m)) {
return true;
}

return false;
},
serialize(valueToSerialize: string, config, indentation, depth, refs, printer) {
return printer(
valueToSerialize.replace(/ +?\n/gm, '\n'),
config,
indentation,
depth,
refs,
false
);
},
};

return plugin;
}

export function getCleanAllPathsPrettyFormatPlugin(
processCwd: string
): jest.SnapshotSerializerPlugin {
Expand Down
@@ -0,0 +1,16 @@
/* eslint-disable import/no-extraneous-dependencies */

// @ts-nocheck

// Avoid registering ts-node twice
if (!process[Symbol.for('ts-node.register.instance')]) {
const tsNode = require('ts-node');

tsNode.register({
transpileOnly: true,
compilerOptions: require('@testim/root-cause-jest/tsconfig').compilerOptions,
});
}
const Env = require('@testim/root-cause-jest/lib/RootCauseJestEnv');

module.exports = Env;
@@ -0,0 +1,19 @@
/* eslint-disable no-useless-catch */
describe('Some test suite', () => {
it('This test should pass', async () => {
await page.goto('http://jsbin.testim.io/tog');
await page.click('#forwarning');
await expect(page).toHaveText('#forlog', 'Make log');

await page.click('#forlog');
}, 7_000);

it('This that should fail', async () => {
await page.goto('http://jsbin.testim.io/tog');
await page.click('#sometable');

await expect(page).toHaveText('#forviolation', 'Make violation... no so much');

await page.click('#not-found-element');
}, 10_000);
});
@@ -0,0 +1,19 @@
'use strict';

/* eslint-disable import/no-extraneous-dependencies */

const tsJestPreset = require('ts-jest/jest-preset');
const playwrightPreset = require('jest-playwright-preset/jest-preset.json');

// read runId from root jest config if defined
const runId = global.runId || Date.now().toString();

module.exports = {
...tsJestPreset,
...playwrightPreset,
testEnvironment: '../RootCauseJestEnvTranspile',
reporters: [['../reporterTranspile', { runId }]],
globals: {
runId,
},
};
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"types": ["jest-playwright-preset", "expect-playwright", "jest"],
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
}
}
@@ -0,0 +1,25 @@
/* eslint-disable no-useless-catch */
describe('Some test suite', () => {
it('This test should pass', async () => {
await page.goto('http://jsbin.testim.io/tog');
await page.click('#forwarning');
// expect-puppeteer
// await expect(page).toMatchElement('#forlog', { text: 'Make log' });

// expect-playwright
// @ts-ignore
await expect(page).toMatchElement('#forlog', { text: 'Make log' });

await page.click('#forlog');
}, 7_000);

it('This that should fail', async () => {
await page.goto('http://jsbin.testim.io/tog');

await page.click('#sometable');

await expect(page).toMatchElement('#forviolation', { text: 'Make violation... no so much' });

await page.click('#not-found-element');
}, 10_000);
});
@@ -0,0 +1,8 @@
'use strict';

module.exports = {
launch: {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
},
};
@@ -0,0 +1,19 @@
'use strict';

/* eslint-disable import/no-extraneous-dependencies */

const tsJestPreset = require('ts-jest/jest-preset');
const puppeteerPreset = require('jest-puppeteer-preset/jest-preset.json');

// read runId from root jest config if defined
const runId = global.runId || Date.now().toString();

module.exports = {
...tsJestPreset,
...puppeteerPreset,
testEnvironment: '../RootCauseJestEnvTranspile',
reporters: [['../reporterTranspile', { runId }]],
globals: {
runId,
},
};
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"types": ["jest-environment-puppeteer", "expect-puppeteer"],
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true
}
}
18 changes: 18 additions & 0 deletions packages/jest-integration-test-projects/reporterTranspile.js
@@ -0,0 +1,18 @@
/* eslint-disable import/no-extraneous-dependencies */

// jest can't transpile reporters on the fly so we help him
// https://github.com/facebook/jest/issues/10105

// make sure ts-node is loaded only once
if (!process[Symbol.for('ts-node.register.instance')]) {
const tsNode = require('ts-node');

tsNode.register({
transpileOnly: true,
compilerOptions: require('@testim/root-cause-jest/tsconfig').compilerOptions,
});
}

const Reporter = require('@testim/root-cause-jest/lib/reporter/default');

module.exports = Reporter;