Java selenium - skip span element within div - java

Here's my html structure and I am trying to skip a span within a div to get div's text only (which is dynamic) for testing.
<div class="items">
<div class="payment void" id="payment-000000899799">
<div class="payment__details">
<div class="method">CASH <span class="label"><span>Payment Voided</span></span></div>
<div class="date">2/12/2021, 3:02:15 PM</div>
</div>
<div class="payment__details">
<div class="amount">$20.00</div>
<div class="ref">Ref ID: REF-ID-01</div>
</div>
</div>
<div class="payment sale" id="payment-000000899806">
<div class="payment__details">
<div class="method">CASH </div>
<div class="date">2/12/2021, 3:02:21 PM</div>
</div>
<div class="payment__details">
<div class="amount">$100.00</div>
<div class="ref">Ref ID: REF-ID-02</div>
</div>
</div>
</div>
In my step definition I've
List<List<String>> data = capturedData.raw();
WebElement paymentDetails = driver.findElement(By.xpath("(//*[#class='payment__details']/div[#class='method'])[" + data.get(1).get(0) + "]"));
String paymentType = paymentDetails.getText();
System.out.println(paymentType); //This prints CASH Payment Voided
But actually I want only 'CASH' which is a text of div and skip the text 'Payment Voided' of span. And data is coming from a feature file.
How do I get text of div only and skip the text span which is inside the same div?

You cannot skip it directly since it is part of element.
1st Approach
String fulltext = driver.findElement(By.xpath("//*[#class='payment__details']/div[#class='method'][1]")).getText();
String spantext = driver.findElement(By.xpath("//*[#class='payment__details']/div[#class='method'][1]/span")).getText();
//Now replace span text with ""
String output = fulltext.replace(span,"");
2nd Approach
WebElement parent = driver.findElement(By.xpath("//*[#class='payment__details']/div[#class='method'][1]"));
JavascriptExecutor js = (JavascriptExecutor) driver;
String output = (String) js.executeScript("return arguments[0].firstChild.textContent",parent);

Related

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>

How to get the tagName of an element with no identifier or css classes using Selenium and Java

Using selenium how do I fetch a html tags element, the html tag does not have any unique identifiers, below is the html code:
<form data-v-48e2f75a="">
<header data-v-48e2f75a="">
<h4 data-v-48e2f75a="">via email</h4>
</header>
<div data-v-48e2f75a="" class="form-wrap">
<div data-v-cccee08c="" data-v-48e2f75a="" class="input-wrap email-input" type="email">
<label data-v-cccee08c="">
<div data-v-cccee08c="" class="input-inner-wrap has-icon">
<!--The below input tag is one of the tags I need to fetch-->
<input data-v-cccee08c="" placeholder=" " type="email"> <i data-v-cccee08c="" class="input-label-icon icon-envelope-o"></i> <span data-v-cccee08c="" class="input-label">Your E-mail</span> <!---->
</div>
<!----> <!----> <!---->
</label>
</div>
<div data-v-cccee08c="" data-v-48e2f75a="" class="input-wrap password-input" type="password">
<label data-v-cccee08c="">
<div data-v-cccee08c="" class="input-inner-wrap has-icon">
<input data-v-cccee08c="" placeholder=" " type="password"> <i data-v-cccee08c="" class="input-label-icon icon-unlock"></i> <span data-v-cccee08c="" class="input-label">Your Password</span> <!---->
</div>
<!----> <!----> <!---->
</label>
</div>
</div>
<p data-v-48e2f75a="" class="secondary-utilities forgot-password"><span data-v-48e2f75a="">Forgot password?</span></p>
<footer data-v-48e2f75a="" class="form-footer">
<div data-v-48e2f75a="" class="secondary-utilities registration">
<p data-v-48e2f75a="">Don't have an account?</p>
<span data-v-48e2f75a="">Sign up new account</span>
</div>
<button data-v-48e2f75a="" class="app-button rose-button min-width">Sign in</button>
</footer>
</form>
How I have been trying to get the element / things I've tried:
public static boolean login(WebDriver browser, String email, String password){
List<WebElement> elements = browser.findElements(By.xpath("//input[#type='email' or #type='password']"));
System.out.println();
for (WebElement element : elements){
System.out.println(element.getTagName());
System.out.println(element.toString());
}
return false;
}
however the above method keeps returning null, below are some of the other methods I've tried:
List<WebElement> elements = browser.findElements(By.id("input[type='email']"));
List<WebElement> elements = browser.findElements(By.cssSelector("*[type='email']"));
List<WebElement> elements = browser.findElements(By.cssSelector("*[type='email']"));
The tag is surrounded by some dividers...
As the elements are React elements as well as <input> elements to extract the <tagName> of the element using Selenium, you have to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following Locator Strategies:
Using css-selectors and the type attribute of the <input>:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("//[type='email'][placeholder]"))).getTagName());
Using xpath and the text Your E-mail of the <span>:
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[text()='Your E-mail']//preceding::*[#type='email' and #placeholder]"))).getTagName());
Should it be like this?
List<WebElement> elements = browser.findElements(By.xpath("//input[#type='email']"));
Instead of:
List<WebElement> elements = browser.findElements(By.id("input[type='email']"));
Because your element has no "id" attribute, you can't find it by By.id.
Try this:
WebElement emailElement = driver.findElement(By.xpath("//input[#type='email']"));
WebElement passwordElement = driver.findElement(By.xpath("//input[#type='password']"));
Or if you want to get a list of elements, use this:
driver.findElements(By.xpath("//input[#type='email']|//input[#type='password']"))

How to get input value by using class?

I am using the code below
WebElement inputele = driver.findElement(By.className("class_name"));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);
but the value is empty. The HTML is below.
<div id="main">
<div id="hiddenresult">
<div class="tech-blog-list">
<label for="Question">1st Question</label>
<input id="txt60" class="form-control" type="text" value="sddf sd sdfsdf sdf sdfsdf sdfsdfsd fsd" />
</div>
</div>
<div class="pagination_main pull-left">
<div id="Pagination">
<div class="pagination">
<a class="previous" onclick="PreviousBtnClickEvent();" href="javascript:void(0)">Previous</a>
<a id="pg59" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">1</a>
<a id="pg41" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">2</a>
<a id="pg40" class="ep" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textarea">3</a>
<a id="pg60" class="ep current" onclick="PaginationBtnClickEvent(this);" href="javascript:void(0)" name="Textbox">4</a>
</div>
</div>
</div>
</div>
Try using WebDriverWait to wait until element fully loaded on page and visible as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement inputele= wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("class_name")));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);
Note :-By.className("class_name") will give that element which class attribute equal to class_name. Make sure which element you want to locate is unique element with class attribute equal to class_name otherwise wise it will give first element with condition true.
Hope it will work..:)
Looks like your code is pretty close but you have the wrong class name? In your code above, you had "class_name" instead of "form-control". I'm assuming that was some sample code and not the actual code you are using? There is only one INPUT in the HTML and the code below should work. It also has an ID so that should be more specific in case there are more than one INPUTs on the page.
WebElement inputele= driver.findElement(By.className("form-control"));
String inputeleval = inputele.getAttribute("value");
System.out.println(inputeleval);

How to find same element from item grid using loop in java selenium?

I am trying to find button add to cart is present or not using loop from all item box from following code
<div class="page-body">
<div class="product-selectors">
<div class="product-filters-wrapper">
<div class="product-grid">
<div class="item-box">
<div class="item-box">
<div class="item-box">
<div class="item-box">
</div>
in each item box folowing code
<div class="item-box">
<div class="product-item" data-productid="20">
<div class="picture">
<div class="details">
<h2 class="product-title">
<div class="product-rating-box" title="1 review(s)">
<div class="description"> 12x optical zoom; SuperRange Optical Image Stabilizer </div>
<div class="add-info">
<div class="prices">
<div class="buttons">
<input class="button-2 product-box-add-to-cart-button" type="button" onclick="AjaxCart.addproducttocart_catalog('/addproducttocart/catalog/20/1/1 ');return false;" value="Add to cart">
</div>
</div>
</div>
</div>
</div>
I need to find that all itembox have add to cart button present or not using loop. if anyone can help please
I suggest to avoid looping if not necessary. You do not need to do the loop to find out unless there is an explicit need of doing so. You can find the count of Add to cart button and compare with a known value
By byCss = By.cssSelector(".item-box>div input[value='Add to cart']");
int cartCount = driver.findElements(byCss).size();
if (cartCount != 4){
//fail the test
}
If you exactly one to looping and check if the input button exist or not.
By itemBoxes = By.className("item-box");
By button = By.cssSelector("[type='button'][value='Add to cart']");
List<WebElement> webElementList = driver.findElements(itemBoxes);
for (WebElement element: webElementList){
//simply taking size if exist it will return 1
if (element.findElements(button).size() != 1){
//fail
}
}
you can use searching by xpath inside of the loop.
Something like
".//input[#value='Add to cart'][1]"
".//input[#value='Add to cart'][2]"
".//input[#value='Add to cart'][3]"
etc
not sure that this xpath is correct, but generally it will work for you, bro.
Or something like this:
string xpath=".//input[#value='Add to cart']";
var AddToCartBtnsList = driver.findElements(By.Xpath(xpath));
foreach(IWebElement button in AddToCartBtnsList )
{
button.click();
}

How do I correctly parse data using JSoup (java)

I want to parse the data out of this HTML (CompanyName, Location, jobDescription,...) using JSoup (java). I get stuck when trying to iterate the joblistings
The extract from the HTML is one of many "JOBLISTING" divs which I want to iterate and extract the Data out of it. I just can't handle how to iterate the specific div objects. Sorry for this noob question, but maybe someone can help me who already knows which function to use. Select?
<div class="between_listings"><!-- local.spacer --></div>
<div id="joblisting-2944914" class="joblisting listing-even listing-even company-98028 " itemscope itemtype="http://schema.org/JobPosting">
<div class="company_logo" itemprop="hiringOrganization" itemscope itemtype="http://schema.org/Organization">
<a href="/stellenangebote-des-unternehmens--Delivery-Hero-Holding-GmbH--98028.html" title="Jobs Delivery Hero Holding GmbH" itemprop="url">
<img src="/upload_de/logo/D/logoDelivery-Hero-Holding-GmbH-98028DE.gif" alt="Logo Delivery Hero Holding GmbH" itemprop="image" width="160" height="80" />
</a>
</div>
<div class="job_info">
<div class="h3 job_title">
<a id="jobtitle-2944914" href="/stellenangebote--Junior-Business-Intelligence-Analyst-CRM-m-f-Berlin-Delivery-Hero-Holding-GmbH--2944914-inline.html?ssaPOP=204&ssaPOR=203" title="Arbeiten bei Delivery Hero Holding GmbH" itemprop="url">
<span itemprop="title">Junior Business Intelligence Analyst / CRM (m/f)</span>
</a>
</div>
<div class="h3 company_name" itemprop="hiringOrganization" itemscope itemtype="http://schema.org/Organization">
<span itemprop="name">Delivery Hero Holding GmbH</span>
</div>
</div>
<div class="job_location_date">
<div class="job_location target-location">
<div class="job_location_info" itemprop="jobLocation" itemscope itemtype="http://schema.org/Place">
<div class="h3 locality" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="addressLocality"> Berlin</span>
</div>
<span class="location_actions">
<a href="javaScript:PopUp('http://www.stepstone.de/5/standort.html?OfferId=2944914&ssaPOP=203&ssaPOR=203','resultList',800,520,1)" class="action_showlistingonmap showlabel" title="Google Maps" itemprop="maps">
<span class="location-icon"><!-- --></span>
<span class="location-label">Google Maps</span>
</a>
</span>
</div>
</div>
<div class="job_date_added" itemprop="datePosted"><time datetime="2014-07-04">04.07.14</time></div>
</div>
<div class="job_actions">
</div>
</div>
<div class="between_listings"><!-- local.spacer --></div>
File input = new File("C:/Talend/workspace/WEBCRAWLER/output/keywords_SOA.txt"); // Load file into extraction1 Document ParseResult = Jsoup.parse(input, "UTF-8", "http://example.com/"); Elements jobListingElements = ParseResult.select(".joblisting"); for (Element jobListingElement: jobListingElements) { jobListingElement.select(".companyName span[itemprop=\"name\"]"); // other element properties System.out.println(jobListingElements);
Java code:
File input = new File("C:/Talend/workspace/WEBCRAWLER/output/keywords_SOA.txt");
// Load file into extraction1
Document ParseResult = Jsoup.parse(input, "UTF-8", "http://example.com/");
Elements jobListingElements = ParseResult.select(".joblisting");
for (Element jobListingElement: jobListingElements) {
jobListingElement.select(".companyName span[itemprop=\"name\"]");
// other element properties
System.out.println(jobListingElements);
}
Thank you!
So you got your Jsoup document right? Than it seems pretty easy if the css class joblisting does not appear anywhere else.
Document document = Jsoup.parse(new File("d:/bla.html"), "utf-8");
Elements elements = document.select(".joblisting");
for (Element element : elements) {
Elements jobTitleElement = element.select(".job_title span");
Elements companyNameElement = element.select(".company_name spanspan[itemprop=name]");
String companyName = companyNameElement.text();
String jobTitle = jobTitleElement.text();
System.out.println(companyName);
System.out.println(jobTitle);
}
I don't know why the attribute [itemprop*=\"name\"] selector does not find the span (Further reading: http://jsoup.org/cookbook/extracting-data/selector-syntax )
Got it: span[itemprop=name] without any quotes or escapes. Other attributes or values also should work to get a more specific selection.

Categories