All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.carousell.testrails.services.TestRailService Maven / Gradle / Ivy

package io.github.carousell.testrails.services;

import com.codepine.api.testrail.TestRail;
import com.codepine.api.testrail.model.Case;
import com.codepine.api.testrail.model.CaseField;
import com.codepine.api.testrail.model.Field;
import com.codepine.api.testrail.model.Plan.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestRailService {

  private static final Logger LOG = LoggerFactory.getLogger(TestRailService.class);

  private TestRail testRail;

  // Save Custom Field Configuration
  private Map testPlatformOptions;
  private Map testTypeOptions;
  private Map automationStatusOptions;

  // Test Case List
  private List allTestCaseList;
	private List filteredTestCaseList;

	// Test Run Information
	private String runId;
	private String entryId;

	/**
   * Constructor Init TestRail Instance and Configuration
   *
   * @param url : TestRail Url
   * @param username : TestRail Username
   * @param password : TestRail Password
   * @param projectId : TestRail Project Id
   * @param suiteId : TestRail Suite Id
	 * @param platform : Support iOS, Android, Web
   */
  public TestRailService(String url, String username, String password, int projectId, int suiteId, String platform) {
    LOG.info("Init TestRail Instance");
    testRail = TestRail.builder(url, username, password).applicationName("playground").build();

    LOG.info("Get whole Custom Fields");
    List customCaseFields = testRail.caseFields().list().execute();

    LOG.info("Get whole Test Cases from project {} suite {}", projectId, suiteId);
		allTestCaseList = getAllTestCases(projectId, suiteId, customCaseFields);

    LOG.info("Set Test Case Custom Field Configuration");
		testPlatformOptions = getTargetFieldMultiSelectOptionsItems(customCaseFields, "test_platform");
		testTypeOptions = getTargetFieldMultiSelectOptionsItems(customCaseFields, "testtype");
		if (platform.equalsIgnoreCase("ios")) {
			automationStatusOptions = getTargetFieldDropDownListItems(customCaseFields, "automatonstatusios");
		} else if (platform.equalsIgnoreCase("android")) {
			automationStatusOptions = getTargetFieldDropDownListItems(customCaseFields, "automationstatusandroid");
		} else if (platform.equalsIgnoreCase("web")) {
			automationStatusOptions = getTargetFieldDropDownListItems(customCaseFields, "automationstatusweb");
		}
  }

	/**
	 * Filter out test case by testPlatform and testType
	 *
	 * @param testPlatform support ios, android, web
	 * @param testType support sanity, regression, fft
	 * @param testStatus support not started, stable, unstable
	 * @return List
	 */
	public List filteredTestCases(String testPlatform, String testType, String testStatus) {

		LOG.info("Start to filter test cases by testPlatform : {} , testType : {}, testStatus : {}", testPlatform, testType, testStatus);
		String testPlatformId = getTestPlatformId(testPlatform);
		LOG.info("Set testPlatformId : {}", testPlatformId);
		String testTypeId = getTestTypeId(testType);
		LOG.info("Set testTypeId : {}", testTypeId);
		String testStatusId = getTestStatusId(testStatus);
		LOG.info("Set testStatusId : {}", testStatusId);

		filteredTestCaseList = new ArrayList();

		//Fetch test cases by test platform and test type
		for (Case c : allTestCaseList) {
			Integer testCaseId = c.getId();
			ArrayList testPlatformIdList = c.getCustomField("test_platform");
			ArrayList testTypeIdList = c.getCustomField("testtype");
			String automationStatus = null;
			if (testPlatform.equalsIgnoreCase("ios")){
				automationStatus = c.getCustomField("automatonstatusios");
			} else if (testPlatform.equalsIgnoreCase("android")) {
				automationStatus = c.getCustomField("automationstatusandroid");
			} else if (testPlatform.equalsIgnoreCase("web")) {
				automationStatus = c.getCustomField("automationstatusweb");
			}

			if ((testPlatformIdList.contains(testPlatformId)) && (testTypeIdList.contains(testTypeId))) {
				if (testStatusId != null) {
					if ((automationStatus.equalsIgnoreCase(testStatusId))){
						LOG.info("Add Test Case Id : {}, testPlatform : {}, testType : {}, testStatus : {}",
										testCaseId, testPlatformIdList, testTypeIdList, automationStatus);
						filteredTestCaseList.add(c);
					} else {
						LOG.info("Skip Test Case Id : {}, testPlatform : {}, testType : {}, testStatus : {}",
										testCaseId, testPlatformIdList, testTypeIdList, automationStatus);
					}
				} else {
					LOG.info("Add Test Case Id : {}, testPlatform : {}, testType : {}, testStatus : {}",
									testCaseId, testPlatformIdList, testTypeIdList, automationStatus);
					filteredTestCaseList.add(c);
				}
			} else {
				LOG.info("Skip Test Case Id : {}, testPlatform : {}, testType : {}, testStatus : {}",
								testCaseId, testPlatformIdList, testTypeIdList, automationStatus);
			}
		}

		LOG.info("Total Filtered Test Cases Number : {}", filteredTestCaseList.size());
		return filteredTestCaseList;
	}

	public void createTestRun(int planId, int suiteId, String testRunName) {
		LOG.info("Get all case id from filteredTestCaseList");
		List testCaseIds = new ArrayList();
		for (Case c : filteredTestCaseList) {
			testCaseIds.add(c.getId());
		}
		LOG.info("Create Test Run - planId : {} , suiteId : {}, testRunName : {}, testCaseIds : {}");
		Entry entry = testRail.plans().addEntry(planId, new Entry()
											.setSuiteId(suiteId)
                      .setName(testRunName)
                      .setIncludeAll(false)
                      .setCaseIds(testCaseIds))
              .execute();

		runId = String.valueOf(entry.getRuns().get(0).getId());
		LOG.info("Set runId : {}", runId);
		entryId = entry.getId();
		LOG.info("Set entryId : {}", entryId);
	}

	/**
	 * Get Run ID
	 * @return String
	 */
	public String getRunId() {
		return runId;
	}

	/**
	 * Get Entry ID
	 * @return String
	 */
	public String getEntryId() {
		return entryId;
	}

  /**
   * Converting a dropdown list content to Map object
   *
   * @param customCaseFields all custom fields
   * @param caseFieldName target custom field name
   * @return
   */
  private Map getTargetFieldDropDownListItems(
      List customCaseFields, String caseFieldName) {
    // Set result default as null
    Map result = new HashMap<>();
    // Find Target Field
    for (CaseField caseField : customCaseFields) {
      String fieldName = caseField.getName();
      String fieldType = caseField.getType().toString();
      List fieldConfigs = caseField.getConfigs();
      if ((fieldName.equals(caseFieldName)) && (fieldType.equals("DROPDOWN"))) {
        for (Field.Config config : fieldConfigs) {
          Field.Config.DropdownOptions option = (Field.Config.DropdownOptions) config.getOptions();
          result = option.getItems();
          LOG.info("Find {} Items : {}", caseFieldName, result);
        }
      }
    }
    if (result.isEmpty()) {
      LOG.warn("Return value is empty, please check the result !");
    }
    return result;
  }

  /**
   * Coverting a MultiSelectOption list to Map object
   *
   * @param customCaseFields all custom fields
   * @param caseFieldName target custom field name
   * @return Map
   */
  private Map getTargetFieldMultiSelectOptionsItems(
      List customCaseFields, String caseFieldName) {
    // Set result default as null
    Map result = new HashMap<>();
    // Find Target Field
    for (CaseField caseField : customCaseFields) {
      String fieldName = caseField.getName();
      String fieldType = caseField.getType().toString();
      List fieldConfigs = caseField.getConfigs();
      if ((fieldName.equals(caseFieldName)) && (fieldType.equals("MULTI_SELECT"))) {
        for (Field.Config config : fieldConfigs) {
          Field.Config.MultiSelectOptions option =
              (Field.Config.MultiSelectOptions) config.getOptions();
          result = option.getItems();
          LOG.info("Find {} Items : {}", caseFieldName, result);
        }
      }
    }
    if (result.isEmpty()) {
      LOG.warn("Return value is empty, please check the result !");
    }
    return result;
  }

  /**
   * Get whole test cases from target project id and suite id
	 *
   * @param projectId project id on testrail
   * @param suiteId suite id on testrail
	 * @return List
   */
  private List getAllTestCases(int projectId, int suiteId, List customCaseFields) {
    LOG.info(
        "Start to get all test cases from TestRail ( Project Id : {}, Suite Id : {} )",
        projectId,
        suiteId);
    List testCaseList = testRail.cases().list(projectId, suiteId, customCaseFields).execute();
    LOG.info("Total Test Cases Number : {}", testCaseList.size());

    if (testCaseList.isEmpty()) {
      LOG.warn("Return value is empty, please check the project {} and suite {} on TestRail");
    }
    return testCaseList;
  }

	/**
	 * Get Test Platform Id by testPlatform
	 * @param testPlatform support ios, android, web
	 * @return testPlatformId
	 */
	private String getTestPlatformId(String testPlatform) {
		String testPlatformId = null;
		if (!(isTestPlatformFormat(testPlatform))) {
			throw new IllegalArgumentException("Please check inputted value 'testPlatform' !");
		}
		for(Map.Entry entry : testPlatformOptions.entrySet()) {
			if (entry.getValue().equalsIgnoreCase(testPlatform)) {
				testPlatformId = entry.getKey();
			}
		}
		return testPlatformId;
	}

	/**
	 * Get Test Type Id by testType
	 * @param testType support sanity, regression, fft
	 * @return testTypeId
	 */
	private String getTestTypeId(String testType) {
		String testTypeId = null;
		if (!(isTestTypeFormat(testType))) {
			throw new IllegalArgumentException("Please check inputted value 'testType' !");
		}
		for(Map.Entry entry : testTypeOptions.entrySet()) {
			if (entry.getValue().equalsIgnoreCase(testType)) {
				testTypeId = entry.getKey();
			}
		}
		return testTypeId;
	}

	/**
	 * Get Test Status Id by testStatus
	 * @param testStatus support 'not started', 'stable', 'unstable'
	 * @return testTypeId
	 */
	private String getTestStatusId(String testStatus) {
		String testStatusId = null;
		if (testStatus == null) {
			return testStatusId;
		}
		if (isTestStatusFormat(testStatus)) {
			for(Map.Entry entry : automationStatusOptions.entrySet()) {
				if (entry.getValue().equalsIgnoreCase(testStatus)) {
					testStatusId = entry.getKey();
				}
			}
		} else {
			throw new IllegalArgumentException("Please check inputted value 'testStatus' !");
		}
		return testStatusId;
	}

	/**
	 * Check the format on testPlatform
	 *
	 * @param testPlatform support ios, android, web
	 * @return boolean
	 */
	private boolean isTestPlatformFormat(String testPlatform) {
		if (testPlatform.isEmpty()) {
			LOG.error("testPlatform is empty, please check value : {}", testPlatform);
			return false;
		}
		for (Map.Entry option : testPlatformOptions.entrySet()) {
			if (option.getValue().equalsIgnoreCase(testPlatform)) {
				return true;
			}
		}
		LOG.error("Can not find value in testPlatformOptions, please check value : {}", testPlatform);
		return false;
	}

	/**
	 * Check the format on testType
	 *
	 * @param testType support sanity, regression, fft
	 * @return boolean
	 */
	private boolean isTestTypeFormat(String testType) {
		if (testType.isEmpty()) {
			LOG.error("testType is empty, please check value : {}", testType);
			return false;
		}
		for (Map.Entry option : testTypeOptions.entrySet()) {
			if (option.getValue().equalsIgnoreCase(testType)) {
				return true;
			}
		}
		LOG.error("Can not find value in testTypeOptions, please check value : {}", testType);
		return false;
	}

	/**
	 * Check the format on testStatus
	 *
	 * @param testStatus support 'not started', 'stable', 'unstable'
	 * @return boolean
	 */
	private boolean isTestStatusFormat(String testStatus) {
		for (Map.Entry option : automationStatusOptions.entrySet()) {
			if (option.getValue().equalsIgnoreCase(testStatus)) {
				return true;
			}
		}
		LOG.error("Can not find value in automatedStatusOptions, please check value : {}", testStatus);
		return false;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy