
Security News
/Research
Wallet-Draining npm Package Impersonates Nodemailer to Hijack Crypto Transactions
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
preact-render-spy
Advanced tools
Render preact components with access to the produced virtual dom for testing.
preact-render-spy is a package designed to cover many of the use cases for testing preact components. The API is roughly modeled after enzyme, but we do not support as many options currently.
We do our best to support Node.JS v6.11.0 and up, and speficially testing with jest, though other test runners should have no problems.
import {h} from 'preact';
import {shallow} from 'preact-render-spy';
import Testable from './testable';
it('lets you do cool things with preact components', () => {
const context = shallow(<Testable />);
expect(context.find('div').contains(<a>link</a>)).toBeTruthy();
context.find('[onClick]').simulate('click');
expect(context.find('a').text()).toBe('clicked');
});
The main render method takes some arbitrary JSX and replaces any component nodes with spies which wrap the component. These spies then look at the rendered output of the second level of JSX and stores a big map of all the JSX virtual DOM nodes that have been created by your component.
There is also concept of limiting the depth
of the rendering such that it will only resolve
a certain number of levels deep in the component tree. The depth
of the default renderer
is set to Infinity
, and we provide another renderer called shallow
to render with
{ depth: 1 }
.
We provide a plugin for rendering your jsx snapshots to a formatted string that you can enable using the jest configuration:
{
"snapshotSerializers": [ "preact-render-spy/snapshot" ]
}
deep(jsx, {depth = Infinity} = {})
Creates a new RenderContext
and renders using opts.depth
to specify how many components deep
it should allow the renderer to render. Also exported as render
and default
.
Example:
const Deeper = () => <div>Until Infinity!</div>;
const Second = () => <Deeper />;
const First = () => <Second />;
let context;
context = deep(<First />);
expect(context.find('div').text()).toBe('Until Infinity!');
context = deep(<First />, { depth: 2 });
// We rendered First and Second, but not Deeper, so we never render a <div>
expect(context.find('div').length).toBe(0);
shallow(jsx)
Creates a new RenderContext
with { depth: 1 }
.
RenderContext#find(selector)
Given a rendered context, find
accepts a "css like" language of selectors to search through the
rendered vdom for given nodes. NOTE: We only support this very limited set of "selectors", and no nesting.
We may expand this selector language in future versions, but it acheives our goals so far!
find('.selector')
- searches for any nodes with class
or className
attribute that matches selector
find('#selector')
- searches for any nodes with an id
attribute that matches selector
find('[selector]')
- searches for any nodes which have an attribute named selector
find('Selector')
- searches for any nodes which have a nodeName that matches Selector
,
this wills search for function/classes whos name
is Selector
, or displayName
is Selector
.
If the Selector
starts with a lower case letter, it will also check for tags like div
.This will return you a FindWrapper
which has other useful methods for testing.
RenderContext
extends FindWrapper
Like #find(selector)
RenderContext
has the rest of FindWrapper
's methods.
RenderContext#render(jsx)
Re-renders the root level jsx node using the same depth initially requested. This can be useful for testing
componentWillReceiveProps
hooks.
Example:
const Node = ({name}) => <div>{name}</div>
const context = shallow(<Node name="example" />);
expect(context.find('div').text()).toBe('example');
context.render(<Node name="second" />);
expect(context.find('div').text()).toBe('second');
FindWrapper
Contains a selection of nodes from RenderContext#find(selector)
.
Has numeric indexed properties and length like an array.
FindWrapper#at(index)
Returns another FindWrapper
at the specific index in the selection. Similar to wrapper[0]
but will
allow using other FindWrapper
methods on the result.
FindWrapper#attr(name)
Requires a single node selection to work.
Returns the value of the name
attribute on the jsx node.
FindWrapper#attrs()
Requires a single node selection to work. Returns a copy of the attributes passed to the jsx node.
FindWrapper#contains(vdom)
Searches for any children matching the vdom or text passed.
FindWrapper#text()
Returns the flattened string of any text children of any child component.
FindWrapper#simulate(event, ...args)
Looks for an attribute properly named onEvent
or onEventCapture
and calls it, passing the arguments.
FindWrapper#output()
Requires a single Component or functional node. Returns the vdom output of the given component. Any Component or functional nodes will be "recursive" up to the depth you specified. I.E.:
Example:
const Second = ({ children }) => <div>second {children}</div>;
const First = () => <Second>first</Second>;
// rendered deep, we get the div output
expect(deep(<First />).output()).toEqual(<div>second first</div>);
// rendered shallow, we get the <Second> jsx node back
expect(shallow(<First />).output()).toEqual(<Second>first</Second>);
FindWrapper#filter(selector)
Returns a new FindWrapper
with a subset of the previously selected elements given the selector argument.
Uses the same possible selectors as RenderContext#find(selector)
.
FindWrapper#find(selector)
Selects descendents of the elements previously selected. Returns a new FindWrapper
with the newly selected elements.
Uses the same possible selectors as RenderContext#find(selector)
.
There are many examples in the source files. Some tests specific to shallow, tests specific to deep, and many more tests against both.
class Node extends Component {
constructor(...args) {
super(...args);
this.state = {count: 0};
this.onClick = this.onClick.bind(this);
}
onClick() {
this.setState({count: this.state.count + 1});
}
render({}, {count}) {
return <div onClick={this.onClick}>{count}</div>;
}
}
const context = shallow(<Node/>);
expect(context.find('div').contains('0')).toBeTruthy();
context.find('[onClick]').simulate('click');
expect(context.find('div').contains('1')).toBeTruthy();
FAQs
Render preact components with access to the produced virtual dom for testing.
The npm package preact-render-spy receives a total of 2,387 weekly downloads. As such, preact-render-spy popularity was classified as popular.
We found that preact-render-spy demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.