I'm writing a test using Selenium and JavaScript. I'm new to both, and also new to functional programming and promises. I'm trying to create a function that needs to do 3 things:
- Click on an input
- Clear the input
- SendKeys to input
My current function does not work:
var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
var returnValue;
driver.findElement(elementIdentifier).then(function(inputField){
inputField.click().then(function() {
inputField.clear().then(function() {
returnValue = inputField.sendKeys(sendKeys);
});
});
});
return returnValue;
}
The function would then be called as for example:
clearAndSendKeys(driver, webdriver.By.id('date_field'), '14.09.2015').then(function(){
//Do stuff
});
I expected the variable returnValue
to contain the promise from sendKeys
. However the function clearAndSendKeys
returns the undefined variable before sendKeys is ran. I assume this is because returnValue
was never defined as a promise, and so the program does not know that it needs to wait for sendKeys
.
How can I make my function clearAndSendKeys
return the promise from sendKeys
? I'd rather avoid having to add a callback to the clearAndSendKeys
function.
Edit: Removed .then({return data})
from the code as this was a typo.
I'm writing a test using Selenium and JavaScript. I'm new to both, and also new to functional programming and promises. I'm trying to create a function that needs to do 3 things:
- Click on an input
- Clear the input
- SendKeys to input
My current function does not work:
var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
var returnValue;
driver.findElement(elementIdentifier).then(function(inputField){
inputField.click().then(function() {
inputField.clear().then(function() {
returnValue = inputField.sendKeys(sendKeys);
});
});
});
return returnValue;
}
The function would then be called as for example:
clearAndSendKeys(driver, webdriver.By.id('date_field'), '14.09.2015').then(function(){
//Do stuff
});
I expected the variable returnValue
to contain the promise from sendKeys
. However the function clearAndSendKeys
returns the undefined variable before sendKeys is ran. I assume this is because returnValue
was never defined as a promise, and so the program does not know that it needs to wait for sendKeys
.
How can I make my function clearAndSendKeys
return the promise from sendKeys
? I'd rather avoid having to add a callback to the clearAndSendKeys
function.
Edit: Removed .then({return data})
from the code as this was a typo.
-
you need to assign returnValue to the promise, first line should be
var returnValue = driver.findElement(...
, – Saar Commented Sep 14, 2015 at 13:06 - jsfiddle/arunpjohny/s2b0v8nu/1 - use callbacks – Arun P Johny Commented Sep 14, 2015 at 13:06
- Hi Arun, why should he use callbacks when trying to use promises? – Saar Commented Sep 14, 2015 at 13:08
-
are any/all of those functions (
.findElement()
.click()
.clear()
and.sendKeys()
) even asynchronous? I'm guessingsendKeys
at least returns a promise, do any of the others? – Jaromanda X Commented Sep 14, 2015 at 13:37
2 Answers
Reset to default 4You have to return each promise from the .then
callback:
var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
return driver.findElement(elementIdentifier).then(function(inputField){
return inputField.click().then(function() {
return inputField.clear().then(function() {
return inputField.sendKeys(sendKeys);
});
});
});
}
The promise returned by .then
will resolve to the same value as the value returned from the callback.
See Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference for why your current code does not work. Promises are asynchronous.
First of all its probably not the best idea to nest promises, pletely defeating their main purpose of eliminating callback hell. then
callback can return Thenable
object that allows to create nice chains of async operations.
In this case you just need to store reference to input field available as a result of the first async operation in the scope of the main function and then create chain of async operations that can be returned from this function.
var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
var inputFieldRef;
return driver.findElement(elementIdentifier)
.then(function(inputField){
inputFieldRef = inputField;
return inputField.click();
}).then(function() {
return inputFieldRef.clear();
}).then(function() {
return inputFieldRef.sendKeys(sendKeys);
});
}