问题
So I am currently working on reading elements and a situation can be that it says example on the tag:
<div class="stock-controller" style="transition: border-bottom 0.3s ease 0s, opacity 0.3s ease 0s;">
<div class="message">
<svg width="14" height="14" viewBox="0 0 14 14">
<g fill="none" fill-rule="evenodd">
<path fill="#E00751" d="M14 7A7 7 0 1 1 0 7a7 7 0 0 1 14 0z"></path>
<path fill="#FFF" fill-rule="nonzero" d="M8.45 7.036L10.414 9 9 10.414 7.036 8.45 5.07 10.414 3.657 9l1.964-1.964L3.5 4.914 4.914 3.5l2.122 2.121L9.156 3.5l1.415 1.414L8.45 7.036z"></path>
</g>
</svg>Sorry, we only have 10000 of this product.</div> //Need to read here how many avaliable products
<div class="quantity-input invalid">
<button class="btn left" aria-label="Decrease"> //How many user have choose - how many in stock = amout of click time.
<svg class="svg-icon" viewBox="0 0 24 24">
<path fill-rule="evenodd" d="M7 11h10v2H7z"></path>
</svg>
</button>
<input type="number" pattern="[0-9]*" min="0" max="10002" value="10002"> //Need to read how many we have choose
<button class="btn right" aria-label="Increase" disabled="">
<svg class="svg-icon" viewBox="0 0 24 24">
<path fill-rule="evenodd" d="M13 17v-4h4v-2h-4V7h-2v4H7v2h4v4z"></path>
</svg>
</button>
</div>
</div>
basically we have 3 tags to look here. the first one is to check the text to see how many products there are in stock and in this case its 10000. Then we have to check how many items a user have choose which is 10002. So we need to use 10002- 10000 = Click this many items on <button class="btn left" aria-label="Decrease">
What I have done so far is:
it('Check descrease button', function (done) {
let allBtns = element.all(by.className('stock-controller'));
element.all(by.className('stock-controller')).each(function (element, index) {
// Will print Sorry, we only have 4 of this product., Sorry, we only have 10000 of this product.
element.getText().then(function (text) {
console.log(index, text);
});
});
allBtns.count()
.then(function (countElement) {
console.log('Find decrease buttons: ', countElement)
//for (let i = 0; i < countElement; i++) { // let variables are scoped to the immediate enclosing block denoted by { }
//browser.executeScript("arguments[0].click();", allBtns.get(i).getWebElement())
//browser.sleep(1000) // sleep 1s
//}
})
.then(() => {
done();
})
});
The other problem is that it can be more than 1 stock-controller. So it means it can be etc 5 stock-controller but the all have the same elements but different product in stock and what user have choose.
So my question is:
How am I able to read how many stock-controller there is and then check how many times I need to click decrease button for each stock-controller?
Worked code:
it('Clicked all decrease button', function (done) {
let allProds = element.all(by.css('div.stock-controller'));
allProds.count()
.then(function (cnt) { // amount of products
for(let index=0;index<cnt;index++) {
let section = allProds.get(index),
// message string which include qty in stock
stock_qty_str = section.element(by.css('div.message')).getText(),
// user inputed qty
user_qty_str = section.element(by.css('input[type="number"]')).getAttribute('value'),
// button Descrease
btn_dec = section.element(by.css('button[aria-label="Decrease"]'));
Promise.all([stock_qty_str, user_qty_str])
.then(function(data){
// use RegExp to extract qty in stock
let group = data[0].trim().match(/^Sorry.*?(\d+)/)
if(group) {
let stock_qty = group[1] * 1,
user_qty = data[1].trim() * 1,
gap = user_qty - stock_qty; // click times of Decrease button
for (let i = 0; i < gap; i++) {
browser.executeScript("arguments[0].click();", btn_dec.getWebElement());
}
}
})
}
})
.then(()=>{
done();
})
});
回答1:
Try below code, give explain inline
it('Click remove button', function (done) {
let allProds = element.all(by.css('div.stock-controller'));
allProds.count()
.then(function (cnt) { // amount of products
for(let index=0;index<cnt;index++) {
let section = allProds.get(index),
// message string which include qty in stock
stock_qty_str = section.element(by.css('div.message')).getText(),
// user inputed qty
user_qty_str = section.element(by.css('div.quantity-input input'))
.getAttribute('value'),
// button Descrease
btn_dec = section.element(by.css('button[aria-label="Decrease"]'));
Promise.all([stock_qty_str, user_qty_str])
.then(function(data){
// use RegExp to extract qty in stock
let group = data[0].trim().match(/^Sorry.*?(\d+)/)
if(group) {
let stock_qty = group[1] * 1,
user_qty = data[1].trim() * 1,
gap = user_qty - stock_qty; // click times of Decrease button
for(let i=0;i<gap;i++) {
btn_dec.click();
browser.sleep(1000).then(function(){
console.log('Click Decrease button: ' + i + '/' + gap)
})
}
}
})
}
})
.then(()=>{
done();
})
});
回答2:
I'm not into protractor, but in java i would do a list of WebElements with xpath like //div[@class='stock-controller']
Then foreach of stock-controllers read amount to click and do it.
Pseudocode:
List stockcontrollers = findby.xpath(//div[@class='stock-controller')
foreach(item in stockcontrollers)
{
get.item
read amount to click
for(x<amount to click)
{click}
}
来源:https://stackoverflow.com/questions/60206145/how-to-read-elements-values-and-click-amout-of-time