Getting the Return Value of JavaScript Code in Selenium

Getting the return value of Javascript code in Selenium

To return a value, simply use the return JavaScript keyword in the string passed to the execute_script() method, e.g.

>>> from selenium import webdriver
>>> wd = webdriver.Firefox()
>>> wd.get("http://localhost/foo/bar")
>>> wd.execute_script("return 5")
5
>>> wd.execute_script("return true")
True
>>> wd.execute_script("return {foo: 'bar'}")
{u'foo': u'bar'}
>>> wd.execute_script("return foobar()")
u'eli'

Return value from JavaScript to Python using Selenium

Basically the problem here and how you want to solve it is a little bit more complicated.

First of all the javascript code is not valid and executing this script will return None.
Much simpler version of the script is driver.execute_script("return confirm('...')") but the problem here will be that the alert will pop up and the python code will continue so it will still return None.

What you can do is to execute confirm('Yes or No?') store it in variable, wait until alert is gone and return this variable.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoAlertPresentException

# small helper class to wait untill alert is no longer present
class alert_is_not_present(object):
""" Expect an alert to not to be present."""
def __call__(self, driver):
try:
alert = driver.switch_to.alert
alert.text
return False
except NoAlertPresentException:
return True

self.driver.execute_script("choice = confirm('yes or no')")

# Give some large timeout so you're sure that someone will have time to click
# Wait until user makes a choice
WebDriverWait(self.driver, 10000).until(alert_is_not_present())
# retrieve the choice
choice = self.driver.execute_script('return choice')
if choice:
print('Success!')
else:
print('Failed')

How to return value from JavaScript using Selenium?

You can just return the value like this:

Java:

JavascriptExecutor js = (JavascriptExecutor) driver;         
js.executeScript("return document.title");

Python:

driver.execute_script("return document.title")
driver.execute_script("return document.querySelector('.somecssclass')")

Return value from Javascript function in Selenium webdriver

As you have found out the executeScript method creates a function using the first argument and pass the remaining arguments to it.

To break out of the scope of this function, simply define something in the global object or manipulate the DOM.

For example, call the jse.executeScript("window.showList = function(){... from your first code snippet somewhere in your test but do not pass it the span argument. This defines the showList function in the global scope.

Later you can simply do jse.executeScript("return showList.apply(null, arguments)", span) to call it.

Similarly, you can include an external script using the snippet

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

(or simply hard-code the url).

For both cases, remember to only run the definition/include call once to avoid redefining things.

How to get the return value of a JavaScript function to a Python Variable

This will navigate to this page where you asked this question and return the localStorage item "se:fkey" using javascript:

from selenium import webdriver

driver = webdriver.Chrome(executable_path=r'C:\\Path\\To\\Your\\chromedriver.exe')
driver.get('https://stackoverflow.com/questions/63283026/how-to-get-the-return-value-of-a-javascript-function-to-a-python-variable')

a_returned = driver.execute_script("""
a_function = function(){
console.log(localStorage.getItem("se:fkey"));
return localStorage.getItem("se:fkey");
};
return a_function();

""")

print("a_returned:", a_returned)

Return value from a JQuery script in Selenium Webdriver

Ok, I have solved problem.
There are 2 ways of achieving result - obtaining href's from links.

script = "return $('a.class0.class1.link');"

execute such script and get an Array of WebElements from which it is possible to get attributes:

val js = browser.asInstanceOf[JavascriptExecutor]
val scriptResult = js.executeScript(script)
val result = ListBuffer.empty[String]

scriptResult.asInstanceOf[util.ArrayList[WebElement]].forEach(x => result +=
x.getAttribute("href"))

result.toList

or in second way - execute such JQuery code:

val script = "return (function() {var table = [];$('a.class0.class1.link').each(function() { table.push($(this).attr('href'));});return table;})();"

and collect result:

val js = browser.asInstanceOf[JavascriptExecutor]
val scriptResult = js.executeScript(javascript)
scriptResult.asInstanceOf[util.ArrayList[String]].asScala.toList

Returning javascript data from Python Selenium Web Driver

All problem can be because you run function() inside ready() and it return sends text to ready(), not to you. You have to directly run function to get its result.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
import os
import time

driver = webdriver.Chrome()# executable_path='chromedriver')
driver.get('http://quotes.toscrape.com/js/')

#script = '$(document).ready(function() { return "Hello World"; })';
script = 'function test() { return "Hello World"; })()';

time.sleep(3)

# Attempt 1
text = driver.execute_script(script)
print(text) # None

# Attempt 2
text = driver.execute_script(f'return {script}')
print(text) # Hello World

# Attempt 3
#text = WebDriverWait(driver, 20).until(lambda driver: driver.execute_script(script))
#print(text) # error

# Attempt 4
text = WebDriverWait(driver, 20).until(lambda driver: driver.execute_script(f'return {script}'))
print(text) # Hello World

EDIT:

if you really need to check if document is ready then you should do it inside your function. You could try to use while-loop with variable $.isReady

In JQuery, how do I check if the DOM is ready?

In JavaScript, retrieve the value and performed the addition after that want to return the value after the for loop in cypress automation?

Cypress commands are asynchronous.
cy.log captures the sum value before the first xpath command gets really executed.
To synchronize access to the sum you can use a then callback:

verifyActiveInterfacesViaConnectionStatus() {
var sum = 0
var i;
for (i = 1; i <= 5; i++) {
cy.xpath(`(//*[name()='g' and @class ='highcharts-label highcharts-data-label highcharts-data-label-color-undefined']//*[name()='text']//*[@class='highcharts-text-outline'])[${i}]`).invoke("text").then(($text1) => {

var textValue1 = $text1 + "\n"
cy.log(textValue1)
var total = parseInt(textValue1)
sum += total
})
}
cy.then(() => {
cy.log("Total of all connected OS= " + sum)
})
}

Look at this article for details on how to handle variables at Cypress.



Related Topics



Leave a reply



Submit