예제 #1
0
    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
예제 #2
0
    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)
예제 #3
0
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