Testing two elements with the same text - cypress

I have a page with two element containing the "some text", but cannot confirm it in my test.
Simplest example is this:
<div>some text</div>
<div>some text</div>
const selector = 'div'
const text = 'some text'
cy.get(selector)
.contains(text)
.should('have.length', 2);
Cypress log
expected to have a length of 2 but got 1

Unfortunately .contains() only ever returns one element. If multiple are found, the first one is returned.
You can instead add :contains() into the selector.
Since the selector and text are variables, a string template can build the final selector.
cy.get(`${selector}:contains(${text})`)
.should('have.length', 2);
or put it in a .filter()
cy.get(selector)
.filter(`:contains(${text})`)
.should('have.length', 2);

You can also do something like this, using eq:
const selector = 'div'
const text = 'some text'
cy.contains(selector, text).eq(0).should('be.visible')
cy.contains(selector, text).eq(1).should('be.visible')

Related

Clicking right side of inserted CKEditor5 element results in extra empty element

I'm trying to insert a button in CKEditor5. Most of it is working OK but when I click on the right side of an inserted element it results in an extra empty element.
Here is the YouTube video of the behavior: https://www.youtube.com/watch?v=XXLyJcJJk00
...And some of the code to insert the View Fragment:
editor.model.change(writer => {
const viewFragment = editor.data.processor.toView('' + value.text + '');
const modelFragment = editor.data.toModel(viewFragment);
writer.model.insertContent(modelFragment);
writer.setSelection( editor.model.document.getRoot(), 'end' );
});
You can see there are &NoBreak; ASCII characters in there.
I've been stuck on this for several days now so any help would be much appreciated.

How to print text value of the div element in Cypress?

Code
Hey guys,
I am new to Cypress and have a hard time finding solution for this problem. The #label element which is a div has a text value and I dont know how to print it to a web console. Appreciate all help
You can do like this:
cy.get('selector')
.find('selector')
.find('selector')
.find('selector')
.eq(0)
.find('selector')
.eq(1)
.find('#label')
.invoke('text')
.then((text) => {
cy.log(text) //logs the text
})

document.querySelectorAll("span + a") didn't work?

I have a HTML like this.
<span class="vm-video-side-notification-text-item">
Includes copyrighted content
</span>
I use
var x = document.querySelectorAll("span + a");
alert(x.length);
the alert is "0"... I don't know why.
I see the w3school says
element+element
div + p
Selects all <p> elements that are placed immediately after <div> elements
so I try span + a. Can anyone correct my mistake?
You're conflating elements with tags.
While the start tag of the a is directly after the start tag of the span indeed, the a element is inside the span element.
So, in order for your example to work, you can either
change the query selector to "span > a" for "any a directly inside a span"
var x = document.querySelectorAll("span > a");
alert(x.length);
or change the html to have the a element after the span element
<span class="vm-video-side-notification-text-item">
</span>
Includes copyrighted content
(... but not both!)

How to retrieve hidden elements when visibility is hidden

I want to retrieve hidden text when the visibiility attribute is hidden:
<div id = "tt52433002" class="yui-module yui-overlay yui-tt yui-overlay-hidden" style="z-index: 2; visibility: hidden;">
<div class="bd">Associated with the domain : testci20160503105556.com</div>
</div>
I tried:
browser.hidden(:class, 'bd').text
and
browser.hidden(:class, 'bd').value
But I get this error:
"unable to locate element, using {:class=>"bd", :tag_name=>"input", :type=>"hidden"}"
Watir is designed to act like a user. So if a user can not see the text in an element, then Watir will not return the text of the element.
Also, the element you are looking for is a div not a hidden.
If you need the text you can do:
browser.div(class: 'bd').inner_html
which makes a JavaScript call to provide the result.
This works:
browser.div.attribute_value('id') => tt52433002
as does this:
browser.div(class: 'bd').inner_html[/testci\d{14}/] => testci20160503105556
First things first. The error says that Watir cannot find an element using the criteria you specified. That means either that no such thing exists anywhere in the DOM, or that it might be inside a frame.
Since the element you want is a div, then you should be using the .div method to access it
browser.div(:class => 'bd') #finds first matching div
A potential second problem could occur if that classname is not very unique. Unless you specify an additional parameter, such as index, or perhaps a portion of the text contained by the div, you may not find the div you are looking for. A fast debugging trick (I like to do it from IRB) is to get a collection of matching divs and check the size
div_count = browser.divs(:class => 'bd').size
puts "there are #{divcount} divs of class bd in the dom"
If the count is anything more than 1, then you likely need to change how you are selecting it to ensure you get the right one. for example
browser.div(:class => 'bd', :text => /Associated with the domain/)
If the count is zero, then check for frames
frame_count = browser.frames.size
iframe_count = browser.iframes.size
If there are frames you will have to tell watir to look inside the frame for the div, if more than one frame then be sure you specify the right one
browser.frame.div(:class => 'bd') #looks for div inside first frame
Once you are sure you have the right div, then you ought to be able to use a method like .text or as in another answer .inner_html to get the contents of the div.

changing text inside element script

I have a script which contains 2 functions.
First function is responsible for creating a paragraph element inside existing div.
Second part of the script is a function which changes the predefined text (the text is predefined in the first function) triggered by onclick event.
HTML:
Change Text
<div id='box'></div>
Javascript:
var x, el;
window.onload = function createEl() {
x = document.getElementById('box');
el = document.createElement('p');
el.appendChild(document.createTextNode("Hello"));
x.appendChild(el);
}
function changeText() {
el.innerHTML = 'other text';
}
My question is: Is there any way to achieve the same result but do this without using global variables? I know there should be an option just to pass the variable from one function to another and then update it there, but I am not sure how to do this though
Just give the p tag an id and use document.getElementById to get it.

Resources