How to Develop a Custom getText() Function for a Selenium Element?

Creating a custom Selenium getText() method that can retrieve either the node text or the node plus child text of an element is my current challenge. The default behavior of Selenium appears to utilize the Xpath .//string() method which includes the text of immediate children. I aim to harness the power of XPaths for a more targeted approach to fetching text. So, my question is: am I misinterpreting this or is there a more efficient way to achieve this?

public String getText(By locationOfText, boolean childText)
{
  By locator = null;
  if (childText)
  {
    locator = ByChained(locationOfText, By.xpath(".//string()"));
  } else {
    locator = ByChained(locationOfText, By.xpath(".//text()"));
  }
  JavascriptExecutor jse = (JavascriptExecutor)driver;
  String elementText = jse.executeScript("document.evaluate(locator, document.body, null, 
     XPathResult.STRING_TYPE, null);");

  return elementText;
} 

Below is an HTML snippet:

<h5 class="class-name clearfix">Inner Text
   <a class="info-link class-description" href="#">i</a>
</h5>

The issue arises when using Selenium to extract text like this:

driver.findElement(".//h5").getText();

Instead of only "Inner Text", it retrieves Inner Texti. This leads me to expect that by utilizing the above method, I can employ it in this manner:

String text = elementHelper.getText(By.xpath(".//h5"), false);

Answer №1

string() is an XPath 2.0 feature, but most browsers only support XPath 1.0. Using XPath for querying the DOM tree can have a performance overhead. Instead of relying solely on XPath, consider following this approach:

public String getText(By locationOfText, boolean childText)
{
  WebElement el = driver.findElement(locationOfText);
  if (childText)
  {
    return el.getText();
  }

  JavascriptExecutor jse = (JavascriptExecutor) driver;
  return jse.executeScript(
    "var parent = arguments[0]; "+
    "var child = parent.firstChild; "+
    "var ret = ""; "+
    "while(child) { "+
    "    if (child.nodeType === Node.TEXT_NODE) "+
    "        ret += child.textContent; "+
    "    child = child.nextSibling; "+
    "} "+
    "return ret;", el);
}

The locationOfText parameter allows any supported Selenium By method to be used.

If using ByChained for location in your code, make sure to pass it correctly to executeScript. Combining CSS selectors with XPath using ByChained may not work seamlessly across all browsers due to their different engines and capabilities.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an OutofMemory error when attempting to crop an image

Here is the code I've been working on, but unfortunately running into an out-of-memory exception. The goal is to crop an image of a specific element from a screenshot captured using Selenium. byte[] image = driver.GetScreenshot().AsByteArray; using ...

It seems that BeautifulSoup and Selenium are unable to locate the div or text elements on the website

I have been attempting to utilize BeautifulSoup or Selenium in order to retrieve the Head to Head text or its corresponding div element on betexplorer (link provided below), but my efforts have unfortunately proved to be unsuccessful. Despite being able to ...

What is the preferred method for logging out: using window.location.replace('/') or setting window.location.href to window.location.origin?

When it comes to a logout button, which is the better option: window.location.replace('/') or window.location.href=window.location.origin? Can you explain the difference between these two methods? It's my understanding that both of them remo ...

Python 3.7 experiences an InvalidSelectorException when using Selenium's common exceptions

I am currently working on automating a process using selenium that involves opening a specific website, logging in, and searching for particular articles. While I have been successful with some of the steps, I encountered an error during the 'sign-in& ...

Display markers on the canvas

I am having trouble painting points from a JSON object on canvas using the following code. Can someone help me identify where I went wrong? var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); var t = [{"prevX":39,"prevY":58,"currX ...

"Is it possible to keep an eye on two different events and take action once they both

I have a menu with different submenus for each list item, all utilizing the same background tag. Currently, when one submenu is open and I hover over another list item, the previous submenus hide and the new one opens. What I want is for the content to cha ...

Is it possible to use Selenium in Python to solicit user input and display it on a website?

Greetings all! This is my first time sharing here, so please forgive any errors. Here's my situation: I have a script that logs into my school's website, checks off an indicator showing I'm feeling good (and COVID-free). I'd like to sh ...

Choose an XPath formula that will target every single element, text node, and comment node in the original sequence

How can we write an XPath expression that selects all elements, text nodes, and comment nodes in the order they appear in the document? The code below selects all elements but not text nodes and comment nodes: let result = document.evaluate('//*&apo ...

The picture is displayed just once, despite the fact that it was supposed to be returned 50 times within the loop

I'm encountering an issue while trying to use a for loop to render an image in a React component. The loop is not functioning as expected, resulting in the image being displayed only once on the screen even though the intention is to show the same ima ...

Find the quantity of items in each list individually and add them to a new list

Seeking a solution for a seemingly simple issue. I am attempting to calculate the number of list items and then add this count to the list in the parent div. The problem lies in the fact that it always displays the value of the last item in the list. For i ...

Implementing AJAX in Rails for the new/create action can greatly enhance the user

I have a timeline with event sections on it that allow you to create, view, update, and delete events directly on the timeline page. Currently, the functionality for deleting an event is working smoothly as the delete section refreshes along with the timel ...

Struggling to merge two variables together and receiving this error message: "mergedObject is not defined."

New to Node.js/Express and trying to combine two objects to save them to a collection. Any advice would be greatly appreciated! Thank you in advance for your time. This is what I've put together, but it's not functioning as expected: app.post( ...

JavaScript: Incorporating an operator into a specific object (instead of the entire class)

Are you familiar with how to include an operator in an object (rather than the entire class)? When it comes to a method, I know you can achieve that by: my_object.new_function = function(){return 1}; Then invoking my_object.new_function() will output ...

Encountering an error in Vue.js where a "cannot read property of undefined" message is displayed when attempting to use v

While attempting to use v-model on an array item's property, I encountered the error message "[Vue warn]: Error in render function: 'TypeError: Cannot read property 'viewFood' of undefined' when loading the page. This resulted in a ...

Clickable elements are not functioning on dynamically generated divs

In the process of developing an application using Angular, I encountered a scenario where I needed to fetch and display data from a web service. The challenge was in dynamically creating div elements with the retrieved data: for(var i = 0 ; i < data.Ou ...

What is the mechanism behind the functioning of StackOverflow's notification system?

Could you explain the technique that is utilized to transmit and receive data from the client to the server? How does it manage to provide almost real-time results when new changes take place? Can anyone demonstrate the code being used for this process? ...

Ensure that an HTML table row remains fixed on the screen at all times

I'm looking to make a specific row in my HTML table always visible on the screen, either at the bottom if scrolled off or top. The row should scroll normally as part of the table when it's visible on the screen. How can I accomplish this using bo ...

Visualize data retrieved from a third-party website through scraping in a chart

After attempting to extract data from a website's data.asp file (formatted in json) and display it as a chart on my site using Google Chart API or FusionCharts, I'm facing issues. Although I can retrieve the json data, it doesn't render as a ...

Can the rxjs take operator be utilized to restrict the number of observables yielded by a service?

As someone who is just starting to learn Angular, I am working on a website that needs to display a limited list of 4 cars on the homepage. To achieve this, I have created a service that fetches all the cars from the server. import { Response } from &apos ...

In this JavaScript tool for counting characters, every carriage return is counted as two characters

Hello there! I have created a character counter in JavaScript that looks like this: <textarea class="SmsText" id="txttemplate" maxlength="160" /> <span id="charsCount">160</span></strong><span>character(s) left</span> ...