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));
  }
  /** Tests the UI of edit course. */
  private void testEditCourseAction() throws Exception {
    courseEditPage = getCourseEditPage();

    ______TS("edit course valid name");

    assertFalse(courseEditPage.isCourseEditFormEnabled());
    courseEditPage.clickEditCourseLink();
    assertTrue(courseEditPage.isCourseEditFormEnabled());

    courseEditPage.clickSaveCourseButton();
    courseEditPage.changePageType(InstructorCourseEditPage.class);
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_EDITED);

    ______TS("edit course invalid name");
    assertFalse(courseEditPage.isCourseEditFormEnabled());
    courseEditPage.clickEditCourseLink();
    assertTrue(courseEditPage.isCourseEditFormEnabled());
    courseEditPage.editCourseName("");
    courseEditPage.clickSaveCourseButton();
    courseEditPage.changePageType(InstructorCourseEditPage.class);
    courseEditPage.verifyStatus(
        getPopulatedErrorMessage(
            FieldValidator.SIZE_CAPPED_NON_EMPTY_STRING_ERROR_MESSAGE,
            "",
            FieldValidator.COURSE_NAME_FIELD_NAME,
            FieldValidator.REASON_EMPTY,
            FieldValidator.COURSE_NAME_MAX_LENGTH));
  }
  private void testDeleteInstructorAction() {
    courseEditPage = getCourseEditPage();

    ______TS("delete instructor then cancel");
    courseEditPage.clickDeleteInstructorLinkAndCancel();
    assertNotNull(BackDoor.getInstructorAsJsonByGoogleId(instructorId, courseId));

    ______TS("delete instructor successfully");
    courseEditPage.clickDeleteInstructorLinkAndConfirm();
    courseEditPage.verifyHtml("/instructorCourseEditDeleteInstructorSuccessful.html");

    ______TS("failed to delete the last instructor");
    courseEditPage.clickDeleteInstructorLinkAndConfirm();
    courseEditPage.clickDeleteInstructorLinkAndConfirm();
    courseEditPage.clickDeleteInstructorLinkAndConfirm();
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_DELETE_NOT_ALLOWED);

    ______TS("deleted own instructor role and redirect to courses page");
    // Change login id to another instructor
    BackDoor.createInstructor(testData.instructors.get("InsCrsEdit.coord"));
    instructorId = testData.instructors.get("InsCrsEdit.coord").googleId;

    courseEditPage = getCourseEditPage();
    courseEditPage.clickDeleteInstructorLinkAndConfirm();

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

    // Change back login id to original instructor to ensure remaining test cases work properly
    instructorId = testData.instructors.get("InsCrsEdit.test").googleId;
  }
  private void testEditInstructorAction() {

    ______TS("success: edit an instructor");

    courseEditPage = getCourseEditPage();
    courseEditPage.editInstructor(instructorId, "New name", "*****@*****.**");
    courseEditPage.verifyStatus(Const.StatusMessages.COURSE_INSTRUCTOR_EDITED);

    ______TS("failure: edit failed due to invalid parameters");
    String invalidEmail = "InsCrsEdit.email.com";

    courseEditPage = getCourseEditPage();
    courseEditPage.editInstructor(instructorId, "New name", invalidEmail);
    courseEditPage.verifyStatus(
        (new FieldValidator()).getInvalidityInfo(FieldType.EMAIL, invalidEmail));
  }
  private void testInviteInstructorAction() {
    ______TS("success: invite an uregistered instructor");
    int unregisteredInsturctorIndex = 4;

    courseEditPage.clickInviteInstructorLink(unregisteredInsturctorIndex);
    courseEditPage.verifyStatus(
        Const.StatusMessages.COURSE_REMINDER_SENT_TO + "*****@*****.**");
  }
  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 testEditInstructorAction() throws Exception {

    ______TS("failure: ajax error on clicking edit button");
    int editInstructorIndex = 1;

    courseEditPage.changeCourseIdInForm(editInstructorIndex, "InvalidCourse");
    courseEditPage.clickEditInstructorLinkUnsuccessfully(editInstructorIndex);
    courseEditPage.waitForAjaxLoaderGifToDisappear();
    assertTrue(
        courseEditPage
            .getEditInstructorLink(editInstructorIndex)
            .getText()
            .contains("Edit failed."));
    courseEditPage.reloadPage();

    ______TS("success: edit an instructor");

    courseEditPage.editInstructor(
        editInstructorIndex,
        "New name",
        "*****@*****.**",
        Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);
    courseEditPage.verifyStatus(
        String.format(Const.StatusMessages.COURSE_INSTRUCTOR_EDITED, "New name"));

    ______TS(
        "success: edit an instructor (InsCrsEdit.coord)--viewing instructor permission details");

    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    assertTrue(courseEditPage.isInstructorEditable(editInstructorIndex));

    ______TS("view details: manager");

    courseEditPage.clickViewDetailsLinkForInstructor(
        editInstructorIndex, InstructorCourseEditPage.INSTRUCTOR_TYPE_MANAGER);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));
    courseEditPage.closeModal();

    ______TS("view details: observer");

    courseEditPage.clickViewDetailsLinkForInstructor(
        editInstructorIndex, InstructorCourseEditPage.INSTRUCTOR_TYPE_OBSERVER);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));
    courseEditPage.closeModal();

    ______TS("view details: tutor");

    courseEditPage.clickViewDetailsLinkForInstructor(
        editInstructorIndex, InstructorCourseEditPage.INSTRUCTOR_TYPE_TUTOR);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInModalChecked(
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));
    courseEditPage.closeModal();

    ______TS("view details: co-owner");

    courseEditPage.clickViewDetailsLinkForInstructor(
        editInstructorIndex, InstructorCourseEditPage.INSTRUCTOR_TYPE_COOWNER);
    courseEditPage.verifyHtmlMainContent("/instructorCourseEditEditInstructorPrivilegesModal.html");
    courseEditPage.closeModal();

    ______TS("verify that custom has no privileges by default");

    int customInstrNum = 5;
    courseEditPage.clickEditInstructorLink(customInstrNum);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifycourse"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifyinstructor"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifysession"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifystudent"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canviewstudentinsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "cangivecommentinsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canviewcommentinsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifycommentinsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "cansubmitsessioninsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canviewsessioninsection"));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            customInstrNum, "canmodifysessioncommentinsection"));
    courseEditPage.clickSaveInstructorButton(customInstrNum);

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

    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    assertTrue(courseEditPage.getDisplayedToStudentCheckBox(editInstructorIndex).isSelected());
    // not displayed to students
    courseEditPage.clickDisplayedToStudentCheckBox(editInstructorIndex);
    // select the role as Custom for instr1
    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Custom");

    // deselect some privileges from Co-owner default values
    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_COURSE);
    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_INSTRUCTORS);
    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_OTHERS_COMMENTS);
    courseEditPage.clickAddSectionLevelPrivilegesLink(editInstructorIndex);
    courseEditPage.clickSectionSelectionCheckBox(editInstructorIndex, 0, 0);
    courseEditPage.clickSectionSelectionCheckBox(editInstructorIndex, 0, 1);
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, 0, InstructorCourseEditPage.SECTION_VIEW_STUDENTS);
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, 0, InstructorCourseEditPage.SECTION_VIEW_OTHERS_COMMENTS);
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, 0, InstructorCourseEditPage.SECTION_VIEW_RESPONSES_IN_SESSION);
    courseEditPage.clickSessionLevelInSectionLevel(editInstructorIndex, 0);
    courseEditPage.clickAddSectionLevelPrivilegesLink(editInstructorIndex);
    courseEditPage.clickSectionSelectionCheckBox(editInstructorIndex, 1, 1);
    courseEditPage.clickAddSectionLevelPrivilegesLink(editInstructorIndex);
    courseEditPage.clickSectionSelectionCheckBox(editInstructorIndex, 2, 1);
    courseEditPage.clickSectionSelectionCheckBox(editInstructorIndex, 2, 2);
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, 2, InstructorCourseEditPage.SECTION_MODIFY_RESPONSES_IN_SESSION);
    // after 3 sections added, no more things to add
    assertFalse(courseEditPage.getAddSectionLevelPrivilegesLink(editInstructorIndex).isDisplayed());
    courseEditPage.verifyHtmlMainContent(
        "/instructorCourseEditEditInstructorPrivilegesBeforeSubmit.html");

    courseEditPage.clickSaveInstructorButton(editInstructorIndex);
    courseEditPage.verifyHtmlMainContent(
        "/instructorCourseEditEditInstructorPrivilegesSuccessful.html");
    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    assertTrue(courseEditPage.isInstructorEditable(editInstructorIndex));
    courseEditPage.verifyHtmlMainContent(
        "/instructorCourseEditEditInstructorPrivilegesSuccessfulAndCheckEditAgain.html");
    courseEditPage.clickSaveInstructorButton(editInstructorIndex);

    ______TS("failure: edit failed due to invalid parameters");
    String invalidEmail = "InsCrsEdit.email.tmt";

    courseEditPage.editInstructor(
        editInstructorIndex,
        "New name",
        invalidEmail,
        Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);
    courseEditPage.verifyStatus(new FieldValidator().getInvalidityInfoForEmail(invalidEmail));

    String invalidName = "";

    courseEditPage.editInstructor(
        editInstructorIndex,
        invalidName,
        "*****@*****.**",
        Const.InstructorPermissionRoleNames.INSTRUCTOR_PERMISSION_ROLE_COOWNER);
    courseEditPage.verifyStatus(new FieldValidator().getInvalidityInfoForPersonName(invalidName));

    ______TS(
        "success: test Custom radio button getting other privileges' default values when selected");
    editInstructorIndex = 2;
    courseEditPage.clickEditInstructorLink(editInstructorIndex);

    ______TS("tutor->custom");

    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Tutor");
    courseEditPage.clickSaveInstructorButton(editInstructorIndex);
    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Custom");
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    ______TS("observer->custom");

    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Observer");
    courseEditPage.clickSaveInstructorButton(editInstructorIndex);
    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Custom");
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    ______TS("manager->custom");

    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Manager");
    courseEditPage.clickSaveInstructorButton(editInstructorIndex);
    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Custom");
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    ______TS("co-owner->custom");

    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Co-owner");
    courseEditPage.clickSaveInstructorButton(editInstructorIndex);
    courseEditPage.clickEditInstructorLink(editInstructorIndex);
    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Custom");
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COURSE));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_INSTRUCTOR));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_STUDENT));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_SUBMIT_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    ______TS("verify that session level checkboxes are accessible");

    int sectionToCheck = 0;

    courseEditPage.clickAddSectionLevelPrivilegesLink(editInstructorIndex);
    courseEditPage.clickSessionLevelInSectionLevel(editInstructorIndex, sectionToCheck);
    assertTrue(
        courseEditPage.isTuneSessionPermissionsDivVisible(editInstructorIndex, sectionToCheck));

    ______TS("verify checkbox toggling to false");

    int sessionToCheck = 0;

    // course level
    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_VIEW_STUDENTS);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));

    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_VIEW_OTHERS_COMMENTS);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));

    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_VIEW_RESPONSES_IN_SESSION);
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertFalse(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    // section level
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, sectionToCheck, InstructorCourseEditPage.SECTION_VIEW_STUDENTS);
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex, sectionToCheck, InstructorCourseEditPage.SECTION_VIEW_STUDENTS));
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_GIVE_STUDENT_COMMENTS));

    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex, sectionToCheck, InstructorCourseEditPage.SECTION_VIEW_OTHERS_COMMENTS);
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_VIEW_OTHERS_COMMENTS));
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_MODIFY_OTHERS_COMMENTS));

    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        InstructorCourseEditPage.SECTION_VIEW_RESPONSES_IN_SESSION);
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_VIEW_RESPONSES_IN_SESSION));
    assertFalse(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_MODIFY_RESPONSES_IN_SESSION));

    // session level
    courseEditPage.clickSessionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        sessionToCheck,
        InstructorCourseEditPage.SESSION_VIEW_RESPONSES);
    assertFalse(
        courseEditPage.isSessionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            sessionToCheck,
            InstructorCourseEditPage.SESSION_VIEW_RESPONSES));
    assertFalse(
        courseEditPage.isSessionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            sessionToCheck,
            InstructorCourseEditPage.SESSION_MODIFY_RESPONSES));

    ______TS("verify checkbox toggling to true");

    // course level
    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_GIVE_STUDENT_COMMENTS);
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_STUDENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_GIVE_COMMENT_IN_SECTIONS));

    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_OTHERS_COMMENTS);
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_COMMENT_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_COMMENT_IN_SECTIONS));

    courseEditPage.clickCourseLevelPrivilegesLink(
        editInstructorIndex, InstructorCourseEditPage.COURSE_MODIFY_RESPONSES_IN_SESSION);
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex, Const.ParamsNames.INSTRUCTOR_PERMISSION_VIEW_SESSION_IN_SECTIONS));
    assertTrue(
        courseEditPage.isPrivilegeCheckboxInPermissionDivChecked(
            editInstructorIndex,
            Const.ParamsNames.INSTRUCTOR_PERMISSION_MODIFY_SESSION_COMMENT_IN_SECTIONS));

    // section level
    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        InstructorCourseEditPage.SECTION_GIVE_STUDENT_COMMENTS);
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex, sectionToCheck, InstructorCourseEditPage.SECTION_VIEW_STUDENTS));
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_GIVE_STUDENT_COMMENTS));

    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        InstructorCourseEditPage.SECTION_MODIFY_OTHERS_COMMENTS);
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_VIEW_OTHERS_COMMENTS));
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_MODIFY_OTHERS_COMMENTS));

    courseEditPage.clickSectionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        InstructorCourseEditPage.SECTION_MODIFY_RESPONSES_IN_SESSION);
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_VIEW_RESPONSES_IN_SESSION));
    assertTrue(
        courseEditPage.isSectionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            InstructorCourseEditPage.SECTION_MODIFY_RESPONSES_IN_SESSION));

    // session level
    courseEditPage.clickSessionLevelPrivilegeLink(
        editInstructorIndex,
        sectionToCheck,
        sessionToCheck,
        InstructorCourseEditPage.SESSION_MODIFY_RESPONSES);
    assertTrue(
        courseEditPage.isSessionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            sessionToCheck,
            InstructorCourseEditPage.SESSION_VIEW_RESPONSES));
    assertTrue(
        courseEditPage.isSessionLevelPrivilegeLinkClicked(
            editInstructorIndex,
            sectionToCheck,
            sessionToCheck,
            InstructorCourseEditPage.SESSION_MODIFY_RESPONSES));

    courseEditPage.selectRoleForInstructor(editInstructorIndex, "Co-owner");
  }
  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));
  }