Skip to content

Commit

Permalink
[#12048] Migrate InstructorCourseDetailsPageE2ETest (#12908)
Browse files Browse the repository at this point in the history
* Add teammates.e2e.cases.sql.InstructorCourseDetailsPageE2ETest

* Remove data properly to prevent clashes

* Add SQL data bundle

* Verify loaded details

* Use email address when getting a student row

* Check student links

* Verify the sending of invites

* Verify the reminding of all students to join

* Remove SQL data properly to prevent clashes

* Verify the downloading of the student list

* Implement helper methods for Student

* Add BaseTestCaseWithSqlDatabaseAccess::verifyAbsentInDatabase

* Add to testng-e2e-sql.xml

* Verify the deleting of students

* Verify the deleting of all the students

* Fix lint

* Remove duplicate equality check for students
  • Loading branch information
jayasting98 authored Mar 27, 2024
1 parent 20df6b6 commit a9423da
Show file tree
Hide file tree
Showing 7 changed files with 443 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;
import java.util.Set;

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

Expand Down Expand Up @@ -77,26 +78,26 @@ public void testAll() {
StudentAttributes studentToView = testData.students.get("[email protected]");

InstructorCourseStudentDetailsViewPage studentDetailsViewPage =
detailsPage.clickViewStudent(studentToView);
detailsPage.clickViewStudent(studentToView.getEmail());
studentDetailsViewPage.verifyIsCorrectPage(course.getId(), studentToView.getEmail());
studentDetailsViewPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("link: edit student details page");

InstructorCourseStudentDetailsEditPage studentDetailsEditPage =
detailsPage.clickEditStudent(studentToView);
detailsPage.clickEditStudent(studentToView.getEmail());
studentDetailsEditPage.verifyIsCorrectPage(course.getId(), studentToView.getEmail());
studentDetailsEditPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("link: view all records page");

InstructorStudentRecordsPage studentRecordsPage =
detailsPage.clickViewAllRecords(studentToView);
detailsPage.clickViewAllRecords(studentToView.getEmail());
studentRecordsPage.verifyIsCorrectPage(course.getId(), studentToView.getName());
studentRecordsPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("send invite");
detailsPage.sendInvite(student);
detailsPage.sendInvite(student.getEmail());

detailsPage.verifyStatusMessage("An email has been sent to " + student.getEmail());
String expectedEmailSubject = "TEAMMATES: Invitation to join course ["
Expand All @@ -121,7 +122,7 @@ public void testAll() {
detailsPage.sortByName();
detailsPage.sortByStatus();
StudentAttributes[] studentsAfterDelete = { students[0], students[3], students[1] };
detailsPage.deleteStudent(student);
detailsPage.deleteStudent(student.getEmail());

detailsPage.verifyStatusMessage("Student is successfully deleted from course \""
+ course.getId() + "\"");
Expand All @@ -139,6 +140,11 @@ public void testAll() {
}
}

@AfterClass
public void classTearDown() {
BACKDOOR.removeDataBundle(testData);
}

private void verifyCourseDetails(InstructorCourseDetailsPage detailsPage, CourseAttributes course,
InstructorAttributes[] instructors, StudentAttributes[] students) {
Set<String> sections = new HashSet<>();
Expand Down
11 changes: 11 additions & 0 deletions src/e2e/java/teammates/e2e/cases/sql/BaseE2ETestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
import teammates.e2e.util.TestProperties;
import teammates.storage.sqlentity.FeedbackQuestion;
import teammates.storage.sqlentity.FeedbackResponse;
import teammates.storage.sqlentity.Student;
import teammates.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.test.FileHelper;
import teammates.test.ThreadHelper;
import teammates.ui.output.FeedbackQuestionData;
import teammates.ui.output.FeedbackResponseData;
import teammates.ui.output.StudentData;

/**
* Base class for all browser tests.
Expand Down Expand Up @@ -254,4 +256,13 @@ FeedbackResponseData getFeedbackResponse(String questionId, String giver, String
protected FeedbackResponseData getFeedbackResponse(FeedbackResponse fr) {
return getFeedbackResponse(fr.getFeedbackQuestion().getId().toString(), fr.getGiver(), fr.getRecipient());
}

StudentData getStudent(String courseId, String studentEmailAddress) {
return BACKDOOR.getStudentData(courseId, studentEmailAddress);
}

@Override
protected StudentData getStudent(Student student) {
return getStudent(student.getCourseId(), student.getEmail());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package teammates.e2e.cases.sql;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import teammates.common.util.AppUrl;
import teammates.common.util.Const;
import teammates.e2e.pageobjects.InstructorCourseDetailsPage;
import teammates.e2e.pageobjects.InstructorCourseStudentDetailsEditPage;
import teammates.e2e.pageobjects.InstructorCourseStudentDetailsViewPage;
import teammates.e2e.pageobjects.InstructorStudentRecordsPage;
import teammates.e2e.util.TestProperties;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Instructor;
import teammates.storage.sqlentity.Student;

/**
* SUT: {@link Const.WebPageURIs#INSTRUCTOR_COURSE_DETAILS_PAGE}.
*/
public class InstructorCourseDetailsPageE2ETest extends BaseE2ETestCase {
private Course course;
private Student student3;
private String downloadedFileName;

@Override
protected void prepareTestData() {
testData = loadSqlDataBundle("/InstructorCourseDetailsPageE2ESqlTest.json");
student3 = testData.students.get("[email protected]");
student3.setEmail(TestProperties.TEST_EMAIL);
removeAndRestoreDataBundle(testData);
course = testData.courses.get("ICDet.CS2104");
downloadedFileName = "/" + course.getId() + "_studentList.csv";
}

@BeforeClass
public void classSetup() {
deleteDownloadsFile(downloadedFileName);
}

@AfterClass
public void classTearDown() {
deleteDownloadsFile(downloadedFileName);
BACKDOOR.removeSqlDataBundle(testData);
}

@Test
@Override
protected void testAll() {
Instructor instructor1 = testData.instructors.get("ICDet.instr");
AppUrl detailsPageUrl = createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_COURSE_DETAILS_PAGE)
.withCourseId(course.getId());
InstructorCourseDetailsPage detailsPage =
loginToPage(detailsPageUrl, InstructorCourseDetailsPage.class, instructor1.getGoogleId());

______TS("verify loaded details");
List<Instructor> instructors = Arrays.asList(instructor1, testData.instructors.get("ICDet.instr2"));
List<Student> students = Arrays.asList(
testData.students.get("[email protected]"),
testData.students.get("[email protected]"),
testData.students.get("[email protected]"),
testData.students.get("[email protected]")
);
Set<String> sectionNames = new HashSet<>();
Set<String> teamNames = new HashSet<>();
students.forEach(student -> {
sectionNames.add(student.getSectionName());
teamNames.add(student.getTeamName());
});
detailsPage.verifyCourseDetails(course, instructors, sectionNames.size(), teamNames.size(), students.size());
detailsPage.verifyNumStudents(students.size());
detailsPage.verifyStudentDetails(students);

______TS("link: view student details page");
Student studentToView = testData.students.get("[email protected]");
InstructorCourseStudentDetailsViewPage studentDetailsViewPage =
detailsPage.clickViewStudent(studentToView.getEmail());
studentDetailsViewPage.verifyIsCorrectPage(course.getId(), studentToView.getEmail());
studentDetailsViewPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("link: edit student details page");
InstructorCourseStudentDetailsEditPage studentDetailsEditPage =
detailsPage.clickEditStudent(studentToView.getEmail());
studentDetailsEditPage.verifyIsCorrectPage(course.getId(), studentToView.getEmail());
studentDetailsEditPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("link: view all records page");
InstructorStudentRecordsPage studentRecordsPage =
detailsPage.clickViewAllRecords(studentToView.getEmail());
studentRecordsPage.verifyIsCorrectPage(course.getId(), studentToView.getName());
studentRecordsPage.closeCurrentWindowAndSwitchToParentWindow();

______TS("send invite");
detailsPage.sendInvite(student3.getEmail());
detailsPage.verifyStatusMessage("An email has been sent to " + student3.getEmail());
String expectedEmailSubject = "TEAMMATES: Invitation to join course ["
+ course.getName() + "][Course ID: " + course.getId() + "]";
verifyEmailSent(student3.getEmail(), expectedEmailSubject);

______TS("remind all students to join");
detailsPage.remindAllToJoin();
detailsPage.verifyStatusMessage("Emails have been sent to unregistered students.");
verifyEmailSent(student3.getEmail(), expectedEmailSubject);

______TS("download student list");
detailsPage.downloadStudentList();
String status = "Yet to Join";
String[] studentInfo = { student3.getTeamName(), student3.getName(), status, student3.getEmail() };
List<String> expectedContent = Arrays.asList("Course ID," + course.getId(),
"Course Name," + course.getName(), String.join(",", studentInfo));
verifyDownloadedFile(downloadedFileName, expectedContent);

______TS("delete student");
detailsPage.sortByName();
detailsPage.sortByStatus();
List<Student> studentsAfterDelete = Arrays.asList(
testData.students.get("[email protected]"),
testData.students.get("[email protected]"),
testData.students.get("[email protected]")
);
detailsPage.deleteStudent(student3.getEmail());
detailsPage.verifyStatusMessage("Student is successfully deleted from course \""
+ course.getId() + "\"");
detailsPage.verifyNumStudents(studentsAfterDelete.size());
detailsPage.verifyStudentDetails(studentsAfterDelete);
verifyAbsentInDatabase(student3);

______TS("delete all students");
detailsPage.deleteAllStudents();
detailsPage.verifyStatusMessage("All the students have been removed from the course");
detailsPage.verifyNumStudents(0);
studentsAfterDelete.forEach(this::verifyAbsentInDatabase);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import teammates.common.datatransfer.attributes.InstructorAttributes;
import teammates.common.datatransfer.attributes.StudentAttributes;
import teammates.e2e.util.TestProperties;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.Instructor;
import teammates.storage.sqlentity.Student;
import teammates.test.ThreadHelper;

/**
Expand Down Expand Up @@ -62,16 +65,31 @@ public void verifyCourseDetails(CourseAttributes course, InstructorAttributes[]
assertEquals(getExpectedInstructorString(instructors), instructorsField.getText());
}

public void verifyCourseDetails(Course course, List<Instructor> instructors, int numSections, int numTeams,
int numStudents) {
assertEquals(course.getId(), courseIdField.getText());
assertEquals(course.getName(), courseNameField.getText());
assertEquals(course.getInstitute(), courseInstituteField.getText());
assertEquals(Integer.toString(numSections), numSectionsField.getText());
assertEquals(Integer.toString(numTeams), numTeamsField.getText());
assertEquals(Integer.toString(numStudents), numStudentsField.getText());
assertEquals(getExpectedInstructorsString(instructors), instructorsField.getText());
}

public void verifyStudentDetails(StudentAttributes[] students) {
verifyTableBodyValues(getStudentList(), getExpectedStudentValues(students));
}

public void verifyStudentDetails(List<Student> students) {
verifyTableBodyValues(getStudentList(), getExpectedStudentValues(students));
}

public void verifyNumStudents(int expected) {
assertEquals(expected, getNumStudents());
}

public void sendInvite(StudentAttributes student) {
clickAndConfirm(getSendInviteButton(student));
public void sendInvite(String studentEmailAddress) {
clickAndConfirm(getSendInviteButton(studentEmailAddress));
}

public void remindAllToJoin() {
Expand All @@ -92,8 +110,8 @@ public void sortByStatus() {
waitUntilAnimationFinish();
}

public void deleteStudent(StudentAttributes student) {
clickAndConfirm(getDeleteButton(student));
public void deleteStudent(String studentEmailAddress) {
clickAndConfirm(getDeleteButton(studentEmailAddress));
}

public void deleteAllStudents() {
Expand All @@ -106,6 +124,13 @@ private String getExpectedInstructorString(InstructorAttributes[] instructors) {
.collect(Collectors.joining(TestProperties.LINE_SEPARATOR));
}

private String getExpectedInstructorsString(List<Instructor> instructors) {
return instructors.stream()
.map(instructor -> instructor.getRole().getRoleName() + ": "
+ instructor.getName() + " (" + instructor.getEmail() + ")")
.collect(Collectors.joining(TestProperties.LINE_SEPARATOR));
}

private WebElement getStudentList() {
return browser.driver.findElement(By.cssSelector("#student-list table"));
}
Expand All @@ -123,13 +148,31 @@ private String[][] getExpectedStudentValues(StudentAttributes[] students) {
return expected;
}

private WebElement getSendInviteButton(StudentAttributes student) {
WebElement studentRow = getStudentRow(student);
private String[][] getExpectedStudentValues(List<Student> students) {
String[][] expected = new String[students.size()][5];
for (int i = 0; i < students.size(); i++) {
Student student = students.get(i);
expected[i][0] = student.getSectionName();
expected[i][1] = student.getTeamName();
expected[i][2] = student.getName();
String googleId = student.getGoogleId();
if (googleId == null || googleId.isEmpty()) {
expected[i][3] = "Yet to Join";
} else {
expected[i][3] = "Joined";
}
expected[i][4] = student.getEmail();
}
return expected;
}

private WebElement getSendInviteButton(String studentEmailAddress) {
WebElement studentRow = getStudentRow(studentEmailAddress);
return studentRow.findElement(By.cssSelector("[id^='btn-send-invite-']"));
}

private WebElement getDeleteButton(StudentAttributes student) {
WebElement studentRow = getStudentRow(student);
private WebElement getDeleteButton(String studentEmailAddress) {
WebElement studentRow = getStudentRow(studentEmailAddress);
return studentRow.findElement(By.cssSelector("[id^='btn-delete-']"));
}

Expand All @@ -145,37 +188,37 @@ private int getNumStudents() {
}
}

private WebElement getStudentRow(StudentAttributes student) {
private WebElement getStudentRow(String studentEmailAddress) {
List<WebElement> studentRows = getAllStudentRows();
for (WebElement studentRow : studentRows) {
List<WebElement> studentCells = studentRow.findElements(By.tagName("td"));
if (studentCells.get(4).getText().equals(student.getEmail())) {
if (studentCells.get(4).getText().equals(studentEmailAddress)) {
return studentRow;
}
}
return null;
}

public InstructorCourseStudentDetailsViewPage clickViewStudent(StudentAttributes student) {
WebElement studentRow = getStudentRow(student);
public InstructorCourseStudentDetailsViewPage clickViewStudent(String studentEmailAddress) {
WebElement studentRow = getStudentRow(studentEmailAddress);
WebElement viewButton = studentRow.findElement(By.cssSelector("[id^='btn-view-details-']"));
click(viewButton);
ThreadHelper.waitFor(2000);
switchToNewWindow();
return changePageType(InstructorCourseStudentDetailsViewPage.class);
}

public InstructorCourseStudentDetailsEditPage clickEditStudent(StudentAttributes student) {
WebElement studentRow = getStudentRow(student);
public InstructorCourseStudentDetailsEditPage clickEditStudent(String studentEmailAddress) {
WebElement studentRow = getStudentRow(studentEmailAddress);
WebElement viewButton = studentRow.findElement(By.cssSelector("[id^='btn-edit-details-']"));
click(viewButton);
ThreadHelper.waitFor(2000);
switchToNewWindow();
return changePageType(InstructorCourseStudentDetailsEditPage.class);
}

public InstructorStudentRecordsPage clickViewAllRecords(StudentAttributes student) {
WebElement studentRow = getStudentRow(student);
public InstructorStudentRecordsPage clickViewAllRecords(String studentEmailAddress) {
WebElement studentRow = getStudentRow(studentEmailAddress);
WebElement viewButton = studentRow.findElement(By.cssSelector("[id^='btn-view-records-']"));
click(viewButton);
ThreadHelper.waitFor(2000);
Expand Down
Loading

0 comments on commit a9423da

Please sign in to comment.