Cypress: save result, then perform web actions, then compare initial result with end result after actions - variables

I would appreciate some help: 1) I am obtaining the total number of items in a list, 2) I perform an action in the website that should remove one item in the list and 3) I need to check that the item is discounted from the list (total items - 1)
static Counter() {
cy.get('.page-number > span')
.invoke('text')
.then((s) => {
return s.match(/([\d\.]*)$/gmi)[0]
}).then(parseInt).should('be.a', 'number')
}
describe('Compare totals before/after performing web actions', () => {
it('Store & compare', () => {
const before = Counter()
//Perform actions in the web
const after = Counter()
expect(after == before - 1).to.equal(true) //?!
})
})
Thank you very much in advance!

I got it if useful:
describe('Compare totals before/after performing web actions', () => {
it.only('Store & compare', () => {
cy.get('.page-number > span')
.invoke('text')
.then((s) => {
//Trim the text: number is mixed with text=> | 1-25 / 10000 +
const u = s.match(/([\d\.]*)$/gmi)[0]
cy.log('u =', u) //√
//perform action that discounts one item from the list [...]
cy.get('.page-number > span')
.invoke('text')
.then((s) => {
//Trim the text: number is mixed with text=> | 1-25 / 10000 +
const p = s.match(/([\d\.]*)$/gmi)[0]
cy.log('p =', p)
expect(p, 'Total before').equal(u + 1, 'Total after')
})
}) //.then(cy.log)

Related

React native - Need to change the state value to pass values to api call on each button click

In my app there is a list(FLatList) with pagination.
There are two buttons for sorting the list
Button 1 -> to remove the sorting key and load the default data from api.
Button 2 -> Each click on this button need to pass the value 'a to z' and 'z to a' to api as params
How to change the state(setSort,setSortAsc) of the value on each click and call api function?
My try -
const [getSort, setSort] = useState(false);
const [getSortAsc, setSortAsc] = useState(false);
Button 1 -> onPress () =>
const onCustomSort = () => {
setSort(false);
checkSorting();
};
Button 2 -> onPress () =>
const onNameSort = () => {
setSort(true);
setSortAsc(!getSortAsc);
checkSorting();
};
const checkSorting = () => {
console.log(TAG, 'Mrbee' + getSort + '---' + getSortAsc);
setviewProduct([]);
setLoader(true);
if (getSort) {
if (getSortAsc === true) {
setSortType('a to z');
} else {
setSortType('z to a');
}
} else {
setSortType('');
}
//api_call
dispatch(productlistAction(...,...,getSortType,),);
};
Issue is -> the state not getting change on button click so the api returns the same response.
On multiple clicks the state getting changed.
Calling of setState is not working for any states!
setviewProduct([]);
setLoader(true);
What is the mistake here. P
const [getSort, setSort] = useState(false);
const [getSortAsc, setSortAsc] = useState(false);
const [extra, setExtra] = useState(0);
Button 1 -> onPress () =>
const onCustomSort = () => {
setSort(false);
setExtra(extra+1) //add this
setTimeout(() => {
checkSorting();
}, "500")// 500 mean 0.5 sec delay, you can add your custom time
};
Button 2 -> onPress () =>
const onNameSort = () => {
setSort(true);
setSortAsc(!getSortAsc);
setExtra(extra+1) //add this
setTimeout(() => {
checkSorting();
}, "500") // 500 mean 0.5 sec delay, you can add your custom time
};
const checkSorting = () => {
console.log(TAG, 'Mrbee' + getSort + '---' + getSortAsc);
setviewProduct([]);
setLoader(true);
if (getSort) {
if (getSortAsc === true) {
setSortType('a to z')
setExtra(extra+1) //add this
} else {
setSortType('z to a');
setExtra(extra+1) //add this
}
} else {
setSortType('');
setExtra(extra+1) //add this
}
//api_call
dispatch(productlistAction(...,...,getSortType,),);
};

The slider in cypress invokes the changes , but the changes are not captured in the textbox

The assertion to verify the selected value from the slider input fails, while the script runs, the slider position changes correctly but it doesn't take any effect on the textbox; the value in the box isn't updated.
describe('Validate the slidervalue', function() {
it('Should assert the slider value correctly', function() {
cy.visit('https://demoqa.com/slider')
cy.get('input[type="range"]').invoke('val', 65).trigger('change')
cy.get('#sliderValue').should('have.value', 65)
})
})
I haven't figured out the problem with val() but stepup() works
it('Should assert the slider value correctly', function() {
cy.visit('https://demoqa.com/slider')
cy.get('input[type="range"]')
.then($el => $el[0].stepUp(40) ) // steps = 65 - 25
.trigger('change')
cy.get('#sliderValue').should('have.value', 65) // passes
})
Or with helper function
const stepTo = ($el, target) => {
const step = $el[0].getAttribute('step') || 1
const current = $el[0].value
const diff = target - current
const steps = Math.abs(diff * step)
if (diff > 0) {
$el[0].stepUp(steps)
else {
$el[0].stepDown(steps)
}
}
it('Should assert the slider value correctly', function() {
cy.visit('https://demoqa.com/slider')
cy.get('input[type="range"]')
.then($el => stepTo($el, 65) )
.trigger('change')
cy.get('#sliderValue').should('have.value', 65) // passes
})

How to make loop in vuex action, axios loop

need help, i have this vuex action that get list of products by category id:
async GET_PRODUCTS({commit}, {cat}) {
let products = []
for (let i = 0; i < 2; i++) {
let arr = await axios.get(
`https://example.com/api/get-items.php`, {
params: {
cat,
token: "0e94e09856a22496613b325473b7de8cb0a",
p: i
}
}
)
console.log(arr);
commit('SET_PRODUCTS', products.push(arr.data))
}
console.log(products);
return products
},
api gives only 100 products, I need to pass a parameter: p=0 its first 100 products, p=1 next 100, p=2 next 100, etc,
how i can stop a loop when api returns less than 100 products in array?
upd:
now i have array of arrays, need to concat them in 1
Instead of pushing new sub-array to the master array, just concatenate them. And then break the cycle when you receive less than 100 items:
async GET_PRODUCTS({commit}, {cat}) {
let products = []
for (let i = 0; true; i++) { // <--- loop forever
let arr = await axios.get(
`https://example.com/api/get-items.php`, {
params: {
cat,
token: "0e94e09856a22496613b325473b7de8cb0a",
p: i
}
}
)
products = products.concat(arr.data) // <--- concatenate new array to the old one
commit('SET_PRODUCTS', products)
if (arr.data.length < 100) break // <--- exit the cycle
}
console.log(products);
return products
},

How to check number exists in Firebase Database? - react-native-firebase

I use react native through firebase database
I have a database creating products each product has a number
I want to take a number and compare it with the product number
And if there is then I want to get a product
the function its give me my correct name but where i use it on render its not found the variable (name)
getAllContact = async key => {
let barCodeData2 = this.props.navigation.state.params.barcodeData
let self = this;
let contactRef = firebase.database().ref()
contactRef.on("value", dataSnapsot => {
if (dataSnapsot.val()) {
let contactResult = Object.values(dataSnapsot.val())
let contactKey = Object.keys(dataSnapsot.val())
contactKey.forEach((value, key) => {
contactResult[key]["key"] = value
})
self.setState({
fname: contactResult.fname,
data: contactResult.sort((a, b) => {
var nameA = a.barcode
var nameB = barCodeData2
const name = a.fname
console.log(`${nameA} What numers issssssss`);
if (nameA == nameB) {
alert(`${name} ........`)
console.log(`${nameA == nameB}is Equqlqlqlql`);
return name
}
}),
})
}
})
}
render() {
let t=this.state.name
alert(`${t} how?`)// is give Not found
// let d = this.props.navigation.state.params.barcodeData
return (
)
}
When you try such a comparison query i.e.
let ref = firebase.firestore();
ref.collection('zoo')
.where("id", "==", myID)
.get()
.then((snapshot) => {
console.log(snap.empty); //this will denote if results are empty
snapshot.forEach(snap => {
console.log(snap.exists); //alternatively this will also tell you if it is empty
})
})
well what you can do is run query based on you product no and if there's a product you will a product if there's none you will get an empty array.
read firebase documentation on queries
https://firebase.google.com/docs/reference/js/firebase.database.Query

Is there a way to wait until a function is finished in React Native?

I'm trying to get information (true/false) from AsyncStorage in a function and create a string which is importent to fetch data in the next step. My problem is, the function is not finished until the string is required.
I tried many solutions from the internet like async function and await getItem or .done() or .then(), but none worked out for me.
//_getFetchData()
AsyncStorage.getAllKeys().then((result) => { //get all stored Keys
valuelength = result.length;
if (valuelength !== 0) {
for (let i = 0; i < valuelength; i++) {
if (result[i].includes("not") == false) { //get Keys without not
AsyncStorage.getItem(result[i]).then((resultvalue) => {
if (resultvalue === 'true') {
if (this.state.firstValue) {
this.state.channels = this.state.channels + "channel_id" + result[i];
console.log("channel: " + this.state.channels);
}
else {
this.state.channels = this.state.channels + "channel" + result[i];
}
}
});
}
return this.state.channels;
_fetchData() {
var channel = this._getFetchData();
console.log("channel required: " + channel);
}
The current behaviour is that the console displays first "channel required: " than "channel: channel_id0".
Aspects in your question are unclear:
You don't say when this.state.firstValue is set, and how that relates to what you are trying to accomplish.
You have a for-loop where you could be setting the same value multiple times.
You mutate the state rather than set it. This is not good, see this SO question for more on that.
There are somethings we can do to make your code easier to understand. Below I will show a possible refactor. Explaining what I am doing at each step. I am using async/await because it can lead to much tidier and easier to read code, rather than using promises where you can get lost in callbacks.
Get all the keys from AsyncStorage
Make sure that there is a value for all the keys.
Filter the keys so that we only include the ones that do not contain the string 'not'.
Use a Promise.all, this part is important as it basically gets all the values for each of the keys that we just found and puts them into an array called items
Each object in the items array has a key and a value property.
We then filter the items so that only the ones with a item.value === 'true' remain.
We then filter the items so that only the ones with a item.value !== 'true' remain. (this may be optional it is really dependent on what you want to do)
What do we return? You need to add that part.
Here is the refactor:
_getFetchData = async () => {
let allKeys = await AsyncStorage.getAllKeys(); // 1
if (allKeys.length) { // 2
let filteredKeys = allKeys.filter(key => !key.includes('not')); // 3
let items = await Promise.all(filteredKeys.map(async key => { // 4
let value = await AsyncStorage.getItem(key);
return { key, value }; // 5
}))
let filteredTrueItems = items.filter(item => items.value === 'true'); // 6
let filteredFalseItems = items.filter(item => items.value !== 'true'); // 7
// now you have two arrays one with the items that have the true values
// and one with the items that have the false values
// at this points you can decide what to return as it is not
// that clear from your question
// return the value that your want // 8
} else {
// return your default value if there are no keys // 8
}
}
You would call this function as follows:
_fetchData = async () => {
let channel = await this._getFetchData();
console.log("channel required: " + channel);
}
Although the above will work, it will not currently return a value as you haven't made it clear which value you wish to return. I would suggest you build upon the code that I have written here and update it so that it returns the values that you want.
Further reading
For further reading I would suggest these awesome articles by Michael Chan that discuss state
https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0
https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296
https://medium.learnreact.com/setstate-takes-a-function-56eb940f84b6
I would also suggest taking some time to read up about async/await and promises
https://medium.com/#bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
And finally this article and SO question on Promise.all are quite good
https://www.taniarascia.com/promise-all-with-async-await/
Using async/await with a forEach loop
Try this instead. Async functions and Promises can be tricky to get right and can be difficult to debug but you're on the right track.
async _getFetchData() {
let channels = "";
let results = await AsyncStorage.getAllKeys();
results.forEach((result) => {
if (result.includes("not") === false) {
let item = await AsyncStorage.getItem(result);
if (item === 'true') {
console.log(`channel: ${result}`)
channels = `channel_id ${result}`;
}
}
});
return channels;
}
_fetchData() {
this._getFetchData().then((channels) => {
console.log(`channel required: ${channel}`);
});
}
what if you wrap the _getFetchData() in a Promise? This would enable you to use
var channel = this._getFetchData().then(console.log("channel required: " + channel));
Otherwise the console.log won't wait for the execution of the _getFetchData().
This is what the console.log is telling you. it just logs the string. the variable is added after the async operation is done.
UPDATE
I would try this:
//_getFetchData()
AsyncStorage.getAllKeys().then((result) => { //get all stored Keys
valuelength = result.length;
if (valuelength !== 0) {
for (let i = 0; i < valuelength; i++) {
if (result[i].includes("not") == false) { //get Keys without not
AsyncStorage.getItem(result[i]).then((resultvalue) => {
if (resultvalue === 'true') {
if (this.state.firstValue) {
this.state.channels = this.state.channels + "channel_id" + result[i];
console.log("channel: " + this.state.channels);
}
else {
this.state.channels = this.state.channels + "channel" + result[i];
}
}
});
}
return new Promise((resolve, reject) => {
this.state.channels !=== undefined ? resolve(this.state.channels) : reject(Error('error '));
}
_fetchData() {
var channel = this._getFetchData().then(console.log("channel required: " + channel));
}
maybe you must change the this.state.channels !=== undefined to an expression that's matches the default value of this.state.channels.