Skip to content

Commit

Permalink
Merge pull request #11 from browserstack/develop
Browse files Browse the repository at this point in the history
Merging develop into master.
  • Loading branch information
Anirudha Khanna authored Jun 30, 2016
2 parents 83d91b5 + 4ba3223 commit 3605509
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 1 deletion.
2 changes: 1 addition & 1 deletion browserstack-teamcity-agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>browserstack-teamcity</artifactId>
<groupId>com.browserstack</groupId>
<version>1.0-SNAPSHOT</version>
<version>1.0.0</version>
</parent>

<artifactId>browserstack-teamcity-agent</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
import java.util.Map;
import java.util.regex.Pattern;


/**
* Component that runs on the Agent side.
* Setups and tears down BrowserStackLocal, if configured.
* Also responsible for copying report files into artifacts after build completion.
*/
public class BrowserStackLocalAgent extends AgentLifeCycleAdapter {
private static final String REPORT_FILE_PATTERN = "**/browserstack-reports/REPORT-*.xml";

Expand Down Expand Up @@ -93,6 +99,8 @@ public void runnerFinished(@NotNull BuildRunnerContext runner, @NotNull BuildFin
killLocal(build);
}

// find and collect report files that match our Ant pattern
// if found, artifacts are published to the artifact directory by appending "=> <path>"
List<File> reportFiles = new ArrayList<File>();
FileUtil.collectMatchedFiles(build.getCheckoutDirectory(),
Pattern.compile(FileUtil.convertAntToRegexp(REPORT_FILE_PATTERN)),
Expand All @@ -110,6 +118,11 @@ public void buildFinished(@NotNull AgentRunningBuild build, @NotNull BuildFinish
}
}

/**
* Loads the build feature for the current build and checks if BrowserStackLocal is enabled
*
* @param build Current build.
*/
private void loadBuildFeature(final AgentRunningBuild build) {
Collection<AgentBuildFeature> buildFeatures = build.getBuildFeaturesOfType(BrowserStackParameters.BUILD_FEATURE_TYPE);
isEnabled = !buildFeatures.isEmpty();
Expand All @@ -121,6 +134,12 @@ private void loadBuildFeature(final AgentRunningBuild build) {
}
}

/**
* Adds environment variables to the build environment.
*
* @param runner Represents current build runner.
* @param config
*/
private void exportEnvVars(final BuildRunnerContext runner, final Map<String, String> config) {
if (!config.containsKey(EnvVars.BROWSERSTACK_USER) || !config.containsKey(EnvVars.BROWSERSTACK_ACCESSKEY)) {
return;
Expand All @@ -145,6 +164,12 @@ private void exportEnvVars(final BuildRunnerContext runner, final Map<String, St
buildLogger.message(EnvVars.BROWSERSTACK_BUILD + "=" + buildId);
}

/**
* Returns a unique Build Id for the currently running build.
*
* @param runner Represents current build runner.
* @return String Unique build Id.
*/
private static String getBuildId(final BuildRunnerContext runner) {
return runner.getBuild().getBuildTypeName() +
"-" +
Expand All @@ -153,6 +178,11 @@ private static String getBuildId(final BuildRunnerContext runner) {
runner.getBuild().getBuildNumber();
}

/**
* Terminates the BrowserStackLocal binary.
*
* @param build Represents running build on the agent side.
*/
private void killLocal(final AgentRunningBuild build) {
if (browserstackLocal != null) {
BuildProgressLogger buildLogger = build.getBuildLogger();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
import java.io.InputStream;
import java.util.List;

/**
* Implementation of BrowserStackLocal for TeamCity.
* Overrides the default {@link ProcessBuilder} APIs to use TeamCity APIs for launching binaries on the command-line.
*/
public class TeamCityBrowserStackLocal extends BrowserStackLocal {
private final BuildProgressLogger buildLogger;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.Map;

/**
* Exposes a JSON API for the frontend to record the iframe load time.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import java.io.File;

/**
* Provides data for Analytics to gather and submit.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
import java.util.HashMap;
import java.util.Map;

/**
* Configuration for the "BrowserStack" build feature for each project.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
public class AutomateBuildFeature extends BuildFeature {

private static final String ERR_INVALID_PATH = "Invalid path";
Expand Down Expand Up @@ -55,6 +61,13 @@ public boolean isMultipleFeaturesPerBuildTypeAllowed() {
return false;
}

/**
* Returns parameters description of the build feature, will be used in the TeamCity UI to
* describe this feature settings. Can contain HTML, so please make sure it is safe in terms of XSS.
*
* @param params parameters to describe
* @return short description of parameters.
*/
@NotNull
@Override
public String describeParameters(@NotNull Map<String, String> params) {
Expand All @@ -78,10 +91,17 @@ public Map<String, String> getDefaultParameters() {
defaults = new HashMap<String, String>();
}

// Analytics are enabled by default
defaults.put(BrowserStackParameters.ENABLE_ANALYTICS, "true");
return defaults;
}

/**
* Checks if the "BrowserStack" build feature has been added to the given build.
*
* @param build
* @return
*/
@Nullable
@Override
public PropertiesProcessor getParametersProcessor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import java.util.Map;

/**
* Tracks the events occurring at the build server.
* Mainly used for Analytics.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
import java.util.regex.Pattern;

/**
* Controller for the "BrowserStack" tab displayed in the UI with test results.
* This handles both views: the list of test cases and the iframe for a single test.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
Expand Down Expand Up @@ -157,6 +160,8 @@ public Continuation processBuildArtifact(@NotNull BuildArtifact artifact) {
if (results != null) {
for (Element elem : results) {
String testCaseId = elem.getAttribute("id").getValue();

// Checks if test case in our report exists in test report XMLs parsed by TeamCity
if (testCaseId != null && testResultMap.containsKey(testCaseId)) {
STestRun testRun = testResultMap.get(testCaseId);
elem.setAttribute("status", testRun.getStatusText());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
import java.util.Map;

/**
* Controller for the link to the BrowserStack tab displayed
* under the stacktrace of a failed test.
*
* @author Shirish Kamath
* @author Anirudha Khanna
*/
Expand All @@ -51,6 +54,7 @@ public void fillModel(@NotNull Map<String, Object> model, @NotNull HttpServletRe
List<STestRun> testRuns = (List<STestRun>) testRunsAttr;
STestRun testRun = null;

// Get the STestRun for the current STest
for (STestRun tr : testRuns) {
if (tr.getTest().getTestNameId() == test.getTestNameId()) {
testRun = tr;
Expand All @@ -74,6 +78,13 @@ public void fillModel(@NotNull Map<String, Object> model, @NotNull HttpServletRe
}
}

/**
* Finds the index for the give test case w.r.t. to other test cases having the same name.
*
* @param testRuns List of test runs executed in this build.
* @param testRun Current test run.
* @return
*/
private int getTestIndex(final List<STestRun> testRuns, final STestRun testRun) {
// TODO: This iterates through all test results with the same name as the test case being queries
// and figure out index for the test case w.r.t other tests with the same name (but different parameters)
Expand All @@ -100,6 +111,15 @@ public boolean isAvailable(@NotNull final HttpServletRequest request) {
return true;
}

/**
* Finds the sessionId for the current test case by parsing the XML artifact files
* and returning the session Id for the matching test case (name{index})
*
* @param testRun Current test run.
* @param testIndex Test index for the test case w.r.t other tests having the same name.
* @return BrowserStack Automate Session Id
* @throws IOException
*/
@SuppressWarnings("unchecked")
private static String findSessionId(final STestRun testRun, final long testIndex) throws IOException {
String testNameFull = ParserUtil.getTestName(testRun);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,21 @@ public class ParserUtil {

private static final String PACKAGE_DEFAULT = "(root)";

/**
* Returns the full class name (packageName.className)
* @param testRun
* @return
*/
public static String getFullClassName(final STestRun testRun) {
TestName testName = testRun.getTest().getName();
return String.format("%s.%s", testName.hasPackage() ? testName.getPackageName() : PACKAGE_DEFAULT, testName.getClassName());
}

/**
* Returns the full test name (packageName.className.testName)
* @param testRun
* @return
*/
public static String getTestName(final STestRun testRun) {
return String.format("%s.%s", getFullClassName(testRun), testRun.getTest().getName().getTestMethodName());
}
Expand All @@ -44,6 +54,13 @@ public static List<Element> parseResultFile(final InputStream inputStream) throw
return null;
}

/**
* Generates a map for all test cases parsed by TeamCity from test report XMLs.
* Keys in the map are unique identifiers for each test case (packageName.className.methodName{testIndex}).
*
* @param allTests
* @return
*/
public static Map<String, STestRun> processTestResults(final List<STestRun> allTests) {
Map<String, STestRun> testStatusMap = new HashMap<String, STestRun>();
Map<String, Long> testCaseIndices = new HashMap<String, Long>();
Expand Down

0 comments on commit 3605509

Please sign in to comment.