2016-11-29 112 views
1

我想在Firefox中使用下面的xpath和名稱值在selenium webdriver中識別元素,但它不工作。 This is link to the web page which I want to automate。在這個頁面上的所有輸入字段看起來很奇怪,我不知道如何填寫它們。Selenium Webdriver findelement我sendKeys()沒有像預期的那樣運行

driver.findElement(By.name("sender-postCode")).sendKeys("02791"); 
driver.findElement(By.xpath(".//*[@id='stepOneForm']/div[2]/div[4]/div[1]/div[1]/div[1]/input")).sendKeys("02791"); 

這是我的代碼:

package SalesBar; 
import org.openqa.selenium.By; 
import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.WebElement; 
import org.openqa.selenium.firefox.FirefoxDriver; 
import org.openqa.selenium.firefox.FirefoxProfile; 
import org.openqa.selenium.firefox.internal.ProfilesIni; 
public class Salesbar { 
public static void main(String[] args) throws Exception { 
    // TODO Auto-generated method stub 
    System.setProperty("webdriver.gecko.driver", "C:/Users/User/Documents/SeleniumWebDriver/geckodriver.exe"); 
    ProfilesIni profil = new ProfilesIni(); 
    FirefoxProfile myprofile = profil.getProfile("default"); 

    WebDriver driver; 
    driver = new FirefoxDriver(myprofile); 

    driver.get("https://wwwuat.dpdpickup.pl/Wycen-i-nadaj-Online"); 
    driver.findElement(By.xpath(".//*[@id='contentWrapper']/div/div/div[2]/div[1]/a")).click(); 
    Thread.sleep(3000); 
    driver.findElement(By.xpath(".//*[@id='stepOneForm']/div[2]/div[3]/span[2]/label/span")).click(); 
    Thread.sleep(3000); 
    driver.findElement(By.name("parcels-1-weight")).sendKeys("5"); 
    } 

請讓我知道如果在webdriver的一種標準方法來尋找和填補這些領域。

回答

0

所有測試自動化工具的問題在於,自動化工具執行時頁面可能尚未完成加載DOM。有各種各樣的複雜程度可以用來使其100%可靠。第一道防線是使用ExpectedConditions。因此,對於你的第一個例子,

WebDriver webDrive = ... // You have to initialize to a browser instance and navigate to your web page 
By bySenderPostCode = By.name("sender-postCode"); 
Wait<WebDriver> wait_element = new WebDriverWait(webDriver, 40); // Wait up to 40 seconds 
WebElement senderPostalCodeElement = wait_element.until(ExpectedConditions.visibilityOfElementLocated(bySenderPostCode)); 
senderPostalCodeElement.sendKeys("02791"); 

有很多執行JavaScript的複雜頁面可能會很痛苦。我用我寫了等待angularJs完成執行程序,等待裝載微調來完成,最後進行頁面的readyState等於完成:

waitForAngularToLoad(webDriver, 40); 
wait_element.until((WebDriver dr1) -> (webDriver.findElement(mySpinner).getAttribute("class").contains("ng-hide"))); 
waitForBrowserReadystateComplete(webDriver); 

這些必須進行調整的環境,您必須在其中運行。等待jQuery完成與等待AngularJs不同。但是我給你的東西應該讓你去。讓我知道結果如何。

編輯

我意識到,告訴你關於我的程序,我用它來等待,但不共享代碼是毫無意義的。加載微調器完全依賴於實現。沒有一種方法可以保證在任何地方都能正常工作,但我給了你AngularJs實現常見的一般形式。

這裏是別人:

public void waitForBrowserReadystateComplete(WebDriver webDriver) { 
    for (int a=0; a<20; a++) { 
     JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver; 
     if (javascriptExecutor.executeScript("return document.readyState") 
       .toString().equals("complete")) { 
      break; 
     } 
     sleepResponsibly(500); 
    } 
} 

public void sleepResponsibly(int timeMillisecond){ 
    try{ 
     Thread.sleep(timeMillisecond); 
    } catch (InterruptedException ex) { 
     Thread.currentThread().interrupt(); 
     throw new RuntimeException(ex); 
    } 
} 

public boolean waitForAngularToLoad(WebDriver driver, int timeout) { 
    driver.manage().timeouts().setScriptTimeout(timeout, TimeUnit.SECONDS); 
    WebDriverWait wait = new WebDriverWait(driver, timeout, 500L); 
    return wait.until(angularHasFinishedProcessing()); 
} 


public static ExpectedCondition<Boolean> angularHasFinishedProcessing() { 
    return new ExpectedCondition<Boolean>() { 
     @Override 
     public Boolean apply(WebDriver driver) { 
      String hasAngularFinishedScript = "var callback = arguments[arguments.length - 1];\n" + 
        "var el = document.querySelector('html');\n" + 
        "if (!window.angular) {\n" + 
        " callback('false')\n" + 
        "}\n" + 
        "if (angular.getTestability) {\n" + 
        " angular.getTestability(el).whenStable(function(){callback('true')});\n" + 
        "} else {\n" + 
        " if (!angular.element(el).injector()) {\n" + 
        "  callback('false')\n" + 
        " }\n" + 
        " var browser = angular.element(el).injector().get('$browser');\n" + 
        " browser.notifyWhenNoOutstandingRequests(function(){callback('true')});\n" + 
        "}"; 

      JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver; 
      String isProcessingFinished = javascriptExecutor.executeAsyncScript(hasAngularFinishedScript).toString(); 

      return Boolean.valueOf(isProcessingFinished); 
     } 
    }; 
} 

請記住,如果你的系統在測試使用AngularJs內置角的人只工作。

EDIT 2查找元素

我使用谷歌Chrome瀏覽 「找到」 的元素。在Chrome中打開您的網頁。右鍵單擊顯示的元素。選擇檢查 - >複製 - >複製選擇器|複製Xpath。您也可以在Firefox下執行此操作。 Chrome只是習慣的力量。

EDIT3

jQuery的

public boolean waitForJquery(WebDriver driver, int timeout) { 
    return waitFor(driver, "return jQuery.active;", "0", timeout); 
} 

public boolean waitFor(WebDriver driver, final String javascriptString, final String targetString, int timeout) { 
    WebDriverWait wait = new WebDriverWait(driver, timeout, 500L); 

    /* 
    * If you are curious about what follows see: 
\ * http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/ExpectedCondition.html 
    * 
    * We are creating an anonymous class that inherits from ExpectedCondition and then implements interface 
    * method apply(...) 
    */ 
    ExpectedCondition<Boolean> isLoaded = new ExpectedCondition<Boolean>() { 

     public Boolean apply(WebDriver driver) { 
     String jsReturnedValue = ""; 

     try { 
      jsReturnedValue = String.valueOf(((JavascriptExecutor)driver).executeScript(javascriptString)); 
      return (jsReturnedValue.equals(targetString)); 
     } catch (Exception e) { 
      log.info("Looking for: " + javascriptString + ", e.message: " + e.getMessage()); 
      return true; // If Javascript not found then don't wait for it 
     } 
     } 
    }; // Terminates statement started by ExpectedCondition<Boolean> isLoaded = ... 

    return wait.until(isLoaded); 
} 

而只是爲了詳談,阿賈克斯

public boolean waitForPrototypeAjax(WebDriver driver, int timeout) { 
    return waitFor(driver, "return Ajax.activeRequestCount;", "0", timeout); 
}  
+0

邁克你好,我知道應用程序使用jQuery不AngularJs。所以我用你的第一個例子。它沒有工作。你打開了我附加的鏈接嗎?當你點擊輻射按鈕時,你會看到窗體。我改變了'等待 wait_element = new WebDriverWait(webDriver,40);'等待 wait_element = new WebDriverWait(driver,40)';因爲它被標記(webDriver無法解析爲變量) –

+0

您能更具體地瞭解「沒有工作」嗎?另外,請發佈您執行的更新後的代碼。請注意,[木偶和geckodriver功能尚未完成。這意味着它尚未完全符合WebDriver標準或與Selenium完全兼容。](https://github.com/mozilla/geckodriver)。所以我使用了selenium-java v2.53.1和firefox v47.0。 – MikeJRamsey56

+0

我已經切換到chrome webdriver和selenium-java v2.53,並解決了我的問題。謝謝邁克。 –

相關問題