package example.domain.web.nodriver;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Browser {
private String currentURI;
public String currentURI() {
return currentURI;
}
public <T> T get(String requestURI, Class<T> pageClass) {
return send(new MockHttpServletRequest("GET", requestURI), pageClass);
}
public <T> T send(MockHttpServletRequest request, Class<T> pageClass) {
try {
MockHttpServletResponse response = sendRequest(request, 0);
return createPage(pageClass, response);
} catch (Exception e) {
handleException(e);
return null;
}
}
private MockHttpServletResponse sendRequest(MockHttpServletRequest request, int requestCount) throws Exception {
if (requestCount > 5) {
throw new IllegalStateException("Too many redirects to " + request.getRequestURI());
}
currentURI = request.getRequestURI();
MockHttpServletResponse response = SpringDispatcherServlet.create().process(request);
String redirect = response.getRedirectedUrl();
if (redirect != null) {
response = sendRequest(new MockHttpServletRequest("GET", redirect), requestCount + 1);
}
return response;
}
private <T> T createPage(Class<T> pageClass, MockHttpServletResponse response) throws Exception {
HtmlPage htmlPage = new HtmlPage(response, this);
Constructor<T> constructor = pageClass.getConstructor(htmlPage.getClass());
return constructor.newInstance(htmlPage);
}
private void handleException(Throwable ex) {
if (ex instanceof InvocationTargetException) {
handleException(ex.getCause());
} else if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
} else if (ex instanceof Error) {
throw (Error) ex;
} else {
throw new RuntimeException(ex);
}
}
}