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
How to Count Certain Elements in Array
ASP.NET Postback with JavaScript
What Is the Order of Execution in JavaScript Promises
Calling a JavaScript Function Named in a Variable
How to Watch for a Route Change in Angularjs
Using _ (Underscore) Variable with Arrow Functions in Es6/Typescript
Removing Event Listener Which Was Added with Bind
How to Programatically Select an HTML Option Using JavaScript
Stringify (Convert to JSON) a JavaScript Object with Circular Reference
How to Find Indices of All Occurrences of One String in Another in JavaScript
The Entity Name Must Immediately Follow the '&' in the Entity Reference
How to Create Dynamic Variable Names Inside a Loop
Call a Function After Previous Function Is Complete
Where to Write to Localstorage in a Redux App
Set Additional Data to Highcharts Series