modules/testrail_script_set_null_automation_status_to_untriaged.py (101 lines of code) (raw):

import logging import os from dotenv import load_dotenv from modules.testrail_integration import testrail_init # Set up logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) # Load env file from project root script_dir = os.path.dirname(__file__) project_root = os.path.abspath(os.path.join(script_dir, "..")) env_file_path = os.path.join(project_root, "testrail_credentials.env") load_dotenv(dotenv_path=env_file_path) # TestRail project ID (Fx Desktop) PROJECT_ID = 17 def get_all_suites(tr, project_id): """Get all suites from the project""" suites = tr.client.send_get(f"get_suites/{project_id}") logging.info(f"Found {len(suites)} suites in project {project_id}") return suites # Set limit below maximum value as a precaution to avoid API errors def get_all_test_cases(tr, project_id, suite_id): """Fetch all test cases from a suite by handling pagination.""" all_cases = [] offset = 0 limit = 240 # Default limit for TestRail API is 250 while True: # Build endpoint with pagination parameters endpoint = ( f"get_cases/{project_id}&suite_id={suite_id}&limit={limit}&offset={offset}" ) response = tr.client.send_get(endpoint) cases = response.get("cases", []) if not cases: break all_cases.extend(cases) # If the number of cases returned is less than the limit, we've reached the last page. if len(cases) < limit: break offset += limit logging.info(f"Total cases fetched from suite {suite_id}: {len(all_cases)}") return all_cases def update_null_automation_status(tr, project_id, dry_run=True): """Update test cases with None automation status to Untriaged""" try: # Get all suites in the project suites = get_all_suites(tr, project_id) # Track statistics total_null_cases = 0 updated_count = 0 # Process each suite for suite in suites: suite_id = suite["id"] suite_name = suite["name"] logging.info(f"Processing suite {suite_name} (ID: {suite_id})...") # Retrieve test cases for this suite try: cases = get_all_test_cases(tr, project_id, suite_id) # Filter cases with null automation status null_status_cases = [ case for case in cases if case.get("custom_automation_status") is None ] suite_null_count = len(null_status_cases) total_null_cases += suite_null_count logging.info( f"Found {suite_null_count} cases with null automation status in suite {suite_name}" ) # Update each case that meets the criteria for case in null_status_cases: case_id = case["id"] try: if dry_run: logging.info( f"[DRY RUN] Would update case {case_id}: set automation status to Untriaged (1)" ) else: # Perform the update tr.update_case_field( case_id, "custom_automation_status", "1" ) logging.info( f"Updated case {case_id}: set automation status to Untriaged (1)" ) updated_count += 1 except Exception as e: logging.error(f"Error updating case {case_id}: {e}") except Exception as e: logging.error(f"Error processing suite {suite_id}: {e}") continue # Log summary logging.info( f"Summary: Found {total_null_cases} cases with null automation status across all suites" ) if not dry_run: logging.info(f"Updated {updated_count} cases to Untriaged") else: logging.info( f"Would update {total_null_cases} cases to Untriaged (dry run)" ) except Exception as e: logging.error(f"Error processing cases: {e}") def main(): # Read credentials from environment base_url = os.environ.get("TESTRAIL_BASE_URL") username = os.environ.get("TESTRAIL_USERNAME") api_key = os.environ.get("TESTRAIL_API_KEY") if not all([base_url, username, api_key]): logging.error("Missing TestRail credentials. Check your .env file.") return logging.info(f"Loaded credentials for user: {username}") logging.info(f"Base URL: {base_url}") tr = testrail_init() # Safe approach to not accidentally update cases dry_run = True # Process all cases in the project logging.info(f"Processing project ID: {PROJECT_ID}...") update_null_automation_status(tr, PROJECT_ID, dry_run) if __name__ == "__main__": main()