How to get code input as component in react.js - javascript

I'm creating a webpage that has a code editor where the user can write code in react.js and run the test script on the terminal with the code that the user input. I have a test script using #testing-library/react. I'd like to get a code input from the text editor which is currently just a string and render it as a component on the test file so that I can run the test with the user's code input.
The test file is looking like this.
import { render } from "#testing-library/react";
import ToggleMessage from "./ToggleMessage";
import "#testing-library/jest-dom/extend-expect";
test("Render ToggleMessage component and check if it has text:'Want to buy a new car?'", () => {
const { getByText } = render(<ToggleMessage />); //<= Here I want to render codeInput as component.
const linkElement = getByText(/Want to buy a new car?/i);
expect(linkElement).toBeInTheDocument();
});
This is ToggleMessage.js where getting codeInput as a prop from a text editor.
import React, { useState, useRef } from "react";
function ToggleMessage({ codeInput }) {
const [display, setDisplay] = useState("none");
const toggle = () => {
display === "none" ? setDisplay("block") : setDisplay("none");
};
return (
<div>
<a href="#" onClick={toggle}>
Want to buy a new car?
</a>
<p style={{ display }}>Call +11 22 33 44 now!</p>
</div>
);
}
export default ToggleMessage;
Are there any ways to pass the codeInput prop to the test file and render it as a component? Any suggestions or help would be appreciated. Thank you!

Related

React Testing Library: Testing boolean state

I am currently writing a test using the testing-library/react package.
On the second click of my test, the text should not be in the document, but it is.
Here is the component I am testing:
import { useState } from 'react'
import { InfoType } from '../../constants'
type Props = {
type: InfoType
}
const HelpWidget = ({ type }: Props) => {
const [isHover, setHover] = useState<boolean>(false)
return (
<div className="help-widget">
<img
src={require('../../../public/images/info.svg')}
onMouseEnter={() => setHover(true)}
onMouseOut={() => setHover(false)}
onClick={() => setHover(!isHover)}
/>
{isHover ? <div className="info">{type}</div> : <div></div>}
</div>
)
}
export default HelpWidget
Here is the test I wrote:
import React from 'react'
import { screen, render, waitFor } from '#testing-library/react'
import userEvent from '#testing-library/user-event'
import HelpWidget from '../components/helpWidget/helpWidget'
// Testing if the HelpWidget conditionally renders based on the isHover boolean state.
test('helpWidget conditionally renders to the page', () => {
const epk4Post = 'Select a persona to post this'
render(<HelpWidget type={epk4Post} />)
const imageElement = screen.getByRole("img")
userEvent.click(imageElement)
screen.debug()
expect(screen.getByText(/select a persona to post this/i)).toBeInTheDocument()
userEvent.click(imageElement)
screen.debug()
});
And here is what I get when I run screen.debug() to see the DOM output. Here you can clearly see that on the second click, the text is still within the document when it should not be:
Please share your thoughts! Thank you.

onClick event listeners are not working in Remix

In my Remix app, I'm trying to conditionally display a UI widget, based on the value of a state variable. Here is my code.
import { useState } from "react";
import type { LinksFunction } from "remix";
import stylesUrl from "../styles/index.css";
export const links: LinksFunction = () => {
return [
{
rel: "stylesheet",
href: stylesUrl
}
];
};
export default function Index() {
const [isMenuOpen,setMenuOpen] = useState(false)
function toggleNav(){
window.alert("hh") // no alert is shown
console.log("hi") // no console statement is printed
setMenuOpen(!isMenuOpen)
}
return (
<div className="landing">
<button onClick={toggleNav}>test</button>
</div>
);
}
However, toggleNav function doesn't seem to be triggered on button click. I couldn't see any alert or output in the console.
I couldn't understand why it's not working. It would be great, if someone can point me out what I'm doing wrong here. TIA.
Ensure that you are rendering the Scripts component from Remix in the root route, without it you app will not load any JS client side.
See https://remix.run/docs/en/v1/api/remix#meta-links-scripts

Show a skeleton placeholder until Facebook Comments component loads completely in React (Next.js)

Using Next.js, I want to show a skeleton placeholder until Facebook Comments component loads completely.
Here is the code.
import { useState, useEffect } from "react";
import { initFacebook } from "../utils/initFacebook";
export default function IndexPage() {
const [loaded, setLoaded] = useState(false);
useEffect(() => {
const loadFacebook = async () => {
await initFacebook();
setLoaded(true);
};
loadFacebook();
}, []);
const skeletonComponent = (
<div>
<h1>Some skeleton placeholder</h1>
</div>
);
const facebookComponent = (
<div
className="fb-comments"
data-href="https://developers.facebook.com/docs/plugins/comments#configurator"
data-width="580"
data-numposts="10"
/>
);
return (
<div>
{loaded ? facebookComponent : skeletonComponent}
</div>
);
}
I'm using the state to switch between two components.
But the skeleton component does not wait until the Facebook component is fully loaded, and therefore users see the blank screen for about 3-5 seconds.
How should I go about having the skeleton component wait out until the Facebook component is visible?
The full code is available on CodeSandbox.
Any help would be appreciated.

Can't get MDX to work in a JavaScript Component. Just want Markdown to be turned to react components

Trying to make a react component with MDX that will turn markdown into react components. I want this so I can transform a blog article with embedded components (such as special article toolings and diagrams) from markdown stored in the DB into something presented on the page.
Been working on it for a few hours now and even my best attempts just result in literally nothing being displayed on the page. Where replacing the 'content' with a string displays.
I'm 100% baffled, lost and confused and really would appreciate help.
Original problem: https://www.reddit.com/r/reactjs/comments/mbdz7k/reactmarkdown_custom_component_declaration_how/
Working solution (but I am struggling to get it to work on my end). Provided by cmdq
https://codesandbox.io/s/dazzling-wescoff-ib8mv?file=/src/index.js
I've basically just moved the entire particular component file into being a JavaScript file but unfortunately I'm still running into many issues-- probably from lack of familiarality.
My current code is this in the file:
import ReactDOM from 'react-dom'
import renderToString from 'next-mdx-remote/render-to-string'
import hydrate from 'next-mdx-remote/hydrate'
import React, { Component } from 'react'
const exampleMdx = `
# h1
**foo**
<MyCustomComponent text="hell yeah" />
a
bar
`
const components = {
h1: (props) => <h1 style={{ color: 'tomato' }} {...props} />,
MyCustomComponent: ({ text }) => <marquee>{text}</marquee>,
}
const functionThing = async () => {
const mdxString = await renderToString(exampleMdx, {
components,
})
return hydrate(mdxString, { components });
}
export const ArticleTextTrial = () => {
let content = functionThing;
console.log(functionThing());
return (
<div className="articleMainTextSectionBody">{exampleMdx}
</div>
)
}

Getting values from a text editor in React js

I'm using a quill js component (a text editor) for Reactjs and I'm testing it to see all it's features.
I managed to build a editor with a toolbar, but now I have a doubt, how can I get everything the user typed and save it in my state? As I'll show you in the code if I console.log(the quillRef.current) I get a div and way inside it I have a p element which contains everything the user has typed. My idea is to place a button in the end, and when the user stops typing and clicks the button I store what they typed.
here's a link to the sandbox where I'm testing it:
codesandbox link
With quill.getText() function :
import React, { useState } from "react";
import { useQuill } from "react-quilljs";
export default () => {
const { quill, quillRef } = useQuill();
const [savedText, setSavedText] = useState("");
const handleSave = () => {
const text = quill.getText();
setSavedText(text);
};
return (
<div style={{ width: 500, height: 300 }}>
<button onClick={handleSave}>SAVE</button>
<div>Saved State : {savedText}</div>
<div ref={quillRef} />
</div>
);
};
Check on codesandbox : https://codesandbox.io/s/react-quilljsbasic-tt6pm?file=/src/App.js

Categories