--
You received this message because you are subscribed to the Google Groups "Serenity BDD Users Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to thucydides-use...@googlegroups.com.
To post to this group, send email to thucydid...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
1. Dynamic wait for AngularJS element using isElementVisible method.
I found a method which is implemented in PageObject.class of serenity BDD library, with help of this method I have performed actions on AngualarJS elements.
In below example, State dropdown is populated depends on Country selected. I need to select particular State from angular dropdown. Here I am iterating for every 300ms until I found the expected angular element.
This is working like a charm for me.
public void selectState(String State) {
boolean isPresent = isElementVisible (By.cssSelector("select[ng-model$='context.state.stateID]"));
boolean isStateFound = false;
for (int i=0; i<=35; ++i) {
System.out.println(i);
if (isPresent==true){
find(selectState).selectByVisibleText(State);
isStateFound= true;
break;
}
waitABit(300);
}
Assert.assertTrue("Unable to find State list in 10 seconds", isPresent);
Assert.assertTrue("The School "+State+ " is not found in the list", isStateFound);
}
2. Use JavascriptExecutor selenium interface to perform actions on AngularJS elements wherever we are unable to locate elements.
JavascriptExecutor jsExecuter = (JavascriptExecutor) driver;
WebElement addItem = driver.findElement(By.xpath("//*[text()='Add Item']"));
jsExecuter.executeScript("arguments[0].click();",addItem);3. Add the following line before calling executeAsyncScript() in waitForAngularRequestsToFinish();
getDriver().manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);Thank you!
public void waitForAngularV1ToFinish(WebDriver driver) {
final String query =
"window.angularFinished;" + "waitForAngular =function() {"
+ " window.angularFinished = false;"
+ " var el = document.querySelector('body');"
+ " var callback = (function(){window.angularFinished=1});"
+ " angular.element(el).injector().get('$browser')."
+ " notifyWhenNoOutstandingRequests(callback);};";
try {
((JavascriptExecutor) driver).executeScript(query);
((JavascriptExecutor) driver).executeScript("waitForAngular()");
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
Object noAjaxRequests = ((JavascriptExecutor) driver).executeScript("return window.angularFinished;");
return "1".equals(noAjaxRequests.toString());
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
} catch (Exception e) {
fail("Unable to load the page correctly");
}
}
public void waitForAngularV2ToFinish(WebDriver driver) {
try {
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return Boolean.valueOf(((JavascriptExecutor) driver).executeScript(
"return (window.angular !== undefined) "
+ "&& (angular.element(document).injector() !== undefined) "
+ "&& (angular.element(document).injector().get('$http').pendingRequests.length === 0)").toString());
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
} catch (Exception e) {
System.out.print(e);
fail("Unable to load the page correctly");
}
}
Note: Angular2 seems to be completely different then 1 and so only the specific wait method will work. The other will timeout. Also if 30 seconds is to much a wait you can change that or pull it out of the method as a parameter