Selenium - select 来自 angularjs 组件的输入
Selenium - select an input from an angularjs component
<md-datepicker ng-model="mc.date.from" required="" md-val="">
<span class="input-group date" style="width:144px">
<input size="16" type="text"
class="form-control"
autocomplete="off">
<span class="input-group-btn">
<button class="btn btn-default" tabindex="-1" >
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</span>
</md-datepicker>
我有一个 AngularJs 组件,其中包含类型 text
的 input
。我已经使用以下代码输入 date
。当我 运行 无头测试时,它大多数时候都失败了。
WebElement fromDate = driver.findElement(
By.tagName("md-datepicker"))
.findElement(By.tagName("input"));
if (fromDate.getAttribute("value").length() > 0) {
fromDate.clear();
}
fromDate.sendKeys(startDate);
我填的datepicker
之前还有几个inputs
,但是当测试到datepciker
的时候,因为找不到,所以失败了。
如何解决这个问题?
更新
我在上面的代码之前就用过这个方法。
public static void waitUntilVisible(By locator) {
final long startTime = System.currentTimeMillis();
final Duration duration = Duration.ofSeconds(2);
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.pollingEvery(duration)
.ignoring(StaleElementReferenceException.class);
while ((System.currentTimeMillis() - startTime) < 91000) {
try {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
break;
} catch (StaleElementReferenceException e) {
log.info("", e);
}
}
}
由于 <input>
元素是 Angular 元素,因此您必须引入 WebDriverWait 才能使所需的 元素可点击,您可以使用以下任一解决方案:
cssSelector
:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("md-datepicker[ng-model$='from']>span.input-group.date>input.form-control")));
elem.click();
elem.clear();
elem.sendKeys(startDate);
xpath
:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//md-datepicker[contains(@ng-model,'from')]/span[@class='input-group date']/input[@class='form-control']")));
elem.click();
elem.clear();
elem.sendKeys(startDate);
更新
根据你的问题更新函数 waitUntilVisible()
对我来说看起来像是一个纯粹的开销,你正在为 presenceOfElementLocated()
实施 FluentWait 忽略 StaleElementReferenceException,这可以通过定制的 WebDriverWait 和 ExpectedConditions 作为 [=17 轻松实现=].
您可以尝试等待元素的可见性:
WebElement fromDate =
new WebDriverWait(driver, 10)
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("md-datepicker input")));
您可以尝试使用 cssSelector
,不建议使用 xpath 执行 headless
WebElement fromDate = driver.findElement(
By.cssSelector(".input-group.date"))
.findElement(By.cssSelector(".form-control"));
if (fromDate.getAttribute("value").length() > 0) {
fromDate.clear();
}
fromDate.sendKeys(startDate);
我只能通过尝试捕获 StaleElementReferenceException
.
的 catch 块来解决这个问题
WebElement input;
try {
input = driver.findElement(
By.tagName("md-datepicker"))
.findElement(By.tagName("input"));
} catch(StaleElementReferenceException e) {
input = driver.findElement(By.xpath("//md-datepicker/span/input"));
}
if (input.getAttribute("value").length() > 0) {
input.clear();
}
正如我在问题中所述,我使用 waitUntilVisible
方法来等待输入的存在。
我在 2018 年 10 月 29 日问过这个问题。当时我使用的是 selenium 版本 3.14.0
。但是这种方法选择输入也不应该使用 selenium 版本 3.141.0
.
2021 年 9 月 30 日更新
等到元素可点击。
public WebElement getElementWhenClickable(By selector) {
return new WebDriverWait(driver, 60)
.ignoring(StaleElementReferenceException.class)
.until(ExpectedConditions.elementToBeClickable(selector));
}
找到它最近的唯一父级。
WebElement parent = getElementWhenClickable(By.cssSelector("#parent"))
找到输入
WebElement input = parent.findElement(By.cssSelector("md-datepicker[ng-model=\"mc.date.from\"] input"))
<md-datepicker ng-model="mc.date.from" required="" md-val="">
<span class="input-group date" style="width:144px">
<input size="16" type="text"
class="form-control"
autocomplete="off">
<span class="input-group-btn">
<button class="btn btn-default" tabindex="-1" >
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</span>
</md-datepicker>
我有一个 AngularJs 组件,其中包含类型 text
的 input
。我已经使用以下代码输入 date
。当我 运行 无头测试时,它大多数时候都失败了。
WebElement fromDate = driver.findElement(
By.tagName("md-datepicker"))
.findElement(By.tagName("input"));
if (fromDate.getAttribute("value").length() > 0) {
fromDate.clear();
}
fromDate.sendKeys(startDate);
我填的datepicker
之前还有几个inputs
,但是当测试到datepciker
的时候,因为找不到,所以失败了。
如何解决这个问题?
更新
我在上面的代码之前就用过这个方法。
public static void waitUntilVisible(By locator) {
final long startTime = System.currentTimeMillis();
final Duration duration = Duration.ofSeconds(2);
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.pollingEvery(duration)
.ignoring(StaleElementReferenceException.class);
while ((System.currentTimeMillis() - startTime) < 91000) {
try {
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
break;
} catch (StaleElementReferenceException e) {
log.info("", e);
}
}
}
由于 <input>
元素是 Angular 元素,因此您必须引入 WebDriverWait 才能使所需的 元素可点击,您可以使用以下任一解决方案:
cssSelector
:WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("md-datepicker[ng-model$='from']>span.input-group.date>input.form-control"))); elem.click(); elem.clear(); elem.sendKeys(startDate);
xpath
:WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//md-datepicker[contains(@ng-model,'from')]/span[@class='input-group date']/input[@class='form-control']"))); elem.click(); elem.clear(); elem.sendKeys(startDate);
更新
根据你的问题更新函数 waitUntilVisible()
对我来说看起来像是一个纯粹的开销,你正在为 presenceOfElementLocated()
实施 FluentWait 忽略 StaleElementReferenceException,这可以通过定制的 WebDriverWait 和 ExpectedConditions 作为 [=17 轻松实现=].
您可以尝试等待元素的可见性:
WebElement fromDate =
new WebDriverWait(driver, 10)
.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("md-datepicker input")));
您可以尝试使用 cssSelector
,不建议使用 xpath 执行 headless
WebElement fromDate = driver.findElement(
By.cssSelector(".input-group.date"))
.findElement(By.cssSelector(".form-control"));
if (fromDate.getAttribute("value").length() > 0) {
fromDate.clear();
}
fromDate.sendKeys(startDate);
我只能通过尝试捕获 StaleElementReferenceException
.
WebElement input;
try {
input = driver.findElement(
By.tagName("md-datepicker"))
.findElement(By.tagName("input"));
} catch(StaleElementReferenceException e) {
input = driver.findElement(By.xpath("//md-datepicker/span/input"));
}
if (input.getAttribute("value").length() > 0) {
input.clear();
}
正如我在问题中所述,我使用 waitUntilVisible
方法来等待输入的存在。
我在 2018 年 10 月 29 日问过这个问题。当时我使用的是 selenium 版本 3.14.0
。但是这种方法选择输入也不应该使用 selenium 版本 3.141.0
.
2021 年 9 月 30 日更新
等到元素可点击。
public WebElement getElementWhenClickable(By selector) {
return new WebDriverWait(driver, 60)
.ignoring(StaleElementReferenceException.class)
.until(ExpectedConditions.elementToBeClickable(selector));
}
找到它最近的唯一父级。
WebElement parent = getElementWhenClickable(By.cssSelector("#parent"))
找到输入
WebElement input = parent.findElement(By.cssSelector("md-datepicker[ng-model=\"mc.date.from\"] input"))