I have written a custom command for selecting the checkbox based upon the contact name what i provide(Refer the image ) for example I provide Test10 Test10, it does not get selected, However the test case gets passed without selecting, I tried debugging cname variable is empty attaching the debugger screen shot as well
Cypress.Commands.add("SelecttheContact", (contactName) => {
cy.get('tr td:nth-child(2)').each(($el, index, $list) => {
const cname=$el.find(contactName).text()
if(cname.includes(contactName))
{
// cy.get("tr td:nth-child(1)").eq(index).click()
// cy.get("input[type='checkbox']").eq(index).click()
debugger
$e1.find('checkbox').click()
}
}) })
I may be wrong here, but it looks like you are relying on jquery to do the selection work instead of Cypress. I would have used Cypress selection to find the checkbox.
Did you know about the Cypress Selector Playground?
The Selector Playground is an interactive feature that helps you:
Determine a unique selector for an element.
See what elements match a given selector.
See what element matches a string of text.
https://docs.cypress.io/guides/core-concepts/test-runner.html#Selector-Playground
There is also an API option to change the priorities of the selector
The Selector Playground exposes APIs that enable you to:
Change the default selector strategy
Override the selectors that are returned per element
https://docs.cypress.io/api/cypress-api/selector-playground-api.html#Syntax
.find() accepts a selector, according to the docu: https://api.jquery.com/find/
So passing a text content will not work.
text() returns an empty string because if a selector is not found in JQuery you always get an object. And functions called onto that object will return default values I think.
Why the tests passes can not be determined from what we see :-)
I suggest you to adjust the selector for your checkbox.
Btw I am not sure, if you can call cy.get() within each() (the line you have commented out in your code).
Currently I am not at my Laptop, so I can not provide an example for clicking a checkbox. But please try to fix the selector and if it does not work, I can try it for myself.
Related
I'm editing a plugin that creates filters on an table like excel(drop-down), the problem is when I use it on a table that uses a table inside it, in fact the plugin will also take the values of the sub-table.
I therefore decided to exclude from the initial array, made up of all the rows, those elements that have a parent with a table that does not have an id.
So i forEach array and see if have id like:
this.tds.forEach((el) =>{
console.log(el.parentElement.parentElement.parentElement.id);
});
I was wondering if using parentElement three times like this is correct or there is another way
It's perfectly fine, as long as you're sure that the structure will always be the same.
But let's assume that you don't know if the structure will always be like this, but you do know the class of the parent you're looking for (or any other CSS query), then you could use the Element.closest() method to query your way up.
So let's say you want to find the closest table with an id value.
this.tds.forEach((el) => {
const parent = el.closest('table:not([id=""])');
if (parent !== null) {
console.log(parent.id);
}
});
This will walk up the DOM tree from the el as starting point, doing something in the likes of parentElement.parentElement.parentElement... until it reaches an element that has a value in the id attribute.
There's nothing wrong with the code.
But if you want to make the code a little more robust you can use Optional Chaining.
this.tds.forEach((el) =>{
console.log(el?.parentElement?.parentElement?.parentElement?.id);
});
I have a test I am trying to create where I change the name of a card. The problem is there is a hidden error card which has the exact same identifiers as what I am trying to edit. The test returns that the object I am trying to work with is unreachable, which makes sense, it is under the one I am working with.
The locator which I have is: textarea[ng-model="ctrl.currentChartTitle"].
Yes, I know that I can do this by model and tried that, but it yields the same results.
Here is a screenshot of the html the yellow is the on top object I am trying to reach:
Not really sure how do to do the selector for this, so it always works.
So I did a bit more searching and found a solution. It looks a like this:
chartTitleTextArea = this.visualizer.all(by.css('textarea[ng-model="ctrl.currentChartTitle"]')).filter((element) => {
return element.isDisplayed().then((isDisplayed) => {
return isDisplayed
})
}).first()
Basically, what this is doing is getting all of the elements which match that locator. Then filtering them on if isDisplayed() is true. Then grabbing the first one.
I'm trying to get the values of all selected checkboxes with the following code to insert them in a textarea.
$('input[name="user"]:checked').each(function(){
parent.setSelectedGroup($(this).val()+ "\n");
});
but i always get only one value.
How to write the code in a correct way to get the value of ALL selected checkboxes?
Thanks ahead!
EDIT
1) "parent" because the checkboxes are in a fancybox.iframe.
2) setSelectedGroup in the parent window is
function setSelectedGroup(groupText){
$('#users').val(groupText);
You are getting all the values, simply on each loop through the collection you're passing a new value to setSelectedGroup. I assume that method replaces content rather than appending so you are simply not seeing it happen because its too fast.
parent.setSelectedGroup(
//select elements as a jquery matching set
$('[name="user"]:checked')
//get the value of each one and return as an array wrapped in jquery
//the signature of `.map` is callback( (index in the matching set), item)
.map(function(idx, el){ return $(el).val() })
//We're done with jquery, we just want a simple array so remove the jquery wrapper
.toArray()
//so that we can join all the elements in the array around a new line
.join('\n')
);
should do it.
A few other notes:
There's no reason to specify an input selector and a name attribute, usually name attributes are only used with the input/select/textarea series of elements.
I would also avoid writing to the DOM inside of a loop. Besides it being better technique to modify state fewer times, it tends to be worse for performance as the browser will have to do layout calculations on each pass through the loop.
I strongly recommend almost always selecting the parent element for the parts of the page that you're concerned with. And passing it through as the context parameter for jquery selectors. This will help you scope your html changes and not accidentally modify things in other parts of the page.
I'm working with jQuery.validate. One of its options is "success" where a function can be called upon valid user entry on a form. The only argument that can be passed is "label" which (as I understand) is a dynamically added label field to the right of the input element.
I need to perform a series of actions on a sibling "div" but I'm having enormous trouble trying to traverse to the div I want. I can't even find where the label is. Are there tricks to finding it?
I've used things such as alert (label.parents('.formrow').html()); and alert (label.parent().parent().parent().html()); and they all return "null" ... alert (label.html()); returns ""
Similar methods have worked for me in the past. Once I find something I then employ next() or find() and all is well. Is there another way?
PS. Example code:
success: function(label) {
errorspotholder = label.parents('.formrow').find('.rederrorx');
errorspotholder.removeClass('rederrorx').addClass('norederrorx').qtip('destroy');
},
This question is a bit case-specific and therefore probably not very useful to anyone else...
but what I did instead of using "label" was to declare a global variable based on another dynamic selector from jQuery.validate (in this case I used "element" from jQuery.validate's "errorPlacement").
It worked.
Marko also suggested in the comments finding lost elements by looking at the generated code from Firebug (getfirebug.com) console. Great idea! I didn't find my lost label but it should have worked and would probably work for someone else.
I am using jQuery selector to get the values of all CMS components on the page using $('div.cmscomponent') but how can I test this to see if am actually getting the list of compoents on the page.
I use:
var temp = $('div.cmscomponent');
alert(temp);
and result that I get is [object OBJECT] and so how can I test this ? and how can I get values of the object and its properties.
$() returns a jQuery wrapper object, whose contents is usually a list of DOM elements, along with properties and methods that apply to those elements.
If you want to get an element, you can access them using array-style indexes or the get() method:
alert(temp[0].tagName); // Fetch the first element, alert the `tagName`
alert(temp.get(1).tagName); // Fetch second element, alert the tagName
To check to see how many elements the result contains, you can use .length, just like you would on an array or collection/nodelist:
alert(temp.length); // Alerts number of elements found.
Here is a javascrip include that will enable you to view object structure and information.
EX: dump(temp, true);
http://www.netgrow.com.au/files/javascript_dump.cfm
Well it depends on what you want to know about the matched objects. Some examples:
var temp = $('div.cmscomponent');
alert(temp.length); // number of matched elements
// Alert each id attribute of every matched element
$(temp).each(function(index) {
alert(index + ': ' + $(this).attr("id"));
});
var temp = $('div.cmscomponent').length;
alert(temp);
If by "how can I test this", you meant "how can I write a unit test for this?", the answer is that you shouldn't. You didn't write jQuery, so you should assume it's already been unit-tested. (If there were a problem with jQuery, though, you can write integration tests would catch this.)
On the other hand, if you meant "how can I sanity-check what jQuery is telling me to make sure I didn't goof on the inputs?", there are a few ways:
Check that .length matches the expected number of items.
Check that an XPath query for the same nodes ("//div[#class='cmscomponent']") returns the same number of values.
Check that the content of the Nth node matches what you expect.
Otherwise, it's probably best to use a third-party tool like Firebug.
If all you want to do is test if your code is doing what you expect, Firebug is your friend here. It will give you a console to type a command like $('div.cmscomponent') and then interactively explore the results that are returned by it.
You can then mouseover each item that your command returned and it will be highlighted on the page, so you can see which item the command returned, and if those items are the ones you expected/wanted.