Created
December 15, 2020 19:39
-
-
Save rgpower/ff0fcadaa3b95a2d1634838c763ee990 to your computer and use it in GitHub Desktop.
A Junit5 Extension that automagically sets BrowserStack sessions to pass/fail for Browser Automation Tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implements the Browserstack API for setting test sessions to pass/fail status as desribed in | |
* https://www.browserstack.com/docs/automate/selenium/view-test-results/mark-tests-as-pass-fail | |
* | |
**/ | |
package utils.browserstack; | |
import com.google.gson.Gson; | |
import org.apache.http.HttpEntity; | |
import org.apache.http.HttpResponse; | |
import org.apache.http.auth.AuthScope; | |
import org.apache.http.auth.UsernamePasswordCredentials; | |
import org.apache.http.client.CredentialsProvider; | |
import org.apache.http.client.entity.EntityBuilder; | |
import org.apache.http.client.methods.HttpPut; | |
import org.apache.http.client.utils.HttpClientUtils; | |
import org.apache.http.impl.client.BasicCredentialsProvider; | |
import org.apache.http.impl.client.CloseableHttpClient; | |
import org.apache.http.impl.client.HttpClientBuilder; | |
import java.io.IOException; | |
public class Browserstack { | |
public static UsernamePasswordCredentials getCredentials() { | |
UsernamePasswordCredentials creds = null; | |
String browserstackCreds = System.getenv("BROWSERSTACK_CREDS"); | |
if (browserstackCreds != null && !"".equals(browserstackCreds)) { | |
String[] envCreds = browserstackCreds.split(":"); | |
if (envCreds.length == 2) { | |
creds = new UsernamePasswordCredentials(envCreds[0], envCreds[1]); | |
} else { | |
throw new IllegalArgumentException("BROWSERSTACK_CREDS env value must be of form user:key"); | |
} | |
} | |
return creds; | |
} | |
public static void setPassed(String sessionId, String reason) { | |
StatusUpdate passed = new StatusUpdate(); | |
passed.status = "passed"; | |
passed.reason = reason; | |
updateTestStatus(sessionId, passed); | |
} | |
public static void setFailed(String sessionId, String reason) { | |
StatusUpdate failed = new StatusUpdate(); | |
failed.status = "failed"; | |
failed.reason = reason; | |
updateTestStatus(sessionId, failed); | |
} | |
private static void updateTestStatus(String sessionId, StatusUpdate statusUpdate) { | |
UsernamePasswordCredentials credentials = getCredentials(); | |
if (credentials != null) { | |
CredentialsProvider browserStackCreds = new BasicCredentialsProvider(); | |
browserStackCreds.setCredentials(AuthScope.ANY, credentials); | |
String jsonText = new Gson().toJson(statusUpdate, StatusUpdate.class); | |
HttpEntity payload = EntityBuilder.create().setText(jsonText).build(); | |
HttpPut request = new HttpPut(String.format("https://api.browserstack.com/automate/sessions/%s.json", sessionId)); | |
request.setHeader("Content-Type", "application/json"); | |
request.setEntity(payload); | |
CloseableHttpClient client = null; | |
HttpResponse response = null; | |
try { | |
client = HttpClientBuilder.create().setDefaultCredentialsProvider(browserStackCreds).build(); | |
response = client.execute(request); | |
if (200 != response.getStatusLine().getStatusCode()) { | |
throw new RuntimeException("Unable thenTo set browserstack status for sessionId=" + sessionId); | |
} | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} finally { | |
HttpClientUtils.closeQuietly(response); | |
HttpClientUtils.closeQuietly(client); | |
} | |
} | |
} | |
static class StatusUpdate { | |
String status; | |
String reason; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* To use, modify your JUnit 5-based Browser Automation Test Class to use the JUnit5 Extension and | |
* provide the extension with access to your (WebDriver etc) session info by implementing | |
* the BrowserstackStatusUpdateable interface and using the ExtendWith annotation | |
* | |
* This implementation depends on Junit5, Apache HTTP Client, and Google Gson | |
* | |
* | |
* @ExtendWith(BrowserstackStatusUpdater.class) | |
* public class JUnitSeleniumTest implements BrowserstackStatusUpdateable { | |
* ... | |
* @Override | |
* public String getSessionID() { | |
* return this.webDriver.getSessionId().toString(); | |
* } | |
* | |
**/ | |
package utils.browserstack; | |
public interface BrowserstackStatusUpdateable { | |
String getSessionID(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Note that this JUnit5 Extension relies on Browserstack class, and configuration of enviroment variable | |
* BROWSERSTACK_CREDS which will contain the username:password of your BrowserStack Automation credentials | |
* | |
**/ | |
package utils.browserstack; | |
import org.junit.jupiter.api.extension.AfterEachCallback; | |
import org.junit.jupiter.api.extension.ExtensionContext; | |
import java.util.Optional; | |
public class BrowserstackStatusUpdater implements AfterEachCallback { | |
@Override | |
public void afterEach(ExtensionContext context) { | |
Optional testInstance = context.getTestInstance(); | |
if (testInstance.isPresent()) { | |
Object o = testInstance.get(); | |
if (o instanceof BrowserstackStatusUpdateable) { | |
BrowserstackStatusUpdateable test = (BrowserstackStatusUpdateable) o; | |
String sessionId = test.getSessionID(); | |
Optional<Throwable> exception = context.getExecutionException(); | |
String displayName = context.getDisplayName(); | |
if (exception.isPresent()) { | |
Throwable t = exception.get(); | |
Browserstack.setFailed(sessionId, displayName + ": " + t.getMessage()); | |
} else { | |
Browserstack.setPassed(sessionId, displayName); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment