private void testAddInstructorAction() {

    ______TS("success: add an instructor");

    courseEditPage = getCourseEditPage();
    courseEditPage.addNewInstructor("Teammates Instructor", "*****@*****.**");
    courseEditPage.verifyStatus(
        String.format(
            Const.StatusMessages.COURSE_INSTRUCTOR_ADDED,
            "Teammates Instructor",
            "*****@*****.**"));

    Url courseDetailsLink =
        createUrl(Const.ActionURIs.INSTRUCTOR_COURSE_DETAILS_PAGE)
            .withCourseId(courseId)
            .withUserId(testData.instructors.get("InsCrsEdit.test").googleId);

    InstructorCourseDetailsPage courseDetailsPage =
        courseEditPage.navigateTo(courseDetailsLink, InstructorCourseDetailsPage.class);
    courseDetailsPage.verifyHtml("/instructorCourseDetailsAddInstructor.html");

    ______TS("failure: add an existing instructor");

    courseEditPage = getCourseEditPage();
    courseEditPage.addNewInstructor("Teammates Instructor", "*****@*****.**");
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_EXISTS);

    ______TS("failure: add an instructor with an invalid parameter");
    String invalidEmail = "InsCrsEdit.email.com";

    courseEditPage = getCourseEditPage();
    courseEditPage.addNewInstructor("Teammates Instructor", invalidEmail);
    courseEditPage.verifyStatus(
        (new FieldValidator()).getInvalidityInfo(FieldType.EMAIL, invalidEmail));
  }
  private void testUnregisteredInstructorEmailNotEditable() {
    courseEditPage = getCourseEditPage();

    ______TS("make a new unregistered instructor and test that its email can't be edited");

    courseEditPage.addNewInstructor("Unreg Instructor", "*****@*****.**");
    int unregInstrNum = 3;
    assertEquals(
        "Unreg Instructor", courseEditPage.getNameField(unregInstrNum).getAttribute("value"));
    assertFalse(courseEditPage.getNameField(unregInstrNum).isEnabled());

    courseEditPage.clickEditInstructorLink(unregInstrNum);
    assertTrue(courseEditPage.isInstructorEditable(unregInstrNum));
    assertEquals("true", courseEditPage.getEmailField(unregInstrNum).getAttribute("readonly"));
    assertTrue(courseEditPage.getNameField(unregInstrNum).isEnabled());
  }
  private void testDeleteInstructorAction() {

    ______TS("delete instructor then cancel");

    courseEditPage.clickDeleteInstructorLinkAndCancel(1);
    assertNotNull(BackDoor.getInstructorByGoogleId(instructorId, courseId));

    ______TS("delete instructor successfully");

    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    String expectedMsg = "The instructor has been deleted from the course.";
    courseEditPage.verifyStatus(expectedMsg);

    ______TS("delete all other instructors");

    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(2);

    ______TS(
        "test the only registered instructor with the privilege to modify instructors cannot be deleted");

    // Create an registered instructor with all privileges except modifying instructors
    InstructorPrivileges privilege =
        new InstructorPrivileges(
            Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);
    privilege.updatePrivilege(Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR, false);
    InstructorAttributes instructor =
        new InstructorAttributes(
            "InsCrsEdit.reg",
            courseId,
            "Teammates Reg",
            "*****@*****.**",
            Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_CUSTOM,
            "Teammates Reg",
            privilege);
    BackDoor.createInstructor(instructor);

    // Create an unregistered instructor with co-owner privilege
    courseEditPage.addNewInstructor("Unreg Instructor", "*****@*****.**");

    // Delete own instructor role
    courseEditPage.clickDeleteInstructorLinkAndConfirm(2);
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_DELETE_NOT_ALLOWED);

    // Delete other instructors
    courseEditPage.clickDeleteInstructorLinkAndConfirm(3);
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_DELETED);
    courseEditPage.clickDeleteInstructorLinkAndConfirm(1);
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_DELETED);

    ______TS("delete own instructor role and redirect to courses page");

    // Create another registered instructor with co-owner privilege
    BackDoor.createInstructor(testData.instructors.get("InsCrsEdit.coord"));
    courseEditPage = getCourseEditPage();

    // Delete own instructor role
    courseEditPage.clickDeleteInstructorLinkAndConfirm(2);

    InstructorCoursesPage coursesPage = courseEditPage.changePageType(InstructorCoursesPage.class);
    coursesPage.waitForAjaxLoadCoursesSuccess();
    coursesPage.verifyStatus(
        Const.StatusMessages.COURSE_INSTRUCTOR_DELETED + "\n" + Const.StatusMessages.COURSE_EMPTY);

    // Restore own instructor role to ensure remaining test cases work properly
    BackDoor.createInstructor(testData.instructors.get("InsCrsEdit.test"));
  }
  private void testAddInstructorAction() throws Exception {

    ______TS("success: add an instructor with privileges");

    courseEditPage.clickShowNewInstructorFormButton();
    courseEditPage.fillNewInstructorName("Teammates Instructor");
    courseEditPage.fillNewInstructorEmail("*****@*****.**");

    int newInstructorIndex = 8;

    courseEditPage.selectRoleForInstructor(newInstructorIndex, "Custom");
    courseEditPage.clickCourseLevelPrivilegesLink(
        newInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_COURSE);
    courseEditPage.clickCourseLevelPrivilegesLink(
        newInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_STUDENTS);
    courseEditPage.clickCourseLevelPrivilegesLink(
        newInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_OTHERS_COMMENTS);

    courseEditPage.clickAddSectionLevelPrivilegesLink(newInstructorIndex);
    courseEditPage.clickSectionSelectionCheckBox(newInstructorIndex, 0, 1);
    courseEditPage.clickSectionLevelPrivilegeLink(
        newInstructorIndex, 0, InstructorCourseEditPage.SECTION_VIEW_STUDENTS);
    courseEditPage.clickSectionLevelPrivilegeLink(
        newInstructorIndex, 0, InstructorCourseEditPage.SECTION_VIEW_RESPONSES_IN_SESSION);

    courseEditPage.clickAddInstructorButton();

    courseEditPage.verifyStatus(
        String.format(
            Const.StatusMessages.COURSE_INSTRUCTOR_ADDED,
            "Teammates Instructor",
            "*****@*****.**"));

    AppUrl courseDetailsLink =
        createUrl(Const.ActionURIs.INSTRUCTOR_COURSE_DETAILS_PAGE)
            .withCourseId(courseId)
            .withUserId(testData.instructors.get("InsCrsEdit.test").googleId);

    InstructorCourseDetailsPage courseDetailsPage =
        AppPage.getNewPageInstance(browser, courseDetailsLink, InstructorCourseDetailsPage.class);
    courseDetailsPage.verifyHtmlPart(
        By.id("instructors"), "/instructorCourseDetailsAddInstructor.html");
    courseEditPage = getCourseEditPage();
    courseEditPage.clickEditInstructorLink(3);
    courseEditPage.verifyHtmlMainContent("/instructorCourseEditAddInstructor.html");

    ______TS("failure: add an existing instructor");

    courseEditPage.addNewInstructor("Teammates Instructor", "*****@*****.**");
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_EXISTS);

    ______TS("failure: add an instructor with an invalid parameter");

    String invalidEmail = "InsCrsEdit.email.tmt";

    courseEditPage.addNewInstructor("Teammates Instructor", invalidEmail);
    courseEditPage.verifyStatus(new FieldValidator().getInvalidityInfoForEmail(invalidEmail));

    String invalidName = "";

    courseEditPage.addNewInstructor(invalidName, "*****@*****.**");
    courseEditPage.verifyStatus(new FieldValidator().getInvalidityInfoForPersonName(invalidName));
  }