我试图使用下面的 xpath 和 selenium webdriver 中的名称值来识别 Firefox 中的元素,但它不起作用。 This is link to the web page which I want to automate 。此页面上的所有输入字段对我来说看起来很奇怪,我不明白如何填写它们。
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 中是否有标准方法来查找和填充这些字段。
最佳答案
所有测试自动化工具的一个问题是页面可能尚未完成加载 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 构建时,Angular 才有效。
编辑2查找元素
我使用 google chrome 浏览器来“查找”元素。在 chrome 下打开您的网页。右键单击显示的元素。选择检查 -> 复制 -> 复制选择器 |复制 X 路径。您也可以在 Firefox 下执行此操作。 Chrome 只是习惯的力量。
编辑3
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);
}
最后,Ajax
public boolean waitForPrototypeAjax(WebDriver driver, int timeout) {
return waitFor(driver, "return Ajax.activeRequestCount;", "0", timeout);
}
关于java - Selenium Webdriver findelement i sendKeys() 的行为不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40875692/