Get the total number of letters in a text - java

I have to extract to total number of letters in this following example.
<div data-v-2f952c88="" class="text">
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="ABC" class="description__section"><!---->
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>Headline 1<br>
This is my first example</p>
<p> Another Text
this is onother example
</p>
</div>
</section>
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="DEF" class="description__section">
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>Headline 2<br>
Java Rocks</p>
<p> Another Text
Selenium also rocks
</p>
</div>
</section>
</div>
How can I extract all the letters inside the several tags "p" that are under several tags "section"?

have you tried to iterate throught all elements something like this(didn´t look the java syntasys but adapt it for yourself jus take the idea)
foreach(IwebElement element in driver.findElements(By.Tag("p"))){
//Work with the element.Text
}

What about this?
String[] tags = {"p", "section"};
int totalLetters = 0;
for (String tag: tags) {
List<WebElement> elements = driver.findElements(By.tagName(tag));
for (WebElement element: elements) {
totalLetters = totalLetters + element.getText().length();
}
}

how are you? well... first of all do you read something about HTML DOM?
in Javascript Using DOM you can do something like this:
var myCollection = document.getElementsByTagName("p");
Next you will have something like an collection of "p" tags
You can access them by index number: y = myCollection[1]; or loop it:
var i;
for (i = 0; i < myCollection.length; i++) {
//do something with myCollection...
}
Your example can look something like:
var myCollection = document.getElementsByTagName("p");
var i;
var added = 0;
for (i = 0; i < myCollection.length; i++) {
added += myCollection[i].innerText.length;
}
alert(added);
<html>
<head>
</head>
<body>
<div data-v-2f952c88="" class="text">
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="ABC" class="description__section"><!---->
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>Headline 1<br>
This is my first example</p>
<p> Another Text
this is onother example
</p>
</div>
</section>
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="DEF" class="description__section">
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>Headline 2<br>
Java Rocks</p>
<p> Another Text
Selenium also rocks
</p>
</div>
</section>
</div>
</body>
</html>
I hope you find it useful!

Related

How to get product reviews and then click <a> element of product with most reviews (Selenium, Java)

<section id="135156028" data-scrolled="false" class="AdItem_adOuterHolder__Z29Nf">
<article class="AdItem_adHolder__GL0yo">
<a class="Link_link__J4Qd8 Link_inherit___qXEP" target="_self" id="" rel="" role="button"
tabindex="-1" href=".." style="align-items: flex-start;">
<div class="AdItem_imageHolder__DYGd_" style="max-width: 128px; min-width: 128px; height:
120px;">
<img src="...">
</div>
</a>
<div class="AdItem_descriptionHolder__xnkD4">
<div class="AdItem_adInfoHolder___36KR"></div>
<div class="AdItem_price__k0rQn">650 din</div>
<div>
<div class="AdItem_viewAndFavorite__pjskf">
<div class="AdItem_favoriteHolder__bKBRE">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"
xmlns="http://www.w3.org/2000/svg" class="asIcon_greyStroke__NU1Xe
asIcon_svg__Zm34q">
</svg>
<span class="AdItem_count__iNDqG">**144**</span>
</div>
<div class="AdItem_favoriteHolder__bKBRE">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"
xmlns="http://www.w3.org/2000/svg" class="asIcon_greyStroke__NU1Xe
asIcon_svg__Zm34q">
</svg>
<span class="AdItem_count__iNDqG">13</span>
</div>
</div>
<div class="AdItem_postedStatus__C6vfK">...</div>
</div>
</div>
</article>
</section>
This is the code, I deleted some unnecessary thing, but in case I deleted some importat part of the code, link is here: [https://novi.kupujemprodajem.com/mama-i-beba/oprema-za-hranjenje-i-dojenje/grupa/18/2473/1]. I took random product to share code, not the product with most views, but what I want to do is to get views count from here: "xpath = "//div[#class='AdItem_viewAndFavorite__pjskf']//div[1]" , to check which product has highest number, and then I want to click on element of that product. I'm newbie, and I don't know how to connect those, and I didn't find any solutions on the internet.
I tried something like this:
#FindBy(xpath = "//div[#class='AdItem_name__BppRQ']")
List<WebElement> productsList;
#FindBy(xpath = "//div[#class='AdItem_viewAndFavorite__pjskf']//div[1]")
List<WebElement> productViewsList;
public SingleProductPage chooseHighestViewsProduct(){
String productName;
String productViews;
int numberOfViews;
HashMap<Integer,String> mapFinalProducts = new HashMap<Integer, String>();
for (int i=0;i<productsList.size();i++){
productName = productsList.get(i).getText();
productViews = productViewsList.get(i).getText();
numberOfViews = Integer.parseInt(productViews);
mapFinalProducts.put(numberOfViews, productName);
}
Set<Integer> allKeys = mapFinalProducts.keySet();
ArrayList<Integer> listOfProductValues = new ArrayList<Integer>(allKeys);
Collections.sort(listOfProductValues);
int highestViews = listOfProductValues.get(listOfProductValues.size()-1);
}
This way I get the product with most views, but because that span is not clickable, I don't know how to click on its link.
Once you get the most views product then find preceding element of a tag and then click.
productViewsList.get(highestViews).findElement(By.xpath("./preceding::a[1]")).click()

Iterate <div> inside <ul> tag Java - Jsoup

I'm trying to get all <div> inside a <ul> tag using jsoup.
This is the HTML
<html>
<head>
<title>Try jsoup</title>
</head>
<body>
<ul class="product__listing product__grid">
<div class="product-item">
<div class="content-thumb_gridpage">
<a class="thumb" href="index1.html" title="Tittle 1">
</div>
</div>
<div class="product-item">
<div class="content-thumb_gridpage">
<a class="thumb" href="index2.html" title="Tittle 2">
</div>
</div>
<div class="product-item">
<div class="content-thumb_gridpage">
<a class="thumb" href="index3.html" title="Tittle 3">
</div>
</div>
</ul>
</body>
</html>
What I'm trying to iterate is all <div class="product-item"> so then I can add to a list all <a class="thumb"> properties
List-product-details
[0] href="index1.html" title="Tittle 1"
[1] href="index2.html" title="Tittle 2"
[2] href="index3.html" title="Tittle 3"
Note that there can be 'N' product-item div
Here is What I got so far:
Elements productList = sneakerList.select("ul.product__listing product__grid");
Elements product = productList.select("ul.product-item");
for (int i = 0; i < product.size(); i++) {
Elements productInfo = product.get(i).select("div.product-item").select("div.content-thumb_gridpage").select("a.thumb");
System.out.format("%s %s %s\n", productInfo.attr("title"), productInfo.attr("href"), productInfo.text());
}
Did you try debugging line by line and checking at which line your code doesn't do what you expect?
I see two mistakes.
The first selector "ul.product__listing product__grid" contains a space. Now it means: find element ul with class product__listing and inside search for element <product__grid> </product__grid>. You probably meant: select element ul having class product__listing and having class product__grid. You have to use dot . before second class name and remove space to look at the same level. So correct selector will be: "ul.product__listing.product__grid".
Second selector you're using is "ul.product-item". It will return empty result. That's because you're already inside ul and you're searching for another ul. Selector should be relative to where you are so using only ".product-item" will be enough.
And now I get the ouput:
Tittle 1 index1.html
Tittle 2 index2.html
Tittle 3 index3.html

Get number of words in a text

I'm using Java and Selenium, and I have to extract the number of words in a specific text. I'm stuck because I get more results than I expected.
Considering the following HTML
<div data-v-2f952c88="" class="text1">
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="ABC" class="description__section">
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>Headline 1
Hello everyone i´m new at stack overflow</p>
<p> And I need your help
to get the total of words in this exemple
</p>
</div>
</section>
<section data-v-3b70ad5b="" data-v-2f952c88="" data-content-provider="DEF" class="description__section">
<div data-v-051a83e7="" data-v-3b70ad5b="" class="markdown" data-v-2f952c88="">
<p>I Love Coding
I use Java</p>
<p> Another Text
And Selenium
</p>
</div>
</section>
</div>
<div data-v-2f952c99="" class="querty">
<section data-v-3b755ad5b="" data-v-2f952288="" data-content-provider="DEF" class="description__section">
<div data-v-051a18e7="" data-v-3b789d5b="" class="markdown" data-v-2f962c88="">
<p>This is another text along the WEBPAGE
I don´t want to count this words in my total count</p>
</div>
</section>
</div>
In Java I've created this function:
private String countWords(WebDriver driver){
int totalLetters = 0;
try{
List<WebElement> className = driver.findElements(By.cssSelector("[class*='text1']"));
for(WebElement classElement: className){
if(classElement!=null) {
String[] tags = {"p", "section"};
for (String tag: tags) {
List<WebElement> elements = driver.findElements(By.tagName(tag));
for (WebElement element: elements) {
String text=element.getText();
String[] words = text.split("\\s+");
if (words!=null) {
totalLetters = totalLetters + words.length;
}
}
}
}
}
}
catch(NoSuchMethodError e){
//e.printStackTrace();
throw e;
}
String s=String.valueOf(totalLetters);
System.out.println("How many word? " + s);
return s;
So my problem is that my function is extracting all the words inside every "p" and "section" tags in the webpage and I only wanted the "p" and "section" inside the first "div ..... class="text1" ".
What am I doing wrong?
Please refer to the image to check why it gives count of all 'p' and 'section' tag
Is this helpful to find your problem ?
Or your problem is that it is also giving the counts of class ='querty'?
<div data-v-2f952c99="" class="querty">
<section data-v-3b755ad5b="" data-v-2f952288="" data-content-provider="DEF" class="description__section">
<div data-v-051a18e7="" data-v-3b789d5b="" class="markdown" data-v-2f962c88="">
<p>This is another text along the WEBPAGE
I don´t want to count this words in my total count</p>
</div>
</section>
</div>

Find xpaths and extract text & status of checkbox/radio buttons in a loop

I have a page where I need to extract the text from an xpath and the status of the radio or checkbox that is associated with the text.
Each element is contained in a class called "c-form-group", so i have written a loop to iterate through to extract the "Text" the will be 4 elements found on the page. But it is failing on element 3 & 4, i must have something wrong with my xpath. I have yet to add in the check for the checkbox/radio button,
The first two elements are returning the values i require, then fails on element3.
Here are the 4 text elements i am trying to extract:
Plan B Warranty (Taxi) & Breakdown Recovery
Vehicle Asset Protection - Standard Cover
Negative Equity Cover
You confirm that you have received the VAP key facts leaflet?
Here is the code for the loop.
WebElement elem = driver.findElement(By.className("c-form-group"));
System.out.println("a");
List<WebElement> elementz = elem.findElements(By.xpath("//label[contains(#class,'c-option')]"));
for(int i = 0 ; i< elementz.size() ; i++){
System.out.println("Loop : " + i);
String vapval1 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("0 = " + vapval1);
String vapval2 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("1 = " + vapval2);
String vapval3 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid') and not (#class='c-option__checkbox')]")).getText();
System.out.println("3 = " + vapval3);
String vapval4 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__checkbox')]")).getText();
System.out.println("4 = " + vapval4);
}
Here is the full html, which may help.
<!DOCTYPE html>
<html class="ng-scope" ng-app="dan">
<head>
<body class="u-scroll-y ng-scope" ng-controller="CoreController as cc">
<div class="c-animate c-animate--show u-pos-f-t ng-hide" ng-show="global.alerts.length">
<div class="o-grid-fluid u-h-100 u-pl-0">
<div class="o-grid__row u-ml-0 u-h-100">
<div class="c-loader ng-hide" ng-show="loadingHome" style="">
<nav class="o-grid__col-xl-2 o-grid__col-lg-3 o-grid__col-xs-4 u-p-0 c-card__block u-h-100 u-shadowed u-pos-f-t ng-scope" ng-if="global.loggedIn">
<div class="u-p-0 u-h-100 o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right" ng-class="{ 'o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right' : global.loggedIn }">
<header class="o-layout-table__row u-bg-primary u-shadowed u-clearfix u-px ng-scope" ng-if="global.loggedIn">
<main class="o-view-container">
<div class="o-grid-fluid u-py-md">
<div class="o-grid__row">
<div class="c-animate c-animate--view-slide-in-right c-animate--view-slide-out-right ng-scope" ng-view="" style="">
<div class="o-grid__col-md-10 o-grid__col-xl-8 o-grid__col-xl-offset-2 o-grid__col-md-offset-1 ng-scope">
<div class="u-mb-lg u-text-center">
<h1 class="u-text-bold">Recommendations</h1>
</div>
<form class="ng-valid ng-valid-min ng-valid-max ng-valid-required ng-dirty ng-valid-parse" name="recommend" ng-submit="recommend.$valid" style="">
<div class="o-media c-card c-card__block u-shadowed u-mb-lg ng-scope" ng-if="rc.WarrantyEligible && !rc.prevWarranty()">
<label class="c-form-control-label u-px u-py-sm u-w-100">Warranty Options:</label>
<div class="c-form-group u-p-0 u-mb-sm u-clearfix">
<div class="o-grid__col-md-8">
<label class="c-form-control-label u-text-normal">Product Recommendations (Years):</label>
</div>
<div class="o-grid__col-md-4">
<input class="c-form-control ng-pristine ng-untouched ng-valid ng-valid-min ng-valid-max ng-valid-required" required="" placeholder="Years" ng-model="rc.recommend.year" min="1" max="3" type="number">
</div>
</div>
<div class="c-form-group ng-scope" ng-if="data.answer_taxi">
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="!rc.planA && !rc.prestige" ng-click="cc.utils.audit('recommendation_warranty_plan_taxi_b')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.warrantyPlan" value="taxiB" name="warrantyPlan" type="radio">
<i class="c-option__radio"></i>
Plan B Warranty (Taxi) & Breakdown Recovery
</label>
</div>
</div>
<div class="o-media c-card c-card__block u-shadowed u-mb-lg u-text-body u-bg-success" ng-if="!rc.prevVap() && rc.VapEligible ">
<div class="c-form-group">
<label class="c-form-control-label u-px u-py-sm u-w-100">Vehicle Asset Protection Options:</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('recommend_vap')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapPlan.plan" value="standard" name="vapPlan" type="radio">
<i class="c-option__radio"></i>
Vehicle Asset Protection - Standard Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="data.answer_equity == true" ng-click="cc.utils.audit('recommend_negative_equity')">
<input class="ng-untouched ng-valid ng-dirty ng-valid-parse" ng-model="rc.recommend.vapPlan.equity" name="vapPlanEquity" type="checkbox" style="">
<i class="c-option__checkbox"></i>
Negative Equity Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('vap_key_facts_checked')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapCheck" name="vapCheck" type="checkbox">
<i class="c-option__checkbox"></i>
You confirm that you have received the VAP key facts leaflet?
</label>
</div>
</div>
</form>
<div class="c-form-group">
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js">
<script src="./build/app.js?v=2.13" defer="">
<script src="/build/standalone/jspdf.js" defer="">
<script src="/build/standalone/sigWebTablet.js" defer="">
</body>
</html>
I'm a little confused as to what you are trying to do. You mention getting the text from the elements and also getting the state of the checkboxes. Your XPaths on the outer and inner loop overlap. Your elementz list is pulled from a LABEL that contains the c-option class but then you start with an element from elementz and the first part of your XPath you repeat the search for a LABEL that contains the c-option class.
There is an much easier way to do this. Each of these checkboxes/radiobuttons are INPUT tags and have a name specific to their value.
Plan B Warranty (Taxi) & Breakdown Recovery: <input ... name="warrantyPlan" type="radio">
Vehicle Asset Protection - Standard Cover: <input ... name="vapPlan" type="radio">
Negative Equity Cover: <input ... name="vapPlanEquity" type="checkbox" style="">
You confirm that you have received the VAP key facts leaflet?: <input ... name="vapCheck" type="checkbox">
So with that info, you can just get each INPUT with CSS selectors like
By.cssSelector("input[name='warrantyPlan']")
Once you have the INPUT element, you can check if it's selected using .isSelected().
If you really do need the text, you can get the label because it's the parent of the INPUT we just got. We can do this with an XPath, By.xpath(".."), which gets the parent of the current element.
We can put this all together like
// Plan B Warranty (Taxi) & Breakdown Recovery
WebElement e = driver.findElement(By.cssSelector("input[name='warrantyPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Plan B Warranty (Taxi) & Breakdown Recovery
// Vehicle Asset Protection - Standard Cover
e = driver.findElement(By.cssSelector("input[name='vapPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Vehicle Asset Protection - Standard Cover
I just did the first two. You can see the pattern and apply it for the last two.

Multiple fields within an id - Webdriver - Java

The input fields I am needing to grab are within this #id="contractorsWrapper".
In this example, there are 2 input fields within that wrapper (but this number is dynamic depending on the case) located at #class="contactEntry".
What I'm trying to do is say, how many className=contactEntry fields are there within the id=contractorsWrapper. Then, be able to input text into them independently.
<div id="contractorsWrapper" class="contactInputAndInfoDisplays_wrapper">
<div id="contractorsRow_5d1532ba-b37e-4aac-85c2-4a5e6c6c2796" class="contactInputAndInfoDisplay">
<div class="contactName">
<div class="contactFlag"/>
<a class="smallRemove removeAContact" href="#"/>
<span class="littleGreyTitles">
Name
<br/>
</span>
<input class="contactEntry " type="text" value=""/>
</div>
<div class="descriptionInput littleGreyTitles">
Description
<br/>
<input type="text"/>
</div>
<a class="contactLink" href="#" style="display: none;"/>
</div>
<div class="spacerDiv1"/>
<div id="contractorsRow_5fc58f1a-906f-4239-93ae-b0a2e4b8b70c" class="contactInputAndInfoDisplay">
<div class="contactName">
<div class="contactFlag"/>
<a class="smallRemove removeAContact" href="#"/>
<span class="littleGreyTitles">
Name
<br/>
</span>
<input class="contactEntry " type="text" value=""/>
</div>
<div class="descriptionInput littleGreyTitles">
Description
<br/>
<input type="text"/>
</div>
<a class="contactLink" href="#" style="display: none;"/>
</div>
<div class="spacerDiv1"/>
</div>
Find your wrapper:
WebElement wrapperElement = driver.findElement(By.id("contractorsWrapper"));
Number of input elements:
wrapperElement.findElements(By.className("contactEntry ")).size();
I don't know what you mean with "input text into them independently" but here's how you could enter the same thing in all of them:
for (WebElement element : wrapperElement.findElements(By.className(className))) {
element.sendKeys("keysToSend");
};
update
after more details from OP
If you want to insert some "unique" Strings to the element, you can use an ArrayList
// create as much array entries as you need
List<String> namesList = new ArrayList<String>();
namesList.add("John Doe");
namesList.add("Jane Doe");
...
// then
int count = 0;
for (WebElement element : wrapperElement.findElements(By.className(className))) {
element.sendKeys(namesList.get(count++));
};
of course you would then need to make sure, that your list is always longer than the number of input elements...

Categories