Skip to content

Commit

Permalink
pass testConsole to TestEnvironment (#5227)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kent C. Dodds authored and cpojer committed Jan 5, 2018
1 parent 84abf60 commit e776fdd
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@
* `[docs]` Add documentation for .toHaveProperty matcher to accept the keyPath
argument as an array of properties/indices.
([#5220](https://github.com/facebook/jest/pull/5220))
* `[jest-runner]` test environments are now passed a new `options` parameter.
Currently this only has the `console` which is the test console that Jest will
expose to tests. ([#5223](https://github.com/facebook/jest/issues/5223))
* `[jest-environment-jsdom]` pass the `options.console` to a custom
instance of `virtualConsole` so jsdom is using the same console as the
test. ([#5223](https://github.com/facebook/jest/issues/5223))

### Chore & Maintenance

Expand Down
18 changes: 18 additions & 0 deletions integration_tests/__tests__/__snapshots__/console.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,21 @@ Snapshots: 0 total
Time: <<REPLACED>>
"
`;
exports[`the jsdom console is the same as the test console 1`] = `""`;
exports[`the jsdom console is the same as the test console 2`] = `
"PASS __tests__/console.test.js
✓ can mock console.error calls from jsdom
"
`;
exports[`the jsdom console is the same as the test console 3`] = `
"Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
"
`;
11 changes: 11 additions & 0 deletions integration_tests/__tests__/console.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,14 @@ test('does not print to console with --silent', () => {
expect(rest).toMatchSnapshot();
expect(summary).toMatchSnapshot();
});

// issue: https://github.com/facebook/jest/issues/5223
test('the jsdom console is the same as the test console', () => {
const {stderr, stdout, status} = runJest('console-jsdom');
const {summary, rest} = extractSummary(stderr);

expect(status).toBe(0);
expect(stdout).toMatchSnapshot();
expect(rest).toMatchSnapshot();
expect(summary).toMatchSnapshot();
});
40 changes: 40 additions & 0 deletions integration_tests/console-jsdom/__tests__/console.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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.
*/
/* eslint-env browser */
'use strict';

beforeEach(() => {
jest.spyOn(console, 'error');
console.error.mockImplementation(() => {});
});

afterEach(() => {
console.error.mockRestore();
});

test('can mock console.error calls from jsdom', () => {
// copied and modified for tests from:
// https://github.com/facebook/react/blob/46b3c3e4ae0d52565f7ed2344036a22016781ca0/packages/shared/invokeGuardedCallback.js#L62-L147
const fakeNode = document.createElement('react');

const evt = document.createEvent('Event');
const evtType = 'react-invokeguardedcallback';
function callCallback() {
fakeNode.removeEventListener(evtType, callCallback, false);
throw new Error('this is an error in an event callback');
}

function onError(event) {}

window.addEventListener('error', onError);
fakeNode.addEventListener(evtType, callCallback, false);
evt.initEvent(evtType, false, false);
fakeNode.dispatchEvent(evt);
window.removeEventListener('error', onError);

expect(console.error).toHaveBeenCalledTimes(1);
});
5 changes: 5 additions & 0 deletions integration_tests/console-jsdom/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"jest": {
"testEnvironment": "jsdom"
}
}
8 changes: 6 additions & 2 deletions packages/jest-environment-jsdom/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

import type {Script} from 'vm';
import type {ProjectConfig} from 'types/Config';
import type {EnvironmentOptions} from 'types/Environment';
import type {Global} from 'types/Global';
import type {ModuleMocker} from 'jest-mock';

import {FakeTimers, installCommonGlobals} from 'jest-util';
import mock from 'jest-mock';
import {JSDOM} from 'jsdom';
import {JSDOM, VirtualConsole} from 'jsdom';

class JSDOMEnvironment {
dom: ?Object;
Expand All @@ -22,14 +23,17 @@ class JSDOMEnvironment {
errorEventListener: ?Function;
moduleMocker: ?ModuleMocker;

constructor(config: ProjectConfig) {
constructor(config: ProjectConfig, options: EnvironmentOptions = {}) {
this.dom = new JSDOM(
'<!DOCTYPE html>',
Object.assign(
{
pretendToBeVisual: true,
runScripts: 'dangerously',
url: config.testURL,
virtualConsole: new VirtualConsole().sendTo(
options.console || console,
),
},
config.testEnvironmentOptions,
),
Expand Down
10 changes: 5 additions & 5 deletions packages/jest-runner/src/run_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,6 @@ async function runTestInternal(
RuntimeClass,
>);

const environment = new TestEnvironment(config);
const leakDetector = config.detectLeaks
? new LeakDetector(environment)
: null;

const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout;
const consoleFormatter = (type, message) =>
getConsoleOutput(
Expand All @@ -98,6 +93,11 @@ async function runTestInternal(
testConsole = new BufferedConsole();
}

const environment = new TestEnvironment(config, {console: testConsole});
const leakDetector = config.detectLeaks
? new LeakDetector(environment)
: null;

const cacheFS = {[path]: testSource};
setGlobal(environment.global, 'console', testConsole);

Expand Down
6 changes: 5 additions & 1 deletion types/Environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ import type {Global} from './Global';
import type {Script} from 'vm';
import type {ModuleMocker} from 'jest-mock';

export type EnvironmentOptions = {
console?: Object,
};

declare class $JestEnvironment {
constructor(config: ProjectConfig): void;
constructor(config: ProjectConfig, options?: EnvironmentOptions): void;
runScript(script: Script): any;
global: Global;
fakeTimers: {
Expand Down

0 comments on commit e776fdd

Please sign in to comment.