I'm snapshot testing the HTML from a React component:
describe('something', () => {
const wrapper = mount(
<MockProvider>
<MyCompoent />
</MockProvider>,
);
test('matches the snapshot', () => {
expect(wrapper.html()).toMatchSnapshot();
});
});
This works however the snapshot is minified:
exports[`MyCompoent something`] = `"<section class=\\"wrapper\\"><a class=\\"backLink\\" href=\\"#gift-type\\"><i class=\\"icon ArrowLeft backLinkIcon\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 64 64\\"><path fill=\\"currentColor\\" fill-rule=\\"nonzero\\" d=\\"M19.053 30.01h32.12v3h-32.38l13.28 13.28-2.121 2.121L13 31.458 30.004 16l2.018 2.22z\\"></path></svg></i>Back</a><div cla....
How can I have the HTML nicely multiline and indented? The same thing happens when I console.log(wrapper.html())
In my jest-config.js I already have this:
module.exports = {
snapshotSerializers: ['enzyme-to-json/serializer'],
};
If I don't use the render method (eg expect(wrapper).toMatchSnapshot();) then the multiline and indentation works fine.
Related
I'm using tiptap and trying to extend the Paragraph node to wrap some extra stuff around its view. I used <NodeViewWrapper> and <NodeViewContent> as the guides said.
const ParagraphWrapper = () => {
return (
<NodeViewWrapper>
<NodeViewContent />
</NodeViewWrapper>
)
}
const ParagraphExt = Paragraph.extend({
addNodeView() {
return ReactNodeViewRenderer(ParagraphWrapper)
}
})
export default function App() {
const editor = useEditor({
extensions: [
Document,
Text,
ParagraphExt, // <<<< text-align was not rendered
// Paragraph, // <<<< This worked
TextAlign.configure({
types: ["paragraph"]
}),
],
content: `<p style="text-align: center">This is a paragraph</p>`,
})
return (
<>
<EditorContent editor={editor} />
<pre>{JSON.stringify(editor?.getJSON?.(), null, 2)}</pre>
</>
);
}
However, this seems to render the node from scratch. Thus, other extensions, such as textAlign no longer works.
I only need to wrap a thin layer around whatever was rendered originally. How do I do that?
Code Sandbox
You still get access to the attrs being passed to the node which is available in props. You can use that info to style your rendered content as you wish.
const ParagraphWrapper = (props) => {
const textAlign = props.node.attrs.textAlign;
return (
<NodeViewWrapper>
<NodeViewContent style={{textAlign}} />
</NodeViewWrapper>
);
};
I tried to simulate a mouseover in my test, but i have a problem when i use .contain in an expect. The test doesn't pass because of the page render.
Here the result of the test:
Expected substring: "<div id=\"title\"><!--v-if--></div>"
Received string: "<div id=\"title\">
<!--v-if-->
</div>"
Here my code:
describe('mouse event', function() {
test('over change', async (done) => {
const Component = defineComponent({
template: '<div id="title" #mouseover="hoveredIcon"><span v-if="hovered">Hello World</span></div>',
data() {
return {
hovered: false,
}
},
methods: {
hoveredIcon() {
this.hovered = true
},
}
})
const wrapper = mount(Component)
expect(wrapper.html()).toContain('"<div id=\"title\"><!--v-if--></div>"')
wrapper.find("#title").trigger("mouseover");
wrapper.vm.$nextTick( () => {
expect(wrapper.html()).toContain('<div id=\"title\"><span>Hello World!</span></div>')
done();
});
})
})
How can i get the received string on a single line? Or how to made the expect part in few line to match perfectly?
expect(wrapper.html()).toContain('<div id="title"><!--v-if--></div>')
to
expect(wrapper.html()).toContain('<div id="title">
<!--v-if-->
</div>')
Any better solutions?
Thanks for your help
One solution found was to use directly \n directly in the value expected.
expect(wrapper.html()).toContain('\n \n')
I need help, I wanted to test whether the graph is rendering to me by searching for the word that should appear after the graph is rendered, but it gets an error.
I am trying to write tests in JEST
Below is a function drawing a graph
export interface CharProps {
data:Array<any>,
labels:Array<any>
}
export const Graph: React.FC<CharProps> = ({labels,data}) => {
const [chartData, setChartData]= useState({})
const chart = ()=>{
setChartData({
labels:labels,
datasets:[
{
label: 'Annual revenue',
fill: false,
}
]
})
}
useEffect(()=>{
chart()
},[])
return (
<>
<div className={chartBackground}>
<Line data={chartData} options={{responsive:true}}/>
</div>
</>
);
}
And my test below
describe('<Graph /> ', () => {
it('should be redner', () => {
render(<Graph data={[65]} labels={['monday']} ></Graph>);
expect(screen.getByText('monday')).toBeTruthy;
});
})
And my bug
TypeError: Cannot set property '_options' of undefined
8 | describe('<Graph /> ', () => {
9 | it('should be redner', () => {
> 10 | render(<Graph data={[65]} labels={['monday']} ></Graph>);
| ^
11 | expect(screen.getByText('monday')).toBeTruthy;
12 | });
13 | })
I cannot understand it, please help.
With the limited context available I can only guess what the problem is. But it seems like Graph is unknown to jest. Please check if you have properly imported the Graph component in your test file or test helper.
More information on jest and react: https://jestjs.io/docs/en/tutorial-react
I want to test a stencil component and configure a global variable in my test like this:
describe('my-component', () => {
const myVarMock = 1;
let page;
let shadowRoot: ShadowRoot;
beforeEach(async () => {
page = await newSpecPage({
components: [MyComponent],
html: `<my-component></my-component>`,
supportsShadowDom: true,
autoApplyChanges: true
});
shadowRoot = page.root.shadowRoot;
});
it('should test', () => {
page.rootInstance.myVar= myVarMock;
page.rootInstance.componentWillLoad();
page.rootInstance.render();
console.log(shadowRoot.innerHTML.toString());
const buttonElement = shadowRoot.querySelector('.my-button'); //is null because shadow root is empty
});
});
My Component only renders something, when myVar is set. In the console.log of my test, shadowRoot is always empty, although I explicitly call render() in the test and when I go through the render function in debug-mode it has a value for myVar and renders everything. But why is shadowRoot then empty and my buttonElement is undefined?
Component:
#Component({
tag: 'my-component',
shadow: true,
})
export class MyComponent{
public myVar;
componentWillLoad() {
...
}
render() {
return (
<Host>
{this.myVar? (
<div class="my-button"></div>
): null}
</Host>
)
}
}
Calling those life-cycle hooks like componentWillLoad and render manually does not do what I think you're expecting it to do. The Stencil runtime calls render and uses the return value (JSX) to eventually render your component. Manually calling render does not render or re-render your component. In fact, it doesn't do anything except returning some JSX to you but you're not doing anything with the return value.
I think the main issue in your case is that myVar is not declared as a property with the #Prop() decorator. So even though you have marked your class member as public and are able to change it from the outside, Stencil will not wire up anything for you regarding that prop. See https://stenciljs.com/docs/properties.
Instead, you'll have to define it as:
#Prop() myVar?: number;
That way it will cause Stencil to re-render your component every time you update the prop's value.
Your test case should just look like
it('should test', () => {
page.root.myVar = myVarMock;
console.log(shadowRoot.innerHTML.toString());
const buttonElement = shadowRoot.querySelector('.my-button');
expect(buttonElement).not.toBeNull();
});
I'm using a helper method to render a template, like so:
module.exports = (Handlebars) => {
Handlebars.registerHelper('foo', () => {
var template = require('../path/to/template.hbs')
return template;
})
}
In the rendered template, I'd like to call another helper, bar.
// template.hbs
<div>
{{foo}}
</div>
// bar.js
module.exports = (Handlebars) => {
Handlebars.registerHelper('bar', ()=> {
// do something here
}
}
But the rendered template seems to have no visibility of the helper, i.e. bar isn't called. What's a good way to get around this?