diff --git a/CHANGELOG.md b/CHANGELOG.md index aac48933d95d..44945b22f8e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ ### Features +* `[jest-config]` Add `testEnvironmentOptions` to apply to jsdom options or node context. + ([#5003](https://github.com/facebook/jest/pull/5003)) * `[jest-jasmine2]` Update Timeout error message to `jest.timeout` and display current timeout value ([#4990](https://github.com/facebook/jest/pull/4990)) * `[jest-runner]` Enable experimental detection of leaked contexts diff --git a/docs/Configuration.md b/docs/Configuration.md index 08064930b626..ea418231cfe3 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -726,6 +726,17 @@ class CustomEnvironment extends NodeEnvironment { } ``` +### `testEnvironmentOptions` [Object] + +##### available in Jest **22.0.0+** + +Default: `{}` + +Test environment options that will be passed to the `testEnvironment`. The +relevant options depend on the environment. For example you can override +options given to [jsdom](https://github.com/tmpvar/jsdom) such as +`{userAgent: "Agent/007"}`. + ### `testMatch` [array] ##### available in Jest **19.0.0+** diff --git a/integration_tests/__tests__/__snapshots__/show_config.test.js.snap b/integration_tests/__tests__/__snapshots__/show_config.test.js.snap index 5fa329deb625..bc52f635f121 100644 --- a/integration_tests/__tests__/__snapshots__/show_config.test.js.snap +++ b/integration_tests/__tests__/__snapshots__/show_config.test.js.snap @@ -39,6 +39,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` \\"setupFiles\\": [], \\"snapshotSerializers\\": [], \\"testEnvironment\\": \\"jest-environment-jsdom\\", + \\"testEnvironmentOptions\\": {}, \\"testLocationInResults\\": false, \\"testMatch\\": [ \\"**/__tests__/**/*.js?(x)\\", diff --git a/integration_tests/__tests__/config.test.js b/integration_tests/__tests__/config.test.js index 12a29e6edba9..a0a8fa7ac700 100644 --- a/integration_tests/__tests__/config.test.js +++ b/integration_tests/__tests__/config.test.js @@ -59,3 +59,18 @@ test('config from argv is respected with sane config JSON', () => { expect(stdout).toMatch('"watchman": false'); }); + +test('works with jsdom testEnvironmentOptions config JSON', () => { + const result = runJest('environmentOptions', [ + '--config=' + + JSON.stringify({ + testEnvironmentOptions: { + userAgent: 'Agent/007', + }, + }), + ]); + const stderr = result.stderr.toString(); + + expect(result.status).toBe(0); + expect(stderr).toMatch('found userAgent Agent/007'); +}); diff --git a/integration_tests/environmentOptions/__tests__/environmentOptions.test.js b/integration_tests/environmentOptions/__tests__/environmentOptions.test.js new file mode 100644 index 000000000000..504f1c945b52 --- /dev/null +++ b/integration_tests/environmentOptions/__tests__/environmentOptions.test.js @@ -0,0 +1,12 @@ +/** + * 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. + */ +'use strict'; +/*global window */ + +test('found userAgent Agent/007', () => { + expect(window.navigator.userAgent).toBe('Agent/007'); +}); diff --git a/integration_tests/environmentOptions/package.json b/integration_tests/environmentOptions/package.json new file mode 100644 index 000000000000..0ded940b7cb7 --- /dev/null +++ b/integration_tests/environmentOptions/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "jsdom" + } +} diff --git a/packages/jest-config/src/defaults.js b/packages/jest-config/src/defaults.js index 4fe4ac704d7f..404a75b90445 100644 --- a/packages/jest-config/src/defaults.js +++ b/packages/jest-config/src/defaults.js @@ -56,6 +56,7 @@ export default ({ runner: 'jest-runner', snapshotSerializers: [], testEnvironment: 'jest-environment-jsdom', + testEnvironmentOptions: {}, testFailureExitCode: 1, testLocationInResults: false, testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)(spec|test).js?(x)'], diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index d070c3789173..e14dd07b560d 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -146,6 +146,7 @@ const getConfigs = ( skipNodeResolution: options.skipNodeResolution, snapshotSerializers: options.snapshotSerializers, testEnvironment: options.testEnvironment, + testEnvironmentOptions: options.testEnvironmentOptions, testLocationInResults: options.testLocationInResults, testMatch: options.testMatch, testPathIgnorePatterns: options.testPathIgnorePatterns, diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 412289e19071..25d26d10bd13 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -480,6 +480,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { case 'silent': case 'skipNodeResolution': case 'testEnvironment': + case 'testEnvironmentOptions': case 'testFailureExitCode': case 'testLocationInResults': case 'testNamePattern': diff --git a/packages/jest-config/src/valid_config.js b/packages/jest-config/src/valid_config.js index 5c6bf89f166d..d51658901b7d 100644 --- a/packages/jest-config/src/valid_config.js +++ b/packages/jest-config/src/valid_config.js @@ -77,6 +77,7 @@ export default ({ skipNodeResolution: false, snapshotSerializers: ['my-serializer-module'], testEnvironment: 'jest-environment-jsdom', + testEnvironmentOptions: {}, testFailureExitCode: 1, testLocationInResults: false, testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)(spec|test).js?(x)'], diff --git a/packages/jest-environment-jsdom/src/index.js b/packages/jest-environment-jsdom/src/index.js index 33293fe28aec..4d6bada02876 100644 --- a/packages/jest-environment-jsdom/src/index.js +++ b/packages/jest-environment-jsdom/src/index.js @@ -23,11 +23,17 @@ class JSDOMEnvironment { moduleMocker: ?ModuleMocker; constructor(config: ProjectConfig) { - this.dom = new JSDOM('', { - pretendToBeVisual: true, - runScripts: 'dangerously', - url: config.testURL, - }); + this.dom = new JSDOM( + '', + Object.assign( + { + pretendToBeVisual: true, + runScripts: 'dangerously', + url: config.testURL, + }, + config.testEnvironmentOptions, + ), + ); const global = (this.global = this.dom.window.document.defaultView); // Node's error-message stack size is limited at 10, but it's pretty useful // to see more than that when a test fails. diff --git a/packages/jest-environment-node/src/index.js b/packages/jest-environment-node/src/index.js index 89147f3e031c..168afd72ee7d 100644 --- a/packages/jest-environment-node/src/index.js +++ b/packages/jest-environment-node/src/index.js @@ -30,7 +30,10 @@ class NodeEnvironment { constructor(config: ProjectConfig) { this.context = vm.createContext(); - const global = (this.global = vm.runInContext('this', this.context)); + const global = (this.global = vm.runInContext( + 'this', + Object.assign(this.context, config.testEnvironmentOptions), + )); global.global = global; global.clearInterval = clearInterval; global.clearTimeout = clearTimeout; diff --git a/test_utils.js b/test_utils.js index d3bf95950d99..49c4e5136de0 100644 --- a/test_utils.js +++ b/test_utils.js @@ -88,6 +88,7 @@ const DEFAULT_PROJECT_CONFIG: ProjectConfig = { skipNodeResolution: false, snapshotSerializers: [], testEnvironment: 'node', + testEnvironmentOptions: {}, testLocationInResults: false, testMatch: [], testPathIgnorePatterns: [], diff --git a/types/Config.js b/types/Config.js index 585cd27ee8ce..067987a76ebb 100644 --- a/types/Config.js +++ b/types/Config.js @@ -48,6 +48,7 @@ export type DefaultOptions = {| runTestsByPath: boolean, snapshotSerializers: Array, testEnvironment: string, + testEnvironmentOptions: Object, testFailureExitCode: string | number, testLocationInResults: boolean, testMatch: Array, @@ -121,6 +122,7 @@ export type InitialOptions = { skipNodeResolution?: boolean, snapshotSerializers?: Array, testEnvironment?: string, + testEnvironmentOptions?: Object, testFailureExitCode?: string | number, testLocationInResults?: boolean, testMatch?: Array, @@ -222,6 +224,7 @@ export type ProjectConfig = {| skipNodeResolution: boolean, snapshotSerializers: Array, testEnvironment: string, + testEnvironmentOptions: Object, testMatch: Array, testLocationInResults: boolean, testPathIgnorePatterns: Array,