Obtaining the output of a JavaScript function within a Selenium WebDriver script

Is there a way to return an array from a JavaScript function using Selenium WebDriver? Below is the code I have attempted:

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe");
    wd=new ChromeDriver();
    wd.navigate().to("http://www.makemytrip.com");
    wd.manage().window().maximize();
    Thread.sleep(5000);
    wd.findElement(By.id("from_typeahead1")).click();
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span"));

    JavascriptExecutor jse = (JavascriptExecutor)wd;
    jse.executeScript("window.showList = function(){"+
            "var source=[];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
            "for(var i = 0; i < inputs.length; i++) {"+
                "source.push(inputs[i])"+
            "}"+
            "return source;"+
            "};",span);

    /*List<?> al =  (List<?>) jse.executeScript(
            "var source = [];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
            "for(var i = 0; i < inputs.length; i++) {"+
               "source.push(inputs[i])"+      
            "}"+
            "return source;"                 
            ,span);*/

    List<?> al =  (List<?>) jse.executeScript("showList();");
    for(Object web:al){
        System.out.println(((WebElement) web).getText());
    }

I encountered an exception saying - "org.openqa.selenium.WebDriverException: unknown error: Cannot read property 'getElementsByTagName' of undefined."

Coincidentally, when I try this alternative code, it works perfectly:

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe");
    wd=new ChromeDriver();
    wd.navigate().to("http://www.makemytrip.com");
    wd.manage().window().maximize();
    Thread.sleep(5000);
    wd.findElement(By.id("from_typeahead1")).click();
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span"));

    List<?> al =  (List<?>) jse.executeScript(
            "var source = [];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
             "for(var i = 0; i < inputs.length; i++) {"+
            "source.push(inputs[i])"+       
            "}"+
            "return source;"                  
            ,span);

    for(Object web:al){
        System.out.println(((WebElement) web).getText());
    }

My goal is to create a function that returns me the array and then call this function whenever needed. How can I achieve this? Also, if possible, how do I utilize an external .js file to implement the same logic and integrate it into my script? Any guidance on this matter would be highly appreciated. Thank you in advance!

Answer №1

When utilizing the executeScript method, it constructs a function with the first argument and then passes any additional arguments to it.

To escape from the constraints of this function, you can define a variable in the global scope or interact with the DOM.

For instance, execute the

jse.executeScript("window.showList = function(){...
function in your initial code block within your test, excluding the span parameter. This action establishes the showList function globally.

Following that, you can simply use

jse.executeScript("return showList.apply(null, arguments)", span)
to invoke it.

Likewise, you are able to bring in an external script using the following snippet

driver.executeScript("var s = document.createElement('script'); s.type = 'text/javascript'; s.src = arguments[0]; document.body.appendChild(s);", scriptUrl);

(or directly input the URL).

In both scenarios, remember to execute the definition or inclusion call only once to prevent redundant redefinitions.

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

Having trouble parsing JSON, jQuery, and AJAX?

Check out my awesome Java Script code below: $('#addSchoolForm').trigger("reset"); //$(document).ready(function() { $(function() { $("#dialog").dialog({ autoOpen: false, maxWidth:600, maxHeight: 350, width: ...

Execute an AJAX request in JavaScript without using string concatenation

On my webpage, users input code in a programming language which can be over 2000 characters long and include any characters. When they press the send button, the code is sent to a server-side script file using JavaScript AJAX. Currently, I am using the fo ...

Modifying ng-model after file selection in a directive

I have a unique directive that is able to detect changes in an input field of type file. When this change occurs, my goal is to then locate another input field and modify its ng-model. The issue I am facing is that I am unable to trigger the model change s ...

Ways to "refresh" JavaScript / CSS upon user moving from one page to another in Next.js

As I create my inaugural portfolio website, I have successfully completed the main page and am now adding additional pages. The navigation bar component incorporates JavaScript to govern certain functionalities. However, I am noticing an issue when switch ...

What are the top strategies for creating a login form in Eclipse plug-in development?

I am in the process of creating an Eclipse plugin that relies on various REST services which demand authentication. I am curious about the most effective method to integrate a login form within my Eclipse plugin. Would using a pop-up window suffice, or a ...

Arranging elements using the ng-repeat directive in AngularJS

My question pertains to an array I am working with: $scope.answers=["","","",""] This array contains several empty elements. <li ng-repeat="item in answers "><input type="text" ng-model="item"/></li> When running this code, an error i ...

Tips for invoking a JavaScript function within an iframe

I'm looking to add an iframe to my HTML document, but I also need to pass a variable from a JavaScript function that is located on the same page (which retrieves cookie values). <script type=text/JavaScript> var generateLinkerUrl = function(url ...

Unable to get WebdriverWait to function properly. Is there a different solution available for Python Selenium?

I took on the challenge of building scrapers for this specific website. With a total of 39 pages to scrape, I decided to split them into four groups: 1-10, 11-20, 21-30, and 31-39. Below is the snippet of code I used to access those pages: driver = webdri ...

The TypeScript compiler is indicating that the Observable HttpEvent cannot be assigned to the type Observable

Utilizing REST API in my angular application requires me to create a service class in typescript. The goal is to dynamically switch between different url endpoints and pass specific headers based on the selected environment. For instance: if the environmen ...

Modifying the color scheme of the bottom navigation bar in Ionic 5

I am having trouble changing the color of the bottom navigation bar in my app. Even when I switch my app theme to dark, the bottom navigation bar (where overview, home, and back buttons are located) remains light with a white background and black icons. Ho ...

Implementing a line break within a JavaScript function specifically designed for formatting images

As I am not a javascript developer, the code I have been given for debugging is somewhat challenging. The issue at hand involves an iOS module where a .js CSS file has been set up and images are loading improperly, resulting in the need for horizontal scro ...

Mastering the Art of Mocking DOM Methods with Jest

What is the best way to simulate this code snippet using Jest : useEffect(() => { document .getElementById('firstname') ?.querySelector('input-field') ?.setAttribute('type', &apos ...

What is the best way to design a multi-submit form without the need for page refreshing?

I am interested in creating a form with multiple questions where users can click "next" for each question without the page reloading. For instance Click on "Begin" On this page, there is no reload when choosing a radio option and clicking "next". How ca ...

What is the maximum amount of data that can be stored in a single JavaScript object on a server that is used to share state among

In my multiplayer browser game, a socket.io server handles the gameplay by storing separate ongoing matches in a single object on the server-side: const matches = {}; Each time a player creates a match, I generate a unique key to track information about t ...

jQuery animation that smoothly fades out from the left and fades in from the right

This survey is designed to assist individuals in determining where they should go with a specific type of ticket. Currently, everything is functioning smoothly, but I would like to add a sleek animation to each ul transition. Whenever a button is clicked ...

Choosing dropdown options without the <Select> tag in Selenium with Python

Looking to choose a date from the URL highlighted in yellow below: https://i.sstatic.net/UIBLJ.jpg Upon inspecting the HTML code, I couldn't locate any "select" tag as shown: https://i.sstatic.net/fhaaU.jpg Snippet of my code: chrome_options ...

To effectively utilize the expected_conditions.element_to_be_clickable method on a WebElement, remember that the argument following the asterisk must be a collection, not just a single WebElement."

I am encountering issues with my click and arrow_right commands while working on the code below, so I need to include a new condition: value_items = \ (selection_section.find_elements_by_class_name("stuff") + ...

Guide to allowing user-defined table names in SQL

I am attempting to develop a program that can generate a table with a specific name in the database every time it is opened. However, I am facing an issue where two tables may end up having the same name. Is there a way for the program to prompt the user ...

AngularJS - akin to "live updates" in HTTP requests

Currently, I am working with AngularJS 1.3 and my backend only supports HTTP requests (no WebSockets). What would be the most effective solution for achieving "real-time" data updates? I am currently using $interval to send an HTTP request every second, b ...

Error: You cannot assign a value to the left side of the console, it is

JavaScript Code if ($language == 'english') { var displayvalue = ""; if (data[i].report_name.length >= 20) { displayvalue = data[i].report_name.substr(0, 20) + "..."; } else { displayvalue = data[i].report_name; } subMDesign ...