Check contents of javascript element with Cypress - javascript

In our application we use IEPs (it's short for Incident Extended Property) where we store data in. In most cases we store one value in it like 'Yes' or 'Amsterdam' and we have to code to check these.
But we also have ComplexIEPS which store Javascript objects, so no JSON, an example:
[
{
"anotherField": true,
"location": "xxx",
"post": "XXX",
"description": "Whatever",
"transport": "1234"
}
]
Is there a way to completely check this complexIEP? The code we use the simple IEPs:
cy.get('.className').contains('td', iepName)
.parent()
.children()
.should(($children) => {
const value = $children[1].innerHTML;
expect(value).to.include(` ${iepValue}`);
});
});

Related

Find and match string in array object and then sort by object value. React and Javascript

i have an array of nested objects that give each user a permission.
const UserList = [{
0: {
users: {
"email": "user1#gmail.com"
},
permission: {
"id": 1,
"access": "Edit"
}
},
1: {
users: {
"email": "user2#gmail.com"
},
permission: {
"id": 2,
"access": "Read Only"
}
},
2: {
users: {
"email": "user3#gmail.com"
},
permission: {
"id": 1,
"access": "Edit"
}
},
}]
My problem: I want to be able to match a email string to the email in the object and then grab object with the access "read only'. This is all to disable a button. So if the current user's email matches one in the object and the access equals "read only" then pull it out. Im not sure if i want to create a function/prop for this condition but the disable button is in another file.
So lets say this is my email
const myEmail = user2#gmail.com. How do i compare it to UserList and create that condition above. Then transfer it to a button in another file <button disabled={solution goes here}></button>
Edit: I want to find the object that has the current users email, then if that object's access = read only, then disable.
Maybe a .include(myEmail)? Not sure
Thanks for your help!
You can use Object.values(UserList) to get an array with just the values (the user object in this case). Then you can use that list to do your rendering (seems you are using react), so you can just map over the list, and then use the information to check whether a value is `Read Only" etc.
in your HTML, that looks something like:
<button disabled={userObj.permissions.access !== "Read Only"}>
I am not quite following the question about matching email strings.

Update single object in localStorage

I want to update a single Object in my localStorage. I made a detail page, where I can submit new values (progress and value)
When I want to update the value, it changes the value in both objects. How can I change just one object.
Here is my deployment link.(its work in progress)
https://mastery-app.herokuapp.com/
This is my localStorage array:
skills[
{
"title": "Sewing",
"imageSrc": "images.unsplash.com",
"description": "Make your own clothes",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
},
{
"title": "Crocheting",
"imageSrc": "images.unsplash.com",
"description": "Interlock loops of yarn",
"category": "crafting",
"progress": 500,
"isDone": false,
"rank": 0,
"value": 0
}
]
This is how I update the localStorage:
const update = skills.map((skills) => {
skills.title === skills.title;
const updateProgress = skills.progress - value;
const rankNumber = parseInt(ranking);
const updateRank = skills.rank + rankNumber;
console.log(updateRank);
const updateValue = skills.value + value;
return {
title: skills.title,
rank: updateRank,
description: skills.description,
progress: updateProgress.toFixed(1),
imageSrc: skills.imageSrc,
category: skills.category,
isDone: false,
value: updateValue,
};
});
localStorage.setItem('skills', JSON.stringify(update));
You may consider using the find method to find the object you want to update. map is not the right function to be used for your use case.
Also skills.title === skills.title; has no effect at all (Maybe you wanted to use an if statement to do some kind of filtering by using title but that always would return true). Please remove that.
Now, I don't exactly know which field are you going to use to search for the object you want to update, but it has to be unique. If none of the fields in the objects are unique you should consider adding an unique id field in the skills objects. But if title is unique you can use the title to search. Then you can do something like the pseudo code below:
const toUpdate = skills.find(skill => skill.title === your_title_here)
toUpdate.field_to_update_1 = some_value_1
toUpdate.field_to_update_2 = some_value_2
localStorage.setItem('skills', JSON.stringify(skills))
Please also check the MDN docs to see how map, find and other array methods work and some of their use cases.

Get the JSON object that matches a specific value

I'm building a little web-app to practice and learn Vue.js and working with APIs.
For a particular problem I want to solve, I would like to return the object that has the matching uuid that I request.
With my current knowledge, I understand I can do this by implementing some sorts and loops logic.
However I'm still new with JS, Vue.js, so I'm not sure if there is a better way to approach this.
Is there a built in function, or some form of "best practice" to approach this?
methods: {
fetchItem(row) {
// row.target_uuid -- this is the UUID I want
// this.$props.todoItems; -- this contains the json objects
// return this.$props.todoItems[i] where this.$props.todoItems[i]['uuid'] == row.target_uuid
},
This is a snippet of my $props.todoItems for context
[
{
"title": "Install Maris",
"uuid": "9ec9ea6b-0efc-4f6a-be2e-143be5748d3a",
"field_completed": "False"
},
{
"title": "Figure out why VS Code sucks",
"uuid": "85120da5-ee59-4947-a40f-648699365c73",
"field_completed": "False"
},
{
"title": "Start designing portfolio",
"uuid": "243c1960-7ade-4a68-9a74-0ccc4afa3e36",
"field_completed": "False"
},
{
"title": "Meal Prep",
"uuid": "85b64b18-9110-44d8-bd2d-8f818b0a810f",
"field_completed": "False"
},
{
"title": "Sharpen knives",
"uuid": "8a7ac5f6-8180-4f20-b886-628fd3bcfc85",
"field_completed": "False"
},
{
"title": "Set up SSH keys",
"uuid": "f879c441-8c05-4f24-9226-125c62576297",
"field_completed": "False"
}
]
If you know you're looking for exactly one item (or the first item that matches) you should take a closer look at the Array.find() method provided by JS. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
Also take a look at all the other methods the Array prototype provides, most of them are fairly descriptive and solve most of the basic problems you'll encounter.
To use this in your Vue app you can either have a method that returns your todo based on a provided uid like this
todoByUid(uidToFind) {
return this.todos.find(todo => todo.uid == uidToFind)
}
If you only care about a currently selected item a computed value as Jacob mentioned is the way to go:
computed() {
selectedTodo() {
return this.todos.find(todo => todo.uid == this.selectedUid)
}
}

How to change the State in React Redux without mutating data?

I'm aware of "sacred" data is and how dangerous it might get if handled incorrectly; that's why in my app, I'm in a position now where I need to handle a nested long JSON object (that repsents my app state) and it's already a headache to me to get in and out of the nodes/values that need to be amended. I was thinking of including Immutable.js. The question now is: how do I adapt my reducers, actions, state, etc?
Here's an extract of my state when it comes from the MongoDB database:
"shops": [
{
"shopId": "5a0c67e9fd3eb67969316cff",
"picture": "http://placehold.it/150x150",
"name": "Zipak",
"email": "leilaware#zipak.com",
"city": "Rabat",
"location": {
"type": "Point",
"coordinates": [
-6.74736,
33.81514
]
}
},
{
"shopId": "5a0c6b55fd3eb67969316d9d",
"picture": "http://placehold.it/150x150",
"name": "Genekom",
"email": "leilaware#genekom.com",
"city": "Rabat",
"location": {
"type": "Point",
"coordinates": [
-6.74695,
33.81594
]
}
},
...
When a certain action (end-user hits a "Like" button) is triggered, I need to add an attribute to the related Shop object, so it'd become like this:
{
"shopId": "5a0c67e9fd3eb67969316cff",
"picture": "http://placehold.it/150x150",
"name": "Zipak",
"email": "leilaware#zipak.com",
"city": "Rabat",
"liked": true,
"location": {
"type": "Point",
"coordinates": [
-6.74736,
33.81514
]
}
},
Now, I manage to add the liked attribute to the individual Shop object, but when I want to change/amend the state (group of all Shop objects), I get the object duplicated (the new one with the liked attribute and the old one). To avoid this mess, I want to handle these operations using Immutable.js to make sure everything is clean and proper.
Where do I start from? Do I convert the state to an Immutable.js Map? List?
Rather than using Immutable.js you can use immutability-helper which has an update function returns the updated value without mutating the original value.
immutability-helper has a syntax inspired from MongoDB so getting used to it shouldn't be very hard for you.
For your case, you can modify your state with the below sample,
import update from 'immutability-helper';
const id = '5a0c67e9fd3eb67969316cff'; // id of the item you need to update
const newState = update(state, {
shops: {
$apply: (item) => {
if (item.shopId !== id) return item
return {
...item,
liked: true
}
}
}
});
Simply reduce your array of identified shops to an object on fetch success. It's a good practice to do so for any list of unique items to avoid the O(n) complexity of find functions and to mutate your state in a simpler way.
Reduce shops on fetch success in your shops reducer :
shops.reduce((obj, item) => {
obj[item.id] = item
return obj;
}, {})
It will then be easy to manipulate your object inside your shops reducer on any action such as a like success :
return {
...state,
[action.shopId]: {
...state[action.shopId],
liked: true,
},
}

JSON, node.js: access classes via its name (String)

Here's my situation, I have a JSON that looks somewhat like this:
{
"items": [{
"type": "condition",
"data": {
"type": "comparison",
"value1": {
"source": "MyType1",
"component": "Attribute1"
},
"value2": {
"source": "MyType2",
"component": "Attribute2"
},
"operator": "gt"
}
},
{
"type": "then",
"data": {
"result": "failed",
"message": "value1 is too high"
}
}
]
}
and would want it to translate to:
if (MyType1.Attribute1 > MyType2.Attribute2) {
result = "failed";
console.log("value1 is too high");
}
Now my problem is, I don't know how I would translate the entries of value1 and value2 to actual code, or rather, how I could access the Object MyType1(maybe through something like getAttribute("MyType1")).
Since I am going to have a whole bunch of sources which each have different components, I cant really write a huge dictionary. Or I would like to avoid it.
The goal is to allow creating if - then - statements via some interactive UI, and I figured it'd be best to save that code as .json files. (Think rule management system).
So, TL,DR, How would I access a Class Attribute this.MyType, if I only have a String MyType to go from? And how would I access the value this.MyType.MyValue, if I get another String MyValue?
Thanks in advance.
Edit:
I'd really like to avoid using eval, for obvious reasons. And if I have to - I guess I would need to create Dictionaries for possible JSON Values, to validate the input?
You need some kind of parser. At first we need some way to store variables and maybe flags:
const variables = {};
var in = false;
Then we go through the code and execute it:
for(const command of items){
switch( command.type ){
case "condition":
//...
case "then":
//...
}
}
To access a variable we can simply do
var current = variables[ identifier ];
To store its the other way round:
variables[ identifier ] = current;

Categories