In my React app I have a component which embeds an Instagram post.
It renders the following HTML structure:
<div data-testid="instagram"><iframe class="instagram-media instagram-media-rendered" id="instagram-embed-3" //etc....
I am using React testing library.
How do I write a test that checks if the iframe element exists and e.g with the CSS class instagram-media?
For accessibility purposes, it is recommended to always use the title attribute on an <iframe> to label/describe its content.
<div data-testid="instagram">
<iframe title="Instagram embed" className="instagram-media ..." id="instagram-
embed-3"></iframe>
</div>
You can then test if the <iframe> element exists with the getByTitle query.
expect(screen.getByTitle('Instagram embed')).toBeInTheDocument();
Related
I have a React component
<Text>
<div dangerouslySetInnerHTML={{ __html: apiContent}} />
</Text>
that displays HTML coming from an API that may look like the following:
<div>
<p>text</p>
<p>more text</p>
<p>more text</p>
<p>more text</p>
<p>still more text</p>
</div>
How do I insert an image, which is another React component, between the 2nd and 3rd p tag?
I know how to do it in vanilla JS, but have trouble doing it the React way.
I'd be curious to see the other answers, but I feel like inserting a React component inside some raw HTML is pretty much impossible. The options I can think of are:
use some library to turn the raw HTML into a tree of React components, and hopefully this library will also include a way to inject custom components in specific places (I don't know any such library, but there probably is one)
edit the raw HTML to insert an empty container with a unique id at the place you need it (for instance by parsing the HTML into a DocumentFragment, using vanilla JS to insert a div, turning it back into a string, and setting it as innerHTML as you already do), and then use a React portal to inject a React component into that container. Pretty messy...
If it is a react component then it is not html so not logical to put it inside dangerouslySetInnerHTML tag.
you need to rewrite this react component to an HTML string and work with the html that is coming from API as a string.
that means you can split the incoming string of html on the second closing p tag
and add the new html string in the middle.
I have a test app with react-native-web-view rendering a local HTML file
for using JS, it works if I have the JS embedded in the HTML, but if I call it on a separate JS file it won't work...
in my App.tsx:
<WebView source={{uri: `${origin}/${file}`}} style={styles.webview} />
here is the embedded HTML:
<button type="button" onclick="alabama();">Play</button>
<button type="button" onclick="alert('Hello alabama')">music</button>
<script src="./chusa.js"></script>
chusa.js:
function alabama() {
alert('Hello alabama');
}
So, alert works, the function doesn't.
How can I call the script on a separate file?
React-Native Web WebView uses an iframe in replace of the webview component, so the issue is likely due the html file (e.g. the iframe) not having access to external files once mounted/created.
Possible Solution:
If you want the file to still be external, change it to a string and use back-quotes:
export const javascript = `alert("hello")`
Import js component. Something like:
import externalJS from "./filename"
The imported variable is a string and your html should also be a string, so you'll want to append the script string to the end of the html string. Something like this:
html = html.replace('</body>', '<script>${externalJS}</script></body>')
Use the new html string as the source via prop:
<WebView source={{ html: html }/>
Note: When you say "call" the script, if you are referring to calling a function after the web webview has been created without re-rendering, then that isn't possible at this time due when using the web webview instead of an actual webview component. This is actually an issue I am trying to resolve: How do I post a message to a iframe (not webview) in React-Native?
Hopefully this helps you with your issue.
I have set up a Gatsby blog that uses md files to create pages for each blog post. I want to use Narrative.so (photo layouts) for the content of each blog. Using their software, it generates HTML for you to paste into your site's page.
Would this be possible in Gatsby?
Here is the HTML it gave me as an example:
<div class='nar-root' data-post-id='9ab2885d-f0e8-4d00-9c59-135ab04fc384' style='p {text-align:center;opacity: 0.0;animation: nara 0s ease-in 2s forwards;}#keyframes nara {to {opacity: 1.0;}}' >
<img style="width:100%;" src="https://content1.getnarrativeapp.com/static/9ab2885d-f0e8-4d00-9c59-135ab04fc384/featured.jpg">
<noscript><p>Your Narrative blog will appear here, click preview to see it live.<br>For any issues click here</p></noscript>
<script type="text/javascript" src="https://service.getnarrativeapp.com/core/embed/r/9ab2885d-f0e8-4d00-9c59-135ab04fc384.js"></script>
</div>
Yes, it is possible. Here is one possiblity:
Add MDX support to your blog
With MDX you can embed React components into your markdown file.
// markdown file
import { NarrativePhotoLayout } from '../components/NarrativePhotoLayout'
# Here’s a NarrativePhotoLayout
The NarrativePhotoLayout is rendered inside our MDX document.
<NarrativePhotoLayout/>
Build a React component that contains your HTML. This answer tells you how.
Embed your React component in your blog post.
I am building blogging application. and i use summernote for write a blog content.
Blog content are stored in database like this :
<b>hi</b>.....<b>share if you like</b>
But when i fetch and try to disply blog content it will display same html code
ex:
<b>hi</b>.....<b>share if you like</b> insted of hi ..... share if you like.
Now how to display blog content with all styles?
Snap of table:
Snap of html output:
You can use dangerouslySetInnerHTML to render html content.
<div dangerouslySetInnerHTML={{__html: "<p>your html content</p>"}}></div>
I had a working Meteor App with Angular and Blaze before the 1.2.1 Update came out, but now it´s not possible anymore to use for example
{{>sAlert}}
in my Application.
There is a helper package called "angular-with-blaze", where you have the possibility to include Blaze templates, and I thought I´d wrap the {{>sAlert}} into a custom template, and load it with
<template name="custom">
{{>sAlert}}
</template>
<blaze-template name="custom"></blaze-template>
But it tells me, that the template wasn´t found.
So what is now the way to go for including such components in my meteor based angular app?
Your approach is correct. Put the sAlert template helper in a blaze template and render that template with blaze-template. But you need to put the blaze-template line in your angular html file and the actual Blaze template in another html file where you only put your Blaze templates.
example-list.ng.html:
<div>
<header>
<h1>Sample</h1>
</header>
<blaze-template name="test1"></blaze-template>
<blaze-template name="test2"></blaze-template>
</div>
And another file for your Blaze templates:
blaze-templates.html:
<template name="test1">
{{> sAlert}}
Hello {{visitor}}
</template>
<template name="test2">
Hello {{customer}}
</template>
* because I render both test1 and test2 to the same page, only test1 can have the sAlert template helper. If on different pages, repeat the template helper. But that is not part of your question, it is how sAlert works.