You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nested custom Text componentns not working correctly #515
console.log
<View>
<Text
testID="outer"
>
<Text
testID="inner1"
/>
<Text
testID="inner2"
>
Hello
</Text>
</Text>
</View>
at debugDeep (node_modules/@testing-library/react-native/build/helpers/debugDeep.js:19:13)
Error: expect(received).toBe(expected) // Object.is equality
Expected: "inner2"
Received: "outer"
<Click to see difference>
at Object.<anonymous> (/Users/mj/Desktop/Turing/MathKing/src/components/shared/AiTeacherCommentText.test.tsx:79:32)
at Object.asyncJestTest (/Users/mj/Desktop/Turing/MathKing/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
at /Users/mj/Desktop/Turing/MathKing/node_modules/jest-jasmine2/build/queueRunner.js:47:12
at new Promise (<anonymous>)
at mapper (/Users/mj/Desktop/Turing/MathKing/node_modules/jest-jasmine2/build/queueRunner.js:30:19)
at /Users/mj/Desktop/Turing/MathKing/node_modules/jest-jasmine2/build/queueRunner.js:77:41
at processTicksAndRejections (internal/process/task_queues.js:93:5)
Yup, this is an edge case we don't handle at the moment. Please feel free to send a PR fixing that :)
Related work: #489
One question more, If I set displayName of CustomText like CustomText.displayName = 'customText'; why debug just show it as ?
It's because debug will only show host (native) components and CustomText is not one of these. You can call debug.shallow() using a shallow renderer to display custom component hierarchy to some extent.
Trying to match across nested nodes in an attempt to match what the user sees is an issue for several of our tests too. Most notably when we try to fire an event on an inner Text node.
Right now I can't think of a way to achieve this nested matching and the specific matching behaviour beforehand. Landing #573 would at least give us a way to implement our own overrides, but long term WDYT of adding a matching option to ByText queries - something like a smart mode (for the current behaviour) and a basic/legacy/simple mode? @thymikee
We would have to think about how the exact texting matching option in #554 affects this, if at all.
We could still support nested Texts by traversing up the tree once the original query fail. If the direct parents are Text nodes, we could go up to the first one, construct the string and match using the specified matcher/normalizer. What do you think?
I'm not sure I follow. Is this the kind of algorithm you had in mind?
If current node is a Text node, build string from children (string and number) and run through matcher / normalize. Return node if match.
If parent is a Text node, increment stepUp counter, build string from children of parent (and their children to a depth of stepUp counter) and run through matcher / normalizer. Return if match.
Goto 3 for as long as parent is a Text node and there is no match.
It is somewhat complicated by the native view being wrapped with a React.forwardRef, determining if a parent or child is actually a text element is not cleanly possible.
Reversing the search method like this matches the lowest level element, not its parent, because when searching the instance.find is trying to find elements for which getNodeByText returns true, and using this algorithm it will only return true when evaluating the lowest node.
We only care about host (native) components, with type of "string". This will eliminate any ForwardRefs, Functions etc.
I was rather thinking of building a separate tree of host components while searching for the lowest Text node. If the search fails we have the tree which we can then traverse up for finding the Text that's furthest away from the leaf text node, and then construct the text based on its children.
This sounds like some effort needs to go into this feature. I personally don't need it, what I need is parity with v6 for getByText, which is why I suggested bringing back the simple get text node implementation and having the current smarter implementation behind a flag.
Activity
mym0404 commentedon Aug 19, 2020
One question more, If I set
displayNameofCustomTextlikeCustomText.displayName = 'customText';whydebugjust show it as<Text>?thymikee commentedon Aug 19, 2020
Yup, this is an edge case we don't handle at the moment. Please feel free to send a PR fixing that :)
Related work: #489
It's because
debugwill only show host (native) components andCustomTextis not one of these. You can calldebug.shallow()using a shallow renderer to display custom component hierarchy to some extent.mym0404 commentedon Aug 19, 2020
Ok I will try Thank you :)
mym0404 commentedon Aug 20, 2020
This bug is related to a recursive way of find text node in this library.
I can temporary fix like the following.
mikeduminy commentedon Oct 11, 2020
Trying to match across nested nodes in an attempt to match what the user sees is an issue for several of our tests too. Most notably when we try to fire an event on an inner Text node.
Right now I can't think of a way to achieve this nested matching and the specific matching behaviour beforehand. Landing #573 would at least give us a way to implement our own overrides, but long term WDYT of adding a matching option to
ByTextqueries - something like asmartmode (for the current behaviour) and abasic/legacy/simplemode? @thymikeeWe would have to think about how the
exacttexting matching option in #554 affects this, if at all.thymikee commentedon Oct 12, 2020
We could still support nested Texts by traversing up the tree once the original query fail. If the direct parents are Text nodes, we could go up to the first one, construct the string and match using the specified matcher/normalizer. What do you think?
mikeduminy commentedon Oct 12, 2020
I'm not sure I follow. Is this the kind of algorithm you had in mind?
stringandnumber) and run through matcher / normalize. Return node if match.thymikee commentedon Oct 12, 2020
Yea, something like this.
mikeduminy commentedon Oct 13, 2020
I tried it and found the following problems:
It is somewhat complicated by the native view being wrapped with a
React.forwardRef, determining if a parent or child is actually a text element is not cleanly possible.It matches 2 instances in this case:
Reversing the search method like this matches the lowest level element, not its parent, because when searching the
instance.findis trying to find elements for which getNodeByText returns true, and using this algorithm it will only return true when evaluating the lowest node.thymikee commentedon Oct 13, 2020
We only care about host (native) components, with
typeof "string". This will eliminate any ForwardRefs, Functions etc.I was rather thinking of building a separate tree of host components while searching for the lowest Text node. If the search fails we have the tree which we can then traverse up for finding the Text that's furthest away from the leaf text node, and then construct the text based on its children.
mikeduminy commentedon Oct 13, 2020
This sounds like some effort needs to go into this feature. I personally don't need it, what I need is parity with v6 for getByText, which is why I suggested bringing back the simple get text node implementation and having the current smarter implementation behind a flag.
AugustinLF commentedon Mar 28, 2022
Fixed (I believe as part of #489).