Skip to content

Commit db2087f

Browse files
TheZokerbensofficial
authored andcommitted
Development: Add file upload e2e tests (#6940)
1 parent 894133c commit db2087f

21 files changed

+442
-10
lines changed

src/main/webapp/app/exam/participate/exercises/file-upload/file-upload-exam-submission.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<input #fileInput id="fileUploadInput" type="file" class="custom-file-input" (change)="setFileSubmissionForExercise($event)" />
2020
</div>
2121
<div class="col-4">
22-
<button class="btn btn-primary" (click)="saveUploadedFile()">
22+
<button class="btn btn-primary" id="file-upload-submit" (click)="saveUploadedFile()">
2323
{{ 'artemisApp.examParticipation.uploadFile' | artemisTranslate }}
2424
</button>
2525
</div>
@@ -47,7 +47,7 @@ <h6>
4747
<!--endregion-->
4848
<!--region Right Panel-->
4949
<fa-icon right-header [icon]="farListAlt"></fa-icon>&nbsp;
50-
<span right-header jhiTranslate="artemisApp.exercise.problemStatement">Problem Statement</span>
50+
<span id="problem-statement" right-header jhiTranslate="artemisApp.exercise.problemStatement">Problem Statement</span>
5151

5252
<!-- problem statement update & difference highlighter -->
5353
<jhi-exam-exercise-update-highlighter *ngIf="exercise" [exercise]="exercise" (problemStatementUpdateEvent)="updateProblemStatement($event)">

src/main/webapp/app/exercises/file-upload/assess/file-upload-assessment.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<fa-icon right-header [icon]="farListAlt"></fa-icon>&nbsp;
4040
<span right-header jhiTranslate="artemisApp.assessmentInstructions.instructions.instructions">Instructions</span>
4141
<div right-body class="alert alert-info text-center mb-4" role="alert" jhiTranslate="artemisApp.textAssessment.assessmentInstruction"></div>
42-
<jhi-assessment-instructions right-body [exercise]="exercise!" class="markdown-preview"></jhi-assessment-instructions>
42+
<jhi-assessment-instructions id="instructions-card" right-body [exercise]="exercise!" class="markdown-preview"></jhi-assessment-instructions>
4343
<!--endregion-->
4444
</jhi-resizeable-container>
4545
<!--Feedbacks-->

src/main/webapp/app/exercises/file-upload/manage/file-upload-exercise.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
</tr>
2020
</thead>
2121
<tbody class="markdown-preview">
22-
<tr *ngFor="let fileUploadExercise of filteredFileUploadExercises; trackBy: trackId">
22+
<tr *ngFor="let fileUploadExercise of filteredFileUploadExercises; trackBy: trackId" id="exercise-card-{{ fileUploadExercise.id }}">
2323
<td>
2424
<a *ngIf="fileUploadExercise.isAtLeastEditor; else showId" [routerLink]="['/course-management', courseId, 'file-upload-exercises', fileUploadExercise.id]">
2525
{{ fileUploadExercise.id }}
@@ -77,6 +77,7 @@
7777
</a>
7878
<button
7979
*ngIf="fileUploadExercise.isAtLeastInstructor"
80+
id="delete-exercise"
8081
jhiDeleteButton
8182
[entityTitle]="fileUploadExercise.title!"
8283
deleteQuestion="artemisApp.exercise.delete.question"

src/main/webapp/app/exercises/file-upload/participate/file-upload-submission.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
</span>
66
<jhi-button
77
submitbutton
8+
id="submit"
89
*ngIf="isOwnerOfParticipation"
910
[disabled]="(!isActive && !isLate) || !submission || !submissionFile || !!result"
1011
[title]="!isLate ? 'entity.action.submit' : 'entity.action.submitDueDateMissed'"
@@ -76,7 +77,7 @@ <h5><span jhiTranslate="artemisApp.fileUploadExercise.assessedSubmission">Your A
7677
<!--endregion-->
7778
<!--region Right Panel-->
7879
<fa-icon right-header [icon]="farListAlt"></fa-icon>&nbsp;
79-
<span right-header jhiTranslate="artemisApp.exercise.problemStatement">Problem Statement</span>
80+
<span id="problem-statement" right-header jhiTranslate="artemisApp.exercise.problemStatement">Problem Statement</span>
8081
<p right-body class="mb-3 markdown-preview" *ngIf="fileUploadExercise!.problemStatement">
8182
<span [innerHTML]="fileUploadExercise!.problemStatement! | htmlForMarkdown"></span>
8283
</p>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { FileUploadExercise } from 'app/entities/file-upload-exercise.model';
2+
import { Course } from 'app/entities/course.model';
3+
import {
4+
courseAssessment,
5+
courseManagement,
6+
courseManagementRequest,
7+
courseOverview,
8+
exerciseAssessment,
9+
exerciseResult,
10+
fileUploadExerciseAssessment,
11+
fileUploadExerciseEditor,
12+
fileUploadExerciseFeedback,
13+
} from 'src/test/cypress/support/artemis';
14+
import { admin, instructor, studentOne, tutor } from 'src/test/cypress/support/users';
15+
import { convertModelAfterMultiPart } from 'src/test/cypress/support/requests/CourseManagementRequests';
16+
17+
// Common primitives
18+
const tutorFeedback = 'Try to use some newlines next time!';
19+
const tutorFeedbackPoints = 4;
20+
const complaint = "That feedback wasn't very useful!";
21+
22+
describe('File upload exercise assessment', () => {
23+
let course: Course;
24+
let exercise: FileUploadExercise;
25+
26+
before('Creates a file upload exercise and makes a student submission', () => {
27+
cy.login(admin);
28+
courseManagementRequest.createCourse().then((response) => {
29+
course = convertModelAfterMultiPart(response);
30+
courseManagementRequest.addStudentToCourse(course, studentOne);
31+
courseManagementRequest.addTutorToCourse(course, tutor);
32+
courseManagementRequest.addInstructorToCourse(course, instructor);
33+
courseManagementRequest.createFileUploadExercise({ course }).then((textResponse) => {
34+
exercise = textResponse.body;
35+
cy.login(studentOne, `/courses/${course.id}/exercises`);
36+
courseOverview.startExercise(exercise.id!);
37+
courseOverview.openRunningExercise(exercise.id!);
38+
fileUploadExerciseEditor.attachFile('pdf-test-file.pdf');
39+
fileUploadExerciseEditor.submit();
40+
});
41+
});
42+
});
43+
44+
it('Assesses the file upload exercise submission', () => {
45+
cy.login(tutor, '/course-management');
46+
courseManagement.openAssessmentDashboardOfCourse(course.id!);
47+
courseAssessment.clickExerciseDashboardButton();
48+
exerciseAssessment.clickHaveReadInstructionsButton();
49+
exerciseAssessment.clickStartNewAssessment();
50+
fileUploadExerciseAssessment.getInstructionsRootElement().contains(exercise.title!).should('be.visible');
51+
fileUploadExerciseAssessment.getInstructionsRootElement().contains(exercise.problemStatement!).should('be.visible');
52+
fileUploadExerciseAssessment.getInstructionsRootElement().contains(exercise.exampleSolution!).should('be.visible');
53+
fileUploadExerciseAssessment.getInstructionsRootElement().contains(exercise.gradingInstructions!).should('be.visible');
54+
fileUploadExerciseAssessment.addNewFeedback(tutorFeedbackPoints, tutorFeedback);
55+
fileUploadExerciseAssessment.submitFeedback();
56+
});
57+
58+
describe('Feedback', () => {
59+
it('Student sees feedback after assessment due date and complains', () => {
60+
cy.login(studentOne, `/courses/${course.id}/exercises/${exercise.id}`);
61+
const percentage = tutorFeedbackPoints * 10;
62+
exerciseResult.shouldShowExerciseTitle(exercise.title!);
63+
exerciseResult.shouldShowProblemStatement(exercise.problemStatement!);
64+
exerciseResult.shouldShowScore(percentage);
65+
exerciseResult.clickOpenExercise(exercise.id!);
66+
fileUploadExerciseFeedback.shouldShowAdditionalFeedback(tutorFeedbackPoints, tutorFeedback);
67+
fileUploadExerciseFeedback.shouldShowScore(percentage);
68+
fileUploadExerciseFeedback.complain(complaint);
69+
});
70+
71+
it('Instructor can see complaint and reject it', () => {
72+
cy.login(instructor, `/course-management/${course.id}/complaints`);
73+
fileUploadExerciseAssessment.acceptComplaint('Makes sense', false).its('response.statusCode').should('eq', 200);
74+
});
75+
});
76+
77+
after('Delete course', () => {
78+
courseManagementRequest.deleteCourse(course, admin);
79+
});
80+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { Interception } from 'cypress/types/net-stubbing';
2+
import { FileUploadExercise } from 'app/entities/file-upload-exercise.model';
3+
import { Course } from 'app/entities/course.model';
4+
import { generateUUID } from '../../../support/utils';
5+
import dayjs from 'dayjs/esm';
6+
import { courseManagement, courseManagementExercises, courseManagementRequest, fileUploadExerciseCreation, navigationBar } from 'src/test/cypress/support/artemis';
7+
import { admin } from 'src/test/cypress/support/users';
8+
import { convertModelAfterMultiPart } from 'src/test/cypress/support/requests/CourseManagementRequests';
9+
10+
describe('File upload exercise management', () => {
11+
let course: Course;
12+
13+
before(() => {
14+
cy.login(admin);
15+
courseManagementRequest.createCourse().then((response) => {
16+
course = convertModelAfterMultiPart(response);
17+
});
18+
});
19+
20+
it('Creates a file upload exercise in the UI', () => {
21+
cy.visit('/');
22+
navigationBar.openCourseManagement();
23+
courseManagement.openExercisesOfCourse(course.id!);
24+
courseManagementExercises.createFileUploadExercise();
25+
26+
// Fill out file upload exercise form
27+
const exerciseTitle = 'file upload exercise' + generateUUID();
28+
fileUploadExerciseCreation.typeTitle(exerciseTitle);
29+
fileUploadExerciseCreation.setReleaseDate(dayjs());
30+
fileUploadExerciseCreation.setDueDate(dayjs().add(1, 'days'));
31+
fileUploadExerciseCreation.setAssessmentDueDate(dayjs().add(2, 'days'));
32+
fileUploadExerciseCreation.typeMaxPoints(10);
33+
const problemStatement = 'This is a problem statement';
34+
const exampleSolution = 'E = mc^2';
35+
fileUploadExerciseCreation.typeProblemStatement(problemStatement);
36+
fileUploadExerciseCreation.typeExampleSolution(exampleSolution);
37+
let exercise: FileUploadExercise;
38+
fileUploadExerciseCreation.create().then((request: Interception) => {
39+
exercise = request.response!.body;
40+
});
41+
42+
// Make sure file upload exercise is shown in exercises list
43+
cy.visit(`course-management/${course.id}/exercises`).then(() => {
44+
courseManagementExercises.getExercise(exercise.id!).should('be.visible');
45+
});
46+
});
47+
48+
describe('File upload exercise deletion', () => {
49+
let exercise: FileUploadExercise;
50+
51+
before(() => {
52+
cy.login(admin, '/');
53+
courseManagementRequest.createFileUploadExercise({ course }).then((response) => {
54+
exercise = response.body;
55+
});
56+
});
57+
58+
it('Deletes an existing file upload exercise', () => {
59+
cy.login(admin, '/');
60+
navigationBar.openCourseManagement();
61+
courseManagement.openExercisesOfCourse(course.id!);
62+
courseManagementExercises.deleteFileUploadExercise(exercise);
63+
courseManagementExercises.getExercise(exercise.id!).should('not.exist');
64+
});
65+
});
66+
67+
after('Delete course', () => {
68+
courseManagementRequest.deleteCourse(course, admin);
69+
});
70+
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { FileUploadExercise } from 'app/entities/file-upload-exercise.model';
2+
import { Course } from 'app/entities/course.model';
3+
import { courseManagementRequest, courseOverview, fileUploadExerciseEditor } from 'src/test/cypress/support/artemis';
4+
import { admin, studentOne } from 'src/test/cypress/support/users';
5+
import { convertModelAfterMultiPart } from 'src/test/cypress/support/requests/CourseManagementRequests';
6+
import { Interception } from 'cypress/types/net-stubbing';
7+
8+
describe('File upload exercise participation', () => {
9+
let course: Course;
10+
let exercise: FileUploadExercise;
11+
12+
before(() => {
13+
cy.login(admin);
14+
courseManagementRequest.createCourse().then((response) => {
15+
course = convertModelAfterMultiPart(response);
16+
courseManagementRequest.addStudentToCourse(course, studentOne);
17+
courseManagementRequest.createFileUploadExercise({ course }).then((exerciseResponse) => {
18+
exercise = exerciseResponse.body;
19+
});
20+
});
21+
});
22+
23+
it('Creates a file upload exercise in the UI', () => {
24+
cy.login(studentOne, `/courses/${course.id}/exercises`);
25+
courseOverview.startExercise(exercise.id!);
26+
courseOverview.openRunningExercise(exercise.id!);
27+
28+
// Verify the initial state of the text editor
29+
fileUploadExerciseEditor.shouldShowExerciseTitleInHeader(exercise.title!);
30+
fileUploadExerciseEditor.shouldShowProblemStatement();
31+
32+
// Make a submission
33+
fileUploadExerciseEditor.attachFile('pdf-test-file.pdf');
34+
fileUploadExerciseEditor.submit().then((request: Interception) => {
35+
expect(request.response!.body.submitted).to.be.true;
36+
expect(request.response!.statusCode).to.eq(200);
37+
});
38+
});
39+
40+
after('Delete course', () => {
41+
courseManagementRequest.deleteCourse(course, admin);
42+
});
43+
});

src/test/cypress/e2e/exercises/programming/ProgrammingExerciseManagement.cy.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,21 @@ describe('Programming Exercise Management', () => {
3939
});
4040

4141
describe('Programming exercise deletion', () => {
42-
let programmingExercise: ProgrammingExercise;
42+
let exercise: ProgrammingExercise;
4343

4444
before(() => {
4545
cy.login(admin, '/');
4646
courseManagementRequest.createProgrammingExercise({ course }).then((response) => {
47-
programmingExercise = response.body;
47+
exercise = response.body;
4848
});
4949
});
5050

5151
it('Deletes an existing programming exercise', () => {
5252
cy.login(admin, '/');
5353
navigationBar.openCourseManagement();
5454
courseManagement.openExercisesOfCourse(course.id!);
55-
courseManagementExercises.deleteProgrammingExercise(programmingExercise);
56-
courseManagementExercises.getExercise(programmingExercise.id!).should('not.exist');
55+
courseManagementExercises.deleteProgrammingExercise(exercise);
56+
courseManagementExercises.getExercise(exercise.id!).should('not.exist');
5757
});
5858
});
5959

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"files": [
3+
{
4+
"name": "BubbleSort.java",
5+
"path": "programming_exercise_submissions/build_error/BubbleSort.txt"
6+
}
7+
]
8+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"mode": "INDIVIDUAL",
3+
"includedInOverallScore": "INCLUDED_COMPLETELY",
4+
"studentAssignedTeamIdComputed": false,
5+
"secondCorrectionEnabled": false,
6+
"type": "file-upload",
7+
"bonusPoints": 0,
8+
"isAtLeastTutor": false,
9+
"isAtLeastEditor": false,
10+
"isAtLeastInstructor": false,
11+
"teamMode": false,
12+
"assessmentDueDateError": false,
13+
"dueDateError": false,
14+
"exampleSolutionPublicationDateError": false,
15+
"exampleSolutionPublicationDateWarning": false,
16+
"presentationScoreEnabled": false,
17+
"assessmentType": "MANUAL",
18+
"title": "File Upload Exercise 1",
19+
"filePattern": "pdf",
20+
"maxPoints": 10,
21+
"problemStatement": "Problem Statement",
22+
"exampleSolution": "Example Solution",
23+
"gradingInstructions": "Assessment Instructions"
24+
}

0 commit comments

Comments
 (0)