Socket
Socket
Sign inDemoInstall

cypress-react-unit-test

Package Overview
Dependencies
0
Maintainers
1
Versions
109
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.2.0 to 2.3.0

lib/index.ts

163

dist/index.js
"use strict";
/// <reference path="./index.d.ts" />
Object.defineProperty(exports, "__esModule", { value: true });
// having weak reference to styles prevents garbage collection
// and "losing" styles when the next test starts
exports.stylesCache = new Map();
exports.setXMLHttpRequest = function (w) {
var stylesCache = new Map();
var setXMLHttpRequest = function (w) {
// by grabbing the XMLHttpRequest from app's iframe
// and putting it here - in the test iframe
// we suddenly get spying and stubbing 😁
// @ts-ignore
window.XMLHttpRequest = w.XMLHttpRequest;
return w;
};
exports.setAlert = function (w) {
var setAlert = function (w) {
window.alert = w.alert;
return w;
};
/** Initialize an empty document w/ ReactDOM and DOM events.
@function cy.injectReactDOM
**/
Cypress.Commands.add('injectReactDOM', function () {
return cy.log('Injecting ReactDOM for Unit Testing').then(function () {
// Generate inline script tags for UMD modules
var scripts = Cypress.modules
.map(function (module) { return "<script>" + module.source + "</script>"; })
.join('');
// include React and ReactDOM to force DOM to register all DOM event listeners
// otherwise the component will NOT be able to dispatch any events
// when it runs the second time
// https://github.com/bahmutov/cypress-react-unit-test/issues/3
var html = "<body>\n <div id=\"cypress-jsdom\"></div>\n " + scripts + "\n </body>";
var document = cy.state('document');
document.write(html);
document.close();
});
});
Cypress.stylesCache = stylesCache;
/** Caches styles from previously compiled components for reuse
@function cy.copyComponentStyles
@param {Object} component
**/
Cypress.Commands.add('copyComponentStyles', function (component) {
// need to find same component when component is recompiled
// by the JSX preprocessor. Thus have to use something else,
// like component name
var hash = component.type.name;
var document = cy.state('document');
var styles = document.querySelectorAll('head style');
if (styles.length) {
cy.log('injected %d styles', styles.length);
Cypress.stylesCache.set(hash, styles);
}
else {
cy.log('No styles injected for this component, checking cache');
if (Cypress.stylesCache.has(hash)) {
styles = Cypress.stylesCache.get(hash);
}
else {
styles = null;
}
}
if (!styles) {
return;
}
var parentDocument = window.parent.document;
// hmm, is this really project name?
// @ts-ignore
var projectName = Cypress.config('projectName');
var appIframeId = "Your App: '" + projectName + "'";
var appIframe = parentDocument.getElementById(appIframeId);
// @ts-ignore
var head = appIframe.contentDocument.querySelector('head');
styles.forEach(function (style) {
head.appendChild(style);
});
});
/**
* Mount a React component in a blank document; register it as an alias
* To access: use an alias or original component reference
* @function cy.mount
* @param {Object} jsx - component to mount
* @param {string} [Component] - alias to use later
* @example
```
import Hello from './hello.jsx'
// mount and access by alias
cy.mount(<Hello />, 'Hello')
// using default alias
cy.get('@Component')
// using specified alias
cy.get('@Hello').its('state').should(...)
// using original component
cy.get(Hello)
```
**/
exports.mount = function (jsx, alias) {
// Get the display name property via the component constructor
var displayname = alias || jsx.type.prototype.constructor.name;
cy.injectReactDOM()
.log("ReactDOM.render(<" + displayname + " ... />)", jsx.props)
.window({ log: false })
.then(setXMLHttpRequest)
.then(setAlert)
.then(function (win) {
var ReactDOM = win.ReactDOM;
var document = cy.state('document');
var component = ReactDOM.render(jsx, document.getElementById('cypress-jsdom'));
cy.wrap(component, { log: false }).as(displayname);
});
cy.copyComponentStyles(jsx);
};
Cypress.Commands.add('mount', exports.mount);
/** Get one or more DOM elements by selector or alias.
Features extended support for JSX and React.Component
@function cy.get
@param {string|object|function} selector
@param {object} options
@example cy.get('@Component')
@example cy.get(<Component />)
@example cy.get(Component)
**/
Cypress.Commands.overwrite('get', function (originalFn, selector, options) {
switch (typeof selector) {
case 'object':
// If attempting to use JSX as a selector, reference the displayname
if (selector.$$typeof &&
selector.$$typeof.toString().startsWith('Symbol(react')) {
var displayname_1 = selector.type.prototype.constructor.name;
return originalFn("@" + displayname_1, options);
}
case 'function':
// If attempting to use the component name without JSX (testing in .js/.ts files)
var displayname = selector.prototype.constructor.name;
return originalFn("@" + displayname, options);
default:
return originalFn(selector, options);
}
});
var moduleNames = [
{
name: 'react',
type: 'file',
location: 'node_modules/react/umd/react.development.js'
},
{
name: 'react-dom',
type: 'file',
location: 'node_modules/react-dom/umd/react-dom.development.js'
}
];
/*
Before All
- Load and cache UMD modules specified in fixtures/modules.json
These scripts are inlined in the document during unit tests
modules.json should be an array, which implicitly sets the loading order
Format: [{name, type, location}, ...]
*/
before(function () {
Cypress.modules = [];
cy.log('Initializing UMD module cache').then(function () {
var _loop_1 = function (module) {
var name_1 = module.name, type = module.type, location_1 = module.location;
cy.log("Loading " + name_1 + " via " + type)
.readFile(location_1)
.then(function (source) { return Cypress.modules.push({ name: name_1, type: type, location: location_1, source: source }); });
};
for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
var module = moduleNames_1[_i];
_loop_1(module);
}
});
});

@@ -1,5 +0,12 @@

// I hope to get types and docs from functions imported from ./commands one day
// I hope to get types and docs from functions imported from ./index one day
// but for now have to document methods in both places
// like this: import {mount} from './commands'
// like this: import {mount} from './index'
interface ReactModule {
name: string
type: string
location: string
source: string
}
declare namespace Cypress {

@@ -11,6 +18,9 @@ interface Cypress {

Styles: string
modules: ReactModule[]
}
// NOTE: By default, avoiding React.Component/Element typings
// for many cases, we don't want to import @types/react
interface Chainable<Subject = any> {
interface Chainable<Subject> {
state: (key) => any,
injectReactDOM: () => Chainable<void>

@@ -17,0 +27,0 @@ copyComponentStyles: (component: Symbol) => Chainable<void>

2

package.json
{
"name": "cypress-react-unit-test",
"version": "2.2.0",
"version": "2.3.0",
"description": "Unit test React components using Cypress",

@@ -5,0 +5,0 @@ "main": "dist",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc