def take_screenshot(driver, description): """ Save a screenshot of the browser window - should be used after a test fails :param driver: the browser driver :param description: information about the screenshot to be added to the file name :return: boolean representing whether saving the screenshot succeeded """ window_width = driver.get_window_size()["width"] window_height = driver.get_window_size()["height"] scroll_height = driver.execute_script( "return document.body.scrollHeight") # Set the browser to the full height of the page so that everything is captured if scroll_height > window_height: driver.set_window_size(window_width, scroll_height) # Create the screenshots folder if not os.path.exists(SCREENSHOTS_PATH): os.makedirs(SCREENSHOTS_PATH) # Create a file name and ensure it is not too long timestamp = get_current_datetime().strftime("%Y-%m-%d_%H.%M.%S.%f") description = remove_invalid_characters(description) file_name = f"{SCREENSHOTS_PATH}/{timestamp}_{description}" file_name = (file_name[:100] + "---.png") if len(file_name) > 100 else file_name + ".png" # Save the screenshot result = driver.save_screenshot(file_name) # Reset the browser size if it was changed if scroll_height > window_height: driver.set_window_size(window_width, window_height) return result
def move_screenshots_to_folder(folder_name): """ Create a new folder and move all screenshots from the root screenshot folder into it (to be run at end of test) :param folder_name: the name of the folder into which the screenshots should be moved """ folder_name = remove_invalid_characters(folder_name) source = f"{SCREENSHOTS_PATH}/" destination = source + folder_name files = os.listdir(source) if not os.path.exists(destination): os.makedirs(destination) for file in files: if file.endswith(".png"): shutil.move(source + file, destination)
def attach_screenshots(project, args): """ Get the details of the failed tests from a given release and attach the screenshots using Microsoft API calls :param project: the Azure project name e.g. "nhsuk.contact-us" :param args: sys.argv which should contain the release ID and auth token :return: integer: a return value of 0 indicates success, 1 means that any screenshot could not be attached """ # Get the release ID and auth token from the passed arguments params = parse_parameters(args) if not params: return 1 release_id = params[0] auth_token = params[1] # Set the URL for the required API request_url = f"https://dev.azure.com/nhsuk/{project}/_apis/test/runs" # Get the run IDs for the given release run_ids = get_run_ids(release_id, request_url, auth_token) if not run_ids: print_azure_error(f"No test runs found for release {release_id}") return 1 print(f"Run IDs found for release {release_id}: {run_ids}") # Get the list of failed tests failed_tests = get_failed_tests(run_ids, request_url, auth_token) if not failed_tests: return 1 print(f"Failed tests found (run ID, test case result ID, test name): {failed_tests}") # A return value of 0 indicates success, 1 means that any screenshot could not be attached return_value = 0 # Attach the relevant screenshots for failed_test in failed_tests: # Get all of the file names of screenshots for this test screenshots_path = "screenshots/" + remove_invalid_characters(failed_test[2]) file_names = [] if append_file_names(file_names, screenshots_path) == 1: return_value = 1 if not file_names: continue # Attach any screenshots found for this test for file_name in file_names: image_b64 = get_image_base64(f"{screenshots_path}/{file_name}") if not image_b64: print_azure_error(f"Could not convert file to Base64: {screenshots_path}/{file_name}") return_value = 1 continue run_id = failed_test[0] test_case_result_id = failed_test[1] response = requests.post( f"{request_url}/{run_id}/Results/{test_case_result_id}/attachments", params={"api-version": AZURE_API_VERSION_POST}, auth=("", auth_token), headers={"Content-Type": "application/json"}, data=json.dumps({ "attachmentType": "GeneralAttachment", "comment": "Example screenshot", "fileName": file_name, "stream": image_b64.decode("utf-8") }) ) print(f"Attach screenshot {file_name} - response {response.status_code}") if not response.status_code == 200: return_value = 1 return return_value
def attach_files(organisation, project, attachment_file_path, args): """ Get the details of the failed tests from a given release and attach the files using Microsoft API calls The organisation and project names can be found in the project URL e.g. dev.azure.com/organisation/project :param organisation: the Azure organisation name :param project: the Azure project name :param attachment_file_path: the file path to the directory containing the files to attach :param args: sys.argv which should contain the release ID and auth token :return: integer: a return value of 0 indicates success, 1 means that any file could not be attached """ # Get the release ID and auth token from the passed arguments params = parse_parameters(args) if not params: return 1 release_id = params[0] auth_token = params[1] # Set the URL for the required API request_url = f"https://dev.azure.com/{organisation}/{project}/_apis/test/runs" # Get the run IDs for the given release run_ids = get_run_ids(release_id, request_url, auth_token) if not run_ids: print_azure_error(f"No test runs found for release {release_id}") return 1 print(f"Run IDs found for release {release_id}: {run_ids}") # Get the list of failed tests failed_tests = get_failed_tests(run_ids, request_url, auth_token) if not failed_tests: return 1 print( f"Failed tests found (run ID, test case result ID, test name): {failed_tests}" ) # A return value of 0 indicates success, 1 means that any file could not be attached return_value = 0 # Ensure that the file path ends with a "/" if not attachment_file_path.endswith("/"): attachment_file_path += "/" # Attach the relevant files for failed_test in failed_tests: # Get all of the file names to attach for this test file_path = attachment_file_path + remove_invalid_characters( failed_test[2]) file_names = [] if append_file_names(file_names, file_path) == 1: return_value = 1 if not file_names: continue # Attach any files found for this test for file_name in file_names: file_b64 = get_file_base64(f"{file_path}/{file_name}") if not file_b64: print_azure_error( f"Could not convert file to Base64: {file_path}/{file_name}" ) return_value = 1 continue run_id = failed_test[0] test_case_result_id = failed_test[1] response = requests.post( f"{request_url}/{run_id}/Results/{test_case_result_id}/attachments", params={"api-version": AZURE_API_VERSION_POST}, auth=("", auth_token), headers={"Content-Type": "application/json"}, data=json.dumps({ "attachmentType": "GeneralAttachment", "comment": "Attached by UiTestCore", "fileName": file_name, "stream": file_b64.decode("utf-8") })) print(f"Attach file {file_name} - response {response.status_code}") if not response.status_code == 200: return_value = 1 return return_value