Skip to content

Commit

Permalink
Development: Add e2e tests for instructors assessing exams in the sec…
Browse files Browse the repository at this point in the history
…ond round (#9863)
  • Loading branch information
muradium authored Nov 28, 2024
1 parent dcdb973 commit e6e63ba
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ <h4 jhiTranslate="artemisApp.assessmentDashboard.exerciseTable.title"></h4>
<ng-container class="col-lg-3 col-md-6 col-sm-6">
<jhi-second-correction-enable-button
class="me-1 mb-1"
data-testid="toggle-second-correction"
(ngModelChange)="toggleSecondCorrection(exercise.id!)"
[secondCorrectionEnabled]="exercise.secondCorrectionEnabled"
[togglingSecondCorrectionButton]="isTogglingSecondCorrection.get(exercise.id!)!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
@if (exercise.isAtLeastInstructor && exam?.numberOfCorrectionRoundsInExam && exam?.numberOfCorrectionRoundsInExam! > 1 && isExamMode && !isTestRun) {
<div class="d-inline-block">
<jhi-second-correction-enable-button
data-testid="toggle-second-correction"
(ngModelChange)="toggleSecondCorrection()"
[secondCorrectionEnabled]="secondCorrectionEnabled"
[togglingSecondCorrectionButton]="togglingSecondCorrectionButton"
Expand Down
53 changes: 30 additions & 23 deletions src/test/playwright/e2e/exam/ExamAssessment.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ test.beforeAll('Create course', async ({ browser }) => {

test.describe('Exam assessment', () => {
test.describe.configure({ mode: 'serial' });
let programmingAssessmentSuccessful = false;
let modelingAssessmentSuccessful = false;
let textAssessmentSuccessful = false;

test.describe.serial('Programming exercise assessment', { tag: '@sequential' }, () => {
test.beforeAll('Prepare exam', async ({ browser }) => {
Expand All @@ -76,13 +73,10 @@ test.describe('Exam assessment', () => {
await examAssessment.submit();
await login(studentOne, `/courses/${course.id}/exams/${exam.id}`);
await examParticipation.checkResultScore('66.2%');
programmingAssessmentSuccessful = true;
});

test('Complaints about programming exercises assessment', async ({ examAssessment, page, studentAssessment, examManagement, courseAssessment, exerciseAssessment }) => {
if (programmingAssessmentSuccessful) {
await handleComplaint(course, exam, false, ExerciseType.PROGRAMMING, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment);
}
await handleComplaint(course, exam, false, ExerciseType.PROGRAMMING, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment);
});
});

Expand Down Expand Up @@ -117,21 +111,18 @@ test.describe('Exam assessment', () => {
await login(studentOne, `/courses/${course.id}/exams/${exam.id}`);

await examParticipation.checkResultScore('40%');
modelingAssessmentSuccessful = true;
});

test('Complaints about modeling exercises assessment', async ({ examAssessment, page, studentAssessment, examManagement, courseAssessment, exerciseAssessment }) => {
if (modelingAssessmentSuccessful) {
await handleComplaint(course, exam, true, ExerciseType.MODELING, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment);
}
await handleComplaint(course, exam, true, ExerciseType.MODELING, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment);
});
});

test.describe.serial('Text exercise assessment', { tag: '@slow' }, () => {
test.beforeAll('Prepare exam', async ({ browser }) => {
examEnd = dayjs().add(40, 'seconds');
examEnd = dayjs().add(20, 'seconds');
const page = await newBrowserPage(browser);
await prepareExam(course, examEnd, ExerciseType.TEXT, page);
await prepareExam(course, examEnd, ExerciseType.TEXT, page, 2);
});

test('Assess a text exercise submission', async ({ login, examManagement, examAssessment, examParticipation, courseAssessment, exerciseAssessment }) => {
Expand All @@ -144,13 +135,20 @@ test.describe('Exam assessment', () => {
expect(response.status()).toBe(200);
await login(studentOne, `/courses/${course.id}/exams/${exam.id}`);
await examParticipation.checkResultScore('70%');
textAssessmentSuccessful = true;
});

test('Instructor makes a second round of assessment', async ({ login, examManagement, examAssessment, examParticipation, courseAssessment, exerciseAssessment }) => {
await login(instructor);
await startAssessing(course.id!, exam.id!, 60000, examManagement, courseAssessment, exerciseAssessment, true, true);
await examAssessment.fillFeedback(9, 'Great job');
const response = await examAssessment.submitTextAssessment();
expect(response.status()).toBe(200);
await login(studentOne, `/courses/${course.id}/exams/${exam.id}`);
await examParticipation.checkResultScore('90%');
});

test('Complaints about text exercises assessment', async ({ examAssessment, page, studentAssessment, examManagement, courseAssessment, exerciseAssessment }) => {
if (textAssessmentSuccessful) {
await handleComplaint(course, exam, false, ExerciseType.TEXT, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment);
}
await handleComplaint(course, exam, true, ExerciseType.TEXT, page, studentAssessment, examManagement, examAssessment, courseAssessment, exerciseAssessment, false);
});
});

Expand Down Expand Up @@ -296,7 +294,7 @@ test.afterAll('Delete course', async ({ browser }) => {
await courseManagementAPIRequests.deleteCourse(course, admin);
});

export async function prepareExam(course: Course, end: dayjs.Dayjs, exerciseType: ExerciseType, page: Page): Promise<Exam> {
export async function prepareExam(course: Course, end: dayjs.Dayjs, exerciseType: ExerciseType, page: Page, numberOfCorrectionRounds: number = 1): Promise<Exam> {
const examAPIRequests = new ExamAPIRequests(page);
const exerciseAPIRequests = new ExerciseAPIRequests(page);
const examExerciseGroupCreation = new ExamExerciseGroupCreationPage(page, examAPIRequests, exerciseAPIRequests);
Expand Down Expand Up @@ -326,7 +324,7 @@ export async function prepareExam(course: Course, end: dayjs.Dayjs, exerciseType
course,
startDate: dayjs(),
endDate: end,
numberOfCorrectionRoundsInExam: 1,
numberOfCorrectionRoundsInExam: numberOfCorrectionRounds,
examStudentReviewStart: resultDate,
examStudentReviewEnd: resultDate.add(1, 'minute'),
publishResultsDate: resultDate,
Expand Down Expand Up @@ -379,10 +377,17 @@ async function startAssessing(
examManagement: ExamManagementPage,
courseAssessment: CourseAssessmentDashboardPage,
exerciseAssessment: ExerciseAssessmentDashboardPage,
toggleSecondRound: boolean = false,
isFirstTimeAssessing: boolean = true,
) {
await examManagement.openAssessmentDashboard(courseID, examID, timeout);
await courseAssessment.clickExerciseDashboardButton();
await exerciseAssessment.clickHaveReadInstructionsButton();
if (toggleSecondRound) {
await exerciseAssessment.toggleSecondCorrectionRound();
}
if (isFirstTimeAssessing) {
await exerciseAssessment.clickHaveReadInstructionsButton();
}
await exerciseAssessment.clickStartNewAssessment();
exerciseAssessment.getLockedMessage();
}
Expand All @@ -398,6 +403,7 @@ async function handleComplaint(
examAssessment: ExamAssessmentPage,
courseAssessment: CourseAssessmentDashboardPage,
exerciseAssessment: ExerciseAssessmentDashboardPage,
isFirstTimeAssessing: boolean = true,
) {
const complaintText = 'Lorem ipsum dolor sit amet';
const complaintResponseText = ' consetetur sadipscing elitr';
Expand All @@ -411,8 +417,9 @@ async function handleComplaint(
await Commands.login(page, instructor, `/course-management/${course.id}/exams`);
await examManagement.openAssessmentDashboard(course.id!, exam.id!);
await courseAssessment.clickExerciseDashboardButton();
await exerciseAssessment.clickHaveReadInstructionsButton();

if (isFirstTimeAssessing) {
await exerciseAssessment.clickHaveReadInstructionsButton();
}
await exerciseAssessment.clickEvaluateComplaint();
await exerciseAssessment.checkComplaintText(complaintText);
page.on('dialog', (dialog) => dialog.accept());
Expand All @@ -421,7 +428,7 @@ async function handleComplaint(
} else {
await examAssessment.acceptComplaint(complaintResponseText, true, exerciseType);
}
if (exerciseType == ExerciseType.MODELING) {
if (exerciseType == ExerciseType.MODELING || reject) {
await examAssessment.checkComplaintMessage('Response to complaint has been submitted');
} else {
await examAssessment.checkComplaintMessage('The assessment was updated successfully.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export abstract class AbstractExerciseAssessmentPage {

async addNewFeedback(points: number, feedback?: string) {
await this.page.locator('.add-unreferenced-feedback').click();
await this.fillFeedback(points, feedback);
}

async fillFeedback(points: number, feedback?: string) {
const unreferencedFeedback = this.page.locator('.unreferenced-feedback-detail');
await unreferencedFeedback.locator('#feedback-points').clear();
await unreferencedFeedback.locator('#feedback-points').fill(points.toString());
Expand Down Expand Up @@ -61,7 +65,11 @@ export abstract class AbstractExerciseAssessmentPage {
responsePromise = this.page.waitForResponse(`${BASE_API}/programming-submissions/*/assessment-after-complaint`);
break;
case ExerciseType.TEXT:
responsePromise = this.page.waitForResponse(`${BASE_API}/participations/*/submissions/*/text-assessment-after-complaint`);
if (accept) {
responsePromise = this.page.waitForResponse(`${BASE_API}/participations/*/submissions/*/text-assessment-after-complaint`);
} else {
responsePromise = this.page.waitForResponse(`${BASE_API}/complaints/*/response`);
}
break;
case ExerciseType.MODELING:
responsePromise = this.page.waitForResponse(`${BASE_API}/complaints/*/response`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export class ExerciseAssessmentDashboardPage {
await this.page.click('#participate-in-assessment');
}

async clickStartNewAssessment() {
const startAssessingButton = this.page.locator('#start-new-assessment');
async clickStartNewAssessment(assessmentRound: number = 1) {
const startAssessingButton = this.page.locator('#start-new-assessment').nth(assessmentRound - 1);
await Commands.reloadUntilFound(this.page, startAssessingButton);
await startAssessingButton.click();
}
Expand All @@ -38,4 +38,8 @@ export class ExerciseAssessmentDashboardPage {
async checkComplaintText(complaintText: string) {
await expect(this.getComplaintText()).toHaveValue(complaintText);
}

async toggleSecondCorrectionRound() {
await this.page.getByTestId('toggle-second-correction').click();
}
}

0 comments on commit e6e63ba

Please sign in to comment.