Cypress get index row that contain the element I have with the given data attribute - indexing

I have a mat-table with
<mat-row>
<mat-cell>Firstname</mat-cell>
<mat-cell>Lastname</mat-cell>
<mat-cell>Age</mat-cell>
</mat-row>
<mat-row>
<mat-cell>Jill</mat-cell>
<mat-cell>Smith</mat-cell>
<mat-cell> <mat-icon data-mat-icon-name="pinned"> </mat-cell>
</mat-row>
And I need to know the row index of the element that has data-mat-icon-name='pinned'
I tried the below code:
cy.get("mat-table").find("[data-mat-icon-name='pinned']").invoke("index").then((i) => {
cy.log(i); // prints 0. Should print 1
});
But gives me index 0. Should give index 1.
So maybe is just giving some index of the cell and not of the row?
Any idea how I can get the row index?
Do. I need to use cy.parent ?
Edit:
If I do cy.get("mat-table").find("[data-mat-icon-name='pinned']").should("exist");
The element exits in the Dom

From the jQuery docs .index()
If no argument is passed to the .index() method, the return value is an integer indicating the position of the first element within the jQuery object relative to its sibling elements.
But the <mat-icon> you find is by itself in the cell.
You need to navigate to the parent row and find it's index among siblings,
cy.get('mat-table')
.find('[data-mat-icon-name=pinned]')
.parents('mat-row')
.invoke('index')
.then((i) => {
cy.log(i); // prints 1
});

Related

Input changins in V-for does not make update placeholder and input

I'm creating a passengers form, In this form it gets adult and child counts and children ages. At the beginning childCount equals 0 and inputs of childAges are invisible. When i increase child count, they are visible one by one. So far it is ok. However while increasing childAge, input and placeholder value do not change. By the way at the the background value is changing.
I want to be updated value in input while changing. I am sharing code via jsfiddle
Please, not only fix my code, please share how it works.
Thank you.
enter code here
Due to limitations in JavaScript, Vue cannot detect the following
changes to an array:
When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue. When you modify the length of the
array, e.g. vm.items.length = newLength.
Reference.
increaseChildAge: function(index) {
this.$set(this.childAges, index, this.childAges[index] + 1);
},
decreaseChildAge: function(index) {
if (this.childAges[index] > 0) {
this.$set(this.childAges, index, this.childAges[index] - 1);
}
}

JSON Arrays with Same Identifier in React Native

I am trying to iterate through an array to grab each unique value of 5 objects that are named the same thing ("fullimage"). I will need to use the "fullimage" identifier to iterate through each image. Below is an example of the array. I've been able to display all "fullimage" objects of the array as one long string, but not a specific one only.
{"$id":"1", "images":[{"$id":"2","fullimage":"image1.jpg"}, {"$id":"3","fullimage":"image2.jpg"}, {"$id":"4","fullimage":"image3.jpg"}, {"$id":"5","fullimage":"image4.jpg"}, {"$id":"6","fullimage":"image5.jpg"}] }
I've filtered my datasource to a specific item, so in this case "filteredItem" in my code below will have filtered it to "$id":"1". This line of code below displays all "image.jpg" objects as one long string.
{this.state.filteredItem.filter(item => item.images.map(item => item.fullimage))}
This would display: image1.jpgimage2.jpgimage3.jpgimage4.jpgimage5.jpg
How about just this.state.filteredItem.images.map(item => item.fullimage)? That will return an array of strings.
If you want you can map that into an array of components.

Update item in DataSet

I can't find a way to update an item of my item array.
What I want to do is to remove an item before pushing it into the list if this item already exists. What I don't want to do is to iterate through all items to find witch one i have to delete, if there is one.
I tryied to use a watcher :
watch: {
list: function (list, oldList) {
}
}
but since I get the old and new list, I still need to iterate.
Checking the documentation I found a $remove method that :
will search for that value in the array and remove the first occurrence.
So I tryied this.list.$remove(item.Id) but it doesn't work.
I tryied to use JQuery.grep() to select the right item but it needs to iterate so, that's a no.
Is there any way in vue.js to perform what I am trying to do ?
EDIT
I can select the right item to delete with the $eval method :
var expr = "list | filterBy " + value.Id + " in 'Id'";
var item = this.$eval(expr);
this.list.$remove(item);
But now that I have my item, the $remove method seems to not do it's job. Am I using it wrong or something ?
Isn't this.list.$remove(item) enough? Vue will search array for you and remove proper item. Actually that is exactly what you are doing with $eval method.

jQuery DataTable filtering - so confusing

I am new to the jQuery dataTables plugin found on https://datatables.net/
I am trying to implement a custom filter for the table:
Basically, when I click a button, a custom filtering function will test the value of column #1 (numeric value) for all rows, and if the value in the column < 50 for a row, the row stays, otherwise the row is hidden.
The concept should be very simple, but I can't seem to find the right way to use the API:
column.filter() returns an array of column value
column.search() can only accept text data (not function)
What's the API that can achieve the effect?
Is there anything like the following?
var api = $('#table').DataTable();
api.column(1).data().somefilterfunction(function (val, ind) {
return parseFloat(val) < 50;
}).draw();
Have you seen this article in the documentation -> https://datatables.net/examples/plug-ins/range_filtering.html ??
You can create a custom filtering function on-the-fly, triggered by a button :
<button id="filter">filter < 50</button>
script :
$("#filter").click(function() {
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
return parseFloat(data[0])<50
? true
: false
}
);
table.draw();
$.fn.dataTable.ext.search.pop();
});
demo -> http://jsfiddle.net/dpwgqs2o/
Notice that the filter is created inside the click handler itself, and removed again as soon the table is drawn. This makes the filter temporary, i.e when the user click on a column header, the filter is cleared. If you want a permanent filter, make the filter global and do not remove it.

Iterating elements using NightWatchJS

How do i click a button returned by elements command in night watch
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
console.log('Element value is '+element)
allButtons.value.forEach(function (element) {
this.elementIdClick(element, function(res){});
}
}
While running i am getting an error as
Element value is [object Object]
TypeError: Object #<Object> has no method 'elementIdClick'
So how do i get each element from the element list returned by client.elements
I realized the parameters for elementIdClick is wrong, i updated the code as
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
allButtons.value.forEach(function (element) {
console.log('Element value is '+element)
this.elementIdClick(this.elementIdAttribute(allButtons.value[element].ELEMENT, 'id'), function(res){});
Now the error is
Element value is [object Object]
TypeError: Cannot read property 'ELEMENT' of undefined
So again back to original question. How do i get individual elements from a list of webelements using nightwatchJS
The following worked for me:
function iter(elems) {
elems.value.forEach(function(element) {
client.elementIdClick(element.ELEMENT)
})
};
client.elements('css selector', 'button.my-button.to-iterate', iter);
Each element is a JSON object of the form { ELEMENT: string } (so, has no method itself.)
this in forEach does not point to the element, nor client: you need to invoke client.elementIdClick() or will get a TypeError.
Hope it helps.
I used the following strategy to iterate over DOM elements using Nightwatch:
// Executing a function in the application context.
client.execute(function () {
// Get elements by CSS selector.
var elements = document.querySelectorAll('.elements');
// Iterate over them.
[].forEach.call(elements, function (element) {
// Manipulate each element.
element.click();
});
});
That snippet is inside a test of course.
If you use jQuery or something similar you can use that too.
I think the error is getting generated by your console.log() statement.
From the elements() command, allButtons.value will be an array of several objects. To access key pairs in that array, you need need to specify where in the array and then reference the object: allButtons.value[index].ELEMENT
Because you gave your .forEach() loop only one arg, it's interpreting that as the index for the array, and in my code sample below I replaced your local variable element with index for clarity. There is also no need to use the .elementIdAttribute() function; the number returned by allButtons.value[0].ELEMENT will work as the id.
client.elements('xpath', ".//a[#class='abcd')]", function (allButtons){
allButtons.value.forEach(function (index) {
console.log('Element value is '+index.ELEMENT)
client.elementIdClick(index.ELEMENT);}})
Hope that helps.