2016-11-29 187 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,并解决了我的问题。谢谢迈克。 –

相关问题