I'm testing the CRUDs for a page in my application, where a registry requires an unique ID as a 5 digit number to be successfully created.
I would like to get a random available ID of that table to use in the tests, that can be achieved with the following sql query:
cy.task(
'sqlQuery',
`select count(*) as "count" from clients where client_id = '${
Math.floor(Math.random() * 90000) + 10000
}'`
)
The point is that the random number perhaps is not available to be used as the ID, so i would need to loop this same task until the generated number is available:
cy.task(
'sqlQuery',
`select count(*) as "count" from clients where client_id = '${
Math.floor(Math.random() * 90000) + 10000
}'`
).then((result: any) => {
if (result.rows[0].count === 0) {
// My code to submit the form with the generated number
// break the loop
} else {
// Repeat all of this (where i'm asking for help)
}
})
If count returns 0 it means it's there's no registry using it, otherwise it's not available.
I guess the final solution could be using some while loop, but I found this way would be more clear to you all know what i'm needing.
I tried some approachs like this, but just discovery that its impossible to assign a new value to a variable inside the .then block, so it seems like i did an endless loop.
let available = false
do {
cy.task(
'sqlQuery',
`select count(*) as "count" from clients client_id = '${
Math.floor(Math.random() * 90000) + 10000
}'`
).then((result: any) => {
if (result.rows[0].count === 0) {
// Code to submit the form with the generated number
available = true
}
})
} while (available === false)
Ask SQL what ids are present and check the random one against those?
Something like this:
cy.task('sqlQuery', 'select client_id from clients')
.then((result: any) => {
const ids: string[] = result.rows;
function getNewId(trys = 0) {
if (trys > 1000) throw new Error('failed')
const newId = Math.floor(Math.random() * 90000) + 10000
if (ids.includes(newId)) {
return getNewId(++trys)
}
return newId
}
const newId = getNewId()
cy.wrap(newId).as('newId')
})
Update
Changed to a recursive javascript function, as I found when testing .should()
it does not re-evaluate Math.floor(Math.random() * 90000) + 10000
It's been a while since I did some SQL, but maybe this correlated subquery is more efficient
SELECT last + 1 as newId FROM (
SELECT MAX(id) as last FROM clients
)