2015-12-21 160 views
1

如何使用selenium webdriver從javascript函數返回數組? 我已經試過代碼 -Selenium webdriver的Javascript函數返回值

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe"); 
    wd=new ChromeDriver(); 
    wd.navigate().to("http://www.makemytrip.com"); 
    wd.manage().window().maximize(); 
    Thread.sleep(5000); 
    wd.findElement(By.id("from_typeahead1")).click(); 
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span")); 

    JavascriptExecutor jse = (JavascriptExecutor)wd; 
    jse.executeScript("window.showList = function(){"+ 
      "var source=[];"+ 
      "var inputs = arguments[0].getElementsByTagName('div');"+ 
      "for(var i = 0; i < inputs.length; i++) {"+ 
       "source.push(inputs[i])"+ 
      "}"+ 
      "return source;"+ 
      "};",span); 

    /*List<?> al = (List<?>) jse.executeScript(
      "var source = [];"+ 
      "var inputs = arguments[0].getElementsByTagName('div');"+ 
      "for(var i = 0; i < inputs.length; i++) {"+ 
       "source.push(inputs[i])"+  
      "}"+ 
      "return source;"     
      ,span);*/ 

    List<?> al = (List<?>) jse.executeScript("showList();"); 
    for(Object web:al){ 
     System.out.println(((WebElement) web).getText()); 
    } 

我得到一個異常說明 - 「org.openqa.selenium.WebDriverException:未知的錯誤:無法讀取的未定義的屬性‘的getElementsByTagName’。」

順便說一句,當我嘗試這種代碼,它完美的作品 -

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe"); 
    wd=new ChromeDriver(); 
    wd.navigate().to("http://www.makemytrip.com"); 
    wd.manage().window().maximize(); 
    Thread.sleep(5000); 
    wd.findElement(By.id("from_typeahead1")).click(); 
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span")); 

    List<?> al = (List<?>) jse.executeScript(
      "var source = [];"+ 
      "var inputs = arguments[0].getElementsByTagName('div');"+ 
      "for(var i = 0; i < inputs.length; i++) {"+ 
       "source.push(inputs[i])"+  
      "}"+ 
      "return source;"     
      ,span); 

    for(Object web:al){ 
     System.out.println(((WebElement) web).getText()); 
    } 

,但我想先創建返回我的數組的函數,然後調用每當我想要的功能。如何實現這一目標?另外如果可能的話,我該如何使用外部.js文件來執行相同的邏輯並在腳本中使用它? 任何幫助將不勝感激。提前致謝 !

回答

1

正如您發現executeScript方法使用第一個參數創建一個函數並將其餘參數傳遞給它。

要突破這個函數的範圍,只需在全局對象中定義一些東西或者操作DOM即可。

例如,請在您測試的某個地方從您的第一個代碼段調用jse.executeScript("window.showList = function(){...,但不要傳遞span參數。這在全局範圍內定義了showList函數。

稍後,您可以簡單地使用jse.executeScript("return showList.apply(null, arguments)", span)來調用它。

同樣,也可以包括使用片斷

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

(或乾脆硬編碼的URL)外部腳本。

對於這兩種情況,請記住只運行一次定義/包含調用以避免重新定義事物。

+0

謝謝@ billc.cn!你能告訴我一個你正在創建的外部.js文件的工作示例,然後在腳本中調用它嗎?可能是我做錯了什麼(語法錯誤,我猜)它不工作。 –

+1

我手邊沒有一個實際的例子,但基本上你可以在外部腳本中定義全局函數,並使用'executeScript'來調用它們,類似於上面給出的第二個例子。您可以使用瀏覽器的調試控制檯查找JS錯誤(在測試代碼中放置一些斷點,以便您有時間與瀏覽器交互)。如果您無法訪問瀏覽器,則可以獲取大多數驅動程序的瀏覽器控制檯日誌。只需谷歌瀏覽器名稱+「硒日誌」。 –

+0

好的會嘗試。再次感謝 !還有一件事 - 我需要將外部.js文件放在本地web服務器中,還是可以從本地資源訪問它?如果是的話,我如何分配「s.src」中的路徑? –