How to use html and react in Enzyme? - reactjs

My <Header /> component obtains class collapsed in mobile view. I want to write test that will test mobile view scenario
it('should render mobile view', () => {
const wrapper = mount(
<div style={{width: '700px'}}>
<Header content={headerData} useDOMNodeWidth={true} />
</div>
);
expect(wrapper.find('.header-component').first().hasClass('collapsed')).to.equal(true);
});
After running test I have an AssertionError, so it seems that there is a problem with rendering. I assume that render method only accepts clean react component.
Any idea how I can test it ?

Header component might be rendering mobile view based on some condition. You will have to inject that condition in Header component while/before rendering it.
For eg: I have components on web portals which shows different logos based on customer type. This customer type will be set in my appConfig before I render the component.

Related

Is it possible to render a react fragment to an image without spinning up a server

I would like to render a react fragment to an image similar to how react-test-renderer renders html, without needing to create a route for the test and spin up a complete server.
So I would like to do something similar to this:
test("test is exemplified", () => {
const image = renderer.create(
<div class="container">
<component-under-test />
<component-under-test boolean-attribute />
<component-under-test className="some-class"/>
</div>).screenshot('./test-index.tsx');
expect(image).toMatchImageSnapshot();
})
Is it possible to get puppeteer or playwright to render an app inline like that?

React js nesting components/SearchBar component in Header

I have 2 components - a SearchBar component and a Header component.
I want to embed my SearchBar component in the Header component (like we see on Stackoverflow header above). So the header component must show throughtout the application but the Searchbar component should only embed after user logs in.
I have created a variable which has the Header(Header component) and it is nesting SearchBar into it. SearchBar will later perform a logic and return a table based on the search filters[search={changeSearchFilters}].
Issue - I'm able to render both individually, however, i'm not able to nest them and show together (stackoverflow header and the searchbar)
let headerBar=
<Header>
<SearchBar search={changeSearchFilters}></SearchBar>
</Header>
return (
<div className="AppBody">
{headerBar}
<div className="anchor flexGrow" style={{ 'minHeight': '650px' }}>
{Table1}
{Table2}
{Table3}
</div>

How to create popup with YouTube video that not affect main page?

I'm trying to have popup window with YouTube video that not affect the main page.
I can still interact with the main page, similar on this web site when you click track you have small popup video on right bottom corner.
I have App.js with YouTube API
{
getYouTubeApi = (searchTerms1, searchTerms2) => {
fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=10&q=${searchTerms1} ${searchTerms2}&type=video&key=YOUR_KEY`)
.then(res=>res.json())
.then(data=>{
this.setState({videoId: data.items[0].id.videoId})
})
.catch(error=>console.log(error))
}
render(){
return (<YouTube opts={opts} videoId={this.state.videoId} />)
}
}
getYouTubeApi function I call on click on track that just bring to the top of my page where YouTube video loads.
Here is my school project.
Since this describes DOM behavior more than business logic, you could put in whatever you want in a specific component that behaves like a modal (whether by swapping out css classes or setting inline styles based on certain conditions).
To make this modal reusable, I'll suggest you make it a higher order component to wrap around <Youtube /> component or any other component you want to display with modals.
For example, you could have
const Modal = (ComponentToDisplayAsModal, props) => (
<div class="modal">
<ComponentToDisplayAsModal {...props} />
</div>
)
You could then style the modal class to behave like a modal.
On the view you wish to show your modal, you could render
Modal(Youtube, props)

How can I disable some routing components to display?

I am making a web site which classified users into the admin and normal ones.
Some routing components should not be displayed like the view of other users' detail unless he is a authenticated user.
Besides, not only it should be displayed to the normal user, it also could not be accessible by the normal user. Where should I modify the code ReactDOM.render(.....) or inside the component ?
You should do it inside the component. ReactDOM.render takes in a React component and a DOM element. It is used to let React take control of the contents of that DOM element by rendering that component within it. Typically, most web apps only have one ReactDOM.render and it is used at the root of the HTML <body>.
What you want to achieve is called conditional rendering. In the example below, The "Edit profile" button will be rendered if this.state.profileBelongsToUser is true. Else it is not rendered in the DOM. You will have to fetch some data to decide the value of that boolean flag.
class Profile extends React.Component {
constructor(props) {
super(props);
// Initialize / set state probably by fetching some data.
this.state = {
profileBelongsToUser: false
};
}
render() {
return (
<div>
<div>
<h1>Profile page</h1>
<p>Name: John Doe</p>
{this.state.profileBelongsToUser ? <button>Edit profile</button> : null}
</div>
</div>
)
}
}

is there a way to have templates in react

I have built an element which is kind of template. (e.g, thumbnail container with image at the top and something in the footer with dynamic content between them)
the dynamic content can be different types of DOM elements, based on the state.
I did it with adding logic in the render method which "injects" the dynamic part.
Does this make sense (having logic in the render method which returns different react components)?
Is there a better way for templating? (i'm not looking for projects that add this capability, wanted to know if there's a "react way" to do so.
Thanks!
edit: here's the code I was referring to (coffeescript):
internalContent: ->
switch #props.title
when "title1" then SomeReactFactory(props)
when "title2" then SomeOtherReactFactory(props)
render ->
...
DOM.div
className: 'panel'
#internalContent()
the internalContent() method is dynamically adding some React Component based on the prop
This is the React way.. And you should make use of it to target your specific domain.
For example a Button in React could be written like this:
const MyButton = ({ text, type = "normal", color = "blue", onClick }) => {
return (
<button
onClick={onClick}
style={{backgroundColor: color }}
className={"my-button my-button--type" + type}>
{text}
</button>);
};
Or a layout component:
const MyLayout = ({side, nav, main}) => {
return (
<div className="container">
<nav>{nave}</nav>
<aside>{side}</aside>
<div className="main">{main}</div>
</div>
)
}
Now you can composite it for example like this:
class App extends Component {
...
render() {
<MyLayout
nav={<MyNav/>}
side={<MySideBar items={...} />}
main={<MyButton onClick={this.onClick} text="Main Button"}
/>
}
}
Dont try to pack everything in a big Component which will do everything, the trick in React is to make small reusable Components and composite them.
You could also create a bunch of components which you can use across many projects.

Resources