How to get array of specific attributes values in cypress - testing

I have a few elements in DOM and each of them has its own attribute 'id'. I need to create a function which iterates throw all of these elements and pushes values into the array. And the happy end of this story will be when this function will give me this array with all 'id' values.
I have tried this:
function getModelIds() {
let idList = [];
let modelId;
cy.get(someSelector).each(($el) => {
cy.wrap($el).invoke('attr', 'id').then(lid => {
modelId = lid;
idList.push(modelId);
});
});
return idList;
}
Will be very appreciated if you help me with rewriting this code into a function which will return an array with all 'id' values.

You can have a custom command:
Cypress.Commands.add(
'getAttributes',
{
prevSubject: true,
},
(subject, attr) => {
const attrList = [];
cy.wrap(subject).each($el => {
cy.wrap($el)
.invoke('attr', attr)
.then(lid => {
attrList.push(lid);
});
});
return cy.wrap(attrList);
}
);
You can use it later like this:
cy.get(someSelector)
.getAttributes('id')
.then(ids => {
cy.log(ids); // logs an array of strings that represent ids
});

Related

Vuex getter returns undefined value

I'm trying to write a getter for my state the problem is that it returns an undefined value but I'm 100% sure that in articleEan is an object that has an Are_EanNr value of 1234567.
This is the getter I'm writing is supposed to return the first object in the articleEan Array that has the same EanNr as the parameter.
const getters = {
findArByEan: state => {
return (eancode) => { // logging eancode results in 1234567
state.articleEan.find(item => {
return item.Are_EanNr === eancode
})
}
}
}
Where's my mistake?
After Changing it to:
findArByEan: (state) => (eancode) => state.articleEan.find(item => item.Are_EanNr === eancode),
Problem still occurs. This is how I'm calling the getter from a component:
const getters = {
...useGetters('vm', [
'orderRow',
'customer',
'article',
'additionalData',
'findArByEan',
]),
...useGetters('user', ['user']),
};
const Ar = getters.findArByEan.value(eancode.value); // Ar = undefined
Edit:
When looping over the state I'm getting just the indices of the object in array.
log('ArtEan:', artEan.value); // correct output => Array with 38 objects
for(const item in artEan.value) {
log(item); // Logs just the index of array
}
Your second arrow function does not return anything so it's undefined
const getters = {
findArByEan: state => {
return (eancode) => { // logging eancode results in 1234567
return state.articleEan.find(item => {
return item.Are_EanNr === eancode
})
}
}
}
You can also do it this way without any return.
const getters = {
findArByEan: (state) => (eancode) => state.articleEan.find(item => item.Are_EanNr === eancode)
}
I would recommand reading the arrow function documentation.
For example, those 2 functions works the same but one is tidier ;)
const numberSquare1 = (number) => {
return number * number
}
const numberSquare2 = (number) => number * number
console.log(numberSquare1(2))
console.log(numberSquare2(2))

Using set() for computed values correctly in Vue

I'm having an issue with setting a computed property (which is an array). I have the following computed property in my Vue component:
posts: {
get () {
if ( this.type == 'businesses' || this.type == 'business' ) {
return this.$store.getters.getAllBusinesses.map(_business => {
return _business
})
} else if ( this.type == 'shops' || this.type == 'shop' ) {
return this.$store.getters.getAllShops.map(_shop => {
return _shop
})
} else if ( this.type == 'events' || this.type == 'event' ) {
return this.$store.getters.getAllEvents.map(_event => {
return _event
})
} else {
return this.$store.getters.getAllBusinesses.map(_business => {
return _business
})
}
},
set (posts) {
console.log(posts)
this.posts = posts // Doesn't work - this causes a maximum call stack error, recursively setting itself obviously.
return posts // Doesn't work either - this.posts doesn't seem to be changing...
}
},
The console.log(posts) is exactly what I want - a filtered array of posts, see the below console log output.
My question is simply this: how do I go about updated the computed posts value?
If it is useful, I am doing the following manipulation to the posts:
let filteredPosts = []
this.posts.filter(_post => {
_post.category.forEach(category => {
if ( this.categoryFilters.includes(category.slug) ) {
filteredPosts.push(_post)
}
})
})
let uniqueFilteredPosts = [...new Set(filteredPosts)];
this.posts = uniqueFilteredPosts
This is purely to filter them. What I am console.logging is absolutely correct to what I want. So this might be a red herring.
Any pro-Vue tips would be greatly appreciated!
If you want to use a computed setter, you normally assign to whatever values underlie the computed's get function. See the example at the link.
In your case, you examine this.type and return something from the store based on it. The setter should probably examine this.type and set something in the store based on it.

Array of unique objects in react native

There is a method to store an array of objects for question id as key and answer as a value.
But it is creating multiple objects of same question id because of saving the previous state of object.
handleSelect(questionId,index,value){
this.setState((oldState)=>({selectedOptions:[...oldState.selectedOptions,{question:questionId,answer:value}]}))
}
How can i create unique array of objects?
You can achieve this in a number of ways - one way might be to use the Array#reduce() method like so:
handleSelect(questionId,index,value) {
// Your array containing items with duplicate questions
const arrayWithDuplicates = [
...this.state.selectedOptions,
{ question:questionId,answer:value }
];
// Use reduce to create an array of items with unique questions
const selectedOptions = arrayWithDuplicates
.reduce((uniqueArray, item) => {
const isItemInUniqueArray = uniqueArray.find(uniqueItem => {
return uniqueItem.question === item.question;
});
if(!isItemInUniqueArray) {
uniqueArray.push(item);
}
return uniqueArray
}, [])
this.setState((oldState)=>({selectedOptions: selectedOptions}))
}
This thread is closed now. I got the solution for my problem.
handleSelect(questionId,index,value) {
let question = this.state.selectedOptions.find((questions) => {
return questions.question === questionId
});
if(question){
this.setState(prevState => ({
selectedOptions: prevState.selectedOptions.map(
obj => (obj.question === questionId ? Object.assign(obj, { answer: value }) : obj)
)
}));
}
else{
this.setState((oldState)=>({selectedOptions:[...oldState.selectedOptions,{question:questionId,answer:value}]}))
}
}

Lodash reduce array of objects from array of objects

I'm trying to get a list of all guideScenes in all sections via
let combinedScenes = _.reduce(sections,
(prev, section) => {return {...prev, ...section.guideScenes}},
{}
)
It's only returning the first section list, how do I get all of them in there?
const sections = [{guideScenes: ['hello']}, {guideScenes: ['world']}, {guideScenes: ['hi', 'yo']}]
let combinedScenesObj = _.reduce(sections, (prev, section, index) => {
return {...prev, [index]: [...section.guideScenes]}
}, {})
console.log('object:', combinedScenesObj)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.core.js"></script>
You were close you needed a key to be added to each array because you were trying to add to an object
//dummy data
const sections = [{guideScenes: ['hello']}, {guideScenes: ['world']}, {guideScenes: ['hi', 'yo']}]
if you're wanting to resolve to an object you should give the item a key, for instance, I've used the index in this example
let combinedScenesObj = _.reduce(sections, (prev, section, index) => {
return {...prev, [index]:[...section.guideScenes]};
}, {})
// { 0: ["hello"], 1: ["world"], 2: ["hi", "yo"] }

How can I loop object observer on vue.js 2?

If I console.log(this.list), the result like this :
this.list.forEach(function (user) {
selected.push(user.id);
});
There exist error :
Uncaught TypeError: this.list.forEach is not a function
How can I solve this error?
Is this.list not an Array?
If this.list is array-like (there must be a length property on that object), you should be able to do:
Array.prototype.forEach.call(this.list, user => {
// ...
})
or
Array.from(this.list).forEach(user => {
// ...
})
or
[...this.list].forEach(user => {
// ...
})
Otherwise if this.list is just a plain object, you can do:
Object.keys(this.list).forEach(key => {
const user = this.list[key]
// ...
})
or
Object.entries(this.list).forEach(([key, user]) => {
// ...
})
Here is a way to loop over an observer array in Vue:
let keys = Object.keys(myObserverArray);
keys.forEach(key => {
let item = myObserverArray[key];
//...work with item
})