enzyme: wrapper.find('#name') returning two elements but only one element is shown in wrapper.html()
wrapper.find(‘#name’) returning two elements but only one element is shown in wrapper.html().
expected outcome
only one element would be returned by wrapper.find('#name')
and my eventual goal is to get the val of that textarea.
wrapper.find(‘#name’)
wrapper.html()
Note that there is only the one element with id=name
below <textarea id="name">Activate or redeem credit card</textarea>
<div class="App">
<div id="siteModal" class="hide">
<div class="modalInnerContainer">
<div class="modalTitle">
<!-- react-text: 5 --><!-- /react-text --><span class="modalExit">X</span>
</div>
<div class="modalContent"></div>
<div class="modalActions"><button class="action">CANCEL</button><button class="action">CONTINUE</button></div>
</div>
</div>
<div>
<div class="flyoutPanel left ">
<div class="flyoutPanelContent">
<div class="panelHeader">
<svg class="dsi dsiClose closePanel">
<use xlink:href="symbol-defs.svg#dsiClose"></use>
</svg>
<!-- react-text: 17 --><!-- /react-text -->
</div>
<div class="panelContent">
<div>
<div class="sidePanelInnerContainer">
<div class="inputContainer">
<label for="name">Name</label>
<textarea id="name">Activate or redeem credit card</textarea>
<hr>
</div>
<div class="inputContainer">
<label for="description">Description</label>
<textarea id="description" name="description"></textarea>
<hr>
</div>
</div>
<button id="closeDrawer" style="visibility: hidden;">Close Flyout</button>
</div>
</div>
<div class="panelFooter"></div>
</div>
</div>
<a class="closeDrawer" style="z-index: 1;"></a>
<div class="flyoutPanel right show">
<div class="flyoutPanelContent">
<div class="panelHeader">
<svg class="dsi dsiClose closePanel">
<use xlink:href="symbol-defs.svg#dsiClose"></use>
</svg>
<h3 class="title">Process Step Details</h3>
</div>
<div class="panelContent">
<div>
<div class="sidePanelInnerContainer">
<div class="inputContainer">
<label for="name">Name</label>
<textarea id="name">Activate or redeem credit card</textarea>
<hr>
</div>
<div class="inputContainer">
<label for="description">Description</label>
<textarea id="description" name="description"></textarea>
<hr>
</div>
</div>
<button id="closeDrawer" style="visibility: hidden;">Close Flyout</button>
</div>
</div>
<div class="panelFooter"></div>
</div>
</div>
<a class="closeDrawer active" style="z-index: 1;"></a>
</div>
<div class="App-header">
<span class="app-header-icon"><span class="letter">S</span><span class="dot">.</span></span><span class="app-header-segment">Entity Name Here</span>
<span class="app-header-segment">
<!-- react-text: 170 -->FY16 Year End Audit<!-- /react-text --><!-- react-text: 42 --> <!-- /react-text -->
</span>
<span class="app-header-segment green small-text">STAGE</span><span class="app-header-actions"><span class="temp-action"> </span></span>
</div>
<div class="currentProcess">
<div class="currentProcessNameContainer"><label id="processNameLabel" class="currentProcessLabel">Financial Statement Review</label><input type="hidden" id="processNameInput" class="currentProcessName" value="Financial Statement Review" style="width: 55%;"><span class="last-saved">Last saved: 8:23 PM</span><span class="currentProcessActions"> </span></div>
<div>
<div class="mainContent">
<div class="canvasHeader">
<div class="canvasHeaderLeft">
<div style="display: inline-flex; width: 400px; height: 40px; background-color: rgba(0, 0, 0, 0.01); position: relative; z-index: 100;"></div>
</div>
<div class="canvasHeaderRight">
<svg class="dsi dsiUndo">
<use xlink:href="symbol-defs.svg#dsiUndo"></use>
</svg>
<svg class="dsi dsiRedo">
<use xlink:href="symbol-defs.svg#dsiRedo"></use>
</svg>
<svg class="dsi dsiEye">
<use xlink:href="symbol-defs.svg#dsiEye"></use>
</svg>
<svg class="dsi dsiZoom">
<use xlink:href="symbol-defs.svg#dsiZoom"></use>
</svg>
<svg class="dsi dsiMore">
<use xlink:href="symbol-defs.svg#dsiMore"></use>
</svg>
</div>
</div>
<div class="cardsContainer" style="width: 100%; position: relative;">
<div class="cardContainer">
<div class="toggleEngagementLibrary"></div>
<div class="cardInner mainCanvas" style="display: block; width: 100%; height: 865px; background-color: rgb(255, 255, 255);"></div>
</div>
</div>
<div><button class="button primaryButton" type="submit" style="margin-left: 24px; margin-right: 10px; padding: 10px 16px;">Save</button><textarea id="customTextEditor" class="customTextEditorBlock"></textarea><textarea id="customOffSetTextEditor" class="customTextEditorBlock"></textarea></div>
</div>
</div>
</div>
</div>
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 14
- Comments: 47 (17 by maintainers)
This is indeed correct behavior.
To filter out custom components, use
.hostNodes()
- ie,wrapper.find('#someID').hostNodes()
and you’ll only get HTML elements.@sarneeh because in enzyme 3, the nodes you get are both React component instances, and DOM nodes. If you want to just have DOM nodes, you use
.hostNodes()
. You’re getting 2 because one of them isComponent
, and the other is thediv
thatComponent
renders.I’ve also encountered this issue and don’t really understand the reason why it works like this now? Why do I need to run some
hostNodes()
function on my wrapper?Mounting a single
div
with aclassName
and querying thisclassName
withfind
returns me 2 elements now. IMO it’s something completely opposite to being developer-intuitive.For example this:
Why would I expect to have 2 elements here?
Could someone explain this behaviour to me? @ljharb? 😃
I have a same issue in v3.
Chiming in - I am having the same issue here and was able to get more information using
wrapper.find('#target_id').debug()
Here’s a simplified example:
You can see that enzyme included the react pseudo-element in its markup, so that if
id
is the name of a prop it will match twice!This was done with mount()
@RyanAtViceSoftware Have you found a solution for this issue? Currently having a similar experience trying to locate text in a component.
@ljharb Alright, I understand that. But why it has been decided that this behaviour should be the default one? Couldn’t it be reversed, so by default I’ll get the behaviour from Enzyme v2, and in v3 have an additional method to get all of them?
To be clear: I don’t want to hate anyone nor anything, I just want to understand the decision behind it, because maybe I’m missing something, and maybe I could learn something too 😄
hostNodes()
solves it – but why is this necessary? Could at least be documentedwhat is that “evaluate expression” debugger that you are using? it seems cool 😄
https://github.com/airbnb/enzyme/issues/1174
@ljharb I got a hint from another issue card. This seems to be a compatibility issue with upgrading Enzyme v3. Tests are broken a lot ㅜㅜ. Other users seem to have some similar misunderstanding.
Got the same issue. For me worked adjusting a little bit the selector. Not sure why though. Also,
.hostNodes()
worked as well.oops, sorry 😃
.at(1)
should do it@badaljain i was using web storm at that time
Sure: https://github.com/airbnb/enzyme/issues/2244
Thanks for looking into it.
Thanks, I did discover that from this thread (hooray). I was just providing a concrete example of how this is very surprising behavior. Maybe it could be aliased as
getNode()
or something.Thanks, you are right, sorry… Just in case this was what I ended up doing (TypeScript):
thanks and sorry for the inconvenience.