react storybook addon knobs not showing - reactjs

I cant seem to be getting the #storybook addon knobs working? It doesnt seem to be decorating the actual story. Pretty much followed this
My code below.. Im using getstorybook with create-react-app
Using below packages:
#storybook/addon-actions": "^3.1.2,
#storybook/addon-info": "^3.1.4,
#storybook/addon-knobs": "^3.1.2,
#storybook/react": "^3.1.3
my setup
//.storybook/addons.js
import '#storybook/addon-knobs/register'
//.config
import { configure, setAddon, addDecorator } from '#storybook/react';
import infoAddon from '#storybook/addon-info';
setAddon(infoAddon);
function loadStories() {
require('../stories');
}
configure(loadStories, module);
//stories/index.js
import React from 'react';
import { withKnobs, text, boolean, number } from '#storybook/addon-knobs';
import { storiesOf } from '#storybook/react';
const stories = storiesOf('Storybook Knobs', module);
// Add the `withKnobs` decorator to add knobs support to your stories.
// You can also configure `withKnobs` as a global decorator.
stories.addDecorator(withKnobs);
// Knobs for React props
stories.add('with a button', () => (
<button disabled={boolean('Disabled', false)} >
{text('Label', 'Hello Button')}
</button>
))
This should be a no brainer, but no suck luck.

Hope this helps someone, but for some reason my addons panel suddenly disappeared from view and I couldn't figure out how to get it back. I could see the addons markup being rendered in the "elements" pane in my dev tools - so I knew things were working. Somehow storybook stored a bad value in my localStorage['storybook-layout'] so that the addons were positioned waaaaayyy off screen. Running the following fixed it.
localStorage.removeItem('storybook-layout')

You probably need to create the addons.js file on the storybook config folder. (By default .storybook).
Check the Docs for knobs you need to add the following:
import '#storybook/addon-knobs/register';

Hitting D on your keyboard toggles the layout // Ray Brown
or
You should also be able to expand the sidebar by clicking and dragging on the right side.

Try removing all the query string on the url
eg. http://localhost:6006/?knob-is_block=false&knob-Disabled=false&knob-disabled=false&knob-Style%20lite=false&knob-show=true&knob-Size=md&knob-readOnly=false&knob-Style=default&knob-icon%20name=vertical&knob-Label=Hello%20Button&knob-Active=false&knob-is_loading=false&selectedKind=Button&selectedStory=default%20style&full=0&addons=0&stories=1&panelRight=0&addonPanel=storybooks%2Fstorybook-addon-knobs
to http://localhost:6006
This worked for me.

In Storybook 6.5 I was facing the same issue after manually adding the addon:
npm i #storybook/addon-knobs --dev
All I needed to do is to go to the main.js file inside the .storybook folder and add the following:
"addons": ["#storybook/addon-knobs"]
Then I stopped the already running storybook in the terminal using ctrl/cmd + c and then re-run the storybook:
npm run storybook
Hope it helps. Thank you.

Related

'LeafletProvider' is not exported from 'react-leaflet'

I had this error,
Attempted import error: 'LeafletProvider' is not exported from 'react-leaflet'.
when I tried to import LeafletProvider to one of my component file as follows:
import { withLeaflet, MapControl, LeafletProvider } from "react-leaflet";
I believe I have installed the latest version of react-leaflet (v.3.2.2) and have read the documentation as much as I could but I didn't see LeafletProvider in it.
Hope someone could help me fathom what to do with this. Basically, I just want to be able to change between two or more leaflet map tilelayers.
It seems the Provider has to be imported as such:
import { LeafletContext } from '#react-leaflet/core';
and used as :
<LeafletContext.Provider>
according to this page of the documentation:
https://react-leaflet.js.org/docs/core-api/#leafletprovider
Following the documentation in #Ivo's answer, here's what I did:
First install:
npm install #react-leaflet/core
Then import it like this:
import { LeafletContext } from "#react-leaflet/core"
And then use as:
<LeafletContext.Provider>
// enter code here
</LeafletContext.Provider>

ReactJS Jest Puppeteer tests no longer working: ReferenceError: document is not defined

Scenario
npm test used to work without issue. Over the course of a month or so (I neglected tests) something changed and now I receive ReferenceError: document is not defined when trying to run Jest-Puppeteer tests via npm test.
This error shows up even with document removed so it seems like a puppeteer issue but I'm not sure why this is showing up now. I've checked out code from over a month ago and the tests still work but so much has changed that it's difficult to chase down the actually issue.
Attempted Solutions
upgrade node
reinstall npm packages
revert jest-puppeteer.config.js to previous version
add #jest-environment jsdom to tests which fixes the document issue but then causes ReferenceError: page is undefined
Question
How can I troubleshoot this problem short of starting over from scratch? That said, I'm prepared to start over if that's what it's going to take, which sometimes it does.
Code
this is a basic jest file
import "core-js/stable";
import "regenerator-runtime/runtime";
import {Provider} from "react-redux"
import mockState from "./mocks/mockState"
import configureStore from "redux-mock-store"
import ShallowRenderer from 'react-test-renderer/shallow'
import API from '../src/API'
import getNavigationResponse from '../src/nocks/getNavigation'
import expectedNavigationState from "./static/expectedNavigationState"
import pageObjects from "./static/pageObjects"
import utils from './utils'
import constants from '../src/constants'
describe('API tests', () => {
beforeEach(async() => {
await page.goto('http://localhost:3000');
await page.setViewport({ width: 900, height: 600 });
await page.goto('http://localhost:3000/');
await page.evaluate(() => {
document.getElementById('root').classList.add('animated-test');
});
await page.waitForSelector(pageObjects.navFactory);
});
// PASS
test('API data to be in store', async () => {
await page.waitForSelector(pageObjects.primaryNavLink);
// get state from root
const store = await utils.getStore();
expect(store[0].navigation.urlHashMap).toEqual(expectedNavigationState);
});
test.todo('Make sure content==true on vanity urls (home)')
test.todo('Make sure content==false on url items with children (visitor)')
// PASS
test('API cancel should cancel the API request', async () => {
API.dispatch = () => {
};
API.fetch(constants.NAVIGATION_HREF, 'API_FETCH_TYPE_NAVIGATION');
const promiseCanceled = API.cancel('API_FETCH_TYPE_NAVIGATION');
expect(promiseCanceled).hasOwnProperty('promise');
expect(promiseCanceled).hasOwnProperty('cancel');
});
});
** EDIT **
From what I can find out, this "ReferenceError" seems to be a babel error that is caused because babel can't seem to figure out what "document" is. I traced down where the issue is happening and it is within a third party plugin so I left a note on the developer's github page in the mean time. Currently my "solution" is to comment this test out - I'll put more effort into this again when I have time to find a proper solution
** EDIT 2 **
If I add <rootDir>/node_modules/react-json-view/dist/main.js to babel config's transformIgnorePatterns then I get a different error of
ReferenceError: regeneratorRuntime is not defined
Which is odd because I explicitly have import "regenerator-runtime/runtime" at the top. This seems to be a step closer but I'm not sure. I switched back to babel-polyfill (deprecated) just to try it but ended with a different error of TypeError: jest: failed to cache transform results.
Normally you can do something like this answer which is to add:
npm test --env=jsdom
But since I also need Puppeteer's environment there's a clash because node only seems to support ONE environment.
Ultimately I removed the troubled plugin.

Invariant Violation using react-native-svg

I have the following error when I try to use react-native-svg:
I use react-native-svg like this in my code:
and I call the component like this
import BarChart from './BarChart'
// ...
I am using react-native-svg : 9.13.3 and expo : 36
I installed react-native-svg with expo install react-native-svg and I already try to relaunch with reset cache.....
save me please lol
have a nice day !
The issue is most probably coming from how you import your Svg.
From the documentation I found if you are using Expo, then you need to import as:
/* Use this if you are using Expo */
import * as Svg from 'react-native-svg';
const { Circle, Rect } = Svg;
Instead of your example:
import Svg, { Circle, Rect } from 'react-native-svg';
See under Usage section.

CommonJS require vs. ES6 import discrepancy

So, I am new to React. Apologies if I am missing something obvious, I'm wrestling with a weird issue with my ES6 imports.
I'm using the #typeform/embed module (0.12.1), which oddly links to a GitHub repo on npm but that repo doesn't exist. So I haven't been able to look into potentially related issues.
Anyways, whenever I do the following:
import typeformEmbed from '#typeform/embed'
My text editor shows that the type of typeformEmbed is a string, and when I go to invoke a function on it, it is always undefined. Gives me the 'ole cannot invoke property X on undefined TypeError. It almost looks as if it is trying to import the README?
But, then I opened up my Node REPL and could write:
const typeformEmbed = require('#typeform/embed')
and it works like a charm.
Is there some discrepancy between the two that I am missing?
Edit: I know that this question is pretty text-heavy, let me know if there is crucial information that I'm missing. I should mention that I built this project with create-react-app.
import * as typeformEmbed from '#typeform/embed';
const popUpHandler = () => {
typeformEmbed.makePopup(
'https://admin.typeform.com/to/PlBzgL',
{
mode: 'drawer_left',
autoOpen: true,
autoClose: 3,
hideScrollbars: true,
onSubmit: function () {
console.log('Typeform successfully submitted')
}
}
)}
Should work for you

How do i mock and customise the values of a function imported from a npm package using Jest?

I use isMobileOnly from "react-device-detect" npm package in my React component say(SampleComponent.js).
I would like to customize the return value of isMobileOnly in my jest unit tests.
I have tried Jest manual mocks as mentioned in the link below:
https://jestjs.io/docs/en/manual-mocks
But it does not seem to work for me.
I have also tried:
jest's mockImplementation
jest's mockImplementationOnce
jest's spyOn
import {isMobileOnly} from 'react-device-detect;
In my jest unit tests, i would like to mock the function isMobileOnly in such a way that i should be able to customize its return value to "true". The default value is "false".
This worked for me.
In your test file, add this: import * as deviceDetect from 'react-device-detect';
then you can change things like: deviceDetect.isMobileOnly = true;
eg.
import * as deviceDetect from 'react-device-detect'; //<--important
it.only('clicking on myAccount redirects to /user/myAccount', () => {
///make sure this is before mount or shallow
deviceDetect.isMobileOnly = true; //<--important
component = mount(<Provider store={store}><Sidebar history={mockedHistory} /></Provider>);
component.find('[test-id="myAccount"]').first().simulate('click');
expect(mockedHistory.push).toHaveBeenCalledWith('/user/myAccount');
});
Finally! I figured it out myself after hours of struggle. Here is what i did:
Created __mocks__ folder in the same level as node_modules directory where the package "react-device-detect" is available. Note: smaller case is important for __mocks__.
Created a file named "react-device-detect.js" within the __mocks__ folder.
Added the following code in it:
const deviceDetect = jest.genMockFromModule('react-device-detect');
deviceDetect.isMobileOnly = true;
module.exports = deviceDetect;
Within the test file, i imported the "isMobileOnly" as i did in the original
component:
import { isMobileOnly } from 'react-device-detect';
Now, i can change value of "deviceDetect.isMobileOnly" to true or false in the
mocked file as per the unit test case's need .
For more details, refer the official documentation here https://jestjs.io/docs/en/manual-mocks
Thanks #Roman for reaching out!
I use the " import * as deviceDetect" answer, it worked but I ran into an issue because of typescript and the readonly property of isMobile.
So this solution worked for me :
Object.defineProperty(reactDeviceDetect, 'isIOS', { get: () => true });
as describe here
I hope that help!
You can possibly override the User Agent for testing purposes so react-device-detect package will identify it like You need, here's how to do that.
This topic should also be helpful.

Resources