├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── register.js ├── src └── index.js └── test ├── arguments-should-be-able-to-be-passed-in-in-either-order.js ├── existing-falsey-node-globals-dont-get-overwritten.js ├── existing-node-globals-shouldnt-get-overwritten.js ├── fixtures └── expectedProperties.json ├── function-should-overwrite-dom-globals-on-each-call.js ├── function-should-return-window-instance.js ├── function-should-setup-browser-environment.js ├── function-shouldnt-return-the-same-instance.js ├── jsdom-arg-should-set-jsdom-config.js ├── properties-arg-should-set-globals.js ├── register-entry-must-preload-env.js └── window-properties-should-be-as-expected.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .nyc_output 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'node' 4 | - '6' 5 | script: npm test 6 | after_success: npm run coverage 7 | notifications: 8 | email: 9 | on_success: never 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Luke Childs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # browser-env 2 | 3 | > Simulates a global browser environment using [`jsdom`](https://github.com/tmpvar/jsdom). 4 | 5 | [![Build Status](https://travis-ci.org/lukechilds/browser-env.svg?branch=master)](https://travis-ci.org/lukechilds/browser-env) 6 | [![Coverage Status](https://coveralls.io/repos/github/lukechilds/browser-env/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/browser-env?branch=master) 7 | [![npm](https://img.shields.io/npm/dm/browser-env.svg)](https://www.npmjs.com/package/browser-env) 8 | [![npm](https://img.shields.io/npm/v/browser-env.svg)](https://www.npmjs.com/package/browser-env) 9 | 10 | This allows you to run browser modules in Node.js 6 or newer with minimal or no effort. Can also be used to test browser modules with any Node.js test framework. Please note, only the DOM is simulated, if you want to run a module that requires more advanced browser features (like `localStorage`), you'll need to polyfill that seperately. 11 | 12 | Use `browser-env@2` to support older Node.js versions. 13 | 14 | > ❗️**Important note** 15 | > 16 | > This module adds properties from the `jsdom` window namespace to the Node.js global namespace. This is explicitly [recommended against](https://github.com/tmpvar/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global) by `jsdom`. There may be scenarios where this is ok for your use case but please read through the linked wiki page and make sure you understand the caveats. If you don't need the browser environment enabled globally, [`window`](https://github.com/lukechilds/window) may be a better solution. 17 | 18 | ## Install 19 | 20 | ```shell 21 | npm install --save browser-env 22 | ``` 23 | 24 | Or if you're just using for testing you'll probably want: 25 | 26 | ```shell 27 | npm install --save-dev browser-env 28 | ``` 29 | 30 | ## Usage 31 | 32 | ```js 33 | // Init 34 | require('browser-env')(); 35 | 36 | // Now you have access to a browser like environment in Node.js: 37 | 38 | typeof window; 39 | // 'object' 40 | 41 | typeof document; 42 | // 'object' 43 | 44 | var div = document.createElement('div'); 45 | // HTMLDivElement 46 | 47 | div instanceof HTMLElement 48 | // true 49 | ``` 50 | 51 | By default everything in the `jsdom` window namespace is tacked on to the Node.js global namespace (excluding existing Node.js properties e.g `console`, `setTimout`). If you want to trim this down you can pass an array of required properties: 52 | 53 | ```js 54 | // Init 55 | require('browser-env')(['window']); 56 | 57 | typeof window; 58 | // 'object' 59 | 60 | typeof document; 61 | // 'undefined' 62 | ``` 63 | 64 | You can also pass a config object straight through to `jsdom`. This can be done with or without specifying required properties. 65 | 66 | ```js 67 | require('browser-env')(['window'], { userAgent: 'My User Agent' }); 68 | 69 | // or 70 | 71 | require('browser-env')({ userAgent: 'My User Agent' }); 72 | ``` 73 | 74 | You can of course also assign to a function: 75 | 76 | ```js 77 | var browserEnv = require('browser-env'); 78 | browserEnv(); 79 | 80 | // or 81 | 82 | import browserEnv from 'browser-env'; 83 | browserEnv(); 84 | ``` 85 | 86 | `browser-env` can also be preloaded at node startup as: 87 | 88 | ```sh 89 | node -r browser-env/register test.js 90 | ``` 91 | 92 | ## Related 93 | 94 | - [`window`](https://github.com/lukechilds/window) - Exports a jsdom window object 95 | 96 | ## License 97 | 98 | MIT © Luke Childs 99 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browser-env", 3 | "version": "3.3.0", 4 | "description": "Simulates a global browser environment using jsdom", 5 | "main": "src/index.js", 6 | "engines": { 7 | "node": ">=4" 8 | }, 9 | "scripts": { 10 | "test": "xo && nyc ava", 11 | "coverage": "nyc report --reporter=text-lcov | coveralls" 12 | }, 13 | "xo": { 14 | "extends": "xo-lukechilds", 15 | "envs": [ 16 | "browser" 17 | ] 18 | }, 19 | "repository": { 20 | "type": "git", 21 | "url": "git+https://github.com/lukechilds/browser-env.git" 22 | }, 23 | "keywords": [ 24 | "simulate", 25 | "global", 26 | "node", 27 | "browser", 28 | "environment", 29 | "env" 30 | ], 31 | "author": "Luke Childs (http://lukechilds.co.uk)", 32 | "license": "MIT", 33 | "bugs": { 34 | "url": "https://github.com/lukechilds/browser-env/issues" 35 | }, 36 | "homepage": "https://github.com/lukechilds/browser-env#readme", 37 | "dependencies": { 38 | "window": "4.2.6" 39 | }, 40 | "devDependencies": { 41 | "ava": "^0.25.0", 42 | "coveralls": "^3.0.0", 43 | "eslint-config-xo-lukechilds": "^1.0.0", 44 | "nyc": "^11.0.2", 45 | "xo": "^0.18.2" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /register.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const browserEnv = require('.'); 3 | 4 | browserEnv(); 5 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const Window = require('window'); 2 | 3 | // Default jsdom config. 4 | // These settings must override any custom settings to make sure we can iterate 5 | // over the window object. 6 | const defaultJsdomConfig = { 7 | features: { 8 | FetchExternalResources: false, 9 | ProcessExternalResources: false 10 | } 11 | }; 12 | 13 | // IIFE executed on import to return an array of global Node.js properties that 14 | // conflict with global browser properties. 15 | const protectedproperties = (() => Object 16 | .getOwnPropertyNames(new Window(defaultJsdomConfig)) 17 | .filter(prop => typeof global[prop] !== 'undefined') 18 | )(); 19 | 20 | // Sets up global browser environment 21 | const browserEnv = function () { 22 | // Extract options from args 23 | const args = Array.from(arguments); 24 | const properties = args.filter(arg => Array.isArray(arg))[0]; 25 | const userJsdomConfig = args.filter(arg => !Array.isArray(arg))[0]; 26 | 27 | // Create window object 28 | const window = new Window(Object.assign({}, userJsdomConfig, defaultJsdomConfig)); 29 | 30 | // Get all global browser properties 31 | Object.getOwnPropertyNames(window) 32 | 33 | // Remove protected properties 34 | .filter(prop => protectedproperties.indexOf(prop) === -1) 35 | 36 | // If we're only applying specific required properties remove everything else 37 | .filter(prop => !(properties && properties.indexOf(prop) === -1)) 38 | 39 | // Copy what's left to the Node.js global scope 40 | .forEach(prop => { 41 | Object.defineProperty(global, prop, { 42 | configurable: true, 43 | get: () => window[prop] 44 | }); 45 | }); 46 | 47 | // Return reference to original window object 48 | return window; 49 | }; 50 | 51 | module.exports = browserEnv; 52 | -------------------------------------------------------------------------------- /test/arguments-should-be-able-to-be-passed-in-in-either-order.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | t.is(typeof navigator, 'undefined'); 6 | browserEnv(['navigator'], { userAgent: 'first' }); 7 | t.is(navigator.userAgent, 'first'); 8 | browserEnv({ userAgent: 'second' }, ['navigator']); 9 | t.is(navigator.userAgent, 'second'); 10 | }); 11 | -------------------------------------------------------------------------------- /test/existing-falsey-node-globals-dont-get-overwritten.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | 3 | // We have to require() here as imports have to be top level so we can't set 4 | // globals first 5 | test(t => { 6 | global.document = false; 7 | require('../src')(); 8 | t.is(document, false); 9 | }); 10 | -------------------------------------------------------------------------------- /test/existing-node-globals-shouldnt-get-overwritten.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | const origConsole = console; 6 | browserEnv(); 7 | t.is(origConsole, console); 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/expectedProperties.json: -------------------------------------------------------------------------------- 1 | [ 2 | "AbortController", 3 | "AbortSignal", 4 | "ArrayBuffer", 5 | "Attr", 6 | "Audio", 7 | "BarProp", 8 | "Blob", 9 | "CDATASection", 10 | "CSSImportRule", 11 | "CSSMediaRule", 12 | "CSSRule", 13 | "CSSStyleDeclaration", 14 | "CSSStyleRule", 15 | "CSSStyleSheet", 16 | "CharacterData", 17 | "CloseEvent", 18 | "Comment", 19 | "CompositionEvent", 20 | "CustomEvent", 21 | "DOMException", 22 | "DOMImplementation", 23 | "DOMParser", 24 | "DOMStringMap", 25 | "DOMTokenList", 26 | "Document", 27 | "DocumentFragment", 28 | "DocumentType", 29 | "Element", 30 | "ErrorEvent", 31 | "Event", 32 | "EventTarget", 33 | "File", 34 | "FileList", 35 | "FileReader", 36 | "Float32Array", 37 | "Float64Array", 38 | "FocusEvent", 39 | "FormData", 40 | "HTMLAnchorElement", 41 | "HTMLAreaElement", 42 | "HTMLAudioElement", 43 | "HTMLBRElement", 44 | "HTMLBaseElement", 45 | "HTMLBodyElement", 46 | "HTMLButtonElement", 47 | "HTMLCanvasElement", 48 | "HTMLCollection", 49 | "HTMLDListElement", 50 | "HTMLDataElement", 51 | "HTMLDataListElement", 52 | "HTMLDetailsElement", 53 | "HTMLDialogElement", 54 | "HTMLDirectoryElement", 55 | "HTMLDivElement", 56 | "HTMLDocument", 57 | "HTMLElement", 58 | "HTMLEmbedElement", 59 | "HTMLFieldSetElement", 60 | "HTMLFontElement", 61 | "HTMLFormElement", 62 | "HTMLFrameElement", 63 | "HTMLFrameSetElement", 64 | "HTMLHRElement", 65 | "HTMLHeadElement", 66 | "HTMLHeadingElement", 67 | "HTMLHtmlElement", 68 | "HTMLIFrameElement", 69 | "HTMLImageElement", 70 | "HTMLInputElement", 71 | "HTMLLIElement", 72 | "HTMLLabelElement", 73 | "HTMLLegendElement", 74 | "HTMLLinkElement", 75 | "HTMLMapElement", 76 | "HTMLMarqueeElement", 77 | "HTMLMediaElement", 78 | "HTMLMenuElement", 79 | "HTMLMetaElement", 80 | "HTMLMeterElement", 81 | "HTMLModElement", 82 | "HTMLOListElement", 83 | "HTMLObjectElement", 84 | "HTMLOptGroupElement", 85 | "HTMLOptionElement", 86 | "HTMLOptionsCollection", 87 | "HTMLOutputElement", 88 | "HTMLParagraphElement", 89 | "HTMLParamElement", 90 | "HTMLPictureElement", 91 | "HTMLPreElement", 92 | "HTMLProgressElement", 93 | "HTMLQuoteElement", 94 | "HTMLScriptElement", 95 | "HTMLSelectElement", 96 | "HTMLSlotElement", 97 | "HTMLSourceElement", 98 | "HTMLSpanElement", 99 | "HTMLStyleElement", 100 | "HTMLTableCaptionElement", 101 | "HTMLTableCellElement", 102 | "HTMLTableColElement", 103 | "HTMLTableElement", 104 | "HTMLTableRowElement", 105 | "HTMLTableSectionElement", 106 | "HTMLTemplateElement", 107 | "HTMLTextAreaElement", 108 | "HTMLTimeElement", 109 | "HTMLTitleElement", 110 | "HTMLTrackElement", 111 | "HTMLUListElement", 112 | "HTMLUnknownElement", 113 | "HTMLVideoElement", 114 | "HashChangeEvent", 115 | "History", 116 | "Image", 117 | "InputEvent", 118 | "Int16Array", 119 | "Int32Array", 120 | "Int8Array", 121 | "KeyboardEvent", 122 | "Location", 123 | "MediaList", 124 | "MessageEvent", 125 | "MimeType", 126 | "MimeTypeArray", 127 | "MouseEvent", 128 | "MutationObserver", 129 | "MutationRecord", 130 | "NamedNodeMap", 131 | "Node", 132 | "NodeFilter", 133 | "NodeIterator", 134 | "NodeList", 135 | "Option", 136 | "Performance", 137 | "Plugin", 138 | "PluginArray", 139 | "PopStateEvent", 140 | "ProcessingInstruction", 141 | "ProgressEvent", 142 | "SVGAnimatedString", 143 | "SVGElement", 144 | "SVGGraphicsElement", 145 | "SVGNumber", 146 | "SVGSVGElement", 147 | "SVGStringList", 148 | "SVGTitleElement", 149 | "Screen", 150 | "ShadowRoot", 151 | "Storage", 152 | "StorageEvent", 153 | "StyleSheet", 154 | "StyleSheetList", 155 | "Text", 156 | "TouchEvent", 157 | "TreeWalker", 158 | "UIEvent", 159 | "URL", 160 | "URLSearchParams", 161 | "Uint16Array", 162 | "Uint32Array", 163 | "Uint8Array", 164 | "Uint8ClampedArray", 165 | "ValidityState", 166 | "WebSocket", 167 | "WheelEvent", 168 | "Window", 169 | "XMLDocument", 170 | "XMLHttpRequest", 171 | "XMLHttpRequestEventTarget", 172 | "XMLHttpRequestUpload", 173 | "XMLSerializer", 174 | "XPathEvaluator", 175 | "XPathException", 176 | "XPathExpression", 177 | "XPathResult", 178 | "__stopAllTimers", 179 | "_commonForOrigin", 180 | "_currentOriginData", 181 | "_document", 182 | "_eventHandlers", 183 | "_frameElement", 184 | "_getEventHandlerFor", 185 | "_getEventHandlerTarget", 186 | "_globalEventChanged", 187 | "_globalProxy", 188 | "_initGlobalEvents", 189 | "_length", 190 | "_localStorage", 191 | "_parent", 192 | "_pretendToBeVisual", 193 | "_proxyWindowEventsToWindow", 194 | "_registeredHandlers", 195 | "_resourceLoader", 196 | "_runScripts", 197 | "_sessionHistory", 198 | "_sessionStorage", 199 | "_setEventHandlerFor", 200 | "_storageQuota", 201 | "_top", 202 | "_virtualConsole", 203 | "addEventListener", 204 | "alert", 205 | "atob", 206 | "blur", 207 | "btoa", 208 | "captureEvents", 209 | "clearInterval", 210 | "clearTimeout", 211 | "close", 212 | "confirm", 213 | "console", 214 | "devicePixelRatio", 215 | "dispatchEvent", 216 | "document", 217 | "external", 218 | "focus", 219 | "frameElement", 220 | "frames", 221 | "getComputedStyle", 222 | "history", 223 | "innerHeight", 224 | "innerWidth", 225 | "length", 226 | "localStorage", 227 | "location", 228 | "locationbar", 229 | "menubar", 230 | "moveBy", 231 | "moveTo", 232 | "name", 233 | "navigator", 234 | "onabort", 235 | "onafterprint", 236 | "onautocomplete", 237 | "onautocompleteerror", 238 | "onbeforeprint", 239 | "onbeforeunload", 240 | "onblur", 241 | "oncancel", 242 | "oncanplay", 243 | "oncanplaythrough", 244 | "onchange", 245 | "onclick", 246 | "onclose", 247 | "oncontextmenu", 248 | "oncuechange", 249 | "ondblclick", 250 | "ondrag", 251 | "ondragend", 252 | "ondragenter", 253 | "ondragexit", 254 | "ondragleave", 255 | "ondragover", 256 | "ondragstart", 257 | "ondrop", 258 | "ondurationchange", 259 | "onemptied", 260 | "onended", 261 | "onerror", 262 | "onfocus", 263 | "onhashchange", 264 | "oninput", 265 | "oninvalid", 266 | "onkeydown", 267 | "onkeypress", 268 | "onkeyup", 269 | "onlanguagechange", 270 | "onload", 271 | "onloadeddata", 272 | "onloadedmetadata", 273 | "onloadstart", 274 | "onmessage", 275 | "onmessageerror", 276 | "onmousedown", 277 | "onmouseenter", 278 | "onmouseleave", 279 | "onmousemove", 280 | "onmouseout", 281 | "onmouseover", 282 | "onmouseup", 283 | "onoffline", 284 | "ononline", 285 | "onpagehide", 286 | "onpageshow", 287 | "onpause", 288 | "onplay", 289 | "onplaying", 290 | "onpopstate", 291 | "onprogress", 292 | "onratechange", 293 | "onrejectionhandled", 294 | "onreset", 295 | "onresize", 296 | "onscroll", 297 | "onsecuritypolicyviolation", 298 | "onseeked", 299 | "onseeking", 300 | "onselect", 301 | "onsort", 302 | "onstalled", 303 | "onstorage", 304 | "onsubmit", 305 | "onsuspend", 306 | "ontimeupdate", 307 | "ontoggle", 308 | "onunhandledrejection", 309 | "onunload", 310 | "onvolumechange", 311 | "onwaiting", 312 | "onwheel", 313 | "open", 314 | "outerHeight", 315 | "outerWidth", 316 | "pageXOffset", 317 | "pageYOffset", 318 | "parent", 319 | "performance", 320 | "personalbar", 321 | "postMessage", 322 | "print", 323 | "prompt", 324 | "releaseEvents", 325 | "removeEventListener", 326 | "resizeBy", 327 | "resizeTo", 328 | "screen", 329 | "screenLeft", 330 | "screenTop", 331 | "screenX", 332 | "screenY", 333 | "scroll", 334 | "scrollBy", 335 | "scrollTo", 336 | "scrollX", 337 | "scrollY", 338 | "scrollbars", 339 | "self", 340 | "sessionStorage", 341 | "setInterval", 342 | "setTimeout", 343 | "status", 344 | "statusbar", 345 | "stop", 346 | "toolbar", 347 | "top", 348 | "window" 349 | ] 350 | -------------------------------------------------------------------------------- /test/function-should-overwrite-dom-globals-on-each-call.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | t.is(typeof window, 'undefined'); 6 | const returnValue = browserEnv(); 7 | t.is(returnValue, window); 8 | const secondReturnValue = browserEnv(); 9 | t.not(returnValue, window); 10 | t.is(secondReturnValue, window); 11 | }); 12 | -------------------------------------------------------------------------------- /test/function-should-return-window-instance.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | const returnValue = browserEnv(); 6 | t.is(returnValue, window); 7 | }); 8 | -------------------------------------------------------------------------------- /test/function-should-setup-browser-environment.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | t.is(typeof window, 'undefined'); 6 | t.is(typeof document, 'undefined'); 7 | t.is(typeof navigator, 'undefined'); 8 | t.is(typeof HTMLElement, 'undefined'); 9 | browserEnv(); 10 | t.not(typeof window, 'undefined'); 11 | t.not(typeof document, 'undefined'); 12 | t.not(typeof navigator, 'undefined'); 13 | t.not(typeof HTMLElement, 'undefined'); 14 | }); 15 | -------------------------------------------------------------------------------- /test/function-shouldnt-return-the-same-instance.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | t.not(browserEnv(), browserEnv()); 6 | }); 7 | -------------------------------------------------------------------------------- /test/jsdom-arg-should-set-jsdom-config.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | const userAgent = 'Custom user agent'; 6 | t.is(typeof navigator, 'undefined'); 7 | browserEnv(['navigator'], { userAgent }); 8 | t.is(navigator.userAgent, userAgent); 9 | }); 10 | -------------------------------------------------------------------------------- /test/properties-arg-should-set-globals.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | 4 | test(t => { 5 | t.is(typeof window, 'undefined'); 6 | t.is(typeof document, 'undefined'); 7 | t.is(typeof navigator, 'undefined'); 8 | t.is(typeof HTMLElement, 'undefined'); 9 | browserEnv([]); 10 | t.is(typeof window, 'undefined'); 11 | t.is(typeof document, 'undefined'); 12 | t.is(typeof navigator, 'undefined'); 13 | t.is(typeof HTMLElement, 'undefined'); 14 | browserEnv(['navigator', 'HTMLElement']); 15 | t.is(typeof window, 'undefined'); 16 | t.is(typeof document, 'undefined'); 17 | t.not(typeof navigator, 'undefined'); 18 | t.not(typeof HTMLElement, 'undefined'); 19 | }); 20 | -------------------------------------------------------------------------------- /test/register-entry-must-preload-env.js: -------------------------------------------------------------------------------- 1 | import { spawnSync } from 'child_process'; 2 | import test from 'ava'; 3 | 4 | test(t => { 5 | const { stdout } = spawnSync('node', [ 6 | '-r', '../register', 7 | '--eval', 'console.log(typeof window)' 8 | ]); 9 | 10 | t.not(stdout.toString(), 'undefined'); 11 | }); 12 | -------------------------------------------------------------------------------- /test/window-properties-should-be-as-expected.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import browserEnv from '../src'; 3 | import expectedProperties from './fixtures/expectedProperties'; 4 | 5 | test(t => { 6 | browserEnv(); 7 | const properties = Object.getOwnPropertyNames(window); 8 | t.deepEqual(expectedProperties.sort(), properties.sort()); 9 | }); 10 | --------------------------------------------------------------------------------