Skip to content

Commit

Permalink
Merge branch 'master' into migrate-InstructorNotificationsPageE2ETest
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricongjh authored Feb 24, 2024
2 parents c747cbb + fdba184 commit 0fef2d0
Show file tree
Hide file tree
Showing 9 changed files with 618 additions and 21 deletions.
29 changes: 25 additions & 4 deletions src/e2e/java/teammates/e2e/cases/sql/BaseE2ETestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@
import teammates.e2e.util.BackDoor;
import teammates.e2e.util.EmailAccount;
import teammates.e2e.util.TestProperties;
import teammates.storage.sqlentity.FeedbackQuestion;
import teammates.storage.sqlentity.FeedbackResponse;
import teammates.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.test.FileHelper;
import teammates.test.ThreadHelper;
import teammates.ui.output.FeedbackQuestionData;
import teammates.ui.output.FeedbackResponseData;

/**
* Base class for all browser tests.
Expand Down Expand Up @@ -224,13 +228,30 @@ protected void verifyEmailSent(String email, String subject) {
* Removes and restores the databundle using BACKDOOR.
*/
@Override
protected boolean doRemoveAndRestoreDataBundle(SqlDataBundle testData) {
protected SqlDataBundle doRemoveAndRestoreDataBundle(SqlDataBundle testData) {
try {
BACKDOOR.removeAndRestoreSqlDataBundle(testData);
return true;
return BACKDOOR.removeAndRestoreSqlDataBundle(testData);
} catch (HttpRequestFailedException e) {
e.printStackTrace();
return false;
return null;
}
}

FeedbackQuestionData getFeedbackQuestion(String courseId, String feedbackSessionName, int qnNumber) {
return BACKDOOR.getFeedbackQuestionData(courseId, feedbackSessionName, qnNumber);
}

@Override
protected FeedbackQuestionData getFeedbackQuestion(FeedbackQuestion fq) {
return getFeedbackQuestion(fq.getCourseId(), fq.getFeedbackSession().getName(), fq.getQuestionNumber());
}

FeedbackResponseData getFeedbackResponse(String questionId, String giver, String recipient) {
return BACKDOOR.getFeedbackResponseData(questionId, recipient, recipient);
}

@Override
protected FeedbackResponseData getFeedbackResponse(FeedbackResponse fr) {
return getFeedbackResponse(fr.getFeedbackQuestion().getId().toString(), fr.getGiver(), fr.getRecipient());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package teammates.e2e.cases.sql;

import teammates.common.util.AppUrl;
import teammates.common.util.Const;
import teammates.e2e.pageobjects.FeedbackSubmitPage;
import teammates.e2e.pageobjects.InstructorFeedbackEditPage;
import teammates.storage.sqlentity.Course;
import teammates.storage.sqlentity.FeedbackSession;
import teammates.storage.sqlentity.Instructor;
import teammates.storage.sqlentity.Student;

/**
* Base class for all feedback question related browser tests.
*
* <p>SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE}, {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}.
*
* <p>Only UI-intensive operations, e.g. question creation and response submission, are tested separately.
* This is so that if any part of the testing fails (due to regression or inherent instability), only the
* specific test for the specific feedback question needs to be re-run.
*
* <p>For the above reason, viewing feedback responses/results is not considered to be under this test case.
* This is because viewing results is a fast action and combining all question types together under one test case
* will save some testing time.
*/
public abstract class BaseFeedbackQuestionE2ETest extends BaseE2ETestCase {
Instructor instructor;
Course course;
FeedbackSession feedbackSession;
Student student;

abstract void testEditPage();

abstract void testSubmitPage();

InstructorFeedbackEditPage loginToFeedbackEditPage() {
AppUrl url = createFrontendUrl(Const.WebPageURIs.INSTRUCTOR_SESSION_EDIT_PAGE)
.withCourseId(course.getId())
.withSessionName(feedbackSession.getName());

return loginToPage(url, InstructorFeedbackEditPage.class, instructor.getGoogleId());
}

FeedbackSubmitPage loginToFeedbackSubmitPage() {
AppUrl url = createFrontendUrl(Const.WebPageURIs.STUDENT_SESSION_SUBMISSION_PAGE)
.withCourseId(student.getCourse().getId())
.withSessionName(feedbackSession.getName());

return loginToPage(url, FeedbackSubmitPage.class, student.getGoogleId());
}

FeedbackSubmitPage getFeedbackSubmitPage() {
AppUrl url = createFrontendUrl(Const.WebPageURIs.STUDENT_SESSION_SUBMISSION_PAGE)
.withCourseId(student.getCourse().getId())
.withSessionName(feedbackSession.getName());

return getNewPageInstance(url, FeedbackSubmitPage.class);
}
}
111 changes: 111 additions & 0 deletions src/e2e/java/teammates/e2e/cases/sql/FeedbackTextQuestionE2ETest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package teammates.e2e.cases.sql;

import org.testng.annotations.Test;

import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;
import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;
import teammates.e2e.pageobjects.FeedbackSubmitPage;
import teammates.e2e.pageobjects.InstructorFeedbackEditPage;
import teammates.storage.sqlentity.FeedbackQuestion;
import teammates.storage.sqlentity.FeedbackResponse;
import teammates.storage.sqlentity.Instructor;

/**
* SUT: {@link Const.WebPageURIs#INSTRUCTOR_SESSION_EDIT_PAGE}, {@link Const.WebPageURIs#SESSION_SUBMISSION_PAGE}
* specifically for text questions.
*/
public class FeedbackTextQuestionE2ETest extends BaseFeedbackQuestionE2ETest {

@Override
protected void prepareTestData() {
testData = removeAndRestoreDataBundle(loadSqlDataBundle("/FeedbackTextQuestionE2ESqlTest.json"));

instructor = testData.instructors.get("instructor");
course = testData.courses.get("course");
feedbackSession = testData.feedbackSessions.get("openSession");
student = testData.students.get("[email protected]");
}

@Test
@Override
public void testAll() {
testEditPage();
logout();
testSubmitPage();
}

@Override
protected void testEditPage() {
InstructorFeedbackEditPage feedbackEditPage = loginToFeedbackEditPage();

______TS("verify loaded question");
FeedbackQuestion loadedQuestion = testData.feedbackQuestions.get("qn1ForFirstSession");
FeedbackTextQuestionDetails questionDetails = (FeedbackTextQuestionDetails) loadedQuestion.getQuestionDetailsCopy();
feedbackEditPage.verifyTextQuestionDetails(1, questionDetails);

______TS("add new question");
// add new question exactly like loaded question
loadedQuestion.setQuestionNumber(2);
feedbackEditPage.addTextQuestion(loadedQuestion);

feedbackEditPage.verifyTextQuestionDetails(2, questionDetails);
verifyPresentInDatabase(loadedQuestion);

______TS("copy question");
FeedbackQuestion copiedQuestion = testData.feedbackQuestions.get("qn1ForSecondSession");
questionDetails = (FeedbackTextQuestionDetails) copiedQuestion.getQuestionDetailsCopy();
feedbackEditPage.copyQuestion(copiedQuestion.getCourseId(),
copiedQuestion.getQuestionDetailsCopy().getQuestionText());
copiedQuestion.setQuestionNumber(3);
copiedQuestion.setFeedbackSession(feedbackSession);

feedbackEditPage.verifyTextQuestionDetails(3, questionDetails);
verifyPresentInDatabase(copiedQuestion);

______TS("edit question");
questionDetails.setRecommendedLength(200);
copiedQuestion.setQuestionDetails(questionDetails);
feedbackEditPage.editTextQuestion(3, questionDetails);

feedbackEditPage.verifyTextQuestionDetails(3, questionDetails);
verifyPresentInDatabase(copiedQuestion);
}

@Override
protected void testSubmitPage() {
FeedbackSubmitPage feedbackSubmitPage = loginToFeedbackSubmitPage();

______TS("verify loaded question");
FeedbackQuestion question = testData.feedbackQuestions.get("qn1ForFirstSession");
Instructor receiver = testData.instructors.get("instructor");
question.setQuestionNumber(1);
feedbackSubmitPage.verifyTextQuestion(1, (FeedbackTextQuestionDetails) question.getQuestionDetailsCopy());

______TS("submit response");
FeedbackResponse response = getResponse(question, receiver, "<p>This is the response for qn 1</p>");
feedbackSubmitPage.fillTextResponse(1, receiver.getName(), response);
feedbackSubmitPage.clickSubmitQuestionButton(1);

// TODO: uncomment when SubmitFeedbackResponse is working
// verifyPresentInDatabase(response);

// ______TS("check previous response");
// feedbackSubmitPage = getFeedbackSubmitPage();
// feedbackSubmitPage.verifyTextResponse(1, receiver.getName(), response);

// ______TS("edit response");
// FeedbackResponse editedResponse = getResponse(question, receiver, "<p><strong>Edited response</strong></p>");
// feedbackSubmitPage.fillTextResponse(1, receiver.getName(), editedResponse);
// feedbackSubmitPage.clickSubmitQuestionButton(1);

// feedbackSubmitPage = getFeedbackSubmitPage();
// feedbackSubmitPage.verifyTextResponse(1, receiver.getName(), response);
// verifyPresentInDatabase(editedResponse);
}

private FeedbackResponse getResponse(FeedbackQuestion feedbackQuestion, Instructor instructor, String answer) {
FeedbackTextResponseDetails details = new FeedbackTextResponseDetails(answer);
return FeedbackResponse.makeResponse(
feedbackQuestion, student.getEmail(), null, instructor.getEmail(), null, details);
}
}
16 changes: 16 additions & 0 deletions src/e2e/java/teammates/e2e/pageobjects/FeedbackSubmitPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;
import teammates.common.datatransfer.questions.FeedbackTextResponseDetails;
import teammates.common.util.Const;
import teammates.storage.sqlentity.FeedbackResponse;

/**
* Represents the feedback submission page of the website.
Expand Down Expand Up @@ -155,6 +156,12 @@ public void fillTextResponse(int qnNumber, String recipient, FeedbackResponseAtt
writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());
}

public void fillTextResponse(int qnNumber, String recipient, FeedbackResponse response) {
FeedbackTextResponseDetails responseDetails =
(FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();
writeToRichTextEditor(getTextResponseEditor(qnNumber, recipient), responseDetails.getAnswer());
}

public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponseAttributes response) {
FeedbackTextResponseDetails responseDetails = (FeedbackTextResponseDetails) response.getResponseDetailsCopy();
int responseLength = responseDetails.getAnswer().split(" ").length;
Expand All @@ -163,6 +170,15 @@ public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponseA
+ " words");
}

public void verifyTextResponse(int qnNumber, String recipient, FeedbackResponse response) {
FeedbackTextResponseDetails responseDetails =
(FeedbackTextResponseDetails) response.getFeedbackResponseDetailsCopy();
int responseLength = responseDetails.getAnswer().split(" ").length;
assertEquals(getEditorRichText(getTextResponseEditor(qnNumber, recipient)), responseDetails.getAnswer());
assertEquals(getResponseLengthText(qnNumber, recipient), "Response length: " + responseLength
+ " words");
}

public void verifyMcqQuestion(int qnNumber, String recipient, FeedbackMcqQuestionDetails questionDetails) {
List<String> mcqChoices = questionDetails.getMcqChoices();
List<WebElement> optionTexts = getMcqOptions(qnNumber, recipient);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import teammates.common.datatransfer.questions.FeedbackRubricQuestionDetails;
import teammates.common.datatransfer.questions.FeedbackTextQuestionDetails;
import teammates.common.util.Const;
import teammates.storage.sqlentity.FeedbackQuestion;
import teammates.test.ThreadHelper;

/**
Expand Down Expand Up @@ -535,6 +536,16 @@ private void inputQuestionDetails(int questionNum, FeedbackQuestionAttributes fe
}
}

private void inputQuestionDetails(int questionNum, FeedbackQuestion feedbackQuestion) {
setQuestionBrief(questionNum, feedbackQuestion.getQuestionDetailsCopy().getQuestionText());
setQuestionDescription(questionNum, feedbackQuestion.getDescription());
FeedbackQuestionType questionType = feedbackQuestion.getQuestionDetailsCopy().getQuestionType();
if (!questionType.equals(FeedbackQuestionType.CONTRIB)) {
setFeedbackPath(questionNum, feedbackQuestion);
setQuestionVisibility(questionNum, feedbackQuestion);
}
}

public void duplicateQuestion(int questionNum) {
clickAndWaitForNewQuestion(getQuestionForm(questionNum).findElement(By.id("btn-duplicate-question")));
}
Expand All @@ -558,6 +569,16 @@ public void addTextQuestion(FeedbackQuestionAttributes feedbackQuestion) {
clickSaveNewQuestionButton();
}

public void addTextQuestion(FeedbackQuestion feedbackQuestion) {
addNewQuestion(2);
int questionNum = getNumQuestions();
inputQuestionDetails(questionNum, feedbackQuestion);
FeedbackTextQuestionDetails questionDetails =
(FeedbackTextQuestionDetails) feedbackQuestion.getQuestionDetailsCopy();
fillTextBox(getRecommendedTextLengthField(questionNum), questionDetails.getRecommendedLength().toString());
clickSaveNewQuestionButton();
}

public void editTextQuestion(int questionNum, FeedbackTextQuestionDetails textQuestionDetails) {
clickEditQuestionButton(questionNum);
WebElement recommendedTextLengthField = getRecommendedTextLengthField(questionNum);
Expand Down Expand Up @@ -1073,6 +1094,32 @@ private void setFeedbackPath(int questionNum, FeedbackQuestionAttributes feedbac
getDisplayRecipientName(newRecipient));
}

private void setFeedbackPath(int questionNum, FeedbackQuestion feedbackQuestion) {
FeedbackParticipantType newGiver = feedbackQuestion.getGiverType();
FeedbackParticipantType newRecipient = feedbackQuestion.getRecipientType();
String feedbackPath = getFeedbackPath(questionNum);
WebElement questionForm = getQuestionForm(questionNum).findElement(By.tagName("tm-feedback-path-panel"));
if (!CUSTOM_FEEDBACK_PATH_OPTION.equals(feedbackPath)) {
selectFeedbackPathDropdownOption(questionNum, CUSTOM_FEEDBACK_PATH_OPTION + "...");
}
// Set to type STUDENT first to adjust NumberOfEntitiesToGiveFeedbackTo
selectDropdownOptionByText(questionForm.findElement(By.id("giver-type")),
getDisplayGiverName(FeedbackParticipantType.STUDENTS));
selectDropdownOptionByText(questionForm.findElement(By.id("receiver-type")),
getDisplayRecipientName(FeedbackParticipantType.STUDENTS_EXCLUDING_SELF));
if (feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo() == Const.MAX_POSSIBLE_RECIPIENTS) {
click(questionForm.findElement(By.id("unlimited-recipients")));
} else {
click(questionForm.findElement(By.id("custom-recipients")));
fillTextBox(questionForm.findElement(By.id("custom-recipients-number")),
Integer.toString(feedbackQuestion.getNumOfEntitiesToGiveFeedbackTo()));
}

selectDropdownOptionByText(questionForm.findElement(By.id("giver-type")), getDisplayGiverName(newGiver));
selectDropdownOptionByText(questionForm.findElement(By.id("receiver-type")),
getDisplayRecipientName(newRecipient));
}

private void selectFeedbackPathDropdownOption(int questionNum, String text) {
WebElement questionForm = getQuestionForm(questionNum);
WebElement feedbackPathPanel = questionForm.findElement(By.tagName("tm-feedback-path-panel"));
Expand Down Expand Up @@ -1113,6 +1160,22 @@ private void setQuestionVisibility(int questionNum, FeedbackQuestionAttributes f
selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);
}

private void setQuestionVisibility(int questionNum, FeedbackQuestion feedbackQuestion) {
WebElement questionForm = getQuestionForm(questionNum);
WebElement visibilityPanel = questionForm.findElement(By.tagName("tm-visibility-panel"));
String visibility = visibilityPanel.findElement(By.cssSelector("#btn-question-visibility span")).getText();
if (!CUSTOM_VISIBILITY_OPTION.equals(visibility)) {
selectVisibilityDropdownOption(questionNum, CUSTOM_VISIBILITY_OPTION + "...");
}

FeedbackParticipantType giver = feedbackQuestion.getGiverType();
FeedbackParticipantType receiver = feedbackQuestion.getRecipientType();
WebElement customVisibilityTable = visibilityPanel.findElement(By.id("custom-visibility-table"));
selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowResponsesTo(), 1);
selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowGiverNameTo(), 2);
selectVisibilityBoxes(customVisibilityTable, giver, receiver, feedbackQuestion.getShowRecipientNameTo(), 3);
}

private void selectVisibilityBoxes(WebElement table, FeedbackParticipantType giver,
FeedbackParticipantType receiver, List<FeedbackParticipantType> participants,
int colNum) {
Expand Down
Loading

0 comments on commit 0fef2d0

Please sign in to comment.