Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.testfabrik.webmate.javasdk.browsersession;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.testfabrik.webmate.javasdk.*;
import com.testfabrik.webmate.javasdk.commonutils.HttpHelpers;
import com.testfabrik.webmate.javasdk.utils.JsonUtils;
import org.apache.http.HttpResponse;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.*;
/**
* Facade to webmate's BrowserSession subsystem.
*/
public class BrowserSessionClient {
private WebmateAPISession session;
private BrowserSessionApiClient apiClient;
private Stack currentSpanIds = new Stack<>();
private static final Logger LOG = LoggerFactory.getLogger(BrowserSessionClient.class);
// Sane default Config, extracting DOM and taking non fullpage Screenshots. Otherwise take Webmate Defaults.
private static final BrowserSessionStateExtractionConfig DefaultStateExtractionConfig = new BrowserSessionStateExtractionConfig(null, null, null, null, null, true,
new BrowserSessionScreenshotExtractionConfig(true, false), null);
public interface ActionFunc {
T op(ActionDelegate action);
}
public interface ActionFuncVoid {
void op(ActionDelegate action);
}
public static class ActionDelegate {
private final BrowserSessionClient client;
public ActionDelegate(BrowserSessionClient client) {
this.client = client;
}
/**
* Finish current action successfully.
*/
public void finishAction() {
this.client.finishAction();
}
/**
* Finish current action as failure.
*/
public void finishActionAsFailure(String errorMessage) {
this.client.finishActionAsFailure(errorMessage);
}
}
private static class BrowserSessionApiClient extends WebmateApiClient {
private final static UriTemplate createStateTemplate =
new UriTemplate("/browsersession/${browserSessionId}/states");
private final static UriTemplate checkStateProgressTemplate =
new UriTemplate("/browsersession/${browserSessionId}/artifacts/${browserSessionArtifactId}/progress");
private final static UriTemplate addArtifactTemplate =
new UriTemplate("/browsersession/${expeditionId}/artifacts");
private final static UriTemplate terminateBrowsersessionTemplate =
new UriTemplate("/browsersession/${browserSessionId}");
/**
* Creates an webmate api client.
*
* @param authInfo The authentication information needed for the API interaction
* @param environment The environment the client should be used in, i.e which urls to use for communication
*/
public BrowserSessionApiClient(WebmateAuthInfo authInfo, WebmateEnvironment environment) {
super(authInfo, environment);
}
/**
* Creates an webmate api client using a custom HttpClientBuilder, which allows the use of proxies.
*
* @param authInfo The authentication information needed for the API interaction
* @param environment The environment the client should be used in, i.e which urls to use for communication
* @param httpClientBuilder The HttpClientBuilder that is used for the underlying connection.
*/
public BrowserSessionApiClient(WebmateAuthInfo authInfo, WebmateEnvironment environment, HttpClientBuilder httpClientBuilder) {
super(authInfo, environment, httpClientBuilder);
}
/**
* Tries to terminate a Browsersession. Will return whether the process was successful or not.
*
* @param browserSessionId The id of the session that should be terminated
* @return true, if the Browersession was terminated successfully.
*/
public boolean terminateSession(BrowserSessionId browserSessionId) {
Optional r = sendPOST(terminateBrowsersessionTemplate, ImmutableMap.of("browserSessionId", browserSessionId.toString()), "terminate").getOptHttpResponse();
boolean stopped = false;
if (!r.isPresent()){
throw new WebmateApiClientException("Could not stop Browsersession. Got no response");
}
else {
try {
stopped = EntityUtils.toString(r.get().getEntity()).equals("true");
} catch (IOException e) {
LOG.error("Failed to read response:", e);
}
}
return stopped;
}
/**
* Creates a State for a Browsersession with a matching id. The extraction parameters are set to default.
*
* @param browserSessionId The Browsersession Id for which the state should be associated with.
* @param matchingId The Id for the state. Used for matching.
*/
public BrowserSessionStateId createState(BrowserSessionId browserSessionId, String matchingId, BrowserSessionStateExtractionConfig browserSessionStateExtractionConfig) {
Map params = ImmutableMap.of("optMatchingId", matchingId, "extractionConfig", browserSessionStateExtractionConfig);
JsonNode body = JsonUtils.getJsonFromData(params, JsonInclude.Include.NON_NULL);
Optional optHttpResponse = sendPOST(createStateTemplate, ImmutableMap.of("browserSessionId", browserSessionId.toString()), body).getOptHttpResponse();
return HttpHelpers.getObjectFromJsonEntity(optHttpResponse.get(), BrowserSessionStateId.class);
}
public void startAction(BrowserSessionId expeditionId, StartStoryActionAddArtifactData art) {
Map params = ImmutableMap.of("expeditionId", expeditionId.getValueAsString());
sendPOST(addArtifactTemplate, params, JsonUtils.getJsonFromData(art)).getOptHttpResponse();
}
public void finishAction(BrowserSessionId expeditionId, FinishStoryActionAddArtifactData art) {
Map params = ImmutableMap.of("expeditionId", expeditionId.getValueAsString());
sendPOST(addArtifactTemplate, params, JsonUtils.getJsonFromData(art)).getOptHttpResponse();
}
}
/**
* Creates a BrowserSessionClient based on a WebmateApiSession.
*
* @param session The WebmateApiSession the BrowserSessionClient is supposed to be based on
*/
public BrowserSessionClient(WebmateAPISession session) {
this.session = session;
this.apiClient = new BrowserSessionApiClient(session.authInfo, session.environment);
}
/**
* Creates a BrowserSessionClient based on a WebmateApiSession and a custom HttpClientBuilder.
*
* @param session The WebmateApiSession the BrowserSessionClient is supposed to be based on
* @param httpClientBuilder The HttpClientBuilder that is used for building the underlying connection
*/
public BrowserSessionClient(WebmateAPISession session, HttpClientBuilder httpClientBuilder) {
this.session = session;
this.apiClient = new BrowserSessionApiClient(session.authInfo, session.environment, httpClientBuilder);
}
/**
* Return the webmate BrowserSessionId for a given Selenium session running in webmate.
*
* @param opaqueSeleniumSessionIdString Selenium SessionId that can be obtained by calling WebDriver.getSessionId().toString().
* @return BrowserSessionRef that can be used to interact with the BrowserSession
*/
public BrowserSessionRef getBrowserSessionForSeleniumSession(String opaqueSeleniumSessionIdString) {
// it seems that currently the BrowserSessionId is equal to the Selenium SessionId (which I would consider a bug)
return new BrowserSessionRef(new BrowserSessionId(UUID.fromString(opaqueSeleniumSessionIdString)), session);
}
/**
* Create a new State for the BrowserSession registered in webmate session (there must be only one).
*
* @param matchingId Label for state (should be unique for BrowserSession, otherwise some tests could get confused).
* @param browserSessionStateExtractionConfig configuration controlling the state extraction process. See {@link BrowserSessionStateExtractionConfig}.
* @throws WebmateApiClientException if an error occurs while requesting state extraction or if the timeout is exceeded.
*/
public BrowserSessionStateId createState(String matchingId, BrowserSessionStateExtractionConfig browserSessionStateExtractionConfig) {
List associatedExpeditions = session.getAssociatedExpeditions();
if (associatedExpeditions.size() != 1) {
throw new WebmateApiClientException("If createState is called without browsersession id, there must be only one " +
"BrowserSession associated with the API session (to be able to identify the correct one) " +
"but currently there are " + associatedExpeditions.size());
}
BrowserSessionId browserSessionId = associatedExpeditions.get(0);
LOG.info("Creating state for browsersession " + browserSessionId);
return createState(browserSessionId, matchingId, browserSessionStateExtractionConfig);
}
/**
* Create a new State for the BrowserSession registered in webmate session (there must be only one). Uses defaults for timeout and
* state extraction configuration.
*
* @param matchingId Label for state (should be unique for BrowserSession, otherwise some tests could get confused).
* @throws WebmateApiClientException if an error occurs while requesting state extraction or if the timeout is exceeded.
*/
public BrowserSessionStateId createState(String matchingId) {
List associatedExpeditions = session.getAssociatedExpeditions();
if (associatedExpeditions.size() != 1) {
throw new WebmateApiClientException("If createState is called without browsersession id, there must be only one " +
"BrowserSession associated with the API session (to be able to identify the correct one) " +
"but currently there are " + associatedExpeditions.size());
}
BrowserSessionId browserSessionId = associatedExpeditions.get(0);
LOG.info("Creating state for browsersession " + browserSessionId);
return createState(browserSessionId, matchingId);
}
/**
* Create a new State for the given BrowserSession.
*
* @param browserSessionId BrowserSession, in which the state should be extracted.
* @param matchingId Label for state (should be unique for BrowserSession, otherwise some tests could get confused).
* @throws WebmateApiClientException if an error occurs while requesting state extraction or if the timeout is exceeded.
*/
public BrowserSessionStateId createState(BrowserSessionId browserSessionId, String matchingId) {
return createState(browserSessionId, matchingId, DefaultStateExtractionConfig);
}
/**
* Create a new State for the given BrowserSession.
*
* @param browserSessionId BrowserSession, in which the state should be extracted.
* @param matchingId Label for state (should be unique for BrowserSession, otherwise some tests could get confused).
* @param browserSessionStateExtractionConfig configuration controlling the state extraction process. See {@link BrowserSessionStateExtractionConfig}.
* @throws WebmateApiClientException if an error occurs while requesting state extraction or if the timeout is exceeded.
*/
public BrowserSessionStateId createState(BrowserSessionId browserSessionId, String matchingId, BrowserSessionStateExtractionConfig browserSessionStateExtractionConfig) {
LOG.debug("Creating state with matching id [" + matchingId + "] for browsersession [" + browserSessionId + "]");
return apiClient.createState(browserSessionId, matchingId, browserSessionStateExtractionConfig);
}
/**
* Wrap the given action (lambda) in an Action with the given name. The action can be
* closed explicitly with the ActionDelegate argument provided to the lambda. It also
* implicitly finishes as successful or an error if an exception is throws within the lambda.
*
* @param actionName Name of action
* @param actionFunc function executed within action.
* @param Return value of inner code.
* @return Returned value of lambda
*/
public T withAction(String actionName, ActionFunc actionFunc) {
this.startAction(actionName);
ActionDelegate actionDelegate = new ActionDelegate(this);
T result = null;
try {
result = actionFunc.op(actionDelegate);
} catch (Throwable e) {
this.finishActionAsFailureIgnoreNoneActive("Exception in '" + actionName + "': " + e.getMessage());
} finally {
this.finishActionAsSuccessIgnoreNoneActive();
}
return result;
}
/**
* Wrap the given action (lambda) in an Action with the given name. The action can be
* closed explicitly with the ActionDelegate argument provided to the lambda. It also
* implicitly finishes as successful or an error if an exception is throws within the lambda.
*
* @param actionName Name of action
* @param actionFunc function executed within action.
*/
public void withAction(String actionName, ActionFuncVoid actionFunc) {
this.startAction(actionName);
ActionDelegate actionDelegate = new ActionDelegate(this);
try {
actionFunc.op(actionDelegate);
} catch (Throwable e) {
this.finishActionAsFailureIgnoreNoneActive("Exception in '" + actionName + "': " + e.getMessage());
} finally {
this.finishActionAsSuccessIgnoreNoneActive();
}
}
/**
* Start action with the given name.
*/
public void startAction(String actionName) {
LOG.debug("Start action " + actionName);
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
ActionSpanId spanId = new ActionSpanId(UUID.randomUUID());
StartStoryActionAddArtifactData artifactData = new StartStoryActionAddArtifactData(actionName, spanId);
apiClient.startAction(expeditionId, artifactData);
this.currentSpanIds.push(spanId);
}
/**
* Finish the currently active Action and provide a success message.
*
* @param successMessage message that should be added to the action
* @throws WebmateApiClientException if no action is active
*/
public void finishAction(String successMessage) {
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
if (this.currentSpanIds.isEmpty()) {
throw new WebmateApiClientException("Trying to finish action but none is active.");
}
ActionSpanId spanId = this.currentSpanIds.pop();
apiClient.finishAction(expeditionId, FinishStoryActionAddArtifactData.successful(spanId, successMessage));
}
public void finishAction() {
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
if (this.currentSpanIds.isEmpty()) {
throw new WebmateApiClientException("Trying to finish action but none is active.");
}
ActionSpanId spanId = this.currentSpanIds.pop();
apiClient.finishAction(expeditionId, FinishStoryActionAddArtifactData.successful(spanId));
}
/**
* Finish the currently active Action. Do nothing if there is no active action.
*/
public void finishActionAsSuccessIgnoreNoneActive() {
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
if (this.currentSpanIds.isEmpty()) {
// we don't care
return;
}
ActionSpanId spanId = this.currentSpanIds.pop();
apiClient.finishAction(expeditionId, FinishStoryActionAddArtifactData.successful(spanId));
}
/**
* Finish the currently active Action and mark is as failed. Do nothing if there is no active action.
*
* @param errorMessage Error message indicating why this action has failed.
*/
public void finishActionAsFailureIgnoreNoneActive(String errorMessage) {
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
if (this.currentSpanIds.isEmpty()) {
// we don't care
return;
}
ActionSpanId spanId = this.currentSpanIds.pop();
apiClient.finishAction(expeditionId, FinishStoryActionAddArtifactData.failure(spanId, errorMessage, Optional.absent()));
}
/**
* Finish the currently active Action and mark it as failure.
*
* @param errorMessage Error message indicating why this action has failed.
* @throws WebmateApiClientException if no action is active
*/
public void finishActionAsFailure(String errorMessage) {
BrowserSessionId expeditionId = session.getOnlyAssociatedExpedition();
if (this.currentSpanIds.isEmpty()) {
throw new WebmateApiClientException("Trying to finish action but none is active.");
}
ActionSpanId spanId = this.currentSpanIds.pop();
apiClient.finishAction(expeditionId, FinishStoryActionAddArtifactData.failure(spanId, errorMessage, Optional.absent()));
}
/**
* Terminate the given BrowserSession
*
* @param browserSessionId The Id for the BrowserSession that is supposed to be terminated
* @return true if the Browsersession was successfully terminated
*/
public boolean terminateBrowsersession(BrowserSessionId browserSessionId) {
LOG.debug("Trying to terminate Browsersession with id ["+ browserSessionId +"]");
return apiClient.terminateSession(browserSessionId);
}
}