I have some end to end tests targeting a website, implemented in Javascript using Cypress.io v3.2.0. One of my test steps is implemented like so:
cy.get('h1#feed_header_id').contains('אביזרי'); //('אביזרי' is in Hebrew)
When I run the test in the Cypress GUI, it fails on the CONTAINS step. But when I click on the CONTAINS
step in the log, the snapshot clearly shows the H1
element with the text "אביזרי" in it.
Screenshot:
Please note: The element is: <h1 id="feed_header_id">אביזרי רכב</h1>
and is the only element with this id in the page.
Why does Cypress fail to find the text in the element when the element and the text are clearly visible?
I have some end to end tests targeting a website, implemented in Javascript using Cypress.io v3.2.0. One of my test steps is implemented like so:
cy.get('h1#feed_header_id').contains('אביזרי'); //('אביזרי' is in Hebrew)
When I run the test in the Cypress GUI, it fails on the CONTAINS step. But when I click on the CONTAINS
step in the log, the snapshot clearly shows the H1
element with the text "אביזרי" in it.
Screenshot:
Please note: The element is: <h1 id="feed_header_id">אביזרי רכב</h1>
and is the only element with this id in the page.
Why does Cypress fail to find the text in the element when the element and the text are clearly visible?
Share Improve this question edited Apr 30, 2019 at 9:28 urig asked Apr 30, 2019 at 8:40 urigurig 16.9k32 gold badges118 silver badges208 bronze badges 5- Maybe the HTML element contains only HTML entities of the characters and not the characters itself? – Ulrich Thomas Gabor Commented Apr 30, 2019 at 8:46
-
We can't say without seeing the exact markup for the
h1
including the exact text within it (as text, not an image), copied and pasted. (I assume thecontains
call above is copied-and-pasted, not retyped. If not, copy-and-paste it.) – T.J. Crowder Commented Apr 30, 2019 at 8:50 -
1
Some thoughts (keeping in mind you are much more familiar with the vagaries of bining LTR and RTL in code than I am! :-) ): 1. Could one of them have an RTL mark and the other not? 2. Is there more than one Unicode sequence that encodes that Hebrew text? If so, you probably want to normalize both the text in the
h1
and the search text (for instance, to Normalized Form C). I use French as an example:"Français" === "Français"
is false because one of those uses U+00E7 forç
and the other uses U+0063 and U+0327, but"Français".normalize() === "Français".normalize()
is true. – T.J. Crowder Commented Apr 30, 2019 at 8:52 - T.J.Crowder makes some fine points. I can't repro the problem on my end, using the HTML and assertion you supplied, verbatim. – dwelle Commented Apr 30, 2019 at 9:44
- Thanks @GhostGambler, tj-crowder, dwelle. I've added the markup to the question. No use of HTML entites on my end. I too am unable to create a simple repro. I can add that this is not deterministic. Runs as part of large set of tests and sometimes happens, other times not. :/ – urig Commented Apr 30, 2019 at 11:10
3 Answers
Reset to default 4You can use the alternate 'contains' mand,
cy.contains('#feed_header_id', 'אביזרי');
The reason is that cy.get(...).contains(...)
does not wait for async content.
The get()
part has automatic retry, but the id selector is hard-coded in your html, so get()
succeeds immediately (before the xhr returns it's value), then the element is tested for content (which is initially empty).
The alternate syntax above applies auto-retry to both the selector and the content.
Here is a quick test I used to ensure it is not due to RTL language features.
Spec - contains-rtl.js
describe('contains', () => {
it('waits for content', () => {
cy.visit('app/hebrew-calendar.html').then(x => console.log('x', x))
// cy.get('h1#feed_header_id').contains('כ״ט בְּאִיָּר תשע״א');
cy.contains('h1#feed_header_id', 'כ״ט בְּאִיָּר תשע״א');
})
})
Sample page - hebrew-calendar.html
<h1 id="feed_header_id"></h1>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.hebcal./converter/?cfg=json&gy=2011&gm=6&gd=2&g2h=1', true);
xhr.onload = function () {
const hebrewDate = JSON.parse(xhr.response).hebrew;
const el = document.querySelector('h1#feed_header_id');
el.textContent = hebrewDate;
};
xhr.send(null);
</script>
You might have multiple elements with the same text.
Try cy.get('#feed_header_id').find('h1').contains('אביזרי');
I strongly suspect the blame is in the testing tool.
Some test tools have problems with RTL languages and they reverse the order of the letters. Worse if there is Latin or digit or punctuation in the string it convert the string as well.
I suggest trying:
cy.get('h1#feed_header_id').contains('ירזיבא');