Compare commits
48 Commits
Eden-Tests
...
Hui-Organi
Author | SHA1 | Date |
---|---|---|
|
21918cf883 | |
|
62966c82fa | |
|
bc77fa1aa4 | |
|
9a4a8d2818 | |
|
07ba57eebb | |
|
1f602e3db2 | |
|
5ce55c3f1e | |
|
9d170fea87 | |
|
0f42a68461 | |
|
e8bbce386a | |
|
545915b8be | |
|
aa82e9b5db | |
|
0a12b69d2c | |
|
54cb51d3a6 | |
|
5cef5875f6 | |
|
5e1cfcbbcc | |
|
44aa38be76 | |
|
debd85e74d | |
|
39c14f7425 | |
|
1ed7e2e394 | |
|
a34ab61916 | |
|
33f997412b | |
|
b1dbd94b00 | |
|
7388868678 | |
|
aa85b742f5 | |
|
e1c95395ef | |
|
65920bc0ac | |
|
e66af1f419 | |
|
162b347119 | |
|
5ebb0ccd6c | |
|
5bbd812189 | |
|
162de63b4d | |
|
88d20ed476 | |
|
5d0d0d91f7 | |
|
fea32072c3 | |
|
5639ce4c6b | |
|
8f3919d3bb | |
|
23e192568f | |
|
dc3ff79b5d | |
|
690db8d5fe | |
|
f600f2bc24 | |
|
8e200b647f | |
|
dcd0e522c7 | |
|
64ffc3af1c | |
|
9f03d380cd | |
|
c1f95ce017 | |
|
adc9daef98 | |
|
fc8ad0c0a9 |
44
Admin.php
44
Admin.php
|
@ -30,7 +30,7 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
<ul class="nav nav-tabs" id="myTab">
|
<ul class="nav nav-tabs" id="myTab">
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Create student accounts</a>
|
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Enter student numbers</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
|
@ -66,13 +66,13 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<form method="post" action="Script.php" id="create_account_form">
|
<form method="post" action="Script.php" id="create_account_form">
|
||||||
<input type="hidden" name="form_createlecturrer" value="true" required="" />
|
<input type="hidden" name="form_createlecturer" value="true" required="" />
|
||||||
Full name
|
Full name
|
||||||
<input type="text" name="fullname" placeholder="Full Name" class="form-control" required=""> <br>
|
<input type="text" name="fullname" placeholder="Full Name" class="form-control" required=""> <br>
|
||||||
Email
|
Email
|
||||||
<input type="text" name="email" placeholder="Email / Student Number" class="form-control" > <br>
|
<input type="text" name="email" placeholder="Email / Student Number" class="form-control" > <br>
|
||||||
Initial password (Enter a strong password or leave it empty to let LRR generate one)
|
Initial password (Enter a strong password or leave it empty to let LRR generate one)
|
||||||
<input type="password" class="form-control" name="password" minlength="8" placeholder="Initial password" > <br>
|
<input type="password" class="form-control" name="password" minlength="8" placeholder="Initial password" > <br>
|
||||||
User type:
|
User type:
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
@ -93,10 +93,6 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
||||||
$_SESSION['info_Admin_Users'] = null;
|
$_SESSION['info_Admin_Users'] = null;
|
||||||
}
|
}
|
||||||
if (isset($_SESSION['info_Admin_Users'])) {
|
|
||||||
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
|
||||||
$_SESSION['info_Admin_Users'] = null;
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@ -117,10 +113,21 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
if ($_SESSION['user_type'] == "Lecturer") {
|
if ($_SESSION['user_type'] == "Lecturer") {
|
||||||
|
$user_id = $_SESSION['user_id'];
|
||||||
|
echo "<script>console.log('here {$user_id}');</script>"; // debug trick
|
||||||
|
// find the TAs in the courses taught by this instructor
|
||||||
|
$ta_result = mysqli_query(
|
||||||
|
$con,
|
||||||
|
"SELECT TA FROM course_ta INNER JOIN courses_table ON course_ta.Course_ID=courses_table.Course_ID WHERE courses_table.Lecturer_User_ID=$user_id"
|
||||||
|
);
|
||||||
|
$ta_ids = array(-1); // -1 is non-existent ID
|
||||||
|
while ($row = mysqli_fetch_assoc($ta_result)) {
|
||||||
|
array_push($ta_ids, $row['TA']);
|
||||||
|
}
|
||||||
|
$ta_ids2 = implode(', ', $ta_ids);
|
||||||
$result = mysqli_query(
|
$result = mysqli_query(
|
||||||
$con,
|
$con,
|
||||||
"SELECT * FROM users_table WHERE UserType in ('TA')"
|
"SELECT * FROM users_table WHERE UserType in ('TA') and User_ID in ($ta_ids2)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +138,7 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$num_rows = 0;
|
||||||
while ($row = mysqli_fetch_assoc($result)) {
|
while ($row = mysqli_fetch_assoc($result)) {
|
||||||
$pass = $row['Password'];
|
$pass = $row['Password'];
|
||||||
$btn = "<button class='btn btn-warning' onclick=\"updatePassword(" . $row['User_ID'] . ",'$pass')\">Reset</button>";
|
$btn = "<button class='btn btn-warning' onclick=\"updatePassword(" . $row['User_ID'] . ",'$pass')\">Reset</button>";
|
||||||
|
@ -143,6 +151,10 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "<tr><td>" . $row['User_ID'] . "</td><td>" . $row['Full_Name'] . "</td><td>" . $row['Email'] . "</td><td>$btn</td><td>$btnBlock</td></tr>";
|
echo "<tr><td>" . $row['User_ID'] . "</td><td>" . $row['Full_Name'] . "</td><td>" . $row['Email'] . "</td><td>$btn</td><td>$btnBlock</td></tr>";
|
||||||
|
$num_rows += 1;
|
||||||
|
}
|
||||||
|
if ($num_rows == 0) {
|
||||||
|
echo "<p>No TA</p>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</table>
|
</table>
|
||||||
|
@ -227,8 +239,22 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<?php include 'Footer.php';?>
|
<?php include 'Footer.php';?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/** After creating a TA account, stay on the same tab "Create instructor account"
|
||||||
|
Side effect: ?tacreated will be appended on the URL
|
||||||
|
*/
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
if (url.searchParams.has('tacreated')) {
|
||||||
|
const elem = document.querySelector('#tab_ins_accounts');
|
||||||
|
elem.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function updatePassword(id, pass) {
|
function updatePassword(id, pass) {
|
||||||
if (!confirm('Are you sure to reset user password?')) {
|
if (!confirm('Are you sure to reset user password?')) {
|
||||||
|
|
40
Course.php
40
Course.php
|
@ -86,22 +86,22 @@ include 'Header.php';
|
||||||
|
|
||||||
<ul class="nav nav-tabs" id="myTab">
|
<ul class="nav nav-tabs" id="myTab">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" href="#menu1">New</a>
|
<a class="nav-link <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>" data-toggle="tab" href="#menu1">New</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#menu2">Missed</a>
|
<a class="nav-link <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>" data-toggle="tab" href="#menu2">Missed</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#menu3">Submitted</a>
|
<a class="nav-link <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>" data-toggle="tab" href="#menu3">Submitted</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#menu4">Marked</a>
|
<a class="nav-link <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>" data-toggle="tab" href="#menu4">Marked</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
|
||||||
<div id="menu1" class="tab-pane active">
|
<div id="menu1" class="tab-pane <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ include 'Header.php';
|
||||||
$att3 = $row['Attachment_link_3'];
|
$att3 = $row['Attachment_link_3'];
|
||||||
$att4 = $row['Attachment_link_4'];
|
$att4 = $row['Attachment_link_4'];
|
||||||
$labid = $row['Lab_Report_ID'];
|
$labid = $row['Lab_Report_ID'];
|
||||||
$days_remaining = date_diff(date_create($deadline), date_create())->format('%a days, %h hours, %i minutes');
|
$days_remaining = "Days remaining: ".date_diff(date_create($deadline), date_create())->format('%a days, %h hours, %i minutes');
|
||||||
$full_link = "<a href='~\..\Download.php?file=$att1'>$att1</a>";
|
$full_link = "<a href='~\..\Download.php?file=$att1'>$att1</a>";
|
||||||
|
|
||||||
if($att2 != "") {
|
if($att2 != "") {
|
||||||
|
@ -165,6 +165,11 @@ include 'Header.php';
|
||||||
$full_link = $full_link."| <a href='~\..\Download.php?file=$att4'>$att4</a>";
|
$full_link = $full_link."| <a href='~\..\Download.php?file=$att4'>$att4</a>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the student has already submitted the assignment
|
||||||
|
$query_result = mysqli_query($con, "SELECT * FROM lab_report_submissions WHERE Student_id=$student_id AND Lab_Report_ID=$labid");
|
||||||
|
if (mysqli_num_rows($query_result) > 0)
|
||||||
|
$days_remaining = 'You have already submitted this assignment.';
|
||||||
|
|
||||||
echo "<div class='card mt-md-2' style='word-wrap: break-word;'>
|
echo "<div class='card mt-md-2' style='word-wrap: break-word;'>
|
||||||
<div class='card-body'>
|
<div class='card-body'>
|
||||||
<h5 class='card-title'>$title</h5>
|
<h5 class='card-title'>$title</h5>
|
||||||
|
@ -172,7 +177,7 @@ include 'Header.php';
|
||||||
<p class='card-text'> $ins </p>
|
<p class='card-text'> $ins </p>
|
||||||
<p> <small>Attachments</small>: $full_link </p>
|
<p> <small>Attachments</small>: $full_link </p>
|
||||||
<p class='card-text'> <small> Posted: $posted Deadline: $deadline </small> </p>
|
<p class='card-text'> <small> Posted: $posted Deadline: $deadline </small> </p>
|
||||||
<div class='alert alert-warning'>Time left: $days_remaining</div>
|
<div class='alert alert-warning'>$days_remaining</div>
|
||||||
<p><a href='~\..\SubmitLab.php?id=$labid&url=$url' class='btn btn-primary'>Submit</a></p>
|
<p><a href='~\..\SubmitLab.php?id=$labid&url=$url' class='btn btn-primary'>Submit</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>";
|
</div>";
|
||||||
|
@ -185,7 +190,7 @@ include 'Header.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="menu2" class="tab-pane">
|
<div id="menu2" class="tab-pane <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>">
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$group_id = $_SESSION['group_id'];
|
$group_id = $_SESSION['group_id'];
|
||||||
|
@ -251,7 +256,7 @@ include 'Header.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="menu3" class="tab-pane">
|
<div id="menu3" class="tab-pane <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>">
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$group_id = $_SESSION['group_id'];
|
$group_id = $_SESSION['group_id'];
|
||||||
|
@ -324,10 +329,10 @@ include 'Header.php';
|
||||||
$att2 = $row['Attachment2'];
|
$att2 = $row['Attachment2'];
|
||||||
$att3 = $row['Attachment3'];
|
$att3 = $row['Attachment3'];
|
||||||
$att4 = $row['Attachment4'];
|
$att4 = $row['Attachment4'];
|
||||||
$base_att1 = basename($att1);
|
$base_att1 = basename(rawurldecode($att1));
|
||||||
$base_att2 = basename($att2);
|
$base_att2 = basename(rawurldecode($att2));
|
||||||
$base_att3 = basename($att3);
|
$base_att3 = basename(rawurldecode($att3));
|
||||||
$base_att4 = basename($att4);
|
$base_att4 = basename(rawurldecode($att4));
|
||||||
|
|
||||||
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
||||||
|
|
||||||
|
@ -371,7 +376,7 @@ include 'Header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
<div id="menu4" class="tab-pane">
|
<div id="menu4" class="tab-pane <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>">
|
||||||
<?php
|
<?php
|
||||||
$resultx = mysqli_query($con, "SELECT Submission_ID, Submission_Date, lab_reports_table.Lab_Report_ID, Student_id, Course_Group_id, Notes, lab_report_submissions.Marks, lab_report_submissions.Remarking_Reason, Status, lab_reports_table.Title Lab_Title, lab_reports_table.Marks Original_marks
|
$resultx = mysqli_query($con, "SELECT Submission_ID, Submission_Date, lab_reports_table.Lab_Report_ID, Student_id, Course_Group_id, Notes, lab_report_submissions.Marks, lab_report_submissions.Remarking_Reason, Status, lab_reports_table.Title Lab_Title, lab_reports_table.Marks Original_marks
|
||||||
FROM lab_report_submissions
|
FROM lab_report_submissions
|
||||||
|
@ -647,11 +652,12 @@ include 'Header.php';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function remarking(data)
|
function remarking(url)
|
||||||
{
|
{
|
||||||
const details = prompt("Please enter your remarking reasons","");
|
const details = prompt("Please enter your remarking reasons","");
|
||||||
|
if (details != null) {
|
||||||
window.location.href = data+"&details="+details;
|
window.location.href = url+"&details="+details;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ include 'Header.php';
|
||||||
}
|
}
|
||||||
echo "</div>";
|
echo "</div>";
|
||||||
|
|
||||||
$resultx1 = mysqli_query($con, "SELECT course_students_table.Student_ID, users_table.Full_Name
|
$resultx1 = mysqli_query($con, "SELECT DISTINCT course_students_table.Student_ID, users_table.Full_Name
|
||||||
FROM course_students_table
|
FROM course_students_table
|
||||||
INNER JOIN users_table on users_table.Student_ID=course_students_table.Student_ID
|
INNER JOIN users_table on users_table.Student_ID=course_students_table.Student_ID
|
||||||
WHERE Course_ID=$course_id");
|
WHERE Course_ID=$course_id");
|
||||||
|
@ -494,6 +494,10 @@ include 'Header.php';
|
||||||
echo '<hr><span class="alert alert-success" role="alert">' . $_SESSION['info_Courses_student'] . '</span>';
|
echo '<hr><span class="alert alert-success" role="alert">' . $_SESSION['info_Courses_student'] . '</span>';
|
||||||
$_SESSION['info_Courses_student'] = null;
|
$_SESSION['info_Courses_student'] = null;
|
||||||
}
|
}
|
||||||
|
if (isset($_SESSION['info_signup'])) {
|
||||||
|
echo '<hr><div class="alert alert-danger" role="alert">' . $_SESSION['info_signup'] . '</div>';
|
||||||
|
$_SESSION['info_signup'] = null;
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<br><br>
|
<br><br>
|
||||||
</div>
|
</div>
|
||||||
|
@ -534,7 +538,7 @@ include 'Header.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mysqli_num_rows($result) == 0) {
|
if (mysqli_num_rows($result) == 0) {
|
||||||
echo "No results. <hr>";
|
echo "No such course offered in this academic year. Please check that your have entered the correct course code.<hr>";
|
||||||
} else {
|
} else {
|
||||||
while($row = mysqli_fetch_assoc($result)) {
|
while($row = mysqli_fetch_assoc($result)) {
|
||||||
$name = $row['Course_Name'];
|
$name = $row['Course_Name'];
|
||||||
|
|
|
@ -4,11 +4,16 @@ error_reporting(0);
|
||||||
date_default_timezone_set('Asia/Shanghai');
|
date_default_timezone_set('Asia/Shanghai');
|
||||||
|
|
||||||
include "get_mysql_credentials.php";
|
include "get_mysql_credentials.php";
|
||||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
try {
|
||||||
|
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||||
|
} catch (mysqli_sql_exception $e) {
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
// Check database connection
|
// Check database connection
|
||||||
if (mysqli_connect_errno()) {
|
if (mysqli_connect_errno()) {
|
||||||
echo "Failed to connect to MySQL: " . mysqli_connect_error();
|
echo " Error number: ".mysqli_connect_errno();
|
||||||
|
exit();
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
23
README.md
23
README.md
|
@ -3,9 +3,9 @@
|
||||||
LRR (Lab Report Repository) is an online software application for course instructors to post, receive and mark assignments, and for students to submit assignments, or submit re-marking requests.
|
LRR (Lab Report Repository) is an online software application for course instructors to post, receive and mark assignments, and for students to submit assignments, or submit re-marking requests.
|
||||||
|
|
||||||
This software was originally developed by Mahomed Nor in 2018, a graduate student in the Department of Computer Science at the Zhejiang Normal University,
|
This software was originally developed by Mahomed Nor in 2018, a graduate student in the Department of Computer Science at the Zhejiang Normal University,
|
||||||
while he was taking a graduate course called **Advanced Software Engineering** (http://lanlab.org/course/2018f/se/homepage.html).
|
while he was taking a graduate course called Advanced Software Engineering.
|
||||||
|
|
||||||
The LRR's project home page is at http://121.4.94.30/homepage/. For potential project contributors, we recommend that you browse its home page first to familiarize yourself with the project.
|
For potential project contributors, we recommend that you browse its home page at ./homepage/index.html first to familiarize yourself with the project.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,7 +159,16 @@ https://github.com/spm2020spring/TeamCollaborationTutorial/blob/master/team.rst
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Make sure your changes can pass all the tests in folder [./test](http://121.4.94.30:3000/mrlan/LRR/src/branch/master/test).
|
Make sure your changes can pass all the tests in folder ./test.
|
||||||
|
|
||||||
|
You cannot do too much unit testing for LRR because it almost does not
|
||||||
|
have functions or classes. However, you can do end-to-end testing.
|
||||||
|
It is important that you *restore* the database each time before your
|
||||||
|
run a test case. The fixture *restore_database* in ./test/conftest.py
|
||||||
|
is used to restore the database. Please check that. A use case for
|
||||||
|
this fixture can be found in the test script
|
||||||
|
./test/SeleniumMpiana/test_bug418_yaaqob.py. You could run this test script
|
||||||
|
by typing the following command: `pytest ./SeleniumMpiana/test_bug418_yaaqob.py`
|
||||||
|
|
||||||
|
|
||||||
## Communications Method
|
## Communications Method
|
||||||
|
@ -173,10 +182,10 @@ We can also communicate through pull requests. You make a pull request, I revie
|
||||||
## Frequently Asked Questions
|
## Frequently Asked Questions
|
||||||
|
|
||||||
|
|
||||||
1. Q: The web application's front page does not show properly, i.e., elements are not well aligned.
|
1. Q: The web application's front page does not show properly, i.e., elements are not well aligned.
|
||||||
A: You missed two folders `css` and `font-awesome`. These folders include third-party js or css files and therefore are not included.
|
A: You missed two folders `css` and `font-awesome`. These folders include third-party js or css files and therefore are not included.
|
||||||
|
|
||||||
1. Q: What if I do not have any information about the `lrr` database?
|
1. Q: What if I do not have any information about the `lrr` database?
|
||||||
A: You could use `lrr_database.sql` to make a new database.
|
A: You could use `lrr_database.sql` to make a new database.
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,6 +258,6 @@ Nicole-Rutagengwa - Nicole Rutagengwa - 2019169
|
||||||
|
|
||||||
# References
|
# References
|
||||||
|
|
||||||
- 詹沈晨. (2020). [网页程序测试自动化 (Selenium) 测试效率](http://lanlab.org/ZhanShenchen-On-Automated-Web-Application-Test-Efficiency-with-Selenium.doc)
|
- 詹沈晨. (2020). 网页程序测试自动化 (Selenium) 测试效率.
|
||||||
|
|
||||||
- Ibrahim. (2021). [Defect analysis for LRR](http://lanlab.org/thesis/Defect-Analysis-for-LRR.docx)
|
- Ibrahim. (2021). Defect analysis for LRR]
|
||||||
|
|
154
Script.php
154
Script.php
|
@ -70,15 +70,20 @@ if (!empty($_POST["form_signup"])) {
|
||||||
// check if email is taken
|
// check if email is taken
|
||||||
$result = mysqli_query($con, "SELECT * FROM users_table WHERE email='$email'");
|
$result = mysqli_query($con, "SELECT * FROM users_table WHERE email='$email'");
|
||||||
if (mysqli_num_rows($result) != 0) {
|
if (mysqli_num_rows($result) != 0) {
|
||||||
$_SESSION["info_signup"] = "Email address " . $email . " is already in use.";
|
$_SESSION["info_signup"] = "Email address " . $email . " is already in use. You have already signed up?";
|
||||||
$_SESSION['user_fullname'] = null;
|
|
||||||
header("Location: signup.php");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$_SESSION['user_fullname'] = $_POST["fullname"];
|
||||||
|
$_SESSION['user_fullname_temp'] = $_POST["fullname"];
|
||||||
|
$_SESSION['user_email'] = $_POST["email"];
|
||||||
|
$_SESSION['user_student_id_temp'] = $_POST["user_student_id"];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// validate student number
|
// validate student number
|
||||||
if (!is_valid_student_number($student_id)) {
|
if (!is_valid_student_number($student_id)) {
|
||||||
$_SESSION["info_signup"] = "Invalid student number.";
|
$_SESSION["info_signup"] = "Invalid student number.";
|
||||||
|
$_SESSION['user_fullname'] = null;
|
||||||
header("Location: signup.php");
|
header("Location: signup.php");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +92,10 @@ if (!empty($_POST["form_signup"])) {
|
||||||
$result = mysqli_query($con, "SELECT * FROM `students_data` WHERE Student_ID='$student_id'");
|
$result = mysqli_query($con, "SELECT * FROM `students_data` WHERE Student_ID='$student_id'");
|
||||||
if (mysqli_num_rows($result) == 0) {
|
if (mysqli_num_rows($result) == 0) {
|
||||||
$_SESSION["info_signup"] = "Your entered student number could not be verified. Please contact Student Management Office <lanhui at zjnu.edu.cn>. Thanks.";
|
$_SESSION["info_signup"] = "Your entered student number could not be verified. Please contact Student Management Office <lanhui at zjnu.edu.cn>. Thanks.";
|
||||||
|
$_SESSION['user_fullname'] = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
header("Location: signup.php");
|
header("Location: signup.php");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +106,7 @@ if (!empty($_POST["form_signup"])) {
|
||||||
$student_result = mysqli_query($con, "SELECT * FROM `users_table` WHERE Student_ID='$student_id'");
|
$student_result = mysqli_query($con, "SELECT * FROM `users_table` WHERE Student_ID='$student_id'");
|
||||||
if (mysqli_num_rows($student_result) > 0) {
|
if (mysqli_num_rows($student_result) > 0) {
|
||||||
$_SESSION["info_signup"] = "This Student ID is already in use! Please contact Student Management Office <lanhui at zjnu.edu.cn> for help.";
|
$_SESSION["info_signup"] = "This Student ID is already in use! Please contact Student Management Office <lanhui at zjnu.edu.cn> for help.";
|
||||||
|
$_SESSION['user_fullname'] = null;
|
||||||
header("Location: signup.php");
|
header("Location: signup.php");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -106,15 +116,65 @@ if (!empty($_POST["form_signup"])) {
|
||||||
if (!empty($_POST["form_signup"])) {
|
if (!empty($_POST["form_signup"])) {
|
||||||
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
||||||
$student_id = mysqli_real_escape_string($con, $_POST["user_student_id"]);
|
$student_id = mysqli_real_escape_string($con, $_POST["user_student_id"]);
|
||||||
$_SESSION['user_fullname'] = $fullname;
|
|
||||||
|
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
||||||
|
$password = mysqli_real_escape_string($con, $_POST["password"]);
|
||||||
|
$confirmpassword = mysqli_real_escape_string($con, $_POST["confirmpassword"]);
|
||||||
|
|
||||||
|
$_SESSION['user_student_id'] = $_POST["student_id"];
|
||||||
|
$_SESSION['user_type'] = "Student";
|
||||||
|
|
||||||
|
// check confirmed password
|
||||||
|
if (strcasecmp($password, $confirmpassword) != 0) {
|
||||||
|
$_SESSION['info_signup'] = "Password confirmation failed.";
|
||||||
|
$_SESSION['user_fullname'] = null; // such that Header.php do not show the header information.
|
||||||
|
header("Location: signup.php");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate email
|
||||||
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
$_SESSION['info_signup'] = "Invalid email address.";
|
||||||
|
$_SESSION['user_fullname'] = null;
|
||||||
|
|
||||||
|
header("Location: signup.php");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$upperLetter = preg_match('@[A-Z]@', $password);
|
||||||
|
$smallLetter = preg_match('@[a-z]@', $password);
|
||||||
|
$containsDigit = preg_match('@[0-9]@', $password);
|
||||||
|
$containsSpecial = preg_match('@[^\w]@', $password);
|
||||||
|
$containsAll = $upperLetter && $smallLetter && $containsDigit && $containsSpecial;
|
||||||
|
|
||||||
|
// check for strong password
|
||||||
|
if (!$containsAll) {
|
||||||
|
$_SESSION['info_signup'] = "Password must have at least characters that include lowercase letters, uppercase letters, numbers and special characters (e.g., !?.,*^).";
|
||||||
|
$_SESSION['user_fullname'] = null;
|
||||||
|
|
||||||
|
header("Location: signup.php");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if email is taken
|
||||||
|
$result = mysqli_query($con, "SELECT * FROM users_table WHERE email='$email'");
|
||||||
|
if(mysqli_num_rows($result) != 0)
|
||||||
|
{
|
||||||
|
$_SESSION["info_signup"]="Email address ".$email." is already in use. Do you have an old LRR account?";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$_SESSION['user_type'] = "Student";
|
$_SESSION['user_type'] = "Student";
|
||||||
$_SESSION['user_email'] = $email;
|
$_SESSION['user_email'] = $email;
|
||||||
$_SESSION['user_student_id'] = $student_id;
|
$_SESSION['user_student_id'] = $student_id;
|
||||||
|
|
||||||
// apply password_hash()
|
// apply password_hash()
|
||||||
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
||||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
|
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
|
||||||
. "('$email','$password_hash','$fullname','Student','$student_id')";
|
. "('$email','$password_hash','','$fullname','Student','$student_id')";
|
||||||
|
|
||||||
|
|
||||||
|
$_SESSION['user_fullname'] =$_SESSION['user_fullname_temp'];
|
||||||
|
|
||||||
if ($con->query($sql) === TRUE) {
|
if ($con->query($sql) === TRUE) {
|
||||||
header("Location: Courses.php");
|
header("Location: Courses.php");
|
||||||
|
@ -130,11 +190,15 @@ if (!empty($_POST["form_login"])) {
|
||||||
$user = mysqli_real_escape_string($con, $_POST["user"]); // user could be a 12-digit student number or an email address
|
$user = mysqli_real_escape_string($con, $_POST["user"]); // user could be a 12-digit student number or an email address
|
||||||
$is_student_number = 0;
|
$is_student_number = 0;
|
||||||
|
|
||||||
|
$_SESSION["failed_login_user"] = $user; // Save the entered username in a session variable
|
||||||
|
echo "Failed login user: " . $_SESSION["failed_login_user"];
|
||||||
|
|
||||||
// Validate student number
|
// Validate student number
|
||||||
if (is_valid_student_number($user)) {
|
if (is_valid_student_number($user)) {
|
||||||
$is_student_number = 1;
|
$is_student_number = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Validate email address if what provided is not a student number
|
// Validate email address if what provided is not a student number
|
||||||
if (!$is_student_number && !filter_var($user, FILTER_VALIDATE_EMAIL)) {
|
if (!$is_student_number && !filter_var($user, FILTER_VALIDATE_EMAIL)) {
|
||||||
$_SESSION["info_login"] = "Invalid email address: " . "$user";
|
$_SESSION["info_login"] = "Invalid email address: " . "$user";
|
||||||
|
@ -176,10 +240,19 @@ if (!empty($_POST["form_login"])) {
|
||||||
header("Location: Admin.php");
|
header("Location: Admin.php");
|
||||||
}
|
}
|
||||||
// report wrong pass if not correct
|
// report wrong pass if not correct
|
||||||
} else {
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
$_SESSION["wrong_pass"] = "Wrong Password.";
|
$_SESSION["wrong_pass"] = "Wrong Password.";
|
||||||
|
echo $_SESSION["wrong_pass"]; // Optional: Display the error message for debugging
|
||||||
|
|
||||||
header("Location: index.php");
|
header("Location: index.php");
|
||||||
|
exit(); // Add this line to prevent further execution after redirect
|
||||||
}
|
}
|
||||||
|
// Add the following line to reset the session variable when needed
|
||||||
|
unset($_SESSION["failed_login_user"]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,53 +290,8 @@ if (!empty($_POST["form_recover_password"])) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ################################ RESET Password #####################################
|
|
||||||
|
|
||||||
if (!empty($_POST["form_reset_password"])) {
|
|
||||||
$password = mysqli_real_escape_string($con, $_POST["password"]);
|
|
||||||
$token = mysqli_real_escape_string($con, $_POST["token"]);
|
|
||||||
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
|
||||||
$result = mysqli_query(
|
|
||||||
$con,
|
|
||||||
"SELECT * FROM Users_Table WHERE email='$email'"
|
|
||||||
);
|
|
||||||
if (mysqli_num_rows($result) == 0) {
|
|
||||||
|
|
||||||
echo "invalid email";
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
while ($row = mysqli_fetch_assoc($result)) {
|
|
||||||
|
|
||||||
$userid = $row['User_ID'];
|
|
||||||
|
|
||||||
$email = $row['Email'];
|
|
||||||
$id = $row['Student_ID'];
|
|
||||||
|
|
||||||
$user_token = $userid * $userid * $userid + $userid * 0.00343;
|
|
||||||
if ($user_token == $token) {
|
|
||||||
// Password Update
|
|
||||||
|
|
||||||
// Password Update
|
|
||||||
$hashed_password = hash('sha512', $password);
|
|
||||||
$sql = "UPDATE users_table set HashPassword='$hashed_password' where User_ID='$userid';";
|
|
||||||
if ($con->query($sql) === TRUE) {
|
|
||||||
|
|
||||||
error_reporting(0);
|
|
||||||
|
|
||||||
$_SESSION["info_login"] = " Password changed successfully , you can login now with your new password ";
|
|
||||||
header("Location: index.php");
|
|
||||||
} else {
|
|
||||||
echo "Error: " . $sql . "<br>" . $con->error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo "Invalid Token ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ############################### CREATE Lecturer/TA USER ##################################
|
// ############################### CREATE Lecturer/TA USER ##################################
|
||||||
if (!empty($_POST["form_createlecturrer"])){
|
if (!empty($_POST["form_createlecturer"])){
|
||||||
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
||||||
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
||||||
$type = mysqli_real_escape_string($con, $_POST["type"]);
|
$type = mysqli_real_escape_string($con, $_POST["type"]);
|
||||||
|
@ -283,17 +311,15 @@ if (!empty($_POST["form_createlecturrer"])){
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$password_hash = password_hash("$password", PASSWORD_DEFAULT);
|
$password_hash = password_hash("$password", PASSWORD_DEFAULT);
|
||||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`) VALUES "
|
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`) VALUES ('$email','$password_hash','','$fullname','$type')";
|
||||||
. "('$email','$password_hash','$fullname','$type')";
|
|
||||||
|
|
||||||
if ($con->query($sql) === TRUE) {
|
try {
|
||||||
|
$result = mysqli_query($con, $sql);
|
||||||
$_SESSION["info_Admin_Users"] = $type . " user created successfully. Use email " . $email . " as account name and ". $password ." as password.";
|
$_SESSION["info_Admin_Users"] = $type . " user created successfully. Use email " . $email . " as account name and ". $password ." as password.";
|
||||||
header("Location: Admin.php");
|
header("Location: Admin.php?tacreated");
|
||||||
|
} catch (Exception $ex) {
|
||||||
} else {
|
echo "$ex";
|
||||||
alert("Error: " . $sql . "<br>" . $con->error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ### FUNCTION TO GENERATE INITIAL PASSWORDS ###//
|
// ### FUNCTION TO GENERATE INITIAL PASSWORDS ###//
|
||||||
|
@ -713,8 +739,8 @@ if (!empty($_GET["remarking"])) {
|
||||||
|
|
||||||
if ($con->query($sql) === TRUE) {
|
if ($con->query($sql) === TRUE) {
|
||||||
|
|
||||||
$_SESSION["info_general"] = "Remarking request sent";
|
$_SESSION["info_general"] = "Remarking Request Sent";
|
||||||
header("Location: Course.php?url=" . $url);
|
header("Location: Course.php?url=" . $url . "&tab=Marked");
|
||||||
} else {
|
} else {
|
||||||
echo "Error: " . $sql . "<br>" . $con->error;
|
echo "Error: " . $sql . "<br>" . $con->error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,10 +151,10 @@ echo "<div><a href='Courses.php?course=$url'> $header </a></div>";
|
||||||
$submitted_by = "$student_name ($submitter_student_number) for group $groupname ";
|
$submitted_by = "$student_name ($submitter_student_number) for group $groupname ";
|
||||||
}
|
}
|
||||||
|
|
||||||
$base_att1 = basename($att1);
|
$base_att1 = basename(rawurldecode($att1));
|
||||||
$base_att2 = basename($att2);
|
$base_att2 = basename(rawurldecode($att2));
|
||||||
$base_att3 = basename($att3);
|
$base_att3 = basename(rawurldecode($att3));
|
||||||
$base_att4 = basename($att4);
|
$base_att4 = basename(rawurldecode($att4));
|
||||||
|
|
||||||
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ if (isset($_SESSION["user_fullname"])) {
|
||||||
<legend>Sign in</legend>
|
<legend>Sign in</legend>
|
||||||
<input type="hidden" name="form_login" value="true"/>
|
<input type="hidden" name="form_login" value="true"/>
|
||||||
<label for="user_name" class="form-label">Account name</label>
|
<label for="user_name" class="form-label">Account name</label>
|
||||||
<input type="text" name="user" placeholder="Student Number / Email address" class="form-control" required="required" id="user_name" />
|
<input type="text" name="user" placeholder="Student Number / Email address" class="form-control" required="required" id="user_name" value="<?php echo isset($_SESSION['failed_login_user']) ? htmlspecialchars($_SESSION['failed_login_user']) : ''; ?>" />
|
||||||
<br>
|
<br>
|
||||||
<label for="user_password" class="form-label">Password</label>
|
<label for="user_password" class="form-label">Password</label>
|
||||||
<input type="password" class="form-control" name="password" placeholder="password" required="required" id="user_password" />
|
<input type="password" class="form-control" name="password" placeholder="password" required="required" id="user_password" />
|
||||||
|
|
|
@ -61,7 +61,7 @@ CREATE TABLE `courses_table` (
|
||||||
|
|
||||||
INSERT INTO `courses_table` (`Course_ID`, `Course_Name`, `Academic_Year`, `Faculty`, `Lecturer_User_ID`, `TA_User_ID`, `Course_Code`, `URL`, `Verify_New_Members`) VALUES
|
INSERT INTO `courses_table` (`Course_ID`, `Course_Name`, `Academic_Year`, `Faculty`, `Lecturer_User_ID`, `TA_User_ID`, `Course_Code`, `URL`, `Verify_New_Members`) VALUES
|
||||||
(10, 'Software Engineering', '2018', 'Computing', 8, 0, 'CSC1234', 'CSC12342018', '1'),
|
(10, 'Software Engineering', '2018', 'Computing', 8, 0, 'CSC1234', 'CSC12342018', '1'),
|
||||||
(11, 'Project Management', '2019', 'Computing', 8, 0, 'P.M2019', 'P.M20192019', '0'),
|
(11, 'Project Management', '2024', 'Computing', 8, 0, 'CSC1111', 'CSC11112024', '0'),
|
||||||
(12, 'Ashly Course Testing', '2020', 'Testing', 8, 0, 'Teecloudy', 'Teecloudy2020', '1');
|
(12, 'Ashly Course Testing', '2020', 'Testing', 8, 0, 'Teecloudy', 'Teecloudy2020', '1');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
@ -136,7 +136,7 @@ INSERT INTO `course_students_table` (`Course_ID`, `Student_ID`, `ID`, `Status`)
|
||||||
(10, '201825800050', 13, 'Joined'),
|
(10, '201825800050', 13, 'Joined'),
|
||||||
(10, '201825800054', 14, 'Joined'),
|
(10, '201825800054', 14, 'Joined'),
|
||||||
(12, '201632120150', 15, 'Joined'),
|
(12, '201632120150', 15, 'Joined'),
|
||||||
(12, '2016321201502', 16, 'Joined'),
|
(12, '201632120150', 16, 'Joined'),
|
||||||
(12, '201825800050', 17, 'Joined');
|
(12, '201825800050', 17, 'Joined');
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
@ -200,7 +200,7 @@ CREATE TABLE `lab_reports_table` (
|
||||||
|
|
||||||
INSERT INTO `lab_reports_table` (`Lab_Report_ID`, `Course_ID`, `Posted_Date`, `Deadline`, `Instructions`, `Title`, `Attachment_link_1`, `Attachment_link_2`, `Attachment_link_3`, `Attachment_link_4`, `Marks`, `Type`) VALUES
|
INSERT INTO `lab_reports_table` (`Lab_Report_ID`, `Course_ID`, `Posted_Date`, `Deadline`, `Instructions`, `Title`, `Attachment_link_1`, `Attachment_link_2`, `Attachment_link_3`, `Attachment_link_4`, `Marks`, `Type`) VALUES
|
||||||
(1, 10, '2019-01-11 16:52', '2019-02-11 17:00', 'Description of the lab....', 'Reading 1', '700IMPORTANT WORDS.txt', '', '', '', '4', 'Individual'),
|
(1, 10, '2019-01-11 16:52', '2019-02-11 17:00', 'Description of the lab....', 'Reading 1', '700IMPORTANT WORDS.txt', '', '', '', '4', 'Individual'),
|
||||||
(2, 10, '2019-01-17 11:12', '2019-01-25 23:59', 'Read this paper http://sunnyday.mit.edu/16.355/budgen-david.pdf', 'Reading 2', '586LRR-Test-caseS.pdf', '', '', '', '6', 'Individual'),
|
(2, 10, '2024-09-29 11:12', '2025-07-30 23:59', 'Read this paper http://sunnyday.mit.edu/16.355/budgen-david.pdf', 'Reading 2', '586LRR-Test-caseS.pdf', '', '', '', '6', 'Individual'),
|
||||||
(3, 12, '2020-04-05 02:48', '2020-04-12 ', 'Do this assignment in time for testing', 'First Assignment Testing', '', '', '', '', '3', 'Group'),
|
(3, 12, '2020-04-05 02:48', '2020-04-12 ', 'Do this assignment in time for testing', 'First Assignment Testing', '', '', '', '', '3', 'Group'),
|
||||||
(4, 12, '2020-04-05 05:36', '2020-04-06 ', 'We are testing to see if the instructor can be able to modify the work', 'Second Assignment Testing', '', '', '', '', '3', 'Individual'),
|
(4, 12, '2020-04-05 05:36', '2020-04-06 ', 'We are testing to see if the instructor can be able to modify the work', 'Second Assignment Testing', '', '', '', '', '3', 'Individual'),
|
||||||
(5, 12, '2020-04-05 05:51', '2020-04-08 ', 'ASQDASDASCDD', 'Third Assignment Testingas', '', '', '', '', '3', 'Individual'),
|
(5, 12, '2020-04-05 05:51', '2020-04-08 ', 'ASQDASDASCDD', 'Third Assignment Testingas', '', '', '', '', '3', 'Individual'),
|
||||||
|
@ -235,7 +235,7 @@ CREATE TABLE `lab_report_submissions` (
|
||||||
--
|
--
|
||||||
|
|
||||||
INSERT INTO `lab_report_submissions` (`Submission_ID`, `Submission_Date`, `Lab_Report_ID`, `Student_id`, `Course_Group_id`, `Attachment1`, `Notes`, `Attachment2`, `Attachment3`, `Attachment4`, `Marks`, `Status`, `Title`, `Visibility`, `Remarking_Reason`) VALUES
|
INSERT INTO `lab_report_submissions` (`Submission_ID`, `Submission_Date`, `Lab_Report_ID`, `Student_id`, `Course_Group_id`, `Attachment1`, `Notes`, `Attachment2`, `Attachment3`, `Attachment4`, `Marks`, `Status`, `Title`, `Visibility`, `Remarking_Reason`) VALUES
|
||||||
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', 5, 'Marked', 'Reading 1 submission', 'Public', ''),
|
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', NULL, 'Pending', 'Reading 1 submission', 'Public', ''),
|
||||||
(5, '2019-01-21 08:31:00', 2, '201825800050', 0, 'Trial Balance.txt', ' - @2019-01-21 09:35 : Sorry I missed some details from your report', 'Boorka.jpg', '', '', 6, 'Marked', 'Submission x', 'Private', ''),
|
(5, '2019-01-21 08:31:00', 2, '201825800050', 0, 'Trial Balance.txt', ' - @2019-01-21 09:35 : Sorry I missed some details from your report', 'Boorka.jpg', '', '', 6, 'Marked', 'Submission x', 'Private', ''),
|
||||||
(30, '2020-04-06 23:18:00', 3, '0', 31, '/2016321201502/First Assignment Testing/UR Diagram.pdf', '<br>@2020-04-06 23:19 : ', '', '', '', 3, 'Marked', 'First Assignment Testing', 'Private', '');
|
(30, '2020-04-06 23:18:00', 3, '0', 31, '/2016321201502/First Assignment Testing/UR Diagram.pdf', '<br>@2020-04-06 23:19 : ', '', '', '', 3, 'Marked', 'First Assignment Testing', 'Private', '');
|
||||||
|
|
||||||
|
@ -259,7 +259,8 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES
|
||||||
(1, '201825800054', 'LJ7951632'),
|
(1, '201825800054', 'LJ7951632'),
|
||||||
(2, '201825800050', 'P00581929'),
|
(2, '201825800050', 'P00581929'),
|
||||||
(3, '201632120150', 'FN524516'),
|
(3, '201632120150', 'FN524516'),
|
||||||
(4, '11', '11');
|
(4, '202400000001', 'NA');
|
||||||
|
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
@ -285,8 +286,9 @@ CREATE TABLE `users_table` (
|
||||||
|
|
||||||
INSERT INTO `users_table` (`User_ID`, `Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`, `Passport_Number`, `Status`) VALUES
|
INSERT INTO `users_table` (`User_ID`, `Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`, `Passport_Number`, `Status`) VALUES
|
||||||
(3, 'admin@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Kamal', 'Admin', '0', NULL, 'Active'),
|
(3, 'admin@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Kamal', 'Admin', '0', NULL, 'Active'),
|
||||||
(8, 'lanhui@qq.com', '1234', '', 'Lanhui', 'Lecturer', NULL, '123', 'Active'),
|
(7, 'peter@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Peter', 'Lecturer', NULL, '123', 'Active'),
|
||||||
(9, 'mohamed@qq.com', '123', '', 'Mohamed', 'Student', '201825800050', 'P00581929', 'Active'),
|
(8, 'lanhui@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Lanhui', 'Lecturer', NULL, '123', 'Active'),
|
||||||
|
(9, 'mohamed@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Mohamed', 'Student', '201825800050', 'P00581929', 'Active'),
|
||||||
(10, 'mark@qq.com', '123', '', 'Mark ', 'TA', NULL, '123', 'Active'),
|
(10, 'mark@qq.com', '123', '', 'Mark ', 'TA', NULL, '123', 'Active'),
|
||||||
(11, 'john@qq.com', '123', '', 'John', 'TA', NULL, '123', 'Active'),
|
(11, 'john@qq.com', '123', '', 'John', 'TA', NULL, '123', 'Active'),
|
||||||
(12, 'mehdi@qq.com', '123', '', 'El-mehdi Houzi', 'Student', '201825800054', 'LJ7951632', 'Active'),
|
(12, 'mehdi@qq.com', '123', '', 'El-mehdi Houzi', 'Student', '201825800054', 'LJ7951632', 'Active'),
|
||||||
|
|
|
@ -22,10 +22,10 @@ include 'Header.php';
|
||||||
<input type="hidden" name="form_signup" value="true" />
|
<input type="hidden" name="form_signup" value="true" />
|
||||||
|
|
||||||
Full Name
|
Full Name
|
||||||
<input type="text" name="fullname" placeholder="Your full name" class="form-control" value="<?php echo $_SESSION['user_fullname']; ?>" required="required" id="full_name"/> <br>
|
<input type="text" name="fullname" placeholder="Your full name" class="form-control" value="<?php echo isset($_SESSION['user_fullname_temp']) ? $_SESSION['user_fullname_temp'] : ''; ?>" required="required" id="full_name"/> <br>
|
||||||
|
|
||||||
Student ID
|
Student ID
|
||||||
<input type="text" name="user_student_id" placeholder="Entre your student ID" class="form-control" value="<?php echo $_SESSION['user_student_id']; ?>" required="required" id="student_id"> <br>
|
<input type="text" name="user_student_id" placeholder="Entre your student ID" class="form-control" value="<?php echo isset($_SESSION['user_student_id_1']) ? $_SESSION['user_student_id_temp'] : ''; ?>" required="required" id="student_id"> <br>
|
||||||
|
|
||||||
Email
|
Email
|
||||||
<input type="text" name="email" placeholder="Email" class="form-control" value="<?php echo $_SESSION['user_email']; ?>" required="required" id="email" /> <br>
|
<input type="text" name="email" placeholder="Email" class="form-control" value="<?php echo $_SESSION['user_email']; ?>" required="required" id="email" /> <br>
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException
|
||||||
|
|
||||||
|
|
||||||
|
def login(driver, url, username, password):
|
||||||
|
try:
|
||||||
|
driver.get(url)
|
||||||
|
|
||||||
|
# Fill in the login form
|
||||||
|
user_input = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.ID, "user_name"))
|
||||||
|
)
|
||||||
|
user_input.send_keys(username)
|
||||||
|
|
||||||
|
password_input = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.ID, "user_password"))
|
||||||
|
)
|
||||||
|
password_input.send_keys(password)
|
||||||
|
|
||||||
|
# Click the login button
|
||||||
|
login_button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.ID, "login_btn"))
|
||||||
|
)
|
||||||
|
login_button.click()
|
||||||
|
except (NoSuchElementException, UnexpectedAlertPresentException) as e:
|
||||||
|
return f"Error: {str(e)}"
|
||||||
|
|
||||||
|
|
||||||
|
def logout(driver):
|
||||||
|
logout_button = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable(
|
||||||
|
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
logout_button.click()
|
|
@ -0,0 +1,352 @@
|
||||||
|
from helper import login, logout
|
||||||
|
import time
|
||||||
|
import pytest
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
|
||||||
|
|
||||||
|
def test_admin_can_create_lecturer_account(driver, url, admin_username, admin_password, restore_database):
|
||||||
|
# Administrator (admin@qq.com, password 123) logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, admin_username, admin_password)
|
||||||
|
|
||||||
|
# Create a Lecturer account for Mr Lan (mrlan@qq.com, password [123Abc!])
|
||||||
|
tab = driver.find_element(By.ID, 'tab_ins_accounts')
|
||||||
|
tab.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'fullname')
|
||||||
|
elem.send_keys('Mr Lan')
|
||||||
|
elem = driver.find_element(By.NAME, 'email')
|
||||||
|
elem.send_keys('mrlan@qq.com')
|
||||||
|
elem = driver.find_element(By.NAME, 'password')
|
||||||
|
elem.send_keys('123Abc!!')
|
||||||
|
radio_button = driver.find_element(By.NAME, 'type')
|
||||||
|
radio_button.click()
|
||||||
|
button = driver.find_element(By.NAME, 'create_btn')
|
||||||
|
button.click()
|
||||||
|
|
||||||
|
# Log out Admin account
|
||||||
|
logout(driver)
|
||||||
|
|
||||||
|
# Log in Lecturer account
|
||||||
|
login(driver, url, 'mrlan@qq.com', '123Abc!!')
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
assert '(Lecturer)' in elems[0].text
|
||||||
|
assert 'Mr Lan' in elems[0].text
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_lecturer_can_create_course(driver, url, restore_database):
|
||||||
|
# Lecturer lanhui@qq.com logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, 'lanhui@qq.com', '123')
|
||||||
|
|
||||||
|
# Create a course called CSC1001 Advanced Software Engineering, 2024
|
||||||
|
elem = driver.find_element(By.NAME, 'name')
|
||||||
|
elem.send_keys('Advanced Software Engineering')
|
||||||
|
elem = driver.find_element(By.NAME, 'code')
|
||||||
|
elem.send_keys('CSC1001')
|
||||||
|
elem = driver.find_element(By.NAME, 'academic')
|
||||||
|
elem.send_keys('2004')
|
||||||
|
elem = driver.find_element(By.NAME, 'faculty')
|
||||||
|
elem.send_keys('School of Computer Science and Technology')
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
|
||||||
|
elem.click()
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
|
||||||
|
last_elem = elems[-1]
|
||||||
|
assert 'Advanced Software Engineering' in last_elem.text
|
||||||
|
assert '(CSC1001)' in last_elem.text
|
||||||
|
|
||||||
|
# Logout
|
||||||
|
logout(driver)
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_lecturer_can_post_assignment(driver, url, restore_database):
|
||||||
|
# Lecturer lanhui@qq.com logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, 'lanhui@qq.com', '123')
|
||||||
|
|
||||||
|
# Create an assignment called Take-home quiz 1 for course (CSC1111) - Project Management
|
||||||
|
elem = WebDriverWait(driver, 10).until(
|
||||||
|
EC.element_to_be_clickable((By.XPATH, '//div[@class="col-md-8"]/a[1]/div'))
|
||||||
|
)
|
||||||
|
elem.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'deadlinedate')
|
||||||
|
elem.send_keys('002024/12/30')
|
||||||
|
elem = driver.find_element(By.NAME, 'deadlinetime')
|
||||||
|
elem.send_keys('23:59')
|
||||||
|
elem = driver.find_element(By.NAME, 'title')
|
||||||
|
elem.send_keys('Take-home quiz 1')
|
||||||
|
elem = driver.find_element(By.NAME, 'instructions')
|
||||||
|
elem.send_keys('This is a closed-book quiz.')
|
||||||
|
elem = driver.find_element(By.NAME, 'marks')
|
||||||
|
elem.send_keys('10')
|
||||||
|
radio_button = driver.find_element(By.NAME, 'type')
|
||||||
|
radio_button.click()
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Check if the assignment has been successfully posted
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'card-title')
|
||||||
|
assert 'Take-home quiz 1 (10 Marks, Individual)' in elem.text
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'text-muted')
|
||||||
|
assert 'Deadline: 2024-12-30' in elem.text
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_lecturer_can_add_student_numbers(driver, url, restore_database):
|
||||||
|
# Lecturer lanhui@qq.com logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, 'lanhui@qq.com', '123')
|
||||||
|
|
||||||
|
# Add ASE student numbers
|
||||||
|
student_numbers = '''
|
||||||
|
202420781739
|
||||||
|
202420781740
|
||||||
|
202420781741
|
||||||
|
202420781742
|
||||||
|
202420781743
|
||||||
|
202420781745
|
||||||
|
202420581366
|
||||||
|
202420581368
|
||||||
|
202420581369
|
||||||
|
202420581370
|
||||||
|
202420581372
|
||||||
|
202420581373
|
||||||
|
202420581374
|
||||||
|
202420581376
|
||||||
|
202420581378
|
||||||
|
202420581381
|
||||||
|
'''
|
||||||
|
elem = driver.find_element(By.ID, 'admin_tab')
|
||||||
|
elem.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'users')
|
||||||
|
elem.send_keys(student_numbers)
|
||||||
|
elem = driver.find_element(By.ID, 'register_btn')
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
elems = driver.find_elements(By.CSS_SELECTOR, 'p')
|
||||||
|
added = 0
|
||||||
|
student_lst = [number.strip() for number in student_numbers.strip().split('\n')]
|
||||||
|
print(student_lst)
|
||||||
|
for student_no in student_lst:
|
||||||
|
for elem in elems:
|
||||||
|
if student_no in elem.text and 'added' in elem.text:
|
||||||
|
added += 1
|
||||||
|
break
|
||||||
|
assert added == len(student_lst)
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_with_valid_student_number_can_sign_up(driver, url, restore_database):
|
||||||
|
# Student with recognizable student number 202400000001 can sign up an account
|
||||||
|
driver.get(url)
|
||||||
|
driver.maximize_window()
|
||||||
|
elem = driver.find_element(By.ID, 'signup_link')
|
||||||
|
elem.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'fullname')
|
||||||
|
elem.send_keys('Good Student')
|
||||||
|
elem = driver.find_element(By.NAME, 'user_student_id')
|
||||||
|
elem.send_keys('202400000001')
|
||||||
|
elem = driver.find_element(By.NAME, 'email')
|
||||||
|
elem.send_keys('goodstudent@qq.com')
|
||||||
|
elem = driver.find_element(By.NAME, 'password')
|
||||||
|
elem.send_keys('[123Abc]')
|
||||||
|
elem = driver.find_element(By.NAME, 'confirmpassword')
|
||||||
|
elem.send_keys('[123Abc]')
|
||||||
|
elem = driver.find_element(By.ID, 'signup_btn')
|
||||||
|
elem.click()
|
||||||
|
logout(driver)
|
||||||
|
|
||||||
|
# Log in Student account
|
||||||
|
login(driver, url, '202400000001', '[123Abc]')
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
assert 'Student ID' in elems[0].text
|
||||||
|
assert 'Good Student' in elems[0].text
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_with_invalid_student_number_cannot_sign_up(driver, url, restore_database):
|
||||||
|
# Student with unrecognizable student number cannot sign up an account
|
||||||
|
driver.get(url)
|
||||||
|
driver.maximize_window()
|
||||||
|
elem = driver.find_element(By.ID, 'signup_link')
|
||||||
|
elem.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'fullname')
|
||||||
|
elem.send_keys('Good Student')
|
||||||
|
elem = driver.find_element(By.NAME, 'user_student_id')
|
||||||
|
elem.send_keys('202400000002')
|
||||||
|
elem = driver.find_element(By.NAME, 'email')
|
||||||
|
elem.send_keys('goodstudent@qq.com')
|
||||||
|
elem = driver.find_element(By.NAME, 'password')
|
||||||
|
elem.send_keys('[123Abc]')
|
||||||
|
elem = driver.find_element(By.NAME, 'confirmpassword')
|
||||||
|
elem.send_keys('[123Abc]')
|
||||||
|
elem = driver.find_element(By.ID, 'signup_btn')
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Log in Student account
|
||||||
|
login(driver, url, '202400000002', '[123Abc]')
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
assert not 'Student ID' in elems[0].text
|
||||||
|
assert not 'Good Student' in elems[0].text
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_with_weak_password_cannot_sign_up(driver, url, restore_database):
|
||||||
|
driver.get(url)
|
||||||
|
driver.maximize_window()
|
||||||
|
weak_password = '123Abc'
|
||||||
|
elem = driver.find_element(By.ID, 'signup_link')
|
||||||
|
elem.click()
|
||||||
|
elem = driver.find_element(By.NAME, 'fullname')
|
||||||
|
elem.send_keys('Good Student')
|
||||||
|
elem = driver.find_element(By.NAME, 'user_student_id')
|
||||||
|
elem.send_keys('202400000001')
|
||||||
|
elem = driver.find_element(By.NAME, 'email')
|
||||||
|
elem.send_keys('goodstudent@qq.com')
|
||||||
|
elem = driver.find_element(By.NAME, 'password')
|
||||||
|
elem.send_keys(weak_password)
|
||||||
|
elem = driver.find_element(By.NAME, 'confirmpassword')
|
||||||
|
elem.send_keys(weak_password)
|
||||||
|
elem = driver.find_element(By.ID, 'signup_btn')
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Log in Student account
|
||||||
|
login(driver, url, '202400000001', weak_password)
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
assert not 'Student ID' in elems[0].text
|
||||||
|
assert not 'Good Student' in elems[0].text
|
||||||
|
driver.quit()
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_can_join_course(driver, url, restore_database):
|
||||||
|
# Student can join (CSC1111) - Project Management
|
||||||
|
login(driver, url, '201825800050', '123')
|
||||||
|
driver.maximize_window()
|
||||||
|
|
||||||
|
# Search for CSC1111
|
||||||
|
elem = driver.find_element(By.NAME, 'search')
|
||||||
|
elem.send_keys('CSC1111')
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'btn-primary')
|
||||||
|
elem.click()
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
|
||||||
|
assert 'CSC1111' in elems[0].text
|
||||||
|
|
||||||
|
# Join
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'btn-success') # find the green Join button
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Log out, then log in to check the course-joining status
|
||||||
|
logout(driver)
|
||||||
|
login(driver, url, '201825800050', '123')
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
|
||||||
|
assert 'CSC1111' in elems[0].text
|
||||||
|
assert 'Project Management' in elems[0].text
|
||||||
|
assert 'Joined' in elems[0].text
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_can_submit_assignment(driver, url, restore_database):
|
||||||
|
''' Note: Make sure the fields Posted_Date and Deadline in the second row of lab_reports_table are in the current year'''
|
||||||
|
# Student can submit assignment for CSC1111
|
||||||
|
login(driver, url, '201825800050', '123')
|
||||||
|
driver.maximize_window()
|
||||||
|
|
||||||
|
# Enter into the course and the find the assignment
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
|
||||||
|
elems[1].click()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.XPATH, '//div[@id="menu1"]/div/div/p/a[text()="Submit"]') # find the submit button
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Fill submission title, attach file, and submit
|
||||||
|
elem = driver.find_element(By.NAME, 'title')
|
||||||
|
elem.send_keys('Assignment submission from Mohamed')
|
||||||
|
elem = driver.find_element(By.NAME, 'attachment1')
|
||||||
|
elem.send_keys('/home/mrlan/Downloads/test/SeleniumHui/helper.py') # attach a file
|
||||||
|
elem = driver.find_element(By.XPATH, '//form/button')
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Go the Submitted tab
|
||||||
|
elem = driver.find_element(By.ID, 'myTab')
|
||||||
|
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
elems[2].click()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.XPATH, '//div[@id="menu3"]/div')
|
||||||
|
assert 'Reading 2 (6 Marks)' in elem.text
|
||||||
|
assert 'SUBMITTED' in elem.text
|
||||||
|
assert 'helper.py' in elem.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_student_can_request_remarking(driver, url, restore_database):
|
||||||
|
# Student logs in
|
||||||
|
login(driver, url, '201825800050', '123')
|
||||||
|
driver.maximize_window()
|
||||||
|
|
||||||
|
# Enter into the course
|
||||||
|
elems = driver.find_elements(By.CLASS_NAME, 'btn-default')
|
||||||
|
elems[1].click()
|
||||||
|
|
||||||
|
# Go the Marked tab
|
||||||
|
elem = driver.find_element(By.ID, 'myTab')
|
||||||
|
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
elems[3].click()
|
||||||
|
|
||||||
|
# Send remarking request
|
||||||
|
remarking_buttons = driver.find_elements(By.CLASS_NAME, 'btn-light')
|
||||||
|
remarking_buttons[0].click()
|
||||||
|
alert = driver.switch_to.alert
|
||||||
|
alert.send_keys('I need higher marks, teacher.')
|
||||||
|
alert.accept()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.XPATH, '//div[@id="menu4"]/div/div/p/span')
|
||||||
|
assert 'Remarking request sent' == elem.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_lecturer_can_mark_assignment(driver, url, restore_database):
|
||||||
|
# Lecturer lanhui@qq.com logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, 'lanhui@qq.com', '123')
|
||||||
|
|
||||||
|
# Enter into the course and the find the assignment
|
||||||
|
elem = driver.find_element(By.XPATH, '//div[1]/a[3]/div') # course Software Engineering
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.XPATH, '//div[2]/div[2]/div/a[2]') # View link
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.CLASS_NAME, 'btn-primary') # Blue Mark button
|
||||||
|
elem.click()
|
||||||
|
|
||||||
|
# Submit mark and comment
|
||||||
|
elem = driver.find_element(By.NAME, 'marks')
|
||||||
|
elem.send_keys('1')
|
||||||
|
elem = driver.find_element(By.NAME, 'feedback')
|
||||||
|
elem.send_keys('Inadequate')
|
||||||
|
form = driver.find_element(By.ID, 'submit-form')
|
||||||
|
form.submit()
|
||||||
|
|
||||||
|
elem = driver.find_element(By.ID, 'myTab')
|
||||||
|
elems = elem.find_elements(By.CLASS_NAME, 'nav-link')
|
||||||
|
assert 'Marked submissions (1)' == elems[1].text
|
||||||
|
elems[1].click()
|
||||||
|
elem = driver.find_element(By.XPATH, "//div[@id='menu2']/div/b")
|
||||||
|
assert 'Reading 1 submission' in elem.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_lecturer_cannot_see_tas_not_from_his_course(driver, url, restore_database):
|
||||||
|
# Lecturer lanhui@qq.com logs in
|
||||||
|
driver.maximize_window()
|
||||||
|
login(driver, url, 'peter@qq.com', '123')
|
||||||
|
|
||||||
|
elem = driver.find_element(By.ID, 'admin_tab')
|
||||||
|
elem.click()
|
||||||
|
tab = driver.find_element(By.ID, 'existing_accounts_tab')
|
||||||
|
tab.click()
|
||||||
|
elem = driver.find_element(By.ID, 'tab-existing-accounts')
|
||||||
|
assert 'No TA' in elem.text
|
||||||
|
|
||||||
|
# Logout
|
||||||
|
logout(driver)
|
||||||
|
driver.quit()
|
|
@ -4,14 +4,17 @@
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import pytest
|
import pytest
|
||||||
from faker import Faker
|
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
from selenium.webdriver.support import expected_conditions as EC
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
|
||||||
faker = Faker()
|
|
||||||
@pytest.mark.skip(reason="function to be used in the test_scripts")
|
def test_restore_database(restore_database):
|
||||||
|
assert restore_database is None
|
||||||
|
|
||||||
|
|
||||||
def createTA(driver, TA_name, emails, password):
|
def createTA(driver, TA_name, emails, password):
|
||||||
full_name = driver.find_element('name', 'fullname')
|
full_name = driver.find_element('name', 'fullname')
|
||||||
full_name.send_keys(TA_name)
|
full_name.send_keys(TA_name)
|
||||||
|
@ -24,56 +27,58 @@ def createTA(driver, TA_name, emails, password):
|
||||||
click_create = driver.find_element('name', 'create_btn')
|
click_create = driver.find_element('name', 'create_btn')
|
||||||
click_create.click()
|
click_create.click()
|
||||||
|
|
||||||
def login_lecturer(drivers):
|
|
||||||
|
def login_lecturer(driver, url):
|
||||||
# Open the website
|
# Open the website
|
||||||
drivers.get("http://localhost/lrr/")
|
driver.get(url)
|
||||||
drivers.maximize_window()
|
driver.maximize_window()
|
||||||
|
|
||||||
username_input = drivers.find_element('name', "user")
|
username_input = driver.find_element('name', "user")
|
||||||
|
|
||||||
password_input = drivers.find_element('name', "password")
|
password_input = driver.find_element('name', "password")
|
||||||
|
|
||||||
login_button = drivers.find_element('id', "login_btn")
|
login_button = driver.find_element('id', "login_btn")
|
||||||
|
|
||||||
# login as a Lecturer
|
# login as a Lecturer
|
||||||
username_input.send_keys("lanhui@qq.com")
|
username_input.send_keys("admin@qq.com")
|
||||||
password_input.send_keys("nil1234H@")
|
password_input.send_keys("123")
|
||||||
# Click the login button
|
# Click the login button
|
||||||
time.sleep(5)
|
time.sleep(2)
|
||||||
login_button.click()
|
login_button.click()
|
||||||
admin_tab = drivers.find_element('id', 'admin_tab')
|
admin_tab = driver.find_element('id', 'admin_tab')
|
||||||
admin_tab.click()
|
admin_tab.click()
|
||||||
|
|
||||||
cte_instructor = drivers.find_element('id', 'tab_ins_accounts')
|
cte_instructor = driver.find_element('id', 'tab_ins_accounts')
|
||||||
cte_instructor.click()
|
cte_instructor.click()
|
||||||
time.sleep(25)
|
time.sleep(2)
|
||||||
|
|
||||||
def test_createTA():
|
|
||||||
driver_open = webdriver.Chrome()
|
def test_createTA(driver, url):
|
||||||
|
driver_open = driver
|
||||||
driver_open.maximize_window()
|
driver_open.maximize_window()
|
||||||
login_lecturer(driver_open)
|
login_lecturer(driver_open, url)
|
||||||
try:
|
try:
|
||||||
fullname = faker.name()
|
fullname = "lanhuitest1"
|
||||||
email = faker.email()
|
email = "lanhuitest1@qq.com"
|
||||||
password = "new1452345678"
|
password = "new1452345678"
|
||||||
createTA(driver_open, fullname, email,password) # CREATE A TA WITH FULLNAME lanhuitest email lanhuitest@test.com password lanhui12345678
|
createTA(driver_open, fullname, email,password) # CREATE A TA WITH FULLNAME lanhuitest1 email lanhuitest1@qq.com password new1452345678
|
||||||
|
|
||||||
get_output = WebDriverWait(driver_open, 10).until(
|
get_output = WebDriverWait(driver_open, 20).until(
|
||||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||||
)
|
)
|
||||||
get_output.click()
|
get_output.click()
|
||||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||||
txt_alert = get_output_msg.text
|
txt_alert = get_output_msg.text
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
if txt_alert.find("TA user created successfully") == 0:
|
if txt_alert.find("TA user created successfully") == 0:
|
||||||
logout_button = WebDriverWait(driver_open, 15).until(
|
logout_button = WebDriverWait(driver_open, 20).until(
|
||||||
EC.element_to_be_clickable(
|
EC.element_to_be_clickable(
|
||||||
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
||||||
)
|
)
|
||||||
time.sleep(5)
|
time.sleep(2)
|
||||||
logout_button.click()
|
logout_button.click()
|
||||||
time.sleep(10)
|
time.sleep(2)
|
||||||
username_input = driver_open.find_element('name', "user")
|
username_input = driver_open.find_element('name', "user")
|
||||||
password_input = driver_open.find_element('name', "password")
|
password_input = driver_open.find_element('name', "password")
|
||||||
login_button = driver_open.find_element('id', "login_btn")
|
login_button = driver_open.find_element('id', "login_btn")
|
||||||
|
@ -81,45 +86,45 @@ def test_createTA():
|
||||||
username_input.send_keys(email) # login with credentials of the created TA
|
username_input.send_keys(email) # login with credentials of the created TA
|
||||||
password_input.send_keys(password)
|
password_input.send_keys(password)
|
||||||
# Click the login button
|
# Click the login button
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
login_button.click()
|
login_button.click()
|
||||||
|
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
elif txt_alert.find("Email address ") == 0:
|
elif txt_alert.find("Email address ") == 0:
|
||||||
|
|
||||||
time.sleep(22)
|
time.sleep(2)
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
time.sleep(5)
|
time.sleep(2)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
|
|
||||||
def test_generate_password():
|
def test_generate_password(driver, url):
|
||||||
driver_open = webdriver.Chrome()
|
driver_open = driver
|
||||||
login_lecturer(driver_open)
|
login_lecturer(driver_open, url)
|
||||||
try:
|
try:
|
||||||
fullname = faker.name()
|
fullname = "lanhuitest2"
|
||||||
email = faker.email()
|
email = "lanhuitest2@qq.com"
|
||||||
password = ""
|
password = ""
|
||||||
createTA(driver_open, fullname, email,
|
createTA(driver_open, fullname, email,
|
||||||
password) # CREATE A TA WITH FULLNAME lanhuitest email lanhuitest@test.com password lanhui12345678
|
password) # CREATE A TA WITH FULLNAME lanhuitest2 email lanhuitest2@qq.com password ""
|
||||||
|
|
||||||
get_output = WebDriverWait(driver_open, 5).until(
|
get_output = WebDriverWait(driver_open, 20).until(
|
||||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||||
)
|
)
|
||||||
get_output.click()
|
get_output.click()
|
||||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||||
txt_alert = get_output_msg.text
|
txt_alert = get_output_msg.text
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
if txt_alert.find("TA user created successfully") == 0:
|
if txt_alert.find("TA user created successfully") == 0:
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
email_pattern = r"Use email (\S+) as account name"
|
email_pattern = r"Use email (\S+) as account name"
|
||||||
password_pattern = r" (\S+)\ as password."
|
password_pattern = r" (\S+)\ as password."
|
||||||
email_match = re.search(email_pattern, txt_alert)
|
email_match = re.search(email_pattern, txt_alert)
|
||||||
|
@ -128,12 +133,12 @@ def test_generate_password():
|
||||||
# Extract email and password from the matches
|
# Extract email and password from the matches
|
||||||
email = email_match.group(1)
|
email = email_match.group(1)
|
||||||
password = password_match.group(1)
|
password = password_match.group(1)
|
||||||
logout_button = WebDriverWait(driver_open, 10).until(
|
logout_button = WebDriverWait(driver_open, 20).until(
|
||||||
EC.element_to_be_clickable(
|
EC.element_to_be_clickable(
|
||||||
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
||||||
)
|
)
|
||||||
logout_button.click()
|
logout_button.click()
|
||||||
time.sleep(15)
|
time.sleep(2)
|
||||||
username_input = driver_open.find_element('name', "user")
|
username_input = driver_open.find_element('name', "user")
|
||||||
password_input = driver_open.find_element('name', "password")
|
password_input = driver_open.find_element('name', "password")
|
||||||
login_button = driver_open.find_element('id', "login_btn")
|
login_button = driver_open.find_element('id', "login_btn")
|
||||||
|
@ -141,54 +146,56 @@ def test_generate_password():
|
||||||
username_input.send_keys(email) # login with credentials of the created TA
|
username_input.send_keys(email) # login with credentials of the created TA
|
||||||
password_input.send_keys(password)
|
password_input.send_keys(password)
|
||||||
# Click the login button
|
# Click the login button
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
login_button.click()
|
login_button.click()
|
||||||
|
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
elif txt_alert.find("Email address ") == 0:
|
elif txt_alert.find("Email address ") == 0:
|
||||||
time.sleep(22)
|
time.sleep(2)
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
time.sleep(5)
|
time.sleep(2)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
def test_existingTA():
|
|
||||||
driver_open = webdriver.Chrome()
|
def test_existingTA(driver, url, restore_database):
|
||||||
login_lecturer(driver_open)
|
driver_open = driver
|
||||||
|
login_lecturer(driver, url)
|
||||||
try:
|
try:
|
||||||
# Use email nreyes@example.com as account name and new1452345678 as password.
|
# Use email nreyes@example.com as account name and new1452345678 as password.
|
||||||
fullname = "Maria"
|
fullname = "lanhuitest1"
|
||||||
email = "nreyes@example.com"
|
email = "lanhuitest1@qq.com"
|
||||||
password = "new1452345678"
|
password = "new1452345678"
|
||||||
createTA(driver_open, fullname, email,
|
createTA(driver_open, fullname, email,
|
||||||
password) # CREATE A TA WITH FULLNAME lanhuitest email lanhuitest@test.com password lanhui12345678
|
password) # CREATE A TA WITH FULLNAME lanhuitest1 email lanhuitest1@qq.com password new1452345678
|
||||||
|
|
||||||
get_output = WebDriverWait(driver_open, 5).until(
|
get_output = WebDriverWait(driver_open, 20).until(
|
||||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||||
)
|
)
|
||||||
get_output.click()
|
get_output.click()
|
||||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||||
txt_alert = get_output_msg.text
|
txt_alert = get_output_msg.text
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
if txt_alert.find("TA user created successfully") == 0:
|
if txt_alert.find("TA user created successfully") == 0:
|
||||||
time.sleep(20)
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
elif txt_alert.find("Email address ") == 0:
|
elif txt_alert.find("Email address ") == 0:
|
||||||
time.sleep(22)
|
time.sleep(2)
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
||||||
time.sleep(5)
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
driver_open.quit()
|
driver_open.quit()
|
|
@ -0,0 +1,77 @@
|
||||||
|
import pytest
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
driver = webdriver.Chrome()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Navigate to the page with tabs
|
||||||
|
driver.get("http://localhost:8080/lrr/")
|
||||||
|
driver.maximize_window()
|
||||||
|
wait = WebDriverWait(driver, 10)
|
||||||
|
|
||||||
|
# Login as a Lecturer
|
||||||
|
username_input = wait.until(EC.presence_of_element_located((By.NAME, "user")))
|
||||||
|
password_input = driver.find_element(By.NAME, "password")
|
||||||
|
login_button = driver.find_element(By.ID, "login_btn")
|
||||||
|
|
||||||
|
username_input.send_keys("ashly@qq.com")
|
||||||
|
password_input.send_keys("admin123")
|
||||||
|
time.sleep(5)
|
||||||
|
login_button.click()
|
||||||
|
|
||||||
|
course_but= driver.find_element(By.XPATH, "(//div[@class='btn btn-default'])[1]") # Adjust this XPATH as needed
|
||||||
|
|
||||||
|
|
||||||
|
# Click on the alert
|
||||||
|
course_but.click()
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
marked_tab = wait.until(
|
||||||
|
EC.element_to_be_clickable((By.XPATH, "//a[text()='Marked']"))
|
||||||
|
)
|
||||||
|
marked_tab.click()
|
||||||
|
|
||||||
|
# Wait for the Marked tab content to be present
|
||||||
|
marked_tab_content = wait.until(
|
||||||
|
EC.presence_of_element_located((By.XPATH, "//div[@id='menu4' and contains(@class, 'active')]"))
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
remark_but = wait.until(
|
||||||
|
EC.presence_of_element_located((By.XPATH, "//button[normalize-space()='Request remarking']"))
|
||||||
|
)
|
||||||
|
remark_but.click()
|
||||||
|
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# Switch to the alert
|
||||||
|
alert = driver.switch_to.alert
|
||||||
|
|
||||||
|
# Send keys to the prompt
|
||||||
|
alert.send_keys("Number 2 was correct")
|
||||||
|
|
||||||
|
# Accept the prompt (click OK)
|
||||||
|
alert.accept()
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
except NoSuchElementException as e:
|
||||||
|
print("NoSuchElementException: Could not find an element.")
|
||||||
|
traceback.print_exc()
|
||||||
|
except TimeoutException as e:
|
||||||
|
print("TimeoutException: An element took too long to load.")
|
||||||
|
traceback.print_exc()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An unexpected error occurred: {e}")
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
driver.quit()
|
Loading…
Reference in New Issue