}
@Override
public Object execute(GrapheneContext context, JSCall call) {
ExtendedGrapheneContext c = (ExtendedGrapheneContext) context;
// check name
JSInterface target = call.getTarget();
if (target.getName() == null) {
throw new IllegalStateException("Can't use " + this.getClass() + " for " + target.getInterface() + ", because the @JavaScript annotation doesn't define non empty value()");
}
// register page extension
registerExtension(c.getPageExtensionRegistry(), target);
// try to execute javascript, if fails install the extension
final long LIMIT = context.getConfiguration().getJavascriptInstallationLimit();
for (long i=1; i<=5; i++) {
try {
// execute javascript
Object returnValue = executeScriptForCall((JavascriptExecutor) context.getWebDriver(JavascriptExecutor.class), call);
Object castedResult = castResult(call, returnValue);
return castedResult;
} catch (RuntimeException e) {
// if the limit is reached -> FAIL
if (i == LIMIT) {
throw new IllegalStateException("Can't invoke the javacript " + call.getTarget().getInterface().getName() + "#" + call.getMethod().getMethod().getName() + "()", e);
// try to install the extension
} else {
try {
c.getPageExtensionInstallatorProvider().installator(target.getName()).install();
} catch (RuntimeException ignored) {
}
}
}
}