Compare commits
1 Commits
Hui-Organi
...
BUG352-NEI
Author | SHA1 | Date |
---|---|---|
|
21b643d8d9 |
|
@ -1,5 +1,2 @@
|
|||
.vscode
|
||||
.DS_Store
|
||||
venv/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
|
53
Admin.php
53
Admin.php
|
@ -30,11 +30,11 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
<ul class="nav nav-tabs" id="myTab">
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Enter student numbers</a>
|
||||
<a class="nav-link active" href="#tab-student-accounts" id="batch_tab">Create student accounts</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#tab-ins-accounts" id="tab_ins_accounts">Create instructor account</a>
|
||||
<a class="nav-link" href="#tab-ins-accounts">Create instructor account</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
|
@ -66,14 +66,17 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
|
||||
?>
|
||||
<form method="post" action="Script.php" id="create_account_form">
|
||||
<input type="hidden" name="form_createlecturer" value="true" required="" />
|
||||
<input type="hidden" name="form_createlecturrer" value="true" required="" />
|
||||
Full name
|
||||
<input type="text" name="fullname" placeholder="Full Name" class="form-control" required=""> <br>
|
||||
Email
|
||||
<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)
|
||||
<input type="password" class="form-control" name="password" minlength="8" placeholder="Initial password" > <br>
|
||||
Initial password
|
||||
|
||||
<input type="text" class="form-control" name="passport" minlength="8" placeholder="Initial password" >
|
||||
Leave it empty to let LRR generate a strong password for you.<br><br>
|
||||
User type:
|
||||
|
||||
<?php
|
||||
|
||||
if ($_SESSION['user_type'] == "Lecturer") {
|
||||
|
@ -90,7 +93,11 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
if (isset($_SESSION['info_Admin_Users'])) {
|
||||
echo '<hr><div class="alert alert-warning" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
||||
echo '<hr><div class="alert alert-info" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
||||
$_SESSION['info_Admin_Users'] = null;
|
||||
}
|
||||
if (isset($_SESSION['info_Admin_Users'])) {
|
||||
echo '<hr><div class="alert alert-info" role="alert">' . $_SESSION['info_Admin_Users'] . '</div>';
|
||||
$_SESSION['info_Admin_Users'] = null;
|
||||
}
|
||||
?>
|
||||
|
@ -113,21 +120,10 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
<?php
|
||||
|
||||
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(
|
||||
$con,
|
||||
"SELECT * FROM users_table WHERE UserType in ('TA') and User_ID in ($ta_ids2)"
|
||||
"SELECT * FROM users_table WHERE UserType in ('TA')"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -138,7 +134,6 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
);
|
||||
}
|
||||
|
||||
$num_rows = 0;
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$pass = $row['Password'];
|
||||
$btn = "<button class='btn btn-warning' onclick=\"updatePassword(" . $row['User_ID'] . ",'$pass')\">Reset</button>";
|
||||
|
@ -151,10 +146,6 @@ 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>";
|
||||
$num_rows += 1;
|
||||
}
|
||||
if ($num_rows == 0) {
|
||||
echo "<p>No TA</p>";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
|
@ -239,22 +230,8 @@ if ($_SESSION['user_type'] != "Lecturer" && $_SESSION['user_type'] != "Admin") {
|
|||
|
||||
</div>
|
||||
|
||||
|
||||
<?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>
|
||||
function updatePassword(id, pass) {
|
||||
if (!confirm('Are you sure to reset user password?')) {
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
include 'NoDirectPhpAcess.php';
|
||||
include 'Header.php';
|
||||
include "get_mysql_credentials.php"; // Database credentials
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
// Connect to the database
|
||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Check if user is logged in
|
||||
if (isset($_SESSION['email'])) {
|
||||
$email = $_SESSION['email'];
|
||||
|
||||
// Check if form is submitted
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Get the submitted answers
|
||||
$answer1 = strtolower(trim($_POST['answer1']));
|
||||
$answer2 = strtolower(trim($_POST['answer2']));
|
||||
|
||||
// Fetch correct answers from the database
|
||||
$sql = "SELECT user_id, answer1, answer2 FROM password_recovery_security_questions WHERE email = '$email'";
|
||||
$result = mysqli_query($con, $sql);
|
||||
|
||||
if ($row = mysqli_fetch_assoc($result)) {
|
||||
// Compare submitted answers with stored answers
|
||||
if (hash_equals($row['answer1'], $answer1) && hash_equals($row['answer2'], $answer2)) {
|
||||
$_SESSION['user_id'] = $row['user_id'];
|
||||
header("Location: ResetPassword.php"); // Redirect to password reset page
|
||||
exit;
|
||||
} else {
|
||||
$error_message = "Incorrect answers. Please try again.";
|
||||
}
|
||||
} else {
|
||||
echo '<div class="container mt-5"><div class="alert alert-warning" role="alert">No security questions found for this user.</div></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch security questions from the database for display
|
||||
$sql = "SELECT question1, question2 FROM password_recovery_security_questions WHERE email = '$email'";
|
||||
$result = mysqli_query($con, $sql);
|
||||
|
||||
if ($row = mysqli_fetch_assoc($result)) {
|
||||
// Display the questions in a form
|
||||
echo'<br/><br/><br/>';
|
||||
echo '<div class="container">';
|
||||
echo '<div class="row">';
|
||||
echo '<div class="col-md-5"></div>';
|
||||
echo '<div class="col-md-5">';
|
||||
if (isset($error_message)) {
|
||||
echo '<div id="alertbad" class="alert alert-danger" role="alert">' . $error_message . '</div>'; // Display error message
|
||||
}
|
||||
|
||||
//echo '<center>';
|
||||
echo '<form action="" method="POST" class="">';
|
||||
echo '<legend>Answer Your Security Questions.</legend>';
|
||||
|
||||
// Question 1
|
||||
echo '<div class="mb-3">';
|
||||
echo '<label class="form-label">' . htmlspecialchars($row['question1']) . '</label>';
|
||||
echo '<input type="text" class="form-control" name="answer1" required>';
|
||||
echo '</div>';
|
||||
echo'<br/>';
|
||||
|
||||
// Question 2
|
||||
echo '<div class="mb-3">';
|
||||
echo '<label class="form-label">' . htmlspecialchars($row['question2']) . '</label>';
|
||||
echo '<input type="text" class="form-control" name="answer2" required>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<button id="sub" type="submit" class="btn btn-primary">Submit Answers</button>';
|
||||
echo '</form>';
|
||||
echo '</div></div></div>'; // Close container
|
||||
} else {
|
||||
echo '<div class="container mt-5"><div class="alert alert-warning" role="alert">No security questions found for this user.</div></div>';
|
||||
}
|
||||
} else {
|
||||
header("Location: RecoverPassword.php"); // Redirect if session data is missing
|
||||
exit;
|
||||
}
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
42
Course.php
42
Course.php
|
@ -1,4 +1,6 @@
|
|||
<?php
|
||||
global $con;
|
||||
global $sql_stmt;
|
||||
include 'NoDirectPhpAcess.php';
|
||||
?>
|
||||
|
||||
|
@ -86,22 +88,22 @@ include 'Header.php';
|
|||
|
||||
<ul class="nav nav-tabs" id="myTab">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>" data-toggle="tab" href="#menu1">New</a>
|
||||
<a class="nav-link active" href="#menu1">New</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>" data-toggle="tab" href="#menu2">Missed</a>
|
||||
<a class="nav-link" href="#menu2">Missed</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>" data-toggle="tab" href="#menu3">Submitted</a>
|
||||
<a class="nav-link" href="#menu3">Submitted</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>" data-toggle="tab" href="#menu4">Marked</a>
|
||||
<a class="nav-link" href="#menu4">Marked</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
|
||||
<div id="menu1" class="tab-pane <?php if (!isset($_GET['tab']) || $_GET['tab'] == 'New') echo 'active'; ?>">
|
||||
<div id="menu1" class="tab-pane active">
|
||||
|
||||
<?php
|
||||
|
||||
|
@ -152,7 +154,7 @@ include 'Header.php';
|
|||
$att3 = $row['Attachment_link_3'];
|
||||
$att4 = $row['Attachment_link_4'];
|
||||
$labid = $row['Lab_Report_ID'];
|
||||
$days_remaining = "Days remaining: ".date_diff(date_create($deadline), date_create())->format('%a days, %h hours, %i minutes');
|
||||
$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>";
|
||||
|
||||
if($att2 != "") {
|
||||
|
@ -165,11 +167,6 @@ include 'Header.php';
|
|||
$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;'>
|
||||
<div class='card-body'>
|
||||
<h5 class='card-title'>$title</h5>
|
||||
|
@ -177,7 +174,7 @@ include 'Header.php';
|
|||
<p class='card-text'> $ins </p>
|
||||
<p> <small>Attachments</small>: $full_link </p>
|
||||
<p class='card-text'> <small> Posted: $posted Deadline: $deadline </small> </p>
|
||||
<div class='alert alert-warning'>$days_remaining</div>
|
||||
<div class='alert alert-warning'>Time left: $days_remaining</div>
|
||||
<p><a href='~\..\SubmitLab.php?id=$labid&url=$url' class='btn btn-primary'>Submit</a></p>
|
||||
</div>
|
||||
</div>";
|
||||
|
@ -190,7 +187,7 @@ include 'Header.php';
|
|||
|
||||
|
||||
|
||||
<div id="menu2" class="tab-pane <?php if ($_GET['tab'] == 'Missed') echo 'active'; ?>">
|
||||
<div id="menu2" class="tab-pane">
|
||||
|
||||
<?php
|
||||
$group_id = $_SESSION['group_id'];
|
||||
|
@ -256,7 +253,7 @@ include 'Header.php';
|
|||
|
||||
|
||||
|
||||
<div id="menu3" class="tab-pane <?php if ($_GET['tab'] == 'Submitted') echo 'active'; ?>">
|
||||
<div id="menu3" class="tab-pane">
|
||||
<?php
|
||||
|
||||
$group_id = $_SESSION['group_id'];
|
||||
|
@ -329,10 +326,10 @@ include 'Header.php';
|
|||
$att2 = $row['Attachment2'];
|
||||
$att3 = $row['Attachment3'];
|
||||
$att4 = $row['Attachment4'];
|
||||
$base_att1 = basename(rawurldecode($att1));
|
||||
$base_att2 = basename(rawurldecode($att2));
|
||||
$base_att3 = basename(rawurldecode($att3));
|
||||
$base_att4 = basename(rawurldecode($att4));
|
||||
$base_att1 = basename($att1);
|
||||
$base_att2 = basename($att2);
|
||||
$base_att3 = basename($att3);
|
||||
$base_att4 = basename($att4);
|
||||
|
||||
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
||||
|
||||
|
@ -376,7 +373,7 @@ include 'Header.php';
|
|||
?>
|
||||
|
||||
|
||||
<div id="menu4" class="tab-pane <?php if ($_GET['tab'] == 'Marked') echo 'active'; ?>">
|
||||
<div id="menu4" class="tab-pane">
|
||||
<?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
|
||||
FROM lab_report_submissions
|
||||
|
@ -652,12 +649,11 @@ include 'Header.php';
|
|||
|
||||
|
||||
|
||||
function remarking(url)
|
||||
function remarking(data)
|
||||
{
|
||||
const details = prompt("Please enter your remarking reasons","");
|
||||
if (details != null) {
|
||||
window.location.href = url+"&details="+details;
|
||||
}
|
||||
|
||||
window.location.href = data+"&details="+details;
|
||||
}
|
||||
|
||||
|
||||
|
|
15
Courses.php
15
Courses.php
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
global $con;
|
||||
include 'NoDirectPhpAcess.php';
|
||||
?>
|
||||
|
||||
|
@ -324,7 +325,7 @@ include 'Header.php';
|
|||
}
|
||||
echo "</div>";
|
||||
|
||||
$resultx1 = mysqli_query($con, "SELECT DISTINCT course_students_table.Student_ID, users_table.Full_Name
|
||||
$resultx1 = mysqli_query($con, "SELECT course_students_table.Student_ID, users_table.Full_Name
|
||||
FROM course_students_table
|
||||
INNER JOIN users_table on users_table.Student_ID=course_students_table.Student_ID
|
||||
WHERE Course_ID=$course_id");
|
||||
|
@ -352,7 +353,7 @@ include 'Header.php';
|
|||
|
||||
echo "<h1 class='display-6'>My courses</h1>";
|
||||
|
||||
$result = mysqli_query($con, "SELECT Course_ID, Course_Name, Academic_Year, Faculty, Lecturer_User_ID, TA_User_ID, Course_Code, URL, Verify_New_Members, users_table.Full_Name
|
||||
$result = mysqli_query(($con ) , "SELECT Course_ID, Course_Name, Academic_Year, Faculty, Lecturer_User_ID, TA_User_ID, Course_Code, URL, Verify_New_Members, users_table.Full_Name
|
||||
FROM courses_table
|
||||
INNER JOIN users_table ON users_table.User_ID=courses_table.Lecturer_User_ID
|
||||
WHERE courses_table.Lecturer_User_ID=$user_id
|
||||
|
@ -494,10 +495,6 @@ include 'Header.php';
|
|||
echo '<hr><span class="alert alert-success" role="alert">' . $_SESSION['info_Courses_student'] . '</span>';
|
||||
$_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>
|
||||
</div>
|
||||
|
@ -538,7 +535,7 @@ include 'Header.php';
|
|||
}
|
||||
|
||||
if (mysqli_num_rows($result) == 0) {
|
||||
echo "No such course offered in this academic year. Please check that your have entered the correct course code.<hr>";
|
||||
echo "No results. <hr>";
|
||||
} else {
|
||||
while($row = mysqli_fetch_assoc($result)) {
|
||||
$name = $row['Course_Name'];
|
||||
|
@ -642,5 +639,5 @@ include 'Header.php';
|
|||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
</div>
|
||||
|
|
24
Header.php
24
Header.php
|
@ -1,24 +1,20 @@
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
?>
|
||||
|
||||
<?php
|
||||
session_start();
|
||||
error_reporting(0);
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
include "get_mysql_credentials.php";
|
||||
try {
|
||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
//include "get_mysql_credentials.php";
|
||||
$mysql_host= "localhost";
|
||||
$mysql_username = "root";
|
||||
$mysql_password = "";
|
||||
$mysql_db = "lrr";
|
||||
|
||||
// $mysql_username, $mysql_password variable declared directly
|
||||
$con = mysqli_connect($mysql_host,$mysql_username,$mysql_password,$mysql_db);
|
||||
// Check database connection
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
echo " Error number: ".mysqli_connect_errno();
|
||||
exit();
|
||||
echo "Failed to connect to MySQL: " . mysqli_connect_error();
|
||||
}
|
||||
?>
|
||||
|
||||
|
@ -162,7 +158,7 @@ if (mysqli_connect_errno()) {
|
|||
|
||||
<?php
|
||||
if (isset($_SESSION["user_fullname"])) {
|
||||
if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer' || $_SESSION['user_type'] == 'TA') {
|
||||
if ($_SESSION['user_type'] == "Student" || $_SESSION['user_type'] == 'Lecturer') {
|
||||
echo "<a class='nav-link' href='~\..\Courses.php'><i class='fa fa-book'></i> My courses </a>";
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
// https://stackoverflow.com/questions/33999475/prevent-direct-url-access-to-php-file
|
||||
if (!isset($_SERVER['HTTP_REFERER']) ) {
|
||||
/* choose the appropriate page to redirect users */
|
||||
die( header( 'location: logout.php' ) );
|
||||
}
|
||||
//if (!isset($_SERVER['HTTP_REFERER']) ) {
|
||||
// /* choose the appropriate page to redirect users */
|
||||
// die( header( 'location: logout.php' ) );
|
||||
//}
|
||||
?>
|
||||
|
|
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.
|
||||
|
||||
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.
|
||||
while he was taking a graduate course called **Advanced Software Engineering** (http://lanlab.org/course/2018f/se/homepage.html).
|
||||
|
||||
For potential project contributors, we recommend that you browse its home page at ./homepage/index.html first to familiarize yourself with the project.
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
@ -159,16 +159,7 @@ https://github.com/spm2020spring/TeamCollaborationTutorial/blob/master/team.rst
|
|||
|
||||
## Testing
|
||||
|
||||
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`
|
||||
Make sure your changes can pass all the tests in folder [./test](http://121.4.94.30:3000/mrlan/LRR/src/branch/master/test).
|
||||
|
||||
|
||||
## Communications Method
|
||||
|
@ -182,10 +173,10 @@ We can also communicate through pull requests. You make a pull request, I revie
|
|||
## 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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
@ -258,6 +249,6 @@ Nicole-Rutagengwa - Nicole Rutagengwa - 2019169
|
|||
|
||||
# References
|
||||
|
||||
- 詹沈晨. (2020). 网页程序测试自动化 (Selenium) 测试效率.
|
||||
- 詹沈晨. (2020). [网页程序测试自动化 (Selenium) 测试效率](http://lanlab.org/ZhanShenchen-On-Automated-Web-Application-Test-Efficiency-with-Selenium.doc)
|
||||
|
||||
- Ibrahim. (2021). Defect analysis for LRR]
|
||||
- Ibrahim. (2021). [Defect analysis for LRR](http://lanlab.org/thesis/Defect-Analysis-for-LRR.docx)
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
require_once 'Header.php';
|
||||
require_once 'NoDirectPhpAcess.php';
|
||||
require_once "get_mysql_credentials.php";
|
||||
|
||||
ini_set('display_errors', 0);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
error_log("Database connection failed: " . mysqli_connect_error());
|
||||
die("An error occurred. Please try again later.");
|
||||
}
|
||||
|
||||
// Check if user_id is set in the session
|
||||
if (!isset($_SESSION['email'])) {
|
||||
die("Session expired. Please log in again.");
|
||||
}
|
||||
|
||||
$email = $_SESSION['email'];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Handle password reset
|
||||
if (isset($_POST['new_password']) && isset($_POST['confirm_password'])) {
|
||||
$new_password = $_POST['new_password'];
|
||||
$confirm_password = $_POST['confirm_password'];
|
||||
|
||||
if (!preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\d\s]).{8,}$/', $new_password)) {
|
||||
echo '<div class="alert alert-danger">Password must be at least 8 characters long and include uppercase and lowercase letters, numbers, and special characters.</div>';
|
||||
} elseif ($new_password !== $confirm_password) {
|
||||
echo '<div class="alert alert-danger">Passwords do not match. Please try again.</div>';
|
||||
} else {
|
||||
$hashed_password = password_hash($new_password, PASSWORD_ARGON2ID);
|
||||
$user_id = $_SESSION['user_id'];
|
||||
|
||||
$stmt = $con->prepare("UPDATE users_table SET Password = ? WHERE email = ? AND user_id = ?");
|
||||
$stmt->bind_param("sss", $hashed_password, $email, $user_id);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo '<div class="alert alert-success">Password reset successfully. You can now log in with your new password.</div>';
|
||||
unset($_SESSION['user_id']); // Clear user_id after successful password reset
|
||||
header("Location: index.php");
|
||||
} else {
|
||||
error_log("Error updating password for user ID: $user_id");
|
||||
echo '<div class="alert alert-danger">An error occurred. Please try again later.</div>';
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the reset password form
|
||||
echo '
|
||||
<br/><br/><br/>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-5"></div>
|
||||
<div class="col-md-5">
|
||||
<form action="" method="POST" class="">
|
||||
<legend>Reset Your Password</legend><br/>
|
||||
New Password <label class="form-text">Must include uppercase and lowercase letters, digits and special characters.</label>
|
||||
<input type="password" name="new_password" placeholder=" Enter New Password" class="form-control" required>
|
||||
<br/>
|
||||
Confirm New Password
|
||||
<input type="password" name="confirm_password" placeholder="Confirm New Password" class="form-control" required>
|
||||
<br/>
|
||||
<button id="butt" type="submit" class="btn btn-primary">Reset Password</button>
|
||||
</form>
|
||||
</div></div></div>
|
||||
<style>
|
||||
.guideline { display: none;}
|
||||
#newPassword:focus + .guideline {display: block;}
|
||||
';
|
||||
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
274
Script.php
274
Script.php
|
@ -1,5 +1,16 @@
|
|||
<?php
|
||||
include 'NoDirectPhpAcess.php';
|
||||
function downloadFile($filename)
|
||||
{
|
||||
|
||||
$file_url = './acounts/' . $filename.'.txt';
|
||||
header('content-type: text/plain');
|
||||
header('Cache-Control: no-cache, must-revalidate');
|
||||
header('Content-Disposition: attachment; filename=' . basename($file_url));
|
||||
readfile($file_url);
|
||||
header("Refresh: 5");
|
||||
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
@ -13,8 +24,18 @@ session_start();
|
|||
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
include "get_mysql_credentials.php";
|
||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||
|
||||
// Connect to MySQL database
|
||||
$mysql_host= "localhost";
|
||||
$mysql_username = "root";
|
||||
$mysql_password = "";
|
||||
$mysql_db = "lrr";
|
||||
|
||||
// $mysql_username, $mysql_password variable declared directly
|
||||
$con= mysqli_connect($mysql_host,$mysql_username,$mysql_password,$mysql_db);
|
||||
//$con = mysqli_connect("localhost", "root", "", "lrr");
|
||||
|
||||
|
||||
|
||||
// Check connection
|
||||
if (mysqli_connect_errno()) {
|
||||
|
@ -36,54 +57,10 @@ function is_valid_student_number($student_id)
|
|||
// ############################### SIGN UP ##################################
|
||||
if (!empty($_POST["form_signup"])) {
|
||||
$student_id = trim(mysqli_real_escape_string($con, $_POST["user_student_id"]));
|
||||
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
||||
$password = mysqli_real_escape_string($con, $_POST["password"]);
|
||||
$confirmpassword = mysqli_real_escape_string($con, $_POST["confirmpassword"]);
|
||||
|
||||
$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., !?.,*^).";
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check confirmed password
|
||||
if (strcasecmp($password, $confirmpassword) != 0) {
|
||||
$_SESSION['info_signup'] = "Password confirmation failed.";
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
||||
// validate email
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION['info_signup'] = "Invalid email address.";
|
||||
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. You have already signed up?";
|
||||
}
|
||||
|
||||
$_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
|
||||
if (!is_valid_student_number($student_id)) {
|
||||
$_SESSION["info_signup"] = "Invalid student number.";
|
||||
$_SESSION['user_fullname'] = null;
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
@ -92,10 +69,6 @@ if (!empty($_POST["form_signup"])) {
|
|||
$result = mysqli_query($con, "SELECT * FROM `students_data` WHERE Student_ID='$student_id'");
|
||||
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['user_fullname'] = null;
|
||||
|
||||
|
||||
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
@ -106,7 +79,6 @@ if (!empty($_POST["form_signup"])) {
|
|||
$student_result = mysqli_query($con, "SELECT * FROM `users_table` WHERE Student_ID='$student_id'");
|
||||
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['user_fullname'] = null;
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
@ -116,14 +88,14 @@ if (!empty($_POST["form_signup"])) {
|
|||
if (!empty($_POST["form_signup"])) {
|
||||
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
||||
$student_id = mysqli_real_escape_string($con, $_POST["user_student_id"]);
|
||||
|
||||
$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_fullname'] = $fullname;
|
||||
$_SESSION['user_type'] = "Student";
|
||||
|
||||
$_SESSION['user_email'] = $email;
|
||||
$_SESSION['user_student_id'] = $student_id;
|
||||
|
||||
// check confirmed password
|
||||
if (strcasecmp($password, $confirmpassword) != 0) {
|
||||
$_SESSION['info_signup'] = "Password confirmation failed.";
|
||||
|
@ -135,8 +107,6 @@ if (!empty($_POST["form_signup"])) {
|
|||
// validate email
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION['info_signup'] = "Invalid email address.";
|
||||
$_SESSION['user_fullname'] = null;
|
||||
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
@ -150,41 +120,26 @@ if (!empty($_POST["form_signup"])) {
|
|||
// 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?";
|
||||
if (mysqli_num_rows($result) != 0) {
|
||||
$_SESSION["info_signup"] = "Email address " . $email . " is already in use.";
|
||||
$_SESSION['user_fullname'] = null;
|
||||
header("Location: signup.php");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$_SESSION['user_type'] = "Student";
|
||||
$_SESSION['user_email'] = $email;
|
||||
$_SESSION['user_student_id'] = $student_id;
|
||||
|
||||
// apply password_hash()
|
||||
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
|
||||
. "('$email','$password_hash','','$fullname','Student','$student_id')";
|
||||
|
||||
|
||||
$_SESSION['user_fullname'] =$_SESSION['user_fullname_temp'];
|
||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`, `Student_ID`) VALUES "
|
||||
. "('$email','$password_hash','$fullname','Student','$student_id')";
|
||||
|
||||
if ($con->query($sql) === TRUE) {
|
||||
// Get the newly inserted user's ID
|
||||
$user_id = $con->insert_id;
|
||||
|
||||
//Set the user_id in the session
|
||||
$_SESSION['user_id'] = $user_id;
|
||||
|
||||
//Redirect to SecurityQuestions.php
|
||||
header("Location: SecurityQuestions.php");
|
||||
header("Location: Courses.php");
|
||||
} else {
|
||||
echo "Something really bad (SQL insertion error) happened during sign up.";
|
||||
}
|
||||
|
@ -197,15 +152,11 @@ 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
|
||||
$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
|
||||
if (is_valid_student_number($user)) {
|
||||
$is_student_number = 1;
|
||||
}
|
||||
|
||||
|
||||
// Validate email address if what provided is not a student number
|
||||
if (!$is_student_number && !filter_var($user, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION["info_login"] = "Invalid email address: " . "$user";
|
||||
|
@ -231,91 +182,61 @@ if (!empty($_POST["form_login"])) {
|
|||
$_SESSION['user_type'] = $row['UserType'];
|
||||
$_SESSION['user_fullname'] = $row['Full_Name'];
|
||||
|
||||
// Check if the user is a student and has not set up their password recovery yet
|
||||
|
||||
if ($_SESSION['user_type'] == "Student") {
|
||||
// Query to check if the student has completed the password recovery setup
|
||||
$recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE Student_ID = '" . $row['Student_ID'] . "'");
|
||||
if (mysqli_num_rows($recovery_result) == 0) {
|
||||
// If the student has not set up password recovery, redirect to the setup page
|
||||
header("Location: SecurityQuestions.php");
|
||||
exit();
|
||||
} else {
|
||||
// If the student has set up password recovery, redirect to the Courses page
|
||||
header("Location: Courses.php");
|
||||
}
|
||||
header("Location: Courses.php");
|
||||
}
|
||||
|
||||
// Redirect other user types to their respective pages
|
||||
|
||||
if ($_SESSION['user_type'] == "Lecturer") {
|
||||
$recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'Lecturer'");
|
||||
if (mysqli_num_rows($recovery_result) == 0) {
|
||||
header("Location: SecurityQuestions.php");
|
||||
exit();
|
||||
} else {
|
||||
header("Location: Courses.php"); }
|
||||
header("Location: Courses.php");
|
||||
}
|
||||
|
||||
if ($_SESSION['user_type'] == "TA") {
|
||||
$recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'TA'");
|
||||
if (mysqli_num_rows($recovery_result) == 0) {
|
||||
header("Location: SecurityQuestions.php");
|
||||
exit();
|
||||
} else {
|
||||
header("Location: Courses.php"); }
|
||||
|
||||
header("Location: Courses.php");
|
||||
}
|
||||
|
||||
if ($_SESSION['user_type'] == "Admin") {
|
||||
$recovery_result = mysqli_query($con, "SELECT * FROM password_recovery_security_questions WHERE user_id = '" . $row['User_ID'] . "' AND user_type = 'Admin'");
|
||||
if (mysqli_num_rows($recovery_result) == 0) {
|
||||
header("Location: SecurityQuestions.php");
|
||||
exit();
|
||||
} else {
|
||||
header("Location: Admin.php"); }
|
||||
|
||||
header("Location: Admin.php");
|
||||
}
|
||||
// report wrong pass if not correct
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
} else {
|
||||
$_SESSION["wrong_pass"] = "Wrong Password.";
|
||||
echo $_SESSION["wrong_pass"]; // Optional: Display the error message for debugging
|
||||
|
||||
header("Location: index.php");
|
||||
exit(); // Add this line to prevent further execution after redirect
|
||||
}
|
||||
// Reset the session variable when needed
|
||||
unset($_SESSION["failed_login_user"]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ################################ Recover Password #####################################
|
||||
|
||||
if (!empty($_POST["form_recover_password"])) {
|
||||
|
||||
$student_id = mysqli_real_escape_string($con, $_POST["sno"]);
|
||||
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
||||
|
||||
// Validate email
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION["info_recover_password"] = "Invalid email address.";
|
||||
header("Location: RecoverPassword.php");
|
||||
// validate student number
|
||||
if (strlen($student_id) != 12 || is_numeric($student_id) == FALSE) {
|
||||
$_SESSION["info_recover_password"] = "Invalid student number.";
|
||||
header("Location: recover_password.php");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user exists in the database
|
||||
$result = mysqli_query($con, "SELECT * FROM users_table WHERE Email='$email'");
|
||||
if (mysqli_num_rows($result) == 0) {
|
||||
$_SESSION["info_recover_password"] = "Email address is not recognized.";
|
||||
header("Location: RecoverPassword.php");
|
||||
} else {
|
||||
// Store the student ID and email in the session
|
||||
$_SESSION['email'] = $email;
|
||||
header("Location: AnswerSecurityQuestions.php");
|
||||
}
|
||||
// validate email
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
$_SESSION["info_recover_password"] = "Invalid email address.";
|
||||
// echo "Invalid email address.";
|
||||
header("Location: recover_password.php");
|
||||
return;
|
||||
}
|
||||
|
||||
$result = mysqli_query($con, "SELECT * FROM users_table WHERE Email='$email' and Student_ID='$student_id'");
|
||||
if (mysqli_num_rows($result) == 0) {
|
||||
$_SESSION["info_recover_password"] = "Email address is not recognised.";
|
||||
$_SESSION["info_recover_password"] = "Identity not recognized. Try again or send an inquiry email message to lanhui at zjnu.edu.cn.";
|
||||
header("Location: recover_password.php");
|
||||
} else {
|
||||
$result = mysqli_query($con, "DELETE FROM users_table WHERE Email='$email' and Student_ID='$student_id'");
|
||||
header("Location: signup.php");
|
||||
}
|
||||
}
|
||||
|
||||
// ################################ RESET Password #####################################
|
||||
|
@ -364,35 +285,46 @@ if (!empty($_POST["form_reset_password"])) {
|
|||
}
|
||||
|
||||
// ############################### CREATE Lecturer/TA USER ##################################
|
||||
if (!empty($_POST["form_createlecturer"])){
|
||||
if (!empty($_POST["form_createlecturrer"])){
|
||||
$email = mysqli_real_escape_string($con, $_POST["email"]);
|
||||
$fullname = mysqli_real_escape_string($con, $_POST["fullname"]);
|
||||
$type = mysqli_real_escape_string($con, $_POST["type"]);
|
||||
$password = mysqli_real_escape_string($con, $_POST["password"]);
|
||||
$pass_len = strlen($password);
|
||||
if ($pass_len == 0) {
|
||||
$password = generateStrongPassword();
|
||||
}
|
||||
$password = mysqli_real_escape_string($con, $_POST["passport"]);
|
||||
$pass_len=strlen($password);
|
||||
if ($pass_len==0) {
|
||||
$password = generateStrongPassword();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// $passport_no=$password;
|
||||
// check if email is taken
|
||||
$result = mysqli_query(
|
||||
$con,
|
||||
"SELECT * FROM users_table WHERE email='$email'"
|
||||
"SELECT * FROM Users_Table WHERE email='$email'"
|
||||
);
|
||||
if (mysqli_num_rows($result) != 0) {
|
||||
$_SESSION["info_Admin_Users"] = "Email address : " . $email . " is already in use.";
|
||||
header("Location: Admin.php");
|
||||
exit;
|
||||
// header( "refresh:5;url=Admin.php" );
|
||||
|
||||
}
|
||||
$password_hash = password_hash("$password", PASSWORD_DEFAULT);
|
||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `HashPassword`, `Full_Name`, `UserType`) VALUES ('$email','$password_hash','','$fullname','$type')";
|
||||
$sql = "INSERT INTO `users_table`(`Email`, `Password`, `Full_Name`, `UserType`) VALUES "
|
||||
. "('$email','$password_hash','$fullname','$type')";
|
||||
|
||||
try {
|
||||
$result = mysqli_query($con, $sql);
|
||||
if ($con->query($sql) === TRUE) {
|
||||
// $file_name = $email.'.txt';
|
||||
$_SESSION["info_Admin_Users"] = $type . " user created successfully. Use email " . $email . " as account name and ". $password ." as password.";
|
||||
header("Location: Admin.php?tacreated");
|
||||
} catch (Exception $ex) {
|
||||
echo "$ex";
|
||||
// file_put_contents('./acounts/'.$file_name, $_SESSION["info_Admin_Users"]);
|
||||
//downloadFile($email);
|
||||
header("Location: Admin.php");
|
||||
|
||||
} else {
|
||||
alert("Error: " . $sql . "<br>" . $con->error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ### FUNCTION TO GENERATE INITIAL PASSWORDS ###//
|
||||
|
@ -812,8 +744,8 @@ if (!empty($_GET["remarking"])) {
|
|||
|
||||
if ($con->query($sql) === TRUE) {
|
||||
|
||||
$_SESSION["info_general"] = "Remarking Request Sent";
|
||||
header("Location: Course.php?url=" . $url . "&tab=Marked");
|
||||
$_SESSION["info_general"] = "Remarking request sent";
|
||||
header("Location: Course.php?url=" . $url);
|
||||
} else {
|
||||
echo "Error: " . $sql . "<br>" . $con->error;
|
||||
}
|
||||
|
@ -1033,32 +965,18 @@ if (!empty($_GET["ignoreremarking"])) {
|
|||
#Assign TA
|
||||
|
||||
if (!empty($_GET["assignTA"])) {
|
||||
|
||||
$id = mysqli_real_escape_string($con, $_GET["id"]);
|
||||
$ta = mysqli_real_escape_string($con, $_GET["ta"]);
|
||||
|
||||
// Check if the TA is already assigned to the course
|
||||
$check_sql = "SELECT * FROM course_ta WHERE Course_ID='$id' AND TA='$ta'";
|
||||
$check_result = $con->query($check_sql);
|
||||
$sql = "INSERT INTO `course_ta`(`Course_ID`, `TA`) VALUES ('$id','$ta')";
|
||||
|
||||
if ($check_result->num_rows > 0) {
|
||||
// Alert user about the duplicate assignment
|
||||
echo "<script>
|
||||
alert('The selected TA is already assigned to this course.');
|
||||
window.location.href='Admin.php';
|
||||
</script>";
|
||||
if ($con->query($sql) === TRUE) {
|
||||
|
||||
$_SESSION["info_Admin_Courses"] = $type . " Course TA Assigned ";
|
||||
header("Location: Admin.php");
|
||||
} else {
|
||||
// Proceed with the TA assignment
|
||||
$sql = "INSERT INTO course_ta(Course_ID, TA) VALUES ('$id','$ta')";
|
||||
|
||||
if ($con->query($sql) === TRUE) {
|
||||
$_SESSION["info_Admin_Courses"] = $type . " Course TA Assigned ";
|
||||
header("Location: Admin.php");
|
||||
} else {
|
||||
echo "<script>
|
||||
alert('You must select a TA first!.');
|
||||
window.location.href='Admin.php';
|
||||
</script>";
|
||||
}
|
||||
echo "Error: " . $sql . "<br>" . $con->error;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
session_start();
|
||||
error_reporting(0);
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
include 'NoDirectPhpAcess.php';
|
||||
include "get_mysql_credentials.php"; // Database credentials
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$con = mysqli_connect("localhost", $mysql_username, $mysql_password, "lrr");
|
||||
|
||||
if (mysqli_connect_errno()) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Check if user_id is set in the session
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
echo '<div class="alert alert-danger" role="alert">Session expired. Please log in again.</div>';
|
||||
exit(); // Stop script execution if user_id is not set
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// Get the security questions and answers from the form
|
||||
$question1 = mysqli_real_escape_string($con, $_POST['security_question1']);
|
||||
$answer1 = strtolower(mysqli_real_escape_string($con, $_POST['security_answer1']));
|
||||
$question2 = mysqli_real_escape_string($con, $_POST['security_question2']);
|
||||
$answer2 = strtolower(mysqli_real_escape_string($con, $_POST['security_answer2']));
|
||||
|
||||
// Get the user ID and user type from the session
|
||||
$user_id = $_SESSION['user_id']; // Use user_id from session
|
||||
$user_type = $_SESSION['user_type']; //Get user type from session
|
||||
$email = $_SESSION['user_email'];
|
||||
$student_id = isset($_SESSION['user_student_id']) ? $_SESSION['user_student_id'] : NULL; //Handle student_id for students
|
||||
|
||||
// Prepare SQL statement
|
||||
if($user_type == 'Student') {
|
||||
$sql = "INSERT INTO password_recovery_security_questions (user_id,user_type, student_id, email, question1, answer1, question2, answer2)
|
||||
VALUES ('$user_id', '$user_type', '$student_id', '$email', '$question1', '$answer1', '$question2', '$answer2')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
question1='$question1',
|
||||
answer1='$answer1',
|
||||
question2='$question2',
|
||||
answer2='$answer2'";
|
||||
} else {
|
||||
// For non-students (Lecturer, TA, etc.), exclude student_id
|
||||
$sql = "INSERT INTO password_recovery_security_questions (user_id, user_type, email, question1, answer1, question2, answer2)
|
||||
VALUES ('$user_id', '$user_type', '$email', '$question1', '$answer1', '$question2', '$answer2')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
question1='$question1',
|
||||
answer1='$answer1',
|
||||
question2='$question2',
|
||||
answer2='$answer2'";
|
||||
}
|
||||
|
||||
// Execute the query and check for success
|
||||
if (mysqli_query($con, $sql)) {
|
||||
echo '<div id="alertgood" class="alert alert-success" role="alert">Password recovery details set successfully. Please remember your answers! Redirecting to Courses page...</div>';
|
||||
echo '<script>';
|
||||
echo ' setTimeout(function() {';
|
||||
echo ' var userType = "'. $_SESSION['user_type'] . '";';
|
||||
echo ' if (userType === "Admin") {';
|
||||
echo ' window.location.href = "Admin.php";';
|
||||
echo ' } else {';
|
||||
echo ' window.location.href = "Courses.php";';
|
||||
echo ' }';
|
||||
echo ' }, 2000);';
|
||||
echo '</script>';
|
||||
} else {
|
||||
echo '<div class="alert alert-danger" role="alert">Error: ' . mysqli_error($con) . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
mysqli_close($con);
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Security Questions</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary" style="padding-left:180px;padding-right:150px;margin:auto;">
|
||||
<div class="container-fluid">
|
||||
|
||||
<a class="navbar-brand" href="#"> <img src="logo.png" style="width:30px;height:30px;" alt="LRR Logo"> LRR </a>
|
||||
</nav>
|
||||
<br/><br/><br/>
|
||||
<div class="container">
|
||||
<div class="col-md-5"></div>
|
||||
<form action="SecurityQuestions.php" method="POST">
|
||||
<label> Set Password Recovery (Make sure you remember your answers) </label>
|
||||
<div class="mb-3">
|
||||
<br/>
|
||||
<label for="security_question1" class="form-label">Select Security Question 1</label>
|
||||
<select class="form-select" id="security_question1" name="security_question1" required>
|
||||
<option value="">-- Select a question --</option>
|
||||
<option value="What is the name of your first pet?">What is the name of your first pet?</option>
|
||||
<option value="What is your mother's maiden name?">What is your mother's maiden name?</option>
|
||||
<option value="What is the name of the town where you were born?">What is the name of the town where you were born?</option>
|
||||
<option value="What was the name of your first best friend?">What was the name of your first best friend?</option>
|
||||
<option value="What is your favorite book?">What is your favorite book?</option>
|
||||
<option value="What was the make and model of your first car?">What was the make and model of your first car?</option>
|
||||
<!-- Add more options if needed -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="security_answer1" class="form-label">Answer 1</label>
|
||||
<input type="text" class="form-control" id="security_answer1" name="security_answer1" required>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="mb-3">
|
||||
<label for="security_question2" class="form-label">Select Security Question 2</label>
|
||||
<select class="form-select" id="security_question2" name="security_question2" required>
|
||||
<option value="">-- Select a question --</option>
|
||||
<option value="What was the name of your first school?">What was the name of your first school?</option>
|
||||
<option value="What is your favorite movie?">What is your favorite movie?</option>
|
||||
<option value="What was your childhood nickname?">What was your childhood nickname?</option>
|
||||
<option value="What is the name of your favorite teacher?">What is the name of your favorite teacher?</option>
|
||||
<option value="What street did you grow up on?">What street did you grow up on?</option>
|
||||
<option value="What is your favorite food?">What is your favorite food?</option>
|
||||
<!-- Add more options if needed -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="security_answer2" class="form-label">Answer 2</label>
|
||||
<input type="text" class="form-control" id="security_answer2" name="security_answer2" required>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<button id="submit_recovery" type="submit" class="btn btn-primary">Save Answers</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
global $con;
|
||||
include 'NoDirectPhpAcess.php';
|
||||
?>
|
||||
|
||||
|
@ -151,10 +152,10 @@ echo "<div><a href='Courses.php?course=$url'> $header </a></div>";
|
|||
$submitted_by = "$student_name ($submitter_student_number) for group $groupname ";
|
||||
}
|
||||
|
||||
$base_att1 = basename(rawurldecode($att1));
|
||||
$base_att2 = basename(rawurldecode($att2));
|
||||
$base_att3 = basename(rawurldecode($att3));
|
||||
$base_att4 = basename(rawurldecode($att4));
|
||||
$base_att1 = basename($att1);
|
||||
$base_att2 = basename($att2);
|
||||
$base_att3 = basename($att3);
|
||||
$base_att4 = basename($att4);
|
||||
|
||||
$full_link = "<a href='~\..\Download.php?file=$att1&attachment=1'>$base_att1</a>"; // prevent students from directly accessing their classmates' submissions
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
global $con;
|
||||
include 'NoDirectPhpAcess.php';
|
||||
?>
|
||||
|
||||
|
|
|
@ -4,15 +4,22 @@
|
|||
//数据库信息
|
||||
|
||||
|
||||
include "get_mysql_credentials.php";
|
||||
$servername = "localhost";
|
||||
$username = $mysql_username;
|
||||
$password = $mysql_password;
|
||||
$dbname = "lrr";
|
||||
|
||||
// 创建连接
|
||||
$conn = mysqli_connect($servername, $username, $password, $dbname);
|
||||
//include "get_mysql_credentials.php";
|
||||
//$servername = "localhost";
|
||||
//$username = $mysql_username;
|
||||
//$password = $mysql_password;
|
||||
//$dbname = "lrr";
|
||||
//
|
||||
//// 创建连接
|
||||
//$conn = mysqli_connect($servername, $username, $password, $dbname);
|
||||
global $sql_stmt;
|
||||
$mysql_host= "localhost";
|
||||
$mysql_username = "root";
|
||||
$mysql_password = "";
|
||||
$mysql_db = "lrr";
|
||||
|
||||
// $mysql_username, $mysql_password variable declared directly
|
||||
$conn = mysqli_connect($mysql_host,$mysql_username,$mysql_password,$mysql_db);
|
||||
// 检测连接
|
||||
if (!$conn) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -8,4 +8,4 @@
|
|||
user-select: text;
|
||||
cursor:auto
|
||||
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
Increasing session duration
|
||||
---------------------------
|
||||
|
||||
By default, the session duration in PHP is set to 1,440 seconds (24
|
||||
minutes). However, this is not convenient in most software
|
||||
systems. Therefore, we may need to increase the duration to allow
|
||||
users to have more session time. To increase the session duration, we
|
||||
need to edit the variable *session.gc_maxlifetime* in **php.ini**. We
|
||||
can increase its default value to whatever we want (e.g., 7200). On
|
||||
Ubuntu, the file is located at */etc/php/7.2/apache2/php.ini*. On
|
||||
XAMPP, the file is located at */xampp/php/php.ini*.
|
||||
|
||||
*Last modified on 20 April 2022 by Umar*
|
|
@ -1,94 +0,0 @@
|
|||
Contributed by Aya Boussouf 2025-05-19
|
||||
|
||||
|
||||
# ---------------------- System Update & LAMP Stack Installation ----------------------
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install apache2 mysql-server php libapache2-mod-php php-mysql unzip git -y
|
||||
|
||||
# ---------------------- Start and Enable Apache & MySQL Services ----------------------
|
||||
sudo systemctl start apache2
|
||||
sudo systemctl enable apache2
|
||||
|
||||
sudo systemctl start mysql
|
||||
sudo systemctl enable mysql
|
||||
|
||||
# ---------------------- Configure MySQL Root User ----------------------
|
||||
sudo mysql
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';
|
||||
FLUSH PRIVILEGES;
|
||||
exit;
|
||||
|
||||
# ---------------------- Create LRR Database ----------------------
|
||||
mysql -u root -p
|
||||
CREATE DATABASE lrr;
|
||||
exit;
|
||||
|
||||
# ---------------------- Clone LRR Project Repository ----------------------
|
||||
cd /var/www/html/
|
||||
sudo git clone http://118.25.96.118:3000/mrlan/LRR.git
|
||||
sudo chown -R $USER:$USER /var/www/html/LRR
|
||||
|
||||
# ---------------------- Switch to Hui-Organize Branch ----------------------
|
||||
cd /var/www/html/LRR
|
||||
git branch
|
||||
git checkout -b Hui-Organize
|
||||
git pull origin Hui-Organize
|
||||
|
||||
# ---------------------- Import SQL Data into MySQL ----------------------
|
||||
sudo mysql -u root -p lrr < /var/www/html/LRR/lrr_database.sql
|
||||
|
||||
# ---------------------- Create Submission Folder for Assignments ----------------------
|
||||
cd /var/www/
|
||||
sudo mkdir lrr_submission
|
||||
sudo chown -R www-data:www-data lrr_submission
|
||||
sudo chmod -R g+rw lrr_submission
|
||||
|
||||
# ---------------------- Configure Database Credentials in KeepItSafe.txt ----------------------
|
||||
sudo nano /var/www/lrr_submission/KeepItSafe.txt
|
||||
# Add: root,root (username,password for MySQL connection)
|
||||
|
||||
|
||||
# ---------------------- Configure Apache Virtual Host for LRR ----------------------
|
||||
sudo nano /etc/apache2/sites-available/LRR.conf
|
||||
<VirtualHost *:80>
|
||||
ServerName localhost
|
||||
DocumentRoot /var/www/html
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
</VirtualHost>
|
||||
|
||||
# ---------------------- Enable Apache Config and Rewrite Module ----------------------
|
||||
sudo a2ensite LRR
|
||||
sudo a2enmod rewrite
|
||||
sudo systemctl reload apache2
|
||||
|
||||
# ---------------------- Install Google Chrome (for Selenium Tests) ----------------------
|
||||
cd ~/Downloads
|
||||
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
|
||||
sudo apt install ./google-chrome-stable_current_amd64.deb
|
||||
|
||||
# ---------------------- Install ChromeDriver ----------------------
|
||||
wget https://storage.googleapis.com/chrome-for-testing-public/136.0.7103.92/linux64/chromedriver-linux64.zip
|
||||
unzip chromedriver-linux64.zip
|
||||
sudo mv chromedriver-linux64/chromedriver /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/chromedriver
|
||||
|
||||
# ---------------------- Install Python, pip and Virtual Environment ----------------------
|
||||
sudo apt install python3 python3-pip -y
|
||||
sudo apt install python3-venv -y
|
||||
|
||||
# ---------------------- Create and Activate Virtual Environment for LRR ----------------------
|
||||
cd /var/www/html/LRR
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# ---------------------- Install Required Python Packages ----------------------
|
||||
pip install selenium
|
||||
pip install pytest
|
||||
|
||||
# ---------------------- Run Selenium Tests ----------------------
|
||||
cd test
|
||||
# Make necessary edits in `conftest.py` and `test_lrr.py`.
|
||||
pytest -v SeleniumHui/test_lrr.py
|
||||
|
||||
|
|
@ -1,26 +1,7 @@
|
|||
Todo
|
||||
----
|
||||
|
||||
3. Filter file format and size upon upload.
|
||||
|
||||
4.1. Upon Change password it must ask the old password first before new password.
|
||||
|
||||
4.2. It should not use the GET REQUEST on password which puts user's data at risk since it displays in the URL.
|
||||
|
||||
* Allow submission without file upload
|
||||
|
||||
* Lecturer/TA should see his/her feedback on submissions
|
||||
|
||||
* Remarking request details required
|
||||
|
||||
|
||||
Done
|
||||
----
|
||||
|
||||
1. The connect.php should not echo 'Connected' since there is a redirect already in the header.php [Resolved]
|
||||
|
||||
2. The header.php is connecting to the database twice through inline connection and an external connect.php [Resolved]
|
||||
|
||||
4. Added css into the header.php
|
||||
* Lecturer/TA should see his/her feedback on submissions
|
||||
|
||||
* Check Spelling Issues
|
||||
|
||||
* Remarking request details required
|
|
@ -1,26 +0,0 @@
|
|||
Quick Start Guide
|
||||
|
||||
|
||||
* Use Admin User to Create Lecturer Accounts
|
||||
|
||||
Account: Admin
|
||||
Password: admin@123
|
||||
|
||||
* Create a Lecturer account
|
||||
|
||||
* Login to Lecturer account
|
||||
|
||||
* Create a course ( You can determine whether or not students need approval before they can join the course. )
|
||||
|
||||
* As Student
|
||||
|
||||
You can Sign up with your Student ID, then provide your email address and password.
|
||||
|
||||
* Browse Courses by Deartment
|
||||
|
||||
- Or Search by Course Course
|
||||
- Join Course
|
||||
- You can see the list of your courses in Course Home page
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
<h1> Quick Start Guide </h1>
|
||||
<hr>
|
||||
|
||||
|
||||
* Use Admin User to Create Lecturer Accounts
|
||||
|
||||
user : Admin
|
||||
Password : admin@123
|
||||
|
||||
* Create Lecturer
|
||||
|
||||
* Login to Lecturer Account
|
||||
|
||||
|
||||
* Create Course ( You can define whether or not students require approval to join the course )
|
||||
|
||||
|
||||
* As Student
|
||||
|
||||
You can Sign up with your Student ID
|
||||
Then Provide your Email and Password
|
||||
|
||||
* Browse Courses by Deartment
|
||||
|
||||
- Or Search by Course Course
|
||||
- Join Course
|
||||
- You can see the list of your courses in Course Home page
|
||||
|
||||
*
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
Resetting password
|
||||
------------------
|
||||
|
||||
We can reset a user's password by directly modifying the MySQL
|
||||
database table called `users_table`. More specifically, we delete
|
||||
that user's information from `users_table` so that the user could sign
|
||||
up again. Suppose the user's student number is 201131129138.
|
||||
|
||||
To do so, LRR administrator logs in to MySQL using the following
|
||||
command: `mysql -u mnc -p`. Type the correct password to access
|
||||
the MySQL database.
|
||||
|
||||
After that, issue the following commands in the mysql prompt.
|
||||
|
||||
- `use lrr;`
|
||||
|
||||
- `delete from users_table where Student_ID="201131129138";`
|
||||
|
||||
The first one uses a database called lrr in MySQL. The second one
|
||||
deletes a record from `users_table` where the student number is
|
||||
201131129138.
|
||||
|
||||
|
||||
*Last modified on 20 April 2022 by Umar*
|
|
@ -7,13 +7,13 @@ delete from course_Group_Members_table;
|
|||
delete from course_students_table;
|
||||
|
||||
delete from course_ta;
|
||||
|
||||
delete from extended_deadlines_table;
|
||||
|
||||
|
||||
delete from lab_reports_table;
|
||||
|
||||
delete from lab_report_submissions;
|
||||
|
||||
delete from students_data;
|
||||
|
||||
delete from users_table;
|
||||
Delete from users_table;
|
|
@ -0,0 +1,26 @@
|
|||
LRR User Documentation
|
||||
======================
|
||||
|
||||
|
||||
Resetting password
|
||||
-------------------
|
||||
|
||||
We can reset a user's password by directly modifying the MySQL database table called `users_table`. More specifically, we delete that user's information from `users_table` so that the user could sign up again. Suppose the user's student number is 201131129138.
|
||||
|
||||
To do so, LRR administrator logs in to MySQL using the following command: `mysql -u username -p`. Type the correct password to access the MySQL database.
|
||||
|
||||
After that, issue the following commands in the mysql prompt.
|
||||
|
||||
- `use lrr;`
|
||||
|
||||
- `delete from users_table where Student_ID="201131129138";`
|
||||
|
||||
The first one uses a database called lrr in MySQL. The second one deletes a record from `users_table` where the student number is 201131129138.
|
||||
|
||||
Increasing session duration
|
||||
-------------------
|
||||
|
||||
By default, the session duration in PHP is set to 1,440 seconds (24 minutes). However, this is not convenient in most software systems. Therefore, we may need to increase the duration to allow users to have more session time. To increase the session duration, we need to edit the variable *session.gc_maxlifetime* in **php.ini**. We can increase its default value to whatever we want (e.g., 7200).
|
||||
On Ubuntu, the file is located at */etc/php/7.2/apache2/php.ini*. On XAMPP, the file is located at */xampp/php/php.ini*.
|
||||
|
||||
*Last modified on 20 April 2022 by Umar*
|
|
@ -0,0 +1,10 @@
|
|||
1. The connect.php should not echo 'Connected' since there is a redirect already in the header.php [Resolved]
|
||||
|
||||
2. The header.php is connecting to the database twice through inline connection and an external connect.php [Resolved]
|
||||
|
||||
3. Filter file format and size upon upload.
|
||||
|
||||
4.1. Upon Change password it must ask the old password first before new password.
|
||||
4.2. It should not use the GET REQUEST on password which puts user's data at risk since it displays in the URL.
|
||||
|
||||
4. Added css into the header.php
|
|
@ -1,5 +1 @@
|
|||
<?php
|
||||
$csv = array_map('str_getcsv', file('./../../lrr_submission/KeepItSafe.txt'));
|
||||
$mysql_username = $csv[0][0];
|
||||
$mysql_password = $csv[0][1];
|
||||
?>
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ if (isset($_SESSION["user_fullname"])) {
|
|||
<legend>Sign in</legend>
|
||||
<input type="hidden" name="form_login" value="true"/>
|
||||
<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" value="<?php echo isset($_SESSION['failed_login_user']) ? htmlspecialchars($_SESSION['failed_login_user']) : ''; ?>" />
|
||||
<input type="text" name="user" placeholder="Student Number / Email address" class="form-control" required="required" id="user_name" />
|
||||
<br>
|
||||
<label for="user_password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" name="password" placeholder="password" required="required" id="user_password" />
|
||||
|
@ -41,7 +41,7 @@ if (isset($_SESSION["user_fullname"])) {
|
|||
<label class="form-text">Don't have an account yet?</label> <a href="signup.php" id="signup_link">Sign up</a>
|
||||
|
||||
<br>
|
||||
<label class="form-text">Forget your password?</label> <a id="goRecover" href="RecoverPassword.php">Recover</a>
|
||||
<label class="form-text">Forget your password?</label> <a href="recover_password.php">Recover</a>
|
||||
|
||||
|
||||
<?php
|
||||
|
|
|
@ -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
|
||||
(10, 'Software Engineering', '2018', 'Computing', 8, 0, 'CSC1234', 'CSC12342018', '1'),
|
||||
(11, 'Project Management', '2024', 'Computing', 8, 0, 'CSC1111', 'CSC11112024', '0'),
|
||||
(11, 'Project Management', '2019', 'Computing', 8, 0, 'P.M2019', 'P.M20192019', '0'),
|
||||
(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, '201825800054', 14, 'Joined'),
|
||||
(12, '201632120150', 15, 'Joined'),
|
||||
(12, '201632120150', 16, 'Joined'),
|
||||
(12, '2016321201502', 16, '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
|
||||
(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, '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'),
|
||||
(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'),
|
||||
(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'),
|
||||
(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
|
||||
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', NULL, 'Pending', 'Reading 1 submission', 'Public', ''),
|
||||
(1, '2019-01-17 00:00:00', 1, '201825800050', 0, 'Reading list.txt', '-', '', '', '', 5, 'Marked', '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', ''),
|
||||
(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,11 +259,7 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES
|
|||
(1, '201825800054', 'LJ7951632'),
|
||||
(2, '201825800050', 'P00581929'),
|
||||
(3, '201632120150', 'FN524516'),
|
||||
(4, '202400000001', 'NA'),
|
||||
(5,'201932130101',''),
|
||||
(6,'201920781742','');
|
||||
|
||||
|
||||
(4, '11', '11');
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
@ -272,7 +268,7 @@ INSERT INTO `students_data` (`ID`, `Student_ID`, `Passport_Number`) VALUES
|
|||
--
|
||||
|
||||
CREATE TABLE `users_table` (
|
||||
`User_ID` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`User_ID` int(11) NOT NULL,
|
||||
`Email` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`Password` varchar(250) CHARACTER SET utf8 DEFAULT NULL,
|
||||
`HashPassword` varchar(250) COLLATE utf8mb4_bin NOT NULL,
|
||||
|
@ -280,8 +276,7 @@ CREATE TABLE `users_table` (
|
|||
`UserType` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`Student_ID` varchar(500) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`Passport_Number` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`Status` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT 'Active',
|
||||
PRIMARY KEY (`User_ID`)
|
||||
`Status` varchar(30) COLLATE utf8mb4_bin NOT NULL DEFAULT 'Active'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
--
|
||||
|
@ -289,37 +284,16 @@ CREATE TABLE `users_table` (
|
|||
--
|
||||
|
||||
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'),
|
||||
(7, 'peter@qq.com', '$2y$10$8GCG6lTo1LFRD3bOkAyKYeOMOrFSBUgrTxaPLS5ynWN1bYDHf89pO', '', 'Peter', 'Lecturer', NULL, '123', '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'),
|
||||
(3, 'admin@qq.com', '123', '', 'Kamal', 'Admin', '0', NULL, 'Active'),
|
||||
(8, 'lanhui@qq.com', '1234', '', 'Lanhui', 'Lecturer', NULL, '123', 'Active'),
|
||||
(9, 'mohamed@qq.com', '123', '', 'Mohamed', 'Student', '201825800050', 'P00581929', 'Active'),
|
||||
(10, 'mark@qq.com', '123', '', 'Mark ', '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'),
|
||||
(17, 'teecloudy@qq.com', '$2y$10$8WqSK7QI.3YCb2yoclqutOxyGxojncUvzhqLcE8zjlSvjBdcIQ18O', '', 'Ashly Tafadzwa Dhani', 'Student', '201632120150', NULL, 'Active'),
|
||||
(18, 'ashly@qq.com', 'Testing2', '', 'Ashly 2 Testing', 'Student', '2016321201502', NULL, 'Active'),
|
||||
(19, '11@11.11', 'dfdf', '760a8f4f392f1f6bc3ecb118365c6cd039b59fdce96122897d5157970d9c9c129bd73b3c402dbeedd8fe94d319df7bd7de0025c22839fec06631a025ec1e0e69', '11', 'Student', '11', '', 'Active'),
|
||||
(20,'goodstd@qq.com','$2y$10$RXIjONOK.mw74pSxPrsnGuccQsFq4O4.e71vaxfGHHhtzHREtfqkG','','Good Std','Student','201932130101',NULL,'Active'),(21,'goodstd2@qq.com','$2y$10$kmqrGuZd7hCiiaHFDQr2vObpD7BgEnCKlgQ/EcLHYnsQenMbNKcHy','','Good Std2','Student','201920781742',NULL,'Active');
|
||||
(19, '11@11.11', 'dfdf', '760a8f4f392f1f6bc3ecb118365c6cd039b59fdce96122897d5157970d9c9c129bd73b3c402dbeedd8fe94d319df7bd7de0025c22839fec06631a025ec1e0e69', '11', 'Student', '11', '', 'Active');
|
||||
|
||||
CREATE TABLE `password_recovery_security_questions` (
|
||||
`user_id` int NOT NULL,
|
||||
`user_type` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||
`student_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
`question1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||
`answer1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||
`question2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||
`answer2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||
PRIMARY KEY (`user_id`),
|
||||
CONSTRAINT `password_recovery_security_questions_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users_table` (`User_ID`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
|
||||
|
||||
INSERT INTO `password_recovery_security_questions` VALUES
|
||||
(3,'Admin',NULL,'admin@qq.com','What is the name of your first pet?','mimi','What was the name of your first school?','zjnu'),
|
||||
(7,'Lecturer',NULL,'peter@qq.com','What was the name of your first best friend?','chen','What is your favorite food?','hotpot'),
|
||||
(8,'Lecturer',NULL,'lanhui@qq.com','What is the name of the town where you were born?','jinhua','What is your favorite movie?','titanic'),
|
||||
(9,'Student','201825800050','mohamed@qq.com','What was the make and model of your first car?','audi','What is the name of your favorite teacher?','chen'),
|
||||
(21,'Student','201920781742','goodstd2@qq.com','What is the name of the town where you were born?','wenzhou','What is your favorite food?','hotpot');
|
||||
--
|
||||
-- Indexes for dumped tables
|
||||
--
|
||||
|
@ -373,6 +347,12 @@ ALTER TABLE `lab_report_submissions`
|
|||
ALTER TABLE `students_data`
|
||||
ADD PRIMARY KEY (`ID`);
|
||||
|
||||
--
|
||||
-- Indexes for table `users_table`
|
||||
--
|
||||
ALTER TABLE `users_table`
|
||||
ADD PRIMARY KEY (`User_ID`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for dumped tables
|
||||
--
|
||||
|
@ -430,7 +410,12 @@ ALTER TABLE `students_data`
|
|||
--
|
||||
ALTER TABLE courses_table
|
||||
MODIFY Course_Name varchar(500);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT for table `users_table`
|
||||
--
|
||||
ALTER TABLE `users_table`
|
||||
MODIFY `User_ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20;
|
||||
COMMIT;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
$string = ' string to be encrypted ';
|
||||
//hashPassword($string);
|
||||
function hashPassword($value){
|
||||
$key = 'password to (en/de)crypt';
|
||||
$algo_ini = mcrypt_create_iv(
|
||||
mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC),
|
||||
MCRYPT_DEV_URANDOM
|
||||
);
|
||||
$hash_pass= base64_encode(
|
||||
$algo_ini .
|
||||
mcrypt_encrypt(
|
||||
MCRYPT_RIJNDAEL_128,
|
||||
hash('sha256', $key, true),
|
||||
$value,
|
||||
MCRYPT_MODE_CBC,
|
||||
$algo_ini
|
||||
)
|
||||
);
|
||||
return $hash_pass;
|
||||
|
||||
}
|
||||
|
||||
|
||||
function unhashPassword($hash_pass)
|
||||
{
|
||||
$key = 'password to (en/de)crypt';
|
||||
$data = base64_decode($hash_pass);
|
||||
$algo_ini = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC));
|
||||
$unhash_pass = rtrim(
|
||||
mcrypt_decrypt(
|
||||
MCRYPT_RIJNDAEL_128,
|
||||
hash('sha256', $key, true),
|
||||
substr( $data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)),
|
||||
MCRYPT_MODE_CBC,
|
||||
$algo_ini
|
||||
),
|
||||
"\0"
|
||||
);
|
||||
return $unhash_pass;
|
||||
}
|
|
@ -15,9 +15,11 @@ include 'Header.php';
|
|||
<form method="post" action="Script.php">
|
||||
<legend>Recover password</legend>
|
||||
<input type="hidden" name="form_recover_password" value="true"/>
|
||||
Student number
|
||||
<input type="text" name="sno" placeholder="Enter your student number" class="form-control" required="required" value="<?php echo htmlspecialchars($_SESSION['student_number']); ?>"> <br/>
|
||||
Email
|
||||
<input type="text" name="email" placeholder="Enter your email address" class="form-control" required="required" value="<?php echo htmlspecialchars($_SESSION['user_email']); ?>"> <br/>
|
||||
<button id="rec" type="submit" class="btn btn-primary">Recover</button>
|
||||
<button type="submit" class="btn btn-primary">Recover</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -22,10 +22,10 @@ include 'Header.php';
|
|||
<input type="hidden" name="form_signup" value="true" />
|
||||
|
||||
Full Name
|
||||
<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>
|
||||
|
||||
<input type="text" name="fullname" placeholder="Your full name" class="form-control" value="<?php echo $_SESSION['user_fullname']; ?>" required="required" id="full_name"/> <br>
|
||||
|
||||
Student ID
|
||||
<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>
|
||||
<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>
|
||||
|
||||
Email
|
||||
<input type="text" name="email" placeholder="Email" class="form-control" value="<?php echo $_SESSION['user_email']; ?>" required="required" id="email" /> <br>
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
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()
|
|
@ -1,156 +0,0 @@
|
|||
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
|
||||
from selenium.webdriver.support.ui import Select
|
||||
|
||||
def test_attempt_recovery_with_unanswered_security_questions(driver, url, restore_database):
|
||||
# Student goodstd@qq.com with no answered questions
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
|
||||
elem = driver.find_element(By.ID, 'goRecover')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'email')
|
||||
elem.send_keys("goodstd@qq.com")
|
||||
elem = driver.find_element(By.ID, 'rec')
|
||||
elem.click()
|
||||
|
||||
wait = WebDriverWait(driver, 10)
|
||||
alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-warning")))
|
||||
assert "no security questions found for this user." in alert_elem.text.lower()
|
||||
|
||||
driver.quit()
|
||||
|
||||
def test_set_security_questions(driver, url, restore_database):
|
||||
# Student goodstd@qq.com logs in
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
login(driver, url, 'goodstd@qq.com', '[123Abc]')
|
||||
question1 = driver.find_element(By.ID, 'security_question1')
|
||||
question2 = driver.find_element(By.ID, 'security_question2')
|
||||
select_question1 = Select(question1)
|
||||
select_question1.select_by_index(1)
|
||||
select_question2 = Select(question2)
|
||||
select_question2.select_by_index(2)
|
||||
answer1 = driver.find_element(By.ID, 'security_answer1')
|
||||
answer1.send_keys("mImI")
|
||||
answer2 = driver.find_element(By.ID, 'security_answer2')
|
||||
answer2.send_keys("TitaNic")
|
||||
submit_button = driver.find_element(By.ID, 'submit_recovery')
|
||||
submit_button.click()
|
||||
|
||||
# Assertion: Check if password recovery confirmation or success message appears
|
||||
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, 'alertgood')))
|
||||
recovery_success = driver.find_element(By.ID, 'alertgood')
|
||||
assert recovery_success.is_displayed(), "Password recovery failed or confirmation message not displayed."
|
||||
|
||||
logout(driver)
|
||||
|
||||
#Log in Student account
|
||||
login(driver, url, 'goodstd@qq.com', '[123Abc]')
|
||||
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||
assert 'Student ID' in elems[0].text
|
||||
assert 'Good Std' in elems[0].text
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
def test_password_recover_wrong_answers(driver, url, restore_database):
|
||||
# Student goodstd2@qq.com recover password --> wrong answers
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
elem = driver.find_element(By.ID, 'goRecover')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'email')
|
||||
elem.send_keys("goodstd2@qq.com")
|
||||
elem = driver.find_element(By.ID, 'rec')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'answer1')
|
||||
elem.send_keys("wrong")
|
||||
elem = driver.find_element(By.NAME, 'answer2')
|
||||
elem.send_keys("wrong")
|
||||
elem = driver.find_element(By.ID, 'sub')
|
||||
elem.click()
|
||||
|
||||
driver.quit()
|
||||
|
||||
def test_recover_password_with_weak_password(driver, url, restore_database):
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
elem = driver.find_element(By.ID, 'goRecover')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'email')
|
||||
elem.send_keys("goodstd2@qq.com")
|
||||
elem = driver.find_element(By.ID, 'rec')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'answer1')
|
||||
elem.send_keys("Wenzhou")
|
||||
elem = driver.find_element(By.NAME, 'answer2')
|
||||
elem.send_keys("HotPot")
|
||||
elem = driver.find_element(By.ID, 'sub')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'new_password')
|
||||
elem.send_keys("123")
|
||||
elem = driver.find_element(By.NAME, 'confirm_password')
|
||||
elem.send_keys("123")
|
||||
elem = driver.find_element(By.ID, "butt")
|
||||
elem.click()
|
||||
|
||||
wait = WebDriverWait(driver, 10)
|
||||
alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-danger")))
|
||||
assert "password must be at least 8 characters long and include uppercase and lowercase letters, numbers, and special characters." in alert_elem.text.lower()
|
||||
|
||||
driver.quit()
|
||||
|
||||
def test_recover_password_successfully(driver, url, restore_database):
|
||||
# Student goodstd2@qq.com recover password ---> correct answers
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
elem = driver.find_element(By.ID, 'goRecover')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'email')
|
||||
elem.send_keys("goodstd2@qq.com")
|
||||
elem = driver.find_element(By.ID, 'rec')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'answer1')
|
||||
elem.send_keys("wenzhou")
|
||||
elem = driver.find_element(By.NAME, 'answer2')
|
||||
elem.send_keys("hotpot")
|
||||
elem = driver.find_element(By.ID, 'sub')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'new_password')
|
||||
elem.send_keys("123Abc!!")
|
||||
elem = driver.find_element(By.NAME, 'confirm_password')
|
||||
elem.send_keys("123Abc!!")
|
||||
elem = driver.find_element(By.ID, "butt")
|
||||
elem.click()
|
||||
|
||||
#Log in Student account
|
||||
login(driver, url, 'goodstd2@qq.com', '123Abc!!')
|
||||
elems = driver.find_elements(By.CLASS_NAME, 'nav-link')
|
||||
assert 'Student ID' in elems[0].text
|
||||
assert 'Good Std2' in elems[0].text
|
||||
driver.quit()
|
||||
|
||||
def test_recovery_invalid_user_cannot_recover(driver, url, restore_database):
|
||||
# Unrecognizable user cannot recover
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
elem = driver.find_element(By.ID, 'goRecover')
|
||||
elem.click()
|
||||
elem = driver.find_element(By.NAME, 'email')
|
||||
elem.send_keys("goodstd3@qq.com")
|
||||
elem = driver.find_element(By.ID, 'rec')
|
||||
elem.click()
|
||||
|
||||
wait = WebDriverWait(driver, 10)
|
||||
alert_elem = wait.until(EC.presence_of_element_located((By.CLASS_NAME, "alert-danger")))
|
||||
assert "email address is not recognized." in alert_elem.text.lower()
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
Sign-Up Automation Test Script
|
||||
Overview
|
||||
This script automates the sign-up process for a web application using Selenium WebDriver. It tests whether form values are retained correctly if the initial sign-up attempt fails and requires modification of the student ID before resubmission.
|
||||
|
||||
Prerequisites
|
||||
Python 3
|
||||
Selenium library
|
||||
Chrome WebDriver
|
||||
A running instance of the web application on http://localhost:8080
|
||||
|
||||
Configuration
|
||||
Web Application URL: Make sure the web application is running at http://localhost:8080. Adjust the URL in the script if necessary.
|
||||
|
||||
Update Element Locators: Ensure the IDs used in the script (signup_link, signup_form, full_name, student_id, email, password1, password2, signup_btn) match those in your web application.
|
||||
|
||||
Run the script:
|
||||
|
||||
Script Logic
|
||||
|
||||
Open the Login Page: The script navigates to the login page of the web application.
|
||||
Click the "Sign Up" Link: It waits for the "Sign Up" link to appear and clicks it to navigate to the sign-up page.
|
||||
Fill Out the Sign-Up Form: It fills out the form fields (Full Name, Student ID, Email, Password).
|
||||
Submit the Form: It submits the form and waits for the result.
|
||||
Check for Sign-Up Failure: If sign-up fails, it checks if form values are retained.
|
||||
Modify Student ID: If the form values are retained, it modifies the student ID and resubmits the form.
|
||||
Verify Retained Values: It verifies if other fields retain their values after modifying the student ID.
|
||||
Print Retained Values: If the second attempt is successful, it prints the retained form values.
|
||||
Close the Browser: The browser is closed at the end of the script execution.
|
||||
|
||||
|
||||
|
||||
The script provides the following output:
|
||||
|
||||
Sign-Up Successful: Indicates the sign-up was successful on the first attempt.
|
||||
Sign-Up Failed: Indicates the sign-up failed on the first attempt and checks for retained values.
|
||||
Second Sign-Up Attempt Successful: Indicates the second sign-up attempt was successful and prints the retained values.
|
||||
Second Sign-Up Attempt Failed: Indicates the second sign-up attempt also failed, suggesting further investigation is needed.
|
||||
Notes
|
||||
Form Field IDs: Ensure the IDs used in the script match those in your web application.
|
||||
Password Fields: The script intentionally does not print password fields for security reasons.
|
||||
Adjust Wait Times: Modify the wait times as needed depending on your application's response times.
|
||||
Troubleshooting
|
||||
Element Not Found: Verify the element IDs and update them in the script.
|
||||
WebDriver Errors: Ensure the Chrome WebDriver is installed and matches your Chrome browser version.
|
||||
Connection Errors: Ensure the web application is running and accessible at the specified URL.
|
||||
Contributing
|
|
@ -1,88 +0,0 @@
|
|||
import time # Import time module for waiting
|
||||
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
|
||||
|
||||
# New instance of the Chrome driver
|
||||
driver = webdriver.Chrome()
|
||||
|
||||
try:
|
||||
# Step 1: Open the login page
|
||||
driver.get("http://localhost:8080/lrr/lrr/admin.php") # Replace with your actual login page URL
|
||||
|
||||
# Step 2: Wait for the login page to fully load and locate the "Sign Up" link
|
||||
sign_up_link = WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "signup_link"))
|
||||
)
|
||||
|
||||
# Step 3: Click the "Sign Up" link to navigate to the sign-up page
|
||||
sign_up_link.click()
|
||||
|
||||
# Step 4: Wait for the sign-up page to fully load
|
||||
WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "signup_form"))
|
||||
)
|
||||
|
||||
# Step 5: Fill out the sign-up form
|
||||
driver.find_element(By.ID, "full_name").send_keys("John Doe")
|
||||
driver.find_element(By.ID, "student_id").send_keys("12345678")
|
||||
driver.find_element(By.ID, "email").send_keys("john.doe@example.com")
|
||||
driver.find_element(By.ID, "password1").send_keys("Password123!")
|
||||
driver.find_element(By.ID, "password2").send_keys("Password123!")
|
||||
|
||||
# Step 6: Submit the sign-up form
|
||||
driver.find_element(By.ID, "signup_btn").click()
|
||||
|
||||
# Step 7: Wait for the sign-up result
|
||||
WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.TAG_NAME, "body"))
|
||||
)
|
||||
|
||||
# Check if sign-up failed
|
||||
if "alert-danger" in driver.page_source:
|
||||
print("Sign-up failed. Checking if form values are retained...")
|
||||
|
||||
# Wait for a few seconds (adjust as needed)
|
||||
time.sleep(3)
|
||||
|
||||
# Modify the student ID again
|
||||
driver.find_element(By.ID, "student_id").clear()
|
||||
driver.find_element(By.ID, "student_id").send_keys("87654321")
|
||||
|
||||
# Verify if the other fields retain their values
|
||||
assert driver.find_element(By.ID, "full_name").get_attribute("value") == "John Doe"
|
||||
assert driver.find_element(By.ID, "email").get_attribute("value") == "john.doe@example.com"
|
||||
assert driver.find_element(By.ID, "password1").get_attribute("value") == ""
|
||||
assert driver.find_element(By.ID, "password2").get_attribute("value") == ""
|
||||
|
||||
# Resubmit the form
|
||||
driver.find_element(By.ID, "signup_btn").click()
|
||||
|
||||
# Wait for the result again
|
||||
WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.TAG_NAME, "body"))
|
||||
)
|
||||
|
||||
# Check for success or failure after second attempt
|
||||
if "alert-danger" in driver.page_source:
|
||||
print("Second sign-up attempt failed. Further investigation needed.")
|
||||
|
||||
|
||||
# Print the retained values
|
||||
print("Retained form values after second attempt:")
|
||||
print("Full Name:", driver.find_element(By.ID, "full_name").get_attribute("value"))
|
||||
print("Email:", driver.find_element(By.ID, "email").get_attribute("value"))
|
||||
# Password fields might be intentionally cleared, so they won't be printed here
|
||||
print("Modified Student ID:", driver.find_element(By.ID, "student_id").get_attribute("value"))
|
||||
|
||||
else:
|
||||
print("Second sign-up attempt successful!")
|
||||
else:
|
||||
print("Sign-up successful!")
|
||||
|
||||
|
||||
|
||||
finally:
|
||||
# Close the browser
|
||||
driver.quit()
|
|
@ -1,6 +0,0 @@
|
|||
Sign-up failed. Checking if form values are retained...
|
||||
Second sign-up attempt failed. Further investigation needed.
|
||||
Retained form values after second attempt:
|
||||
Full Name: John Doe
|
||||
Email: john.doe@example.com
|
||||
Modified Student ID: 87654321
|
|
@ -1,37 +0,0 @@
|
|||
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()
|
|
@ -1,364 +0,0 @@
|
|||
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
|
||||
wait = WebDriverWait(driver, 10)
|
||||
wait.until(EC.url_contains('SecurityQuestions.php'))
|
||||
|
||||
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('002025/05/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: 2025-05-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()
|
||||
driver.get(url + 'logout.php')
|
||||
|
||||
# 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
|
||||
wait = WebDriverWait(driver, 10)
|
||||
wait.until(EC.url_contains('SecurityQuestions.php'))
|
||||
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
|
||||
driver.quit()
|
||||
|
||||
|
||||
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('/var/www/html/LRR/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
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
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
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
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
|
||||
|
||||
driver.quit()
|
||||
|
||||
|
||||
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()
|
|
@ -1,33 +0,0 @@
|
|||
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()
|
||||
|
||||
# Wait for the admin_tab to become clickable
|
||||
admin_tab = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "admin_tab"))
|
||||
)
|
||||
except (NoSuchElementException, UnexpectedAlertPresentException) as e:
|
||||
return f"Error: {str(e)}"
|
|
@ -1,125 +0,0 @@
|
|||
import pytest
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import Select
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
|
||||
# New instance of the Chrome driver
|
||||
driver = webdriver.Chrome()
|
||||
|
||||
# Open the login page
|
||||
driver.get("http://localhost/lrr/admin.php")
|
||||
|
||||
# Credentials for login
|
||||
username = "lanhui@qq.com"
|
||||
password = "admin123"
|
||||
|
||||
def login(driver, username, password):
|
||||
try:
|
||||
# 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()
|
||||
|
||||
# Wait for the admin_tab to become clickable
|
||||
admin_tab = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "admin_tab"))
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
except (NoSuchElementException, UnexpectedAlertPresentException) as e:
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
# Call the login function
|
||||
login_result = login(driver, username, password)
|
||||
|
||||
# Click on admin_tab after successful login
|
||||
if login_result:
|
||||
admin_tab = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "admin_tab"))
|
||||
)
|
||||
admin_tab.click()
|
||||
|
||||
# Optionally, wait for the Admin.php page to load
|
||||
admin_url = "http://localhost/lrr/Admin.php"
|
||||
WebDriverWait(driver, 15).until(
|
||||
EC.url_to_be(admin_url)
|
||||
)
|
||||
|
||||
print(login_result)
|
||||
|
||||
def assign_ta(driver, course_id, ta_name):
|
||||
try:
|
||||
# Locate the form and select the TA
|
||||
ta_form = WebDriverWait(driver, 15).until(
|
||||
EC.presence_of_element_located((By.XPATH, f"//form[@id='drop_menu_form_{course_id}']"))
|
||||
)
|
||||
|
||||
ta_dropdown = Select(ta_form.find_element(By.XPATH, ".//select[@name='ta']"))
|
||||
ta_dropdown.select_by_visible_text(ta_name)
|
||||
|
||||
# Submit the form using JavaScript
|
||||
driver.execute_script("arguments[0].submit();", ta_form)
|
||||
|
||||
# Wait for an expected alert and accept it
|
||||
WebDriverWait(driver, 10).until(EC.alert_is_present())
|
||||
alert = driver.switch_to.alert
|
||||
alert_text = alert.text
|
||||
alert.accept()
|
||||
|
||||
return alert_text
|
||||
|
||||
except UnexpectedAlertPresentException as e:
|
||||
# Unexpected alert, handle it as an error
|
||||
return f"Error: Unexpected alert - {str(e)}"
|
||||
|
||||
except (NoSuchElementException, Exception) as e:
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
|
||||
|
||||
# The courses and test cases to test
|
||||
courses_to_test = [
|
||||
{"id": 1, "name": "Teecloudy - Ashly Course Testing", "ta_assignments": {"JAMES": "Ta assigned successfully."}},
|
||||
{"id": 2, "name": "P.M2019 - Project Management", "ta_assignments": {"JAMES": "The selected TA is already assigned to this course."}},
|
||||
]
|
||||
|
||||
# Execute the tests
|
||||
@pytest.mark.parametrize("course", courses_to_test)
|
||||
def test_assign_ta(course):
|
||||
for ta_name, expected_result in course["ta_assignments"].items():
|
||||
alert_text = assign_ta(driver, course["id"], ta_name)
|
||||
# ----- ---- Print the raw strings for debugging ----- ---- ---
|
||||
test_case_number = courses_to_test.index(course) + 1
|
||||
print(f"Test Case {test_case_number} - {course['name']} -- {ta_name}: Expected Result={expected_result}, Actual Alert Text={alert_text}")
|
||||
|
||||
# Determine the result based on the comparison
|
||||
if expected_result.lower() in alert_text.lower():
|
||||
result = "Passed"
|
||||
else:
|
||||
result = "Failed"
|
||||
|
||||
# Write the result to a test file with test case number ---
|
||||
with open("test_results.txt", "a") as file:
|
||||
file.write(f"Test Case {test_case_number} - {course['name']} -- {ta_name}: Result={result}, Expected Result={expected_result}, Actual Alert Text={alert_text}\n")
|
||||
|
||||
# Print the result to the console ---
|
||||
print(f"Test Case {test_case_number} - {course['name']} -- {ta_name}: Result={result}, Expected Result={expected_result}, Actual Alert Text={alert_text}")
|
||||
|
||||
assert result == "Passed", f"Test Case {test_case_number} failed: Result={result}, Expected Result={expected_result}, Actual Alert Text={alert_text}"
|
|
@ -1,122 +0,0 @@
|
|||
import pytest
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import Select
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException
|
||||
from helper import login
|
||||
|
||||
@pytest.mark.parametrize("course_id, course_name, ta_name", [(1, "Teecloudy - Ashly Course Testing", "Mark")])
|
||||
def test_assign_a_new_ta_to_a_course(course_id, course_name, ta_name, driver, url, admin_username, admin_password, restore_database):
|
||||
try:
|
||||
driver.maximize_window()
|
||||
|
||||
login(driver, url, admin_username, admin_password)
|
||||
|
||||
admin_tab = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "admin_tab"))
|
||||
)
|
||||
admin_tab.click()
|
||||
|
||||
# Locate the form and select the TA
|
||||
ta_form = WebDriverWait(driver, 15).until(
|
||||
EC.presence_of_element_located((By.XPATH, f"//form[@id='drop_menu_form_{course_id}']"))
|
||||
)
|
||||
|
||||
ta_dropdown = Select(ta_form.find_element(By.XPATH, ".//select[@name='ta']"))
|
||||
ta_dropdown.select_by_visible_text(ta_name)
|
||||
|
||||
# Submit the form using JavaScript
|
||||
driver.execute_script("arguments[0].submit();", ta_form)
|
||||
|
||||
# find table courses
|
||||
table_courses = WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.XPATH, ".//*[@id='tab-existing-courses']/table"))
|
||||
)
|
||||
# find the row with matching course_name
|
||||
course_row = table_courses.find_element(By.XPATH, f".//tr[td='{course_name}']")
|
||||
# find the column with TA name
|
||||
ta_column = course_row.find_element(By.XPATH, ".//td[4]")
|
||||
|
||||
# assert the TA name in the column
|
||||
assert ta_name in ta_column.text, f"Error: TA name {ta_name} not found in the column {ta_column.text}"
|
||||
|
||||
except NoSuchElementException as e:
|
||||
return f"Error: {str(e)}"
|
||||
except UnexpectedAlertPresentException as e:
|
||||
return f"Error: {str(e)}"
|
||||
except AssertionError as e:
|
||||
return f"Error: {str(e)}"
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
finally:
|
||||
driver.quit()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("course_id, course_name, ta_name", [(1, "Teecloudy - Ashly Course Testing", "Mark")])
|
||||
def test_assign_the_same_ta_to_the_same_course_twice(course_id, course_name, ta_name, driver, url, admin_username, admin_password, restore_database):
|
||||
try:
|
||||
driver.maximize_window()
|
||||
login(driver, url, admin_username, admin_password)
|
||||
|
||||
admin_tab = WebDriverWait(driver, 10).until(
|
||||
EC.element_to_be_clickable((By.ID, "admin_tab"))
|
||||
)
|
||||
admin_tab.click()
|
||||
|
||||
# Hui: assign the TA for the first time
|
||||
# (1) Locate the form and select the TA
|
||||
ta_form = WebDriverWait(driver, 15).until(
|
||||
EC.presence_of_element_located((By.XPATH,
|
||||
f"//form[@id='drop_menu_form_{course_id}']")) )
|
||||
|
||||
ta_dropdown = Select(ta_form.find_element(By.XPATH, ".//select[@name='ta']"))
|
||||
ta_dropdown.select_by_visible_text(ta_name)
|
||||
|
||||
# (2) Submit the form using JavaScript
|
||||
driver.execute_script("arguments[0].submit();", ta_form)
|
||||
|
||||
# (3) Find table courses
|
||||
table_courses_before = WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.XPATH, ".//*[@id='tab-existing-courses']/table"))
|
||||
)
|
||||
# (4) Find the row with matching course_name
|
||||
course_row_before = table_courses_before.find_element(By.XPATH, f".//tr[td='{course_name}']")
|
||||
# (5) Find the column with TA name
|
||||
old_cell_content = course_row_before.find_element(By.XPATH, ".//td[4]").text
|
||||
|
||||
|
||||
# Hui: assign the same TA again
|
||||
ta_form = WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.XPATH, f"//form[@id='drop_menu_form_{course_id}']")))
|
||||
ta_dropdown = Select(ta_form.find_element(By.XPATH, ".//select[@name='ta']"))
|
||||
ta_dropdown.select_by_visible_text(ta_name)
|
||||
driver.execute_script("arguments[0].submit();", ta_form)
|
||||
|
||||
# Wait for an expected alert and accept it
|
||||
WebDriverWait(driver, 10).until(EC.alert_is_present())
|
||||
alert = driver.switch_to.alert
|
||||
alert_text = alert.text
|
||||
alert.accept()
|
||||
|
||||
# find table courses
|
||||
table_courses_after = WebDriverWait(driver, 10).until(
|
||||
EC.presence_of_element_located((By.XPATH, ".//*[@id='tab-existing-courses']/table"))
|
||||
)
|
||||
# find the row with matching course_name
|
||||
course_row_after = table_courses_after.find_element(By.XPATH, f".//tr[td='{course_name}']")
|
||||
# find the column with TA name
|
||||
new_cell_content = course_row_after.find_element(By.XPATH, ".//td[4]").text
|
||||
|
||||
# assert the TA name in the column
|
||||
assert old_cell_content == new_cell_content, f"Error: TA name in the column has changed from {old_cell_content} to {new_cell_content}"
|
||||
|
||||
except NoSuchElementException as e:
|
||||
return f"Error: {str(e)}"
|
||||
except UnexpectedAlertPresentException as e:
|
||||
return f"Error: {str(e)}"
|
||||
except AssertionError as e:
|
||||
return f"Error: {str(e)}"
|
||||
except Exception as e:
|
||||
return f"Error: {str(e)}"
|
||||
finally:
|
||||
driver.quit()
|
|
@ -1,2 +0,0 @@
|
|||
Test Case 1 - Teecloudy - Ashly Course Testing -- JAMES: Result=Passed, Expected Result=Ta assigned successfully., Actual Alert Text=TA assigned successfully.
|
||||
Test Case 2 - P.M2019 - Project Management -- DIEGO: Result=Passed, Expected Result=The selected TA is already assigned to this course., Actual Alert Text=The selected TA is already assigned to this course.
|
|
@ -1,201 +0,0 @@
|
|||
# Each time you run the test script reset the database.
|
||||
# For this test script you won't need it since it changes
|
||||
# the Ta's email and name automatically
|
||||
import re
|
||||
import time
|
||||
import pytest
|
||||
|
||||
from selenium import webdriver
|
||||
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_restore_database(restore_database):
|
||||
assert restore_database is None
|
||||
|
||||
|
||||
def createTA(driver, TA_name, emails, password):
|
||||
full_name = driver.find_element('name', 'fullname')
|
||||
full_name.send_keys(TA_name)
|
||||
email = driver.find_element('name', 'email')
|
||||
email.send_keys(emails)
|
||||
pas = driver.find_element('name', 'password')
|
||||
pas.send_keys(password)
|
||||
usr_type = driver.find_element('name', 'type')
|
||||
usr_type.click()
|
||||
click_create = driver.find_element('name', 'create_btn')
|
||||
click_create.click()
|
||||
|
||||
|
||||
def login_lecturer(driver, url):
|
||||
# Open the website
|
||||
driver.get(url)
|
||||
driver.maximize_window()
|
||||
|
||||
username_input = driver.find_element('name', "user")
|
||||
|
||||
password_input = driver.find_element('name', "password")
|
||||
|
||||
login_button = driver.find_element('id', "login_btn")
|
||||
|
||||
# login as a Lecturer
|
||||
username_input.send_keys("admin@qq.com")
|
||||
password_input.send_keys("123")
|
||||
# Click the login button
|
||||
time.sleep(2)
|
||||
login_button.click()
|
||||
admin_tab = driver.find_element('id', 'admin_tab')
|
||||
admin_tab.click()
|
||||
|
||||
cte_instructor = driver.find_element('id', 'tab_ins_accounts')
|
||||
cte_instructor.click()
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
def test_createTA(driver, url):
|
||||
driver_open = driver
|
||||
driver_open.maximize_window()
|
||||
login_lecturer(driver_open, url)
|
||||
try:
|
||||
fullname = "lanhuitest1"
|
||||
email = "lanhuitest1@qq.com"
|
||||
password = "new1452345678"
|
||||
createTA(driver_open, fullname, email,password) # CREATE A TA WITH FULLNAME lanhuitest1 email lanhuitest1@qq.com password new1452345678
|
||||
|
||||
get_output = WebDriverWait(driver_open, 20).until(
|
||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||
)
|
||||
get_output.click()
|
||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||
txt_alert = get_output_msg.text
|
||||
time.sleep(2)
|
||||
|
||||
if txt_alert.find("TA user created successfully") == 0:
|
||||
logout_button = WebDriverWait(driver_open, 20).until(
|
||||
EC.element_to_be_clickable(
|
||||
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
||||
)
|
||||
time.sleep(2)
|
||||
logout_button.click()
|
||||
time.sleep(2)
|
||||
username_input = driver_open.find_element('name', "user")
|
||||
password_input = driver_open.find_element('name', "password")
|
||||
login_button = driver_open.find_element('id', "login_btn")
|
||||
# login as the new TA
|
||||
username_input.send_keys(email) # login with credentials of the created TA
|
||||
password_input.send_keys(password)
|
||||
# Click the login button
|
||||
time.sleep(2)
|
||||
|
||||
login_button.click()
|
||||
|
||||
time.sleep(2)
|
||||
elif txt_alert.find("Email address ") == 0:
|
||||
|
||||
time.sleep(2)
|
||||
driver_open.quit()
|
||||
|
||||
else:
|
||||
driver_open.quit()
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
finally:
|
||||
driver_open.quit()
|
||||
|
||||
|
||||
def test_generate_password(driver, url):
|
||||
driver_open = driver
|
||||
login_lecturer(driver_open, url)
|
||||
try:
|
||||
fullname = "lanhuitest2"
|
||||
email = "lanhuitest2@qq.com"
|
||||
password = ""
|
||||
createTA(driver_open, fullname, email,
|
||||
password) # CREATE A TA WITH FULLNAME lanhuitest2 email lanhuitest2@qq.com password ""
|
||||
|
||||
get_output = WebDriverWait(driver_open, 20).until(
|
||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||
)
|
||||
get_output.click()
|
||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||
txt_alert = get_output_msg.text
|
||||
time.sleep(2)
|
||||
|
||||
if txt_alert.find("TA user created successfully") == 0:
|
||||
time.sleep(2)
|
||||
email_pattern = r"Use email (\S+) as account name"
|
||||
password_pattern = r" (\S+)\ as password."
|
||||
email_match = re.search(email_pattern, txt_alert)
|
||||
password_match = re.search(password_pattern, txt_alert)
|
||||
if email_match and password_match:
|
||||
# Extract email and password from the matches
|
||||
email = email_match.group(1)
|
||||
password = password_match.group(1)
|
||||
logout_button = WebDriverWait(driver_open, 20).until(
|
||||
EC.element_to_be_clickable(
|
||||
(By.XPATH, "//a[contains(@class, 'nav-link') and contains(@href, 'logout.php')]"))
|
||||
)
|
||||
logout_button.click()
|
||||
time.sleep(2)
|
||||
username_input = driver_open.find_element('name', "user")
|
||||
password_input = driver_open.find_element('name', "password")
|
||||
login_button = driver_open.find_element('id', "login_btn")
|
||||
# login as the new TA
|
||||
username_input.send_keys(email) # login with credentials of the created TA
|
||||
password_input.send_keys(password)
|
||||
# Click the login button
|
||||
time.sleep(2)
|
||||
|
||||
login_button.click()
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
elif txt_alert.find("Email address ") == 0:
|
||||
time.sleep(2)
|
||||
driver_open.quit()
|
||||
|
||||
else:
|
||||
driver_open.quit()
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
finally:
|
||||
driver_open.quit()
|
||||
|
||||
|
||||
def test_existingTA(driver, url, restore_database):
|
||||
driver_open = driver
|
||||
login_lecturer(driver, url)
|
||||
try:
|
||||
# Use email nreyes@example.com as account name and new1452345678 as password.
|
||||
fullname = "lanhuitest1"
|
||||
email = "lanhuitest1@qq.com"
|
||||
password = "new1452345678"
|
||||
createTA(driver_open, fullname, email,
|
||||
password) # CREATE A TA WITH FULLNAME lanhuitest1 email lanhuitest1@qq.com password new1452345678
|
||||
|
||||
get_output = WebDriverWait(driver_open, 20).until(
|
||||
EC.element_to_be_clickable((By.ID, "tab_ins_accounts"))
|
||||
)
|
||||
get_output.click()
|
||||
get_output_msg = driver_open.find_element(By.CLASS_NAME, "alert-warning")
|
||||
txt_alert = get_output_msg.text
|
||||
time.sleep(2)
|
||||
|
||||
if txt_alert.find("TA user created successfully") == 0:
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
elif txt_alert.find("Email address ") == 0:
|
||||
time.sleep(2)
|
||||
driver_open.quit()
|
||||
|
||||
else:
|
||||
driver_open.quit()
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
finally:
|
||||
driver_open.quit()
|
|
@ -1,77 +0,0 @@
|
|||
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()
|
|
@ -1,46 +0,0 @@
|
|||
import os
|
||||
import pytest
|
||||
from selenium import webdriver
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def restore_database():
|
||||
''' Restore the database.
|
||||
It is useful for making sure that each end-to-end test
|
||||
starts with the same database.
|
||||
Benefit: we can reproduce the same test result.
|
||||
'''
|
||||
|
||||
PASSWORD = 'p-@va9' # root password
|
||||
DB_NAME = 'lrr' # database name used for LRR
|
||||
|
||||
# commands used to import data to DB_NAME
|
||||
cmds = [
|
||||
f'mysql -u root -p{PASSWORD} -e "DROP DATABASE IF EXISTS {DB_NAME};"',
|
||||
f'mysql -u root -p{PASSWORD} -e "CREATE DATABASE {DB_NAME};"',
|
||||
f'mysql -u root -p{PASSWORD} -e "GRANT ALL PRIVILEGES ON {DB_NAME}.* TO lrr@localhost WITH GRANT OPTION;"',
|
||||
f'mysql -u root -p{PASSWORD} {DB_NAME} < ../lrr_database.sql']
|
||||
|
||||
for command in cmds:
|
||||
os.system(command)
|
||||
return None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def url():
|
||||
return 'http://localhost/LRR/' # URL of LRR
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def driver():
|
||||
return webdriver.Chrome()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_username():
|
||||
return 'admin@qq.com'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_password():
|
||||
return '123'
|
Loading…
Reference in New Issue