2015-09-14 116 views
0

我正在使用Selenium和JavaScript编写测试。我对这两者都是新手,也是功能编程和承诺的新手。我试图创建一个需要做三件事情的函数:如何从最后的承诺中返回一个函数中的承诺“then”

  1. 点击输入
  2. 清除输入
  3. 的SendKeys输入

我目前的功能不工作:

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; 
    } 

然后该函数将被称为例如:

clearAndSendKeys(driver, webdriver.By.id('date_field'), '14.09.2015').then(function(){ 
     //Do stuff 
    }); 

我期望变量returnValue包含来自sendKeys的承诺。但是,在运行sendKeys之前,函数clearAndSendKeys会返回未定义的变量。我认为这是因为returnValue从未被定义为承诺,所以程序不知道它需要等待sendKeys

如何让我的功能clearAndSendKeyssendKeys返回承诺?我宁愿避免为clearAndSendKeys函数添加回调。

编辑:从代码中删除.then({return data}),因为这是一个错字。

+0

你需要的returnValue分配给承诺,第一条线应该是'VAR的returnValue = driver.findElement(...', – Saar

+0

http://jsfiddle.net/arunpjohny/s2b0v8nu/1/ - 使用回调 –

+0

嗨阿伦,为什么他应该使用回调时试图使用诺言? – Saar

回答

2

你必须从.then回调返回每个承诺:

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); 
      });     
     });     
    }); 
} 

通过.then返回的承诺将解决以相同的值回调函数返回值。


请参阅Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference为什么您当前的代码无法使用。承诺是异步

3

首先它可能不是嵌套承诺的最好主意,完全击败了它们消除回拨地狱的主要目的。 then回调可以返回Thenable对象,允许创建不错的异步操作链。

在这种情况下,您只需将对第一个异步操作的结果可用的输入字段的引用存储在main函数的作用域中,然后创建可从此函数返回的异步操作链。

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); 
     }); 
} 
+0

这个全局的'inputFieldRef'变量是一个特别丑陋的[在.then()链中访问先前承诺结果](http ://stackoverflow.com/q/28250680/1048572)虽然。 – Bergi

+0

比死亡金字塔还好!@Bergi - 我对于如何克服这种丑陋感兴趣,但无法真正看到你发布的链接中有什么更优雅 –

+0

@JaromandaX:好吧ES7 async/await *绝对*更优雅:-)无论如何,我不认为第二层嵌套(更多是不必要的)是不好的,它可以很容易'driver.findElement(...).then(function(inputField){return inputField.click()。then (inputField.clear.bind(inputField))。then(inputField.sendKeys.bind(inputField,sendKeys));})' – Bergi