use of com.seleniumtests.uipage.htmlelements.HtmlElement in project seleniumRobot by bhecquet.
the class ReplayAction method replayHtmlElement.
/**
* Replay all HtmlElement actions annotated by ReplayOnError.
* Classes which are not subclass of HtmlElement won't go there
* See javadoc of the annotation for details
* @param joinPoint
* @throws Throwable
*/
@Around("execution(public * com.seleniumtests.uipage.htmlelements.HtmlElement+.* (..))" + "&& execution(@com.seleniumtests.uipage.ReplayOnError public * * (..)) && @annotation(replay)")
public Object replayHtmlElement(ProceedingJoinPoint joinPoint, ReplayOnError replay) throws Throwable {
Object reply = null;
// update driver reference of the element
// corrects bug of waitElementPresent which threw a SessionNotFoundError because driver reference were not
// updated before searching element (it used the driver reference of an old test session)
HtmlElement element = (HtmlElement) joinPoint.getTarget();
element.setDriver(WebUIDriver.getWebDriver(false));
String targetName = joinPoint.getTarget().toString();
Instant end = systemClock.instant().plusSeconds(element.getReplayTimeout());
TestAction currentAction = null;
String methodName = joinPoint.getSignature().getName();
if (!methodName.equals("getCoordinates")) {
List<String> pwdToReplace = new ArrayList<>();
String actionName = String.format("%s on %s %s", methodName, targetName, LogAction.buildArgString(joinPoint, pwdToReplace, new HashMap<>()));
currentAction = new TestAction(actionName, false, pwdToReplace);
}
// order of steps is the right one (first called is first displayed)
if (currentAction != null && TestStepManager.getParentTestStep() != null) {
TestStepManager.getParentTestStep().addAction(currentAction);
}
boolean actionFailed = false;
boolean ignoreFailure = false;
Throwable currentException = null;
try {
while (end.isAfter(systemClock.instant())) {
// in case we have switched to an iframe for using previous webElement, go to default content
if (element.getDriver() != null && SeleniumTestsContextManager.isWebTest()) {
// TODO: error when clic is done, closing current window
element.getDriver().switchTo().defaultContent();
}
try {
reply = joinPoint.proceed(joinPoint.getArgs());
// wait will be done only if action annotation request it
if (replay.waitAfterAction()) {
WaitHelper.waitForMilliSeconds(getActionDelay());
}
break;
} catch (UnhandledAlertException e) {
throw e;
} catch (MoveTargetOutOfBoundsException | InvalidElementStateException e) {
if (element.isScrollToElementBeforeAction()) {
element.setScrollToElementBeforeAction(false);
} else {
element.setScrollToElementBeforeAction(true);
}
} catch (WebDriverException e) {
// only check that cause is the not found element and not an other error (NoSucheSessionError for example)
if ((e instanceof TimeoutException && joinPoint.getSignature().getName().equals("waitForPresent") && // issue #104: do not log error when waitForPresent raises TimeoutException
e.getCause() instanceof NoSuchElementException) || (e instanceof NotFoundException && // issue #194: return immediately if the action has been performed from ExpectedConditions class
isFromExpectedConditions(Thread.currentThread().getStackTrace()))) // This way, we let the FluentWait process to retry or re-raise the exception
{
ignoreFailure = true;
throw e;
}
if (end.minusMillis(replay.replayDelayMs() + 100L).isAfter(systemClock.instant())) {
WaitHelper.waitForMilliSeconds(replay.replayDelayMs());
} else {
if (e instanceof NoSuchElementException) {
throw new NoSuchElementException(String.format("Searched element [%s] from page '%s' could not be found", element, element.getOrigin()));
} else if (e instanceof UnreachableBrowserException) {
throw new WebDriverException("Browser did not reply, it may have frozen");
}
throw e;
}
}
}
return reply;
} catch (Throwable e) {
if (e instanceof NoSuchElementException && joinPoint.getTarget() instanceof HtmlElement && (joinPoint.getSignature().getName().equals("findElements") || joinPoint.getSignature().getName().equals("findHtmlElements"))) {
return new ArrayList<WebElement>();
} else {
if (!ignoreFailure) {
actionFailed = true;
currentException = e;
}
throw e;
}
} finally {
if (currentAction != null && TestStepManager.getParentTestStep() != null) {
currentAction.setFailed(actionFailed);
scenarioLogger.logActionError(currentException);
}
// restore element scrolling flag for further uses
element.setScrollToElementBeforeAction(false);
}
}
use of com.seleniumtests.uipage.htmlelements.HtmlElement in project seleniumRobot by bhecquet.
the class ReplayAction method updateScrollFlagForElement.
/**
* Updates the scrollToelementBeforeAction flag of HtmlElement for CompositeActions
* Therefore, it looks at origin field of PointerInput$Move CompositeAction and update the flag
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void updateScrollFlagForElement(ProceedingJoinPoint joinPoint, Boolean forcedValue, WebDriverException parentException) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Object actions = joinPoint.getTarget();
// Only the later case is covered here
if (!actions.getClass().toString().contains("BuiltAction")) {
return;
}
Field sequencesField = actions.getClass().getDeclaredField("sequences");
sequencesField.setAccessible(true);
Map<InputSource, Sequence> sequences = (Map<InputSource, Sequence>) sequencesField.get(actions);
for (Sequence sequence : sequences.values()) {
Field actionsField = Sequence.class.getDeclaredField("actions");
actionsField.setAccessible(true);
LinkedList<Interaction> actionsList = (LinkedList<Interaction>) actionsField.get(sequence);
for (Interaction action : actionsList) {
if (action.getClass().getName().contains("PointerInput$Move")) {
Field originField = action.getClass().getDeclaredField("origin");
originField.setAccessible(true);
try {
PointerInput.Origin origin = (PointerInput.Origin) originField.get(action);
// so that it can be treated elsewhere (mainly inside replayHtmlElement())
if (origin.asArg() instanceof HtmlElement) {
HtmlElement element = (HtmlElement) origin.asArg();
if (forcedValue == null) {
if (element.isScrollToElementBeforeAction()) {
element.setScrollToElementBeforeAction(false);
} else {
element.setScrollToElementBeforeAction(true);
}
} else {
element.setScrollToElementBeforeAction(forcedValue);
}
} else if (origin.asArg() instanceof RemoteWebElement && parentException != null) {
throw parentException;
}
} catch (ClassCastException e1) {
// nothing
}
}
}
}
}
use of com.seleniumtests.uipage.htmlelements.HtmlElement in project seleniumRobot by bhecquet.
the class SeleniumNativeActions method interceptPageFactoryElementLocation.
/**
* Intercept "findElement" action done in LocatingElementHandler class so that we can override returned element and replace it by HtmlElement
* This helps handling PageObjectFactory method
* @param joinPoint
* @return
* @throws Throwable
*/
@Around(" this(org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler) && call(public * org.openqa.selenium.support.pagefactory.ElementLocator+.findElement (..))")
public Object interceptPageFactoryElementLocation(ProceedingJoinPoint joinPoint) throws Throwable {
if (Boolean.TRUE.equals(doOverride())) {
DefaultElementLocator locator = ((DefaultElementLocator) joinPoint.getTarget());
Field byField = DefaultElementLocator.class.getDeclaredField("by");
byField.setAccessible(true);
return new HtmlElement("", (By) byField.get(locator), getCurrentFrame());
} else {
return joinPoint.proceed(joinPoint.getArgs());
}
}
use of com.seleniumtests.uipage.htmlelements.HtmlElement in project seleniumRobot by bhecquet.
the class SeleniumNativeActions method getFrameElement.
/**
* Returns a FrameElement based on the object passed in argument
* @param frameArg
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private FrameElement getFrameElement(Object frameArg) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
FrameElement frameEl = null;
if (frameArg instanceof HtmlElement) {
frameEl = new FrameElement("", ((HtmlElement) frameArg).getBy());
} else if (frameArg instanceof WebElement && frameArg.getClass().getName().contains("Proxy")) {
LocatingElementHandler locatingEh = (LocatingElementHandler) Proxy.getInvocationHandler(frameArg);
Field locatorField = LocatingElementHandler.class.getDeclaredField("locator");
locatorField.setAccessible(true);
DefaultElementLocator locator = ((DefaultElementLocator) locatorField.get(locatingEh));
Field byField = DefaultElementLocator.class.getDeclaredField("by");
byField.setAccessible(true);
frameEl = new FrameElement("", (By) byField.get(locator));
} else if (frameArg instanceof By) {
frameEl = new FrameElement("", (By) frameArg);
} else if (frameArg instanceof Integer) {
frameEl = new FrameElement("", By.tagName("iframe"), (Integer) frameArg);
} else if (frameArg instanceof String) {
String name = ((String) frameArg).replaceAll("(['\"\\\\#.:;,!?+<>=~*^$|%&@`{}\\-/\\[\\]\\(\\)])", "\\\\$1");
frameEl = new FrameElement("", By.cssSelector("frame[name='" + name + "'],iframe[name='" + name + "'],frame#" + name + ",iframe#" + name));
}
return frameEl;
}
use of com.seleniumtests.uipage.htmlelements.HtmlElement in project seleniumRobot by bhecquet.
the class TestDriver method testSearchDoneSeveralTimes.
public void testSearchDoneSeveralTimes() {
SeleniumTestsContextManager.getThreadContext().setReplayTimeout(7);
long start = new Date().getTime();
try {
new HtmlElement("", By.id("someNonExistentId")).getText();
} catch (NoSuchElementException e) {
}
// Check we wait at least for the timeout set
Assert.assertTrue(new Date().getTime() - start > 6500);
}
Aggregations