Test page rendering (visually) for next.js + jest - testing

Is there a way to test how the page render in next.js?
Not by comparing the html, but the actual images.
So far I only found a way to "render" the component into a html (tags tree) with toJSON():
import React from 'react'
import TestRenderer from 'react-test-renderer'
import Index from './index'
it(`should render`, () => {
const testRenderer = TestRenderer.create(<Index/>)
expect(testRenderer.toJSON()).toMatchSnapshot()
})
But there is no information on how to do this with the actual rendering and real images.
At the very end I want to be able to compare the current image to the reference with pixel-perfect accuracy.
Is it possible?

You want to look for tools to do visual testing. Generally the setup is such that you run the test once, it creates screenshots, and then when you run it later again it compares against those screenshots to see if any regression occurred.
This person explains a setup with a nextJs app, cypress and applitools

Related

React native Detox e2e OTP Testing

Ive implemented a OTP screen in my react-native project and I cant find a way to test it, I have the code for the OPT screen and I can either display the value and then tell detox to copy the text or tell it to use the state through context.
State & context:
but if I add import {useContext} from 'react' and then delcare my context const appContext = useContext(APP_CONTEXT) then use the appContext.OTPCode in my .typeText like so
await element(by.id('appOTPCode')).typeText(appContext.OTPCode);
it gives me a SyntaxError: Cannot use import statement outside a module error on import {useContext} from 'react'
is there a way to tell Detox e2e to accept such imports ?
Display OPT code on screen and copy
I cant find a way to tell detox to copy and paste the code if I display it as plain text on the screen via state.
is there a way to do something like this ?
If any of you have a solution or another way please be kind and share.
Thanks in andvance
Found a solution
it('it should enter OTP', async () => {
// get the OTP from the text field
const otp = await element(by.id('otpText')).getAttributes();
// enter the OTP into the OTP input field
await element(by.id('otpText')).tap();
await element(by.id('otpText')).typeText(otp.text);
});

React Native dependency import memory consumption: import all illustrations vs import specific illustration from package

If a Component of a React Native application is doing the following:
import * as Illustrations from '#xyz/illustrations';
and using it like:
function App() {
// Method to get an actual ReactElement out of the illustrations
const getIllustration = (illu: string): ReactElement => {
const Illu = (Illustrations as { [key: string]: any })[illu];
return <Illu />;
};
return {getIllustration(illustration)};
}
vs:
import { Myillustration} from '#xyz/illustrations';
function App() {
return <Myillustration />;
}
then what effect does it have on the memory consumption of an Android App builded with React Native? I thought, that importing all illustration by import * as Illustrations from '#xyz/illustrations'; and then just extracting one specific Illustration is a huge memory consumption problem, but my tests with the Android Device Monitor shows me that both methods do not make any difference in memory consumption. The same is valid for the APK size created for both ways. They are identical.
Questions:
Is the bundle loaded completely on app start into the memory (RAM) from the application? As far as I know a ReactNative application runs in one Activity and the screens should be Fragments and therefore it might load everything into RAM, but I might be wrong as I don't find any information regarding that topic.
Why does importing all illustrations out of one package does not increase the memory consumption, like described?
Is there a way to analyze the memory consumption of a specific React Native screen?
UPDATE:
Ok, now I know, that it makes no difference for React Native if I import a Component/Illustration like:
import * as Illustrations from '#xyz/illustrations';
or
import { Myillustration } from '#xyz/illustrations';
because Tree Shaking is not supported and therefore the transpiled Code (into Javascript) looks for both like (I use TypesScript directly via yarn buid:ts and see the output in the /dist folder):
const illustrations_1 = require("#xyz/illustrations");
...
react_1.default.createElement(illustrations_1.Myillustration, null))),

Jest unit test fails everytime Vue component gets mounted

I am currently trying to write some unit tests for my web application that I made with Nuxt, Vue and Vuetify. I decided to use the Jest framework and the vue-test-utils to write unit tests, but it seems like Jest or vue-test-utils refuses to mount my components.
Example
Let’s take this very simple test where i shallowMount my component and see if the component renders a div:
require("jsdom-global")();
import AlbumHeader from "#/components/Album/AlbumHeader";
import { shallowMount } from "#vue/test-utils";
describe("AlbumHeader.vue", () => {
it("renders a div", () => {
const wrapper = shallowMount(AlbumHeader);
expect(wrapper.contains("div")).toBe(true);
});
});
When I run this unit test it always fails with the error:
TypeError: Cannot read property 'child' of undefined
I feel like the problem has something to do with Vuetify. But even after creating new Vuetify instances in my test and creating a localVue I still cannot get it to pass the test. I feel like I have read every article on this topic and none of them seem to help. This is also the first time I use this framework so I really do not have a clue where this problem takes place.
I hope someone can explain to me what i am doing wrong and how i can fix it, i would really appreciate that.

How do I use require('electron') in a quasar vue component environment?

How do I access the main electron process fs module from within a renderer side module like a vue component running within the Quasar framework.
I've tried a few variations in a component with the following error:
const { app } = require('electron')
vue-router.esm.js?8c4f:1897 TypeError: fs.existsSync is not a function
const { app } = window.require('electron')
TypeError: window.require is not a function
After looking at what I could find through my friend Google, I am still searching for an answer on how to access the electron main process functions from within a vue component running under the quasar framework. Anyone... anyone? I've seen some github examples of file explorers, but based on the electron documentation it seems the implementation of just simply calling something like fs.readdirSync() should be a lot simpler than what I'm seeing in those implementations.
Your problem is explained in the Quasar docs
https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
Quasar's suggestion is to use a preload script to attach the node APIs that you want in your renderer processes (ie: BrowserWindows) to the global window object.
https://quasar.dev/quasar-cli/developing-electron-apps/electron-preload-script
Attach preload script to BrowserWindow (Main Process)
src-electron/electron-main.js:
import path from 'path'
win = new BrowserWindow({
...
webPreferences: {
preload: path.resolve(__dirname, 'electron-preload.js')
}
})
Attach Node APIs to window global (Preload Script)
src-electron/electron-preload.js:
window.electron = require('electron')
Use Node API through the window global (Renderer Process)
somefile.vue
window.electron.ipcRenderer.sendSync(
'message',
payload
)
The answer was just beyond my understanding of how all these components are working together. Hopefully this will help someone else just coming up to speed on developing a Quasar/Vue/Electron app. If you launch your app/website using
quasar dev
you get a browser (renderer) that communicates with main electron process that cannot handle node main process stuff like:
const electron = require('electron')
const fs = require('fs')
const files = fs.readdirSync('/')
console.log(files)
I couldn't find a clear, concise and simple way. It appears there is a webpack config that can provide the same 'deep' integration, but I was looking for a more out of the box solution.
If you launch your app
quasar dev -m electron
You get deep integration and now can 'require()' or import the above modules within Vue components in your Quasar app.
const electron = require('electron')

Snapshot Testing with Vue-Router

I'm trying to run jest-snapshot tests in a Vue app created using the Vue-cli app. When I test a component that have a router-link in it, I receive the following warning.
[Vue warn]: Unknown custom element: <router-link> - did you register
the component correctly? For recursive components, make sure to
provide the "name" option.
Following the documentation here Unit tests with View Router I can stub out the router-link, but that doesn't pass my snapshot test. Has anyone run into this issue before?
Updated: A more consistent solution
tl;dr:
The solution I found that works consistently is to create a localVue (usually outside the scope of the describe() blocks) and add the RoutherLinkStub as a component.
import { mount, RouterLinkStub, createLocalVue } from '#vue/test-utils';
const localVue = createLocalVue();
localVue.component('router-link', RouterLinkStub);
const wrapper = mount(Component, { localVue });
The documentation doesn't make the solution obvious because it seems to be something of a hybrid of the page you linked to and this one about RouterLinkStub.
From that page:
import { mount, RouterLinkStub } from '#vue/test-utils'
const wrapper = mount(Component, {
stubs: {
RouterLink: RouterLinkStub
}
})
That solution works in most cases. If you have a case where you need to use mount and your router-link is a not in the component being tested but the one below it, you will still get that warning. Now, if you are in that situation, it's worth reflecting if you're writing your test properly (are you testing too much rather than a small unit?), but I have a situation or two where if I shallow instead of mount, the snapshot test is worthless because it renders children as <!----> when I callexpect(wrapper.html()).toMatchSnapshot()`.
A Note on Snapshot Tests:
I haven't actually seen examples of people using the Wrapper.html() method for snapshot testing, but it really seems like the best solution in my experimenting. vue-server-renderer is a long walk for what appears to be the same result. Accessing the vm property of Wrapper gives you access to the $el property, without much trouble, but it's just a more whitespace-heavy rendering of html().