feat: check for common errors when using the wrong test environment (#8245)

This commit is contained in:
Simen Bekkhus 2020-03-28 11:09:44 +01:00 committed by GitHub
parent b7cd4328b7
commit 2a4b073ff7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 262 additions and 6 deletions

View File

@ -2,6 +2,8 @@
### Features
- `[jest-message-util]` Check for common errors when using the wrong test environment ([#8245](https://github.com/facebook/jest/pull/8245))
### Fixes
- `[jest-circus]` Fix type ellision of jest-runtime imports ([#9717](https://github.com/facebook/jest/pull/9717))

View File

@ -0,0 +1,115 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Wrong globals for environment print useful error for document 1`] = `
FAIL __tests__/node.js
✕ use document
○ skipped use window
○ skipped use navigator
● use document
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: document is not defined
14 |
15 | test('use document', () => {
> 16 | const div = document.createElement('div');
| ^
17 |
18 | console.log(div);
19 |
at Object.document (__tests__/node.js:16:15)
`;
exports[`Wrong globals for environment print useful error for navigator 1`] = `
FAIL __tests__/node.js
✕ use navigator
○ skipped use document
○ skipped use window
● use navigator
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: navigator is not defined
30 |
31 | test('use navigator', () => {
> 32 | const userAgent = navigator.userAgent;
| ^
33 |
34 | console.log(userAgent);
35 |
at Object.navigator (__tests__/node.js:32:21)
`;
exports[`Wrong globals for environment print useful error for unref 1`] = `
FAIL __tests__/jsdom.js
✕ use unref
● use unref
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "node" test environment.
TypeError: setTimeout(...).unref is not a function
11 |
12 | test('use unref', () => {
> 13 | setTimeout(() => {}, 0).unref();
| ^
14 |
15 | expect(1).toBe(1);
16 | });
at Object.unref (__tests__/jsdom.js:13:27)
`;
exports[`Wrong globals for environment print useful error for window 1`] = `
FAIL __tests__/node.js
✕ use window
○ skipped use document
○ skipped use navigator
● use window
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: window is not defined
22 |
23 | test('use window', () => {
> 24 | const location = window.location;
| ^
25 |
26 | console.log(location);
27 |
at Object.window (__tests__/node.js:24:20)
`;
exports[`Wrong globals for environment print useful error when it explodes during evaluation 1`] = `
FAIL __tests__/beforeTest.js
● Test suite failed to run
The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
Consider using the "jsdom" test environment.
ReferenceError: document is not defined
11 | /* eslint-env browser */
12 |
> 13 | const div = document.createElement('div');
| ^
14 |
15 | console.log(div);
16 |
at Object.document (__tests__/beforeTest.js:13:13)
`;

View File

@ -0,0 +1,38 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import wrap from 'jest-snapshot-serializer-raw';
import runJest from '../runJest';
import {extractSummary} from '../Utils';
function assertFailuresAndSnapshot(args: Array<string>) {
const result = runJest('wrong-env', args);
expect(result.exitCode).toBe(1);
expect(wrap(extractSummary(result.stderr).rest)).toMatchSnapshot();
}
describe('Wrong globals for environment', () => {
it('print useful error for window', () => {
assertFailuresAndSnapshot(['node', '-t=window']);
});
it('print useful error for document', () => {
assertFailuresAndSnapshot(['node', '-t=document']);
});
it('print useful error for navigator', () => {
assertFailuresAndSnapshot(['node', '-t=navigator']);
});
it('print useful error for unref', () => {
assertFailuresAndSnapshot(['jsdom', '-t=unref']);
});
it('print useful error when it explodes during evaluation', () => {
assertFailuresAndSnapshot(['beforeTest']);
});
});

View File

@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-environment node
*
*/
/* eslint-env browser */
const div = document.createElement('div');
console.log(div);
test('stub', () => expect(1).toBe(1));

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-environment jsdom
*/
'use strict';
test('use unref', () => {
setTimeout(() => {}, 0).unref();
expect(1).toBe(1);
});

View File

@ -0,0 +1,37 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-environment node
*
*/
/* eslint-env browser */
'use strict';
test('use document', () => {
const div = document.createElement('div');
console.log(div);
expect(1).toBe(1);
});
test('use window', () => {
const location = window.location;
console.log(location);
expect(1).toBe(1);
});
test('use navigator', () => {
const userAgent = navigator.userAgent;
console.log(userAgent);
expect(1).toBe(1);
});

View File

@ -0,0 +1,3 @@
{
"jest": {}
}

View File

@ -92,6 +92,30 @@ const getRenderedCallsite = (
const blankStringRegexp = /^\s*$/;
function checkForCommonEnvironmentErrors(error: string) {
if (
error.includes('ReferenceError: document is not defined') ||
error.includes('ReferenceError: window is not defined') ||
error.includes('ReferenceError: navigator is not defined')
) {
return warnAboutWrongTestEnvironment(error, 'jsdom');
} else if (error.includes('.unref is not a function')) {
return warnAboutWrongTestEnvironment(error, 'node');
}
return error;
}
function warnAboutWrongTestEnvironment(error: string, env: 'jsdom' | 'node') {
return (
chalk.bold.red(
`The error below may be caused by using the wrong test environment, see ${chalk.dim.underline(
'https://jestjs.io/docs/en/configuration#testenvironment-string',
)}.\nConsider using the "${env}" test environment.\n\n`,
) + error
);
}
// ExecError is an error thrown outside of the test suite (not inside an `it` or
// `before/after each` hooks). If it's thrown, none of the tests in the file
// are executed.
@ -126,6 +150,8 @@ export const formatExecError = (
message = separated.message;
}
message = checkForCommonEnvironmentErrors(message);
message = indentAllLines(message, MESSAGE_INDENT);
stack =
@ -285,19 +311,21 @@ export const formatStackTrace = (
return `${renderedCallsite}\n${stacktrace}`;
};
type FailedResults = Array<{
content: string;
result: AssertionResult;
}>;
export const formatResultsErrors = (
testResults: Array<AssertionResult>,
config: StackTraceConfig,
options: StackTraceOptions,
testPath?: Path,
): string | null => {
type FailedResults = Array<{
content: string;
result: AssertionResult;
}>;
const failedResults: FailedResults = testResults.reduce((errors, result) => {
result.failureMessages.forEach(content => errors.push({content, result}));
result.failureMessages
.map(checkForCommonEnvironmentErrors)
.forEach(content => errors.push({content, result}));
return errors;
}, [] as FailedResults);