2015-09-14 156 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