JsWebElementProxyBuilderResolver.java
package io.github.giulong.spectrum.extensions.resolvers;
import io.github.giulong.spectrum.utils.Configuration;
import io.github.giulong.spectrum.utils.js.Js;
import io.github.giulong.spectrum.utils.js.JsWebElementInvocationHandler;
import io.github.giulong.spectrum.utils.js.JsWebElementProxyBuilder;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver;
import org.openqa.selenium.WebElement;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;
import static io.github.giulong.spectrum.extensions.resolvers.ConfigurationResolver.CONFIGURATION;
import static io.github.giulong.spectrum.extensions.resolvers.JsResolver.JS;
import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL;
@Slf4j
public class JsWebElementProxyBuilderResolver extends TypeBasedParameterResolver<JsWebElementProxyBuilder> {
public static final String JS_WEB_ELEMENT_PROXY_BUILDER = "jsWebElementProxyBuilder";
@Override
public JsWebElementProxyBuilder resolveParameter(final ParameterContext arg0, final ExtensionContext context) {
final ExtensionContext.Store rootStore = context.getRoot().getStore(GLOBAL);
final ExtensionContext.Store store = context.getStore(GLOBAL);
log.debug("Resolving {}", JS_WEB_ELEMENT_PROXY_BUILDER);
final Configuration configuration = rootStore.get(CONFIGURATION, Configuration.class);
final List<Method> remainingJsMethods = new ArrayList<>(Arrays.asList(JsWebElementInvocationHandler.class.getDeclaredMethods()));
final List<Method> remainingWebElementMethods = new ArrayList<>(Arrays.asList(WebElement.class.getDeclaredMethods()));
final Map<Method, Method> methods = new HashMap<>(remainingWebElementMethods.size());
do {
final Method webElementMethod = remainingWebElementMethods.getFirst();
final Method jsMethod = remainingJsMethods
.stream()
.filter(method -> methodsEqual(webElementMethod, method))
.findFirst()
.orElseThrow();
methods.put(webElementMethod, jsMethod);
remainingJsMethods.remove(jsMethod);
remainingWebElementMethods.remove(webElementMethod);
} while (!remainingWebElementMethods.isEmpty());
final JsWebElementProxyBuilder jsWebElementProxyBuilder = JsWebElementProxyBuilder
.builder()
.js(store.get(JS, Js.class))
.locatorPattern(Pattern.compile(configuration.getExtent().getLocatorRegex()))
.methods(methods)
.build();
store.put(JS_WEB_ELEMENT_PROXY_BUILDER, jsWebElementProxyBuilder);
return jsWebElementProxyBuilder;
}
boolean methodsEqual(final Method m1, final Method m2) {
final boolean result = m1.getName().equals(m2.getName()) &&
m1.getReturnType().equals(m2.getReturnType()) &&
Arrays.equals(m1.getParameterTypes(), m2.getParameterTypes());
log.trace("Checking if {} binds to {}: {}", m1.getName(), m2.getName(), result);
return result;
}
}