How can i count the elements so that later use this number in random selection in cypress?
I have this code:
> `<table class="authors-rating">`
> `<thead>`
> `<tr>…</tr>`
> `</thead>`
> `<tbody>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `<tr>…</tr>`
> `</tbody>`
>`</table>`
I need to count <tr>…</tr> from <tbody> and use this number for random selection. Because the quantity of <tr>…</tr> changes i can't use const x = (Math.floor(Math.random() * (10 -1) + 1)) because the number 10 is a variable.
I try like this:
cy.visit("//")
cy.get('tbody').then($tbody => {
const count = $tbody.find('.tr')
const _number = (Math.floor(Math.random() * ((count -1) + 1)))
cy.get('tr').parents('tbody').eq(_number).click('left')
but it doesn't work
Try to yield an object to dynamically control your length and replace '.tr' with 'tr' the following way:
cy.get('body')
.find('tr')
.then(children => {
const childrenCount = Cypress.$(children).length;
expect(children).to.have.length(childrenCount);
//Insert here whatever you need using childrenCount variable, for example:
const randomNumber = (Math.floor(Math.random() * ((childrenCount -1) + 1)))
cy.get('tr').parents('tbody').eq(randomNumber).click('left')
});
I do it
cy.visit("//")
cy.xpath("//tbody/tr").then(($elements) => {
const random = Math.floor(Math.random() * $elements.length);
cy.xpath("//table[#class='authorsrating']//tbody/tr").
eq(random).click('left')
Thanks everyone
You can get all the tr elements with querying the DOM then simply get the length property and use that.
cy.get('.authors-rating tbody tr')
.should('have.length.gt', 0)
.its('length')
.then(length => {
//code to random sample
})
Related
Im working on javascript problem code:
function randomNumberInt() {
return Math.floor(Math.random() * (1000 - 100 + 1) + 100);
}
You can use this function:
function genRandom() {
const digitHundreds = Math.floor(Math.random() * 9) + 1;
let digitTens = Math.floor(Math.random() * 9);
if (digitTens >= digitHundreds) digitTens++;
let digitUnits = Math.floor(Math.random() * 8);
if (digitUnits >= digitHundreds || digitUnits >= digitTens) digitUnits++;
if (digitUnits >= digitHundreds && digitUnits >= digitTens) digitUnits++;
return digitHundreds * 100 + digitTens * 10 + digitUnits;
}
console.log(genRandom());
Here digiHundreds, digitTens and digitUnits are the three digits of the number to generate.
digiHundreds has 9 choices: 1..9 (it cannot be 0)
digitTens has 10 choices, but excluding digiHundreds, so we choose from 0..8 and add 1 if it is greater or equal to digiHundreds
digitUnits has 10 choices, but excluding digiHundreds and digitTens, so we choose from 0..7 and add 1 if is greater or equal to either digiHundreds or digitTens, and add 1 more if it is greater or equal than both.
This process guarantees that the three digits are distinct. Combining the three digits to a number is a matter of multiplying them with the correct power of 10.
Fill the array untill the length is 3 and then join.
function getRandomArbitrary(min, max) {
return Math.floor(Math.random() * (max - min) + min) + 1;
}
function randomNumberInt() {
const result = [];
while (result.length !== 3) {
let random = getRandomArbitrary(0, 9);
if (!result.includes(random)) result.push(random);
// To check if the first no is not zero
if (result.length === 1 && random === 0) result.pop();
}
return parseInt( result.join("") );
}
const result = randomNumberInt();
console.log(result);
Decide each number separately.
First get last digit (any 0-9).
Then second (any 0-9, but not first).
Then the first digit (any 0-9, but not first, second, or 0).
function range(n) {
return [...Array(n).keys()] // returns [0,1,2,...,n-1]
}
function randomFromArray(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
function randomNumberInt() {
const digits = range(10) // or [...Array(10).keys()] if u do not want to declare range function
const lastDigit = randomFromArray(digits)
const possibleSecondDigits = digits.filter((n) => n !== lastDigit)
const secondDigit = randomFromArray(possibleSecondDigits)
const possibleFirstDigits = possibleSecondDigits.filter((n) => n !== 0 && n !== secondDigit)
const firstDigit = randomFromArray(possibleFirstDigits)
return firstDigit * 100 + secondDigit * 10 + lastDigit
}
console.log(randomNumberInt())
console.log(randomNumberInt())
console.log(randomNumberInt())
console.log(randomNumberInt())
console.log(randomNumberInt())
I wanted to use values from textboxes but failed so i tried with constant values and now I am getting a NAN error. I am showing my result in a label btw.
function myFunction() {
var translength = 2400
var transSpacing = 150
var transEndOverhang = 75
var transStartOverhang = 75
var longLength = 6000
var LongSpacing = 150
var LongStartOverhang = 75
var LongEndOverhang = 75
if (transSpacing != 0)
document.getElementById('longAmount').value = ((transLength - transStartOverhang - transEndOverhang) / transSpacing) + 1;
document.getElementById('longAmount').innerHTML = document.getElementById('longAmount').value
if (document.getElementById('longAmount').value > 0 && transStartOverhang + ((document.getElementById('longAmount').value - 1) * transSpacing) + transEndOverhang < transLength)
document.getElementById('longAmount').value = longAmount + 1;
document.getElementById('longAmount').innerHTML = document.getElementById('longAmount').value
}
You're mixing innerHTML and value for the same id. If that id is a textbox you should use .value. Also, to convert strings (the text from the textarea) you can use parseInt() or parseFloat().
// Here you're taking a bunch of variables and sets the textareas value
document.getElementById('longAmount').value = ((transLength - transStartOverhang - transEndOverhang) / transSpacing) + 1;
// Makes no sense (textarea doesn't have a innerHTML)
document.getElementById('longAmount').innerHTML = document.getElementById('longAmount').value;
// document.getElementById('longAmount').value is a string here
if (document.getElementById('longAmount').value > 0 && transStartOverhang + ((document.getElementById('longAmount').value - 1) * transSpacing) + transEndOverhang < transLength)
document.getElementById('longAmount').value = longAmount + 1; // longAmount is undefined.
// Again, makes no sense.
document.getElementById('longAmount').innerHTML = document.getElementById('longAmount').value;
I'm trying to make my small function work which adds every number together in a range.
For example when I call the method like: sumAll(3,10) it should do
3+4+5+6+7+8+9+10
It works if I give the function positive integers but if it receives a negative number or a string or an array for example, it doesn't work properly.. I just want to return "ERROR" if the supplied parameter is not a positive integer.
Can I have some help with this please? Is there a more elegant (better) way?
My code:
const sumAll = (...args) => {
let max = Math.max(...args);
let min = Math.min(...args);
if ((min < 0) || (!Number.isInteger(min)) || (!Number.isInteger(max)) || (Array.isArray(...args))) {
return "ERROR";
}
let n = (max - min) + 1;
return ((max + min) * n) / 2;
}
You could use a gaussian formular for getting a count from 1 ... n and subtract the sub count.
For getting only a result if possible, you could add a check for positive integers.
const
isPositiveInt = v => Number.isInteger(v) && v > 0,
sumN = n => n * (n + 1) / 2,
range = (m, n) => isPositiveInt(m) && isPositiveInt(n)
? sumN(Math.max(m, n)) - sumN(Math.min(m, n) - 1)
: 'ERROR';
console.log(range(3, 10));
console.log(range(10, 3));
console.log(range());
console.log(range(3));
console.log(range('', 10));
console.log(range(0.2, 0.3));
This is how I generate 6 different numbers:
window.random_row = Math.floor(Math.random() * (len_board - 1)) + 1;
window.random_column = Math.floor(Math.random() * (len_board - 1)) + 1;
window.random_row2 = Math.floor(Math.random() * ((len_board-1) - 1)) + 1;
window.random_column2 = Math.floor(Math.random() * ((len_board-1) - 1)) + 1;
window.random_row3 = Math.floor(Math.random() * ((len_board+1) - 1)) + 1;
window.random_column3 = Math.floor(Math.random() * ((len_board+1) - 1)) + 1;
However, I don't want the rows/columns to be the same number, e.g random_row == random_column is allowed, but I don't want random_row == random_row2. I was thinking of using an if/else statement. Something along the lines of: if (random_row == random_row2) then generate a new random_row2 but it came to my mind that the number could be the same again so I guess that would not be the right way to go about it. Does anyone have an idea about how to solve this issue?
I saw a good answer in https://stackoverflow.com/a/2380113/5108174
Adapting to your question:
function generate(qt, len_board) {
var arr = [];
while(arr.length < qt) {
var randomnumber = Math.floor(Math.random() * (len_board - 1)) + 1;
if(arr.indexOf(randomnumber) > -1) continue;
arr.push(randomnumber);
}
return arr;
}
var rows=generate(3,len_board);
var columns=generate(3,len_board);
window.random_row = rows[0];
window.random_column = columns[0];
window.random_row2 = rows[1];
window.random_column2 = columns[1];
window.random_row3 = rows[2];
window.random_column3 = columns[2];
Create an array of numbers from 1 .. len-board
shuffle it (sort with Math.random() < 0.5 sort function)
take the first 6.
Think of it as like shuffling a deck of cards, that you cannot pull the same card twice.
All "unique".
What about trying with a while cycle?
while(random2 == random1 || random2 == random3)
{
random2= math.....;
}
I have tried parseInt() to no avail. I still get NaN errors using this code...
$("#belt-length").on("input", function(){
var length = parseInt($("#belt-length").val(), 10);
var width = parseInt($("#belt-width").val(), 10);
if(length > 0 && width > 0) {
var squaremm = length * width;
var square = squaremm / 1000000;
$("#belt-square-meters").html(square.toString() + "m<sup>2</sup>");
} else {
$("#belt-square-meters").html("0.00 m<sup>2</sup>");
};
});
$("#belt-width").on("input", function(){
var length = parseInt($("#belt-length").val(), 10);
var width = parseInt($("#belt-width").val(), 10);
if(length > 0 && width > 0) {
var squaremm = length * width;
var square = squaremm / 1000000;
$("#belt-square-meters").html(square.toString() + "m<sup>2</sup>");
} else {
$("#belt-square-meters").html("0.00 m<sup>2</sup>");
};
});
I have tried converting the fields to type="number". I use the .val() method as it is my understanding that .val() will pull the actual value of the form field and not an object reference to the form field.
1. Of course you can convert .val() result to integert via parseInt. parseInt method accepts string as a first parameter (MDN. parseInt), while .val() returns "the value of the value attribute of the FIRST matched element" (W3Schools. jQuery val() Method) which is string in text-input case (W3Schools. Input Text value Property). So there is no problem with your code and your (length > 0 && width > 0) NaN-protection is pretty common here.
2. I'd recommend do some refactoring. Extract your handlers into a single function and simplify output:
function processInput() {
var length = parseInt($("#belt-length").val(), 10);
var width = parseInt($("#belt-width").val(), 10);
var square = '0.00';
if(length > 0 && width > 0) {
var squaremm = length * width;
square = squaremm / 1000000;
}
$("#belt-square-meters").html(square + "m<sup>2</sup>");
}
$("#belt-length").on("input", processInput);
$("#belt-width").on("input", processInput);
DEMO: https://plnkr.co/edit/D5YcsQGJzqqIUbou0rxI?p=info