Comments (22)
I continue with the same problem. For example:
<span>My name is (${name})</span>
The result for this code is:
<span>
My name is (
Ana
)
</span>
So getByText will fail saying Unable to find an element with the text when I try to do
screen.getByText(`My name is ${name})`)
What can I do to make this work?
from react-testing-library.
I'll take it, since I'll probably also have to do this to jest-dom's .toHaveTextContent
;)
(BTW, this is really a PR for dom-testing-library)
from react-testing-library.
This is also happening for me.
My JSX:
<Text as="h1" size="large">
Leave {data.community.name}?
</Text>
The output:
<h1
class="c-PJLV c-PJLV-ddalwR-size-large"
>
Leave
Foo
?
</h1>
And the test:
it('confirms with the user whether they wish to leave', async () => {
expect(
await screen.findByText('You are about to leave the Foo community'),
).toBeInTheDocument()
})
Not sure if this is actually the same issue, but it's definitely the same symptom. Noticed it when I upgraded to React 17 and started using the new JSX transform.
I was able to work around this by changing my assertion to:
expect(
await screen.findByText(/You are about to leave the(.*)Foo(.*)community./)
).toBeInTheDocument()
from react-testing-library.
That is a very good point. I guess then all you can do is ensure that you concatenate strings like this before inserting them into JSX.
from react-testing-library.
I'm running into the same problem, even with strings that don't have a space between the variable and normal text, e.g. <span>{volts}V<span>
.
In this situation, the DOM node's textContent
property contains a string without spaces, even though there are two Text
nodes behind the scenes.
Live example: https://codesandbox.io/s/w718n5ojq7
from react-testing-library.
Given that in html any extra whitespace between words in text is not meaningful, and the resulting text shown to the user on screen is what you expect in your test above, I think it makes sense to take this into account when matching an element's text content.
Actually I am now wondering if .toHaveTextContent
should also take this into account.
from react-testing-library.
Yes. We should update the matcher
function in dom-testing-library to replace multiple spaces with one before it attempts to do any comparison. I consider this a bug and would love a pull request for it 👍
from react-testing-library.
I'm still having this issue, any idea why it would continue to add white spaces? Updated to the latest dom-testing-library.
from react-testing-library.
@DarrylD your best bet for others to be able to help is to provide a sample repository or codesandbox where the problem can be reproduced.
from react-testing-library.
I have also continued to experience the same issue, and was able to diagnose it (as far as my case goes, at least).
The problem is that the amendment to getText
presupposes that when text is divided over multiple lines, the text on each line will constitute a separate word. Things go wrong when this is not the case; for example:
Pay
£
24.99
will end up as Pay £ 24.99
. This problem is remedied if line 73 here is changed from .join(' ')
to .join('')
.
Then, however, you'd be required to ensure a space is present after each separate word that's on a different line, so Pay
would have to be Pay
(i.e. with a space after it on the same line) in my example. Otherwise, there's no way to differentiate between words on different lines that should be separated by spaces on the one hand, and word fragments/characters on separate lines that should be concatenated on the other.
But I'm not really proposing this change be made, as you shouldn't have to ensure those spaces are present in your JSX.
from react-testing-library.
This is actually how HTML works. If you were to put this in the DOM:
<div>
Pay
£
24.99
</div>
The resulting output would appear to the user as:
Pay £ 24.99
This is why we do the join(' ')
in dom-testing-library.
from react-testing-library.
Ah, this is tricky! What do you propose?
from react-testing-library.
Good question!
I'm not at all familiar with the internals of this library, but following @maxcct's lead, replacing join(' ')
with join('')
in getNodeText
seems to do the trick.
I haven't made a proper fork of dom-testing-library
yet, but I checked out master
, ran the test suite locally with this change, and everything still passed.
I also wrote a quick (passing 🙌) test to see if the change works as expected across text nodes:
test('can get elements by matching their text across adjacent text nodes', () => {
const textDiv = document.createElement('div')
const textNodeContent = ['£', '24', '.', '99']
textNodeContent
.map(text => document.createTextNode(text))
.forEach(textNode => textDiv.appendChild(textNode))
const {container, queryByText} = render('<div />')
container.appendChild(textDiv)
expect(queryByText('£24.99')).toBeInTheDOM()
})
In any event, since this issue doesn't seem specific to React, maybe it would be better to move the discussion over to an issue and/or PR in dom-testing-library
?
from react-testing-library.
Yeah, this should be talked about in dom-testing-library
. Could you make a PR there and we can discuss how to solve this there. Thanks!
from react-testing-library.
I was able to work around this by changing my assertion to:
expect( await screen.findByText(/You are about to leave the(.*)Foo(.*)community./) ).toBeInTheDocument()
I'm using an older version, so maybe an update (not an option right now) would solve this, but I got it working with a solution similar to yours:
expect(screen.getByRole('button', { name: /Factors\s/ })).toBeInTheDocument();
from react-testing-library.
This is still an issue for me. Is there going to be any solution for this?
Can we consider reopening the issue?
My use case:
<Text textStyle="p12" color="typography.titleNormal" mb={6} data-testid="change-created-at">
Created {format(createdAt, DEFAULT_DATE_PATTERN)}
</Text>
I worked around by querying data-testid and then assert with toHaveTextContent
it('should display created at text', () => {
renderWithRouter(<Change {...props} />);
expect(screen.getByTestId('change-created-at')).toHaveTextContent('Created 15 June 2022')
});
from react-testing-library.
Is there any issue about changing the behaviour how this is rendered and so snapshots for me it is just looks false if I have component like this:
<div>
{charactersLeft} {translate('sulu_admin.characters_left')}
<div>
Is snapshoted as:
<div>
-8
sulu_admin.characters_left
</div>
Instead of and doesnt so represent what JSX is rendering:
<div>
-8 sulu_admin.characters_left
</div>
from react-testing-library.
We managed to solve this problem by manually joining the strings like so:
<div>
{charactersLeft + ' ' + translate('sulu_admin.characters_left')}
</div>
The code above generates the following (desired) snapshot result:
<div>
-8 sulu_admin.characters_left
</div>
from react-testing-library.
getting something very similar here - very strange behaviour. This issue is not closed.
-
Snapshot - 0
- Received + 1
@@ -1,6 +1,7 @@
+
it's adding new lines above my elements
from react-testing-library.
Any workaround for the above mentioned issues? This is a really old issue by now, and no idea why its marked as closed, when no specific answer was provided (by anyone) on how should we handle such scenarios.
I, as many others have already stated, am having an issue where the following JSX in my component:
<div>
<h2>{status} text ({count})</h2>
</div>
is rendered like this in the tests:
<h2>
new
ads (
1
)
</h2>
And I cannot use getByText
matcher to target it, as it says its unable to find the element. So.. how can I target it? I do not want to include data-testid
attribute in this case (as this is part of a dynamically generated content for a table).
I tried using await screen.findByText(/new text (1)/gim)
with the global and multi-line flags attached to the regex, but that is not working either.
from react-testing-library.
@pstevovski workaround string concat by @b3h3m0th should work in your case: #53 (comment)
from react-testing-library.
@alexander-schranz Thank you for your answer, and sorry for the late reply, no idea why but I didn't get any notification.
The answer provided by @b3h3m0th doesn't really work for my case in terms of practicality, I'd have to go and change a lot of the pieces trough out the application to convert them to be manually concatenated like that. And also, to be fair, that is just a "workaround" (as you mentioned), but then again accessing and reading dynamic values in React (or in JS in general) has better ways like we're all already using (either that be template literals or the way we use them in react).
===================
Closest thing I could work with was using getByText("Example text", { exact: false })
, but even that didn't always worked.
I know this is an old issue, but I do believe that there really should be a way by RTL to be able to easily target these JSX variables with dynamic values.
==================
And on the other hand, RTL also has problems when targeting elements like:
<p>
<span>Example</span> <strong>text</strong>
</p>
If wanted to target the entire p
element based on the entire text, that wouldn't work like we're expecting. So workaround at least for that type of issue would be a helper matcher function like:
type Query = (queryMatcher: MatcherFunction) => HTMLElement;
/**
*
* Helper matcher function to be used together with React Testing Library matchers.
*
* Helps find an element in the rendered testing UI that has nested HTML elements:
*
* @example
* <h1>
* <span>Title</span> with
* <strong>nested</strong> elements.
* </h1>
*
* @param query The query matcher function to be used, provided by RTL
* @param text The text by which we want to find the targeted element
*
* @returns The targeted element (if found). Otherwise, throws an error.
*
*/
export const getByTextWithMarkup = (query: Query, text: string): HTMLElement => {
return query((_content: string, node: any) => {
const hasText = (node: HTMLElement) => node.textContent === text;
const childrenDontHaveText = Array.from(node.children).every(
child => !hasText(child as HTMLElement),
);
return hasText(node) && childrenDontHaveText;
});
};
Leaving this here as it might help someone out there (although it doesn't really help with the main issue that was reported).
from react-testing-library.
Related Issues (20)
- Module parse failed: Unexpected token for the act-compat.js HOT 1
- asyncWrapper is not executed with act support HOT 3
- Generics not supported when using bound functions
- getByRole ignores role "link" on achors without href attribute or falsy value HOT 2
- Regression: Options not available in `renderHook` HOT 3
- V15 causes tests to throw `act` warnings HOT 4
- TypeScript error with skipLibCheck false HOT 4
- Regression: Types of property `hydrate` are incompatible in `renderHook` options
- Support React 18.3 HOT 2
- act shows up as deprecated when using react 18.3 HOT 1
- Seriously guys, how the fuck do I get started here? HOT 2
- Make @types/react-dom a Peer dependency HOT 2
- TypeScript: unexpected type errors when `exactOptionalPropertyTypes` is enabled
- yarn add --dev @testing-library/react HOT 1
- `ReactDOMTestUtils.act` is deprecated HOT 1
- React does not recognize the `fetchPriority` prop on a DOM element. HOT 1
- Strange behavor when using `renderHook` with `wrapper` option HOT 1
- Hook testing: useReducer doesn't updating state when the reducer action is executed HOT 2
- Bug report
- Issues HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-testing-library.