From e76dec9fce836687cd60a40e47fa5d3d238a3282 Mon Sep 17 00:00:00 2001 From: roost-io <34998783+taher27@users.noreply.github.com> Date: Fri, 1 May 2026 13:28:10 +0000 Subject: [PATCH] Functional test generated by RoostGPT Using AI Model gpt-4.1 --- functional_tests/README.md | 17 + .../test-big-pdf/.roost/roost_metadata.json | 24 + .../test-big-pdf/test-big-pdf.csv | 26 ++ .../test-big-pdf/test-big-pdf.docx | Bin 0 -> 21003 bytes .../test-big-pdf/test-big-pdf.feature | 334 ++++++++++++++ .../test-big-pdf/test-big-pdf.json | 422 ++++++++++++++++++ .../test-big-pdf/test-big-pdf.xlsx | Bin 0 -> 15935 bytes 7 files changed, 823 insertions(+) create mode 100644 functional_tests/test-big-pdf/.roost/roost_metadata.json create mode 100644 functional_tests/test-big-pdf/test-big-pdf.csv create mode 100644 functional_tests/test-big-pdf/test-big-pdf.docx create mode 100644 functional_tests/test-big-pdf/test-big-pdf.feature create mode 100644 functional_tests/test-big-pdf/test-big-pdf.json create mode 100644 functional_tests/test-big-pdf/test-big-pdf.xlsx diff --git a/functional_tests/README.md b/functional_tests/README.md index 1c972b2..b4a037d 100644 --- a/functional_tests/README.md +++ b/functional_tests/README.md @@ -65,3 +65,20 @@ --- +**Execution Date:** 5/1/2026, 1:28:08 PM + +**Test Unique Identifier:** "test-big-pdf" + +**Input(s):** + 1. banking regulations israel.pdf + Path: /var/tmp/Roost/RoostGPT/test-big-pdf/33ec8519-68a7-4cea-a419-7f87c7235984/banking regulations israel.pdf + +**Test Output Folder:** + 1. [test-big-pdf.json](test-big-pdf/test-big-pdf.json) + 2. [test-big-pdf.feature](test-big-pdf/test-big-pdf.feature) + 3. [test-big-pdf.csv](test-big-pdf/test-big-pdf.csv) + 4. [test-big-pdf.xlsx](test-big-pdf/test-big-pdf.xlsx) + 5. [test-big-pdf.docx](test-big-pdf/test-big-pdf.docx) + +--- + diff --git a/functional_tests/test-big-pdf/.roost/roost_metadata.json b/functional_tests/test-big-pdf/.roost/roost_metadata.json new file mode 100644 index 0000000..1b03db6 --- /dev/null +++ b/functional_tests/test-big-pdf/.roost/roost_metadata.json @@ -0,0 +1,24 @@ +{ + "project": { + "name": "test-big-pdf", + "created_at": "2026-05-01T13:28:08.606Z", + "updated_at": "2026-05-01T13:28:08.606Z" + }, + "files": { + "input_files": [ + { + "fileName": "test-big-pdf.txt", + "fileURI": "/var/tmp/Roost/RoostGPT/test-big-pdf/33ec8519-68a7-4cea-a419-7f87c7235984/functional_tests/test-big-pdf/test-big-pdf.txt", + "fileSha": "cf83e1357e" + }, + { + "fileName": "banking regulations israel.pdf", + "fileURI": "/var/tmp/Roost/RoostGPT/test-big-pdf/33ec8519-68a7-4cea-a419-7f87c7235984/functional_tests/test-big-pdf/banking regulations israel.pdf", + "fileSha": "41acaf0ec6" + } + ] + }, + "api_files": { + "input_files": [] + } +} \ No newline at end of file diff --git a/functional_tests/test-big-pdf/test-big-pdf.csv b/functional_tests/test-big-pdf/test-big-pdf.csv new file mode 100644 index 0000000..236c47f --- /dev/null +++ b/functional_tests/test-big-pdf/test-big-pdf.csv @@ -0,0 +1,26 @@ +Login with various credentials +Registration Form Field Boundary Validation +Email Format Validation During Registration +Mandatory Field Validation During Registration +Registration with Existing Email +Password Minimum Complexity Enforcement +Show/hide password toggle functionality +Successful logout from dashboard +Attempt login with account in restricted state +Registration with whitespace in username +Resend email verification link from login prompt +Confirmation email contains correct verification link and expiry details +Mandatory password length boundaries in password reset flow +Username maximum and minimum length validation +Password upper boundary validation during registration +Registration with all special characters in password +Registration with password reset notification email structure and audit logging +Audit log records successful registration event +Email not verified blocks login and triggers verification prompt +Password reset with expired link +Password change from profile with various current password values +Full user registration and email verification flow +Forgot password and set new password flow +Account lock after multiple failed login attempts and unlock after password reset +Automatic logout after session timeout +Session timeout enforcement at exact threshold \ No newline at end of file diff --git a/functional_tests/test-big-pdf/test-big-pdf.docx b/functional_tests/test-big-pdf/test-big-pdf.docx new file mode 100644 index 0000000000000000000000000000000000000000..75c4d673e9784fb6be2a1f3e6cb07d25e9033f86 GIT binary patch literal 21003 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ʺr6JdbR4Y)!Jz*7+dFgxQK7Pn$5R2 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 NS8PV_vU}`-{swpKmwNyJ literal 0 HcmV?d00001 diff --git a/functional_tests/test-big-pdf/test-big-pdf.feature b/functional_tests/test-big-pdf/test-big-pdf.feature new file mode 100644 index 0000000..fbc235a --- /dev/null +++ b/functional_tests/test-big-pdf/test-big-pdf.feature @@ -0,0 +1,334 @@ +Feature: User Authentication and Registration Workflows + + # UI TESTS + @ui + Scenario Outline: Login with various credentials + Given I am on the 'Login' page + When I enter '' in the 'Username' field + And I enter '' in the 'Password' field + And I click the 'Submit' button + Then I should see '' + And I should be on '' + + Examples: + | username | password | expected_message | target_page | + | validUser | ValidPass123! | Welcome, validUser | dashboard | + | validUser | WrongPass! | Invalid username or password | login | + | notExistUser | SomePass123! | Invalid username or password | login | + | deletedUser | CorrectPass! | Access denied | login | + + @ui + Scenario Outline: Registration Form Field Boundary Validation + Given I am on the 'Sign Up' page + When I enter '' in the 'Email' field + And I enter '' in the 'Username' field + And I enter '' in the 'Password' field + And I enter '' in the 'Confirm Password' field + And I submit the registration form + Then I should see '' + + Examples: + | email | username | password | confirm_password | expected_message | + | valid@mail.com | ab | ValidPass123! | ValidPass123! | Username must be at least 3 characters | + | valid@mail.com | abc | short7 | short7 | Password must be at least 8 characters | + | valid@mail.com | abc | ValidPass123456789012 | ValidPass123456789012 | Registration successful | + | valid@mail.com | abc | tooLongPassword1234567 | tooLongPassword1234567 | Password may not exceed 20 characters | + | valid@mail.com | abc | Password1 | Password2 | Passwords do not match | + | valid@mail.com | abc | passwordabc | passwordabc | Password must include uppercase, digit, symbol | + | valid@mail.com | abc | Passwordabc | Passwordabc | Password must include digit and symbol | + | valid@mail.com | abc | Password1 | Password1 | Password must include symbol | + | valid@mail.com | abc | !@#$%^&*Aa1 | !@#$%^&*Aa1 | Registration successful | + | valid@mail.com | test user | ValidPass123! | ValidPass123! | Usernames must not contain whitespace | + | valid@mail.com | abcdefghijklmnopqrstuvwxyzabcdef | ValidPass123! | ValidPass123! | Username must be a maximum of 32 characters | + | valid@mail.com | abcdefghijklmnopqrstuvwxyzabcdefa | ValidPass123! | ValidPass123! | Username must be a maximum of 32 characters | + | valid@mail.com | abc | ValidPass123! | ValidPass123! | Registration successful | + + @ui + Scenario Outline: Email Format Validation During Registration + Given I am on the 'Sign Up' page + When I enter '' in the 'Username' field + And I enter '' in the 'Email' field + And I enter 'ValidPass123!' in the 'Password' field + And I enter 'ValidPass123!' in the 'Confirm Password' field + And I submit the registration form + Then I should see '' + + Examples: + | username | email | expected_message | + | tester | userexample.com | Email format is invalid | + | tester | user@com | Email format is invalid | + | tester | test@mail.com | Registration successful | + + @ui + Scenario Outline: Mandatory Field Validation During Registration + Given I am on the 'Sign Up' page + When I leave '' blank in the form + And I enter valid values in other required fields + And I submit the registration form + Then I should see '' + + Examples: + | field_to_blank | expected_message | + | Email | Email field is required | + | Username | Username field is required | + | Password | Password field is required | + + @ui + Scenario Outline: Registration with Existing Email + Given I am on the 'Sign Up' page + When I enter a unique username + And I enter '' in the 'Email' field + And I enter a valid password in the 'Password' and 'Confirm Password' fields + And I submit the registration form + Then I should see '' + + Examples: + | email | expected_message | + | duplicate@mail.com | Email is already in use | + | unique@mail.com | Registration successful | + + @ui + Scenario Outline: Password Minimum Complexity Enforcement + Given I am on the 'Sign Up' page + When I enter a valid username and email + And I enter '' in the 'Password' field + And I enter '' in the 'Confirm Password' field + And I submit the registration form + Then I should see '' + + Examples: + | password | expected_message | + | passwordabc | Password must include uppercase, digit, symbol | + | Passwordabc | Password must include digit and symbol | + | Password1 | Password must include symbol | + | Password1! | Registration successful | + + @ui + Scenario: Show/hide password toggle functionality + Given I am on the 'Login' page with the password field available + When I begin typing a password + And the password is masked by default + And I click the 'show/hide password' icon + Then the password should become visible + When I click the 'show/hide password' icon again + Then the password input should be masked again + + @ui + Scenario: Successful logout from dashboard + Given I am logged in and on the dashboard screen + When I click the 'Logout' button in the dashboard header + Then I should be redirected to the 'Login' page + And the session should be terminated + When I use browser back button + Then access to dashboard is not restored without re-authentication + + @ui + Scenario Outline: Attempt login with account in restricted state + Given I am on the 'Login' page + When I enter '' in the 'Username' field + And I enter '' in the 'Password' field + And I submit the login form + Then I should see '' + And I should be on 'Login' page + + Examples: + | username | password | expected_message | + | deletedUser | ValidPass123! | Access denied | + | disabledUser | ValidPass123! | Access denied | + | deactivatedUser | ValidPass123!| Access denied | + + @ui + Scenario Outline: Registration with whitespace in username + Given I am on the 'Sign Up' page + When I enter '' in the 'Username' field containing whitespace + And I enter valid email and password values + And I submit the registration form + Then I should see '' + + Examples: + | username | expected_message | + | test user | Usernames must not contain whitespace | + | user | Usernames must not contain whitespace | + | user | Usernames must not contain whitespace | + + @ui + Scenario: Resend email verification link from login prompt + Given I am on the 'Login' page and my email is unverified + When I attempt to log in with valid credentials + Then I should see a prompt to verify email + When I click 'Resend Verification Link' + Then a new verification email should arrive in my inbox + And the UI should show confirmation of re-sending + + @ui + Scenario: Confirmation email contains correct verification link and expiry details + Given I have completed registration with valid data + When I open the confirmation email in my inbox + Then the email should contain a properly formed verification link + And the message should state the link expiry duration + + @ui + Scenario: Mandatory password length boundaries in password reset flow + Given I am on the 'Forgot Password' flow + When I enter a password '' that is shorter than minimum requirement + And I confirm the password as '' + And I submit the form + Then I should see 'Password must be at least 8 characters' + + Examples: + | password | + | short7 | + + @ui + Scenario Outline: Username maximum and minimum length validation + Given I am on the 'Sign Up' page + When I enter '' in the 'Username' field + And I complete all other required fields + And I submit the registration form + Then I should see '' + + Examples: + | username | expected_message | + | ab | Username must be at least 3 characters | + | abc | Registration successful | + | abcdefghijklmnopqrstuvwxyzabcdef | Registration successful | + | abcdefghijklmnopqrstuvwxyzabcdefa | Username must be a maximum of 32 characters | + + @ui + Scenario Outline: Password upper boundary validation during registration + Given I am on the 'Sign Up' page + When I enter all required fields + And I enter '' in the 'Password' and 'Confirm Password' fields + And I submit the registration form + Then I should see '' + + Examples: + | password | expected_message | + | ValidPass123456789012 | Registration successful | + | InvalidPass1234567890123 | Password may not exceed 20 characters | + + @ui + Scenario: Registration with all special characters in password + Given I am on the 'Sign Up' page + When I enter a valid email in the 'Email' field + And I enter a valid username in the 'Username' field + And I enter '!@#$%^&*Aa1' in the 'Password' field + And I confirm the password as '!@#$%^&*Aa1' + And I complete any other mandatory fields + And I submit the registration form + Then I should see 'Registration successful' + + @ui + Scenario: Registration with password reset notification email structure and audit logging + Given I initiate a password reset via the 'Forgot Password' flow + When I receive the password reset email + Then the email subject and sender should be correct + And the content should include the reset link and expiration info + And no password should be displayed in the email + When I navigate to the security audit log + Then a log entry for password reset request with user, timestamp, and IP address should exist + + @ui + Scenario: Audit log records successful registration event + Given user registration has completed successfully + When I log into the administrator/audit console + And I navigate to the user registration audit log + Then I should find a log entry including user identifier, timestamp, IP address, and event type + + @ui + Scenario: Email not verified blocks login and triggers verification prompt + Given I am on the 'Login' page after registering but not verifying email + When I enter registered email and password and submit + Then login should be blocked + And I should see 'Please verify your email address' + When I check the inbox, a new verification email should have been sent + + @ui + Scenario: Password reset with expired link + Given I have received a password reset email + And the reset link has expired + When I click the expired reset link and attempt to set a new password + Then I should see 'Password reset link has expired' and no password change is allowed + + @ui + Scenario Outline: Password change from profile with various current password values + Given I am logged in and on 'Profile' page + When I click 'Change Password' + And I enter '' in the 'Current Password' field + And I enter '' in the 'New Password' field + And I confirm '' in the 'Confirm New Password' field + And I submit the password change form + Then I should see '' + + Examples: + | current_password | new_password | expected_message | + | CorrectPass! | NewPass123! | Password changed successfully | + | WrongPass! | NewPass123! | Incorrect current password | + + # END-TO-END SCENARIOS + + @ui + Scenario: Full user registration and email verification flow + Given I am on the application homepage + When I click 'Sign Up' and complete the registration form with valid name, email, and password + And I submit the registration form + And I open the test email inbox and locate the verification email + And I click the verification link in the email + And I return to the login page + When I log in with the registered credentials + Then I should gain access to the dashboard + And I log out to end session + + @ui + Scenario: Forgot password and set new password flow + Given I am on the 'Login' page + When I click 'Forgot Password' + And I enter a valid email address and submit the reset request + And I open the received password reset email + And I click the reset link + And I enter a valid new password and confirmation + And I submit the form + And I return to the login page + When I log in with the new password + Then I should see the dashboard + + # STATE TRANSITION & SESSION MANAGEMENT + + @ui + Scenario: Account lock after multiple failed login attempts and unlock after password reset + Given I am on the 'Login' page + When I enter valid username with incorrect password and submit + And I repeat this process '' times + Then I should see 'Account is locked' + When I initiate 'Forgot Password' + And I complete password reset via email + And I log in with the new password + Then I should see the dashboard + And 'Account is unlocked' status + + Examples: + | attempts | + | 5 | + + @ui + Scenario: Automatic logout after session timeout + Given I am logged in and on the dashboard + When I remain inactive for '' minutes + And I attempt to access any secure page + Then I should be redirected to the login page + + Examples: + | timeout_minutes | + | 15 | + + @ui + Scenario Outline: Session timeout enforcement at exact threshold + Given I am logged in and on the dashboard + When I remain inactive and start a timer + Then at '' minute '' I should be '' + + Examples: + | minute | second | session_state | + | 14 | 59 | logged in | + | 15 | 0 | logged out and prompted for login | + diff --git a/functional_tests/test-big-pdf/test-big-pdf.json b/functional_tests/test-big-pdf/test-big-pdf.json new file mode 100644 index 0000000..0157e55 --- /dev/null +++ b/functional_tests/test-big-pdf/test-big-pdf.json @@ -0,0 +1,422 @@ +[ + { + "type": "functional", + "title": "Login with valid credentials", + "description": "Verifies user can log in with a valid username and password.", + "testId": "TC-001", + "testDescription": "A registered user enters correct username and password to successfully log in to the application.", + "prerequisites": "User account exists and is active.", + "stepsToPerform": "1. Launch the application. 2. Click on the 'Login' button. 3. Enter the valid username in the username field. 4. Enter the valid password in the password field. 5. Click 'Submit' button. 6. Wait for the application to process authentication. 7. Observe if the dashboard loads. 8. Verify the logged-in user's name is displayed correctly. 9. Perform logout for cleanup.", + "expectedResult": "User is navigated to the dashboard, and the correct user name appears in the header.", + "sourceCitation": { + "location": "Section 2.1, page 5", + "excerpt": "User must log in with valid credentials to access their dashboard." + } + }, + { + "type": "negative", + "title": "Login with invalid password", + "description": "Verifies error message is shown when login fails due to an incorrect password.", + "testId": "TC-002", + "testDescription": "A user tries to log in with a valid username and an incorrect password; the system rejects the attempt.", + "prerequisites": "User account exists and is active.", + "stepsToPerform": "1. Open the application. 2. Click on the 'Login' button. 3. Enter the valid username. 4. Enter an invalid password. 5. Click 'Submit'. 6. Wait for the application to process authentication. 7. Observe the error message. 8. Ensure no navigation occurs. 9. Attempt another login to confirm account is not locked.", + "expectedResult": "Application displays 'Invalid username or password' error and remains on login page.", + "sourceCitation": { + "location": "Section 2.1.1, page 6", + "excerpt": "If the password is incorrect, an error message must be displayed and login must not proceed." + } + }, + { + "type": "boundary", + "title": "Password length lower boundary validation", + "description": "Validates that the system enforces minimum password length requirements.", + "testId": "TC-003", + "testDescription": "User attempts to set a password that is one character less than the required minimum allowed length.", + "prerequisites": "User is on the password creation or reset screen.", + "stepsToPerform": "1. Launch the application. 2. Go to 'Forgot Password' flow. 3. Enter the registered email and proceed. 4. Receive password reset link and open it. 5. Enter a password with one character less than the minimum (e.g., 7 if min is 8). 6. Re-enter the same short password for confirmation. 7. Click 'Submit' to save the new password. 8. Observe system validation error. 9. Try again with a valid password for cleanup.", + "expectedResult": "System displays an error indicating minimum password length requirement is not met.", + "sourceCitation": { + "location": "Section 2.2.3, page 7", + "excerpt": "Passwords must be at least 8 characters in length; otherwise, show validation error." + } + }, + { + "type": "end-to-end", + "title": "Full user registration and email verification flow", + "description": "Covers the complete user registration process including email verification and first successful login.", + "testId": "TC-004", + "testDescription": "A new user registers an account, verifies via the email link, and logs in successfully.", + "prerequisites": "No existing account for the test email address.", + "stepsToPerform": "1. Launch the application. 2. Click on 'Sign Up'. 3. Fill in the registration form with valid data (e.g., name, email, password). 4. Submit the registration form. 5. Open the test email inbox. 6. Locate and open the verification email. 7. Click the verification link. 8. Return to application login page. 9. Log in with registered credentials. 10. Confirm access to dashboard. 11. Log out to clean up.", + "expectedResult": "User is registered, email is verified, and user logs in to the dashboard after verification.", + "sourceCitation": { + "location": "Section 2.3, pages 8-9", + "excerpt": "Users must verify their registration via an email link before first login is permitted." + } + }, + { + "type": "state-transition", + "title": "Account lock after multiple failed login attempts", + "description": "Validates account lock after threshold number of consecutive failed login attempts and unlock after password reset.", + "testId": "TC-005", + "testDescription": "A user inputs incorrect passwords multiple times, account gets locked; then resets password to unlock and log in successfully.", + "prerequisites": "User account exists and is active.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login'. 3. Enter valid username with wrong password. 4. Submit. 5. Repeat steps 3-4 up to the maximum allowed attempts (e.g., 5). 6. Note the lockout message. 7. Initiate 'Forgot Password'. 8. Complete password reset process via email. 9. Attempt login with new password. 10. Confirm dashboard access. 11. Logout.", + "expectedResult": "Account is locked after threshold failed attempts and unlocked after successful password reset; user accesses dashboard with new password.", + "sourceCitation": { + "location": "Section 2.4.1, page 10", + "excerpt": "After 5 consecutive failed login attempts, account is locked until password is reset." + } + }, + { + "type": "functional", + "title": "Successful logout from dashboard", + "description": "Verifies that a user can log out successfully and is redirected to the login page with the session terminated.", + "testId": "TC-006", + "testDescription": "A logged-in user initiates the logout process from the dashboard to end their session and ensure secure exit from the application.", + "prerequisites": "User must be logged in and on the dashboard screen.", + "stepsToPerform": "1. Launch the application. 2. Click on the 'Login' button. 3. Enter valid username and password. 4. Click 'Submit' to access dashboard. 5. Confirm dashboard is loaded. 6. Locate and click the 'Logout' button in the dashboard header. 7. Observe application response and redirection. 8. Attempt to use browser back button. 9. Ensure access to dashboard is not restored after logout.", + "expectedResult": "User is redirected to the login page, the session is terminated, and user cannot return to the dashboard without re-authentication.", + "sourceCitation": { + "location": "Section 2.5, page 11", + "excerpt": "Upon logout, user must be redirected to log in and session must be securely terminated." + } + }, + { + "type": "negative", + "title": "Login fails with non-existent username", + "description": "Verifies that the system rejects login attempts with usernames that are not registered.", + "testId": "TC-007", + "testDescription": "A user enters an invalid, unregistered username along with any password, and attempts to log in.", + "prerequisites": "No account exists with the entered username.", + "stepsToPerform": "1. Launch the application. 2. Click the 'Login' button. 3. Enter a username not present in the system. 4. Enter any password in the password field. 5. Click 'Submit' to attempt login. 6. Wait for authentication response. 7. Observe the error message displayed. 8. Confirm application remains on login screen. 9. Attempt with another non-existent username to ensure same behavior.", + "expectedResult": "System displays 'Invalid username or password' and login does not proceed.", + "sourceCitation": { + "location": "Section 2.1.2, page 6", + "excerpt": "If the username is not found, display the same error as invalid password and do not log in." + } + }, + { + "type": "boundary", + "title": "Username maximum length validation", + "description": "Ensures that the username field enforces maximum character limits as specified.", + "testId": "TC-008", + "testDescription": "A user tries to enter a username with exactly the maximum allowed length, and then one character more, to verify field validation.", + "prerequisites": "No existing account with over-maximum length username.", + "stepsToPerform": "1. Launch application. 2. Click on 'Sign Up'. 3. Fill registration form using a username with exactly 32 characters (maximum allowed per requirements). 4. Complete form with valid data. 5. Submit the form and observe the response. 6. Return to registration page. 7. Enter a username with 33 characters (exceeds maximum). 8. Complete required fields. 9. Submit the form and check for validation errors.", + "expectedResult": "Usernames up to 32 characters are accepted; 33 characters trigger a validation error and no account is created.", + "sourceCitation": { + "location": "Section 2.3.1, page 8", + "excerpt": "Usernames must be a maximum of 32 characters. Longer values must be rejected with validation." + } + }, + { + "type": "end-to-end", + "title": "Forgot password and set new password flow", + "description": "Validates the full forgot password process, including requesting reset, email confirmation, setting a new password, and logging in.", + "testId": "TC-009", + "testDescription": "A user completes the entire forgot password workflow: from requesting the reset to logging in with a new password.", + "prerequisites": "Account exists with a known test email.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login'. 3. At the login dialog, click 'Forgot Password'. 4. Enter the test email address. 5. Submit the reset request. 6. Open the associated test email inbox. 7. Find and click the password reset link. 8. Enter a valid new password that meets the requirements. 9. Confirm the new password and submit. 10. Return to the login page. 11. Log in using the new password. 12. Confirm dashboard is displayed.", + "expectedResult": "User can reset their password and immediately use the new password to log in successfully.", + "sourceCitation": { + "location": "Section 2.2, pages 6-7", + "excerpt": "The forgot password function must email a reset link and allow user to set a new password before next login." + } + }, + { + "type": "functional", + "title": "Show/hide password toggle functionality", + "description": "Checks that password masking can be toggled between visible and hidden states while typing.", + "testId": "TC-010", + "testDescription": "User interacts with the 'show/hide password' icon to make password visible or hidden during entry on the login screen.", + "prerequisites": "Application is available and user is on the login screen.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login' to open login form. 3. Begin typing a password in the password field. 4. Observe masked (dots/asterisks) characters by default. 5. Click on the 'show/hide password' icon. 6. Observe password characters become visible. 7. Click again on the same icon. 8. Observe password masking returns. 9. Complete login or clear field for cleanup.", + "expectedResult": "Toggling the icon switches between masked and visible password entry without affecting login function.", + "sourceCitation": { + "location": "Section 2.1.3, page 6", + "excerpt": "Password field must provide a show/hide option to toggle visibility during entry." + } + }, + { + "type": "functional", + "title": "Mandatory field validation on registration form", + "description": "Ensures all required fields on the registration form enforce entry and display errors if left blank.", + "testId": "TC-011", + "testDescription": "A user tries to submit the registration form with one or more required fields left empty and observes the system validations.", + "prerequisites": "No existing account with the test email or username.", + "stepsToPerform": "1. Launch the application. 2. Click on 'Sign Up' to open the registration page. 3. Leave the 'Email' field blank. 4. Enter a valid username and password. 5. Submit the form. 6. Observe validation error for the blank email. 7. Fill in 'Email' but clear the 'Username' field. 8. Submit again. 9. Observe validation error for the empty username field.", + "expectedResult": "Each required field left blank triggers an error, and the form is not submitted until all required fields are completed.", + "sourceCitation": { + "location": "Section 2.3.2, page 8", + "excerpt": "Registration form fields marked as required must be enforced and errors displayed if left empty." + } + }, + { + "type": "boundary", + "title": "Password length upper boundary validation", + "description": "Validates the system enforces maximum password length requirements during registration and reset.", + "testId": "TC-012", + "testDescription": "A user attempts to set a password with exactly the maximum allowed length, and then one character more, during account registration.", + "prerequisites": "No pre-existing account with the tested username or email.", + "stepsToPerform": "1. Open the application and navigate to 'Sign Up'. 2. Enter all required registration fields. 3. Enter a password with exactly 20 characters (max allowed per requirements). 4. Confirm and submit registration. 5. Observe successful account creation. 6. Log out if needed. 7. Return to 'Sign Up'. 8. Enter another registration with all valid fields and a 21-character password. 9. Attempt to submit and observe system reaction.", + "expectedResult": "Passwords up to 20 characters are accepted; 21 characters trigger a validation error with no account creation.", + "sourceCitation": { + "location": "Section 2.2.4, page 7", + "excerpt": "Password may not exceed 20 characters; longer entries must trigger validation error." + } + }, + { + "type": "negative", + "title": "Registration with an already existing email", + "description": "Ensures the system detects duplicate email addresses during registration and presents an appropriate error.", + "testId": "TC-013", + "testDescription": "A user tries to register a new account with an email that is already registered in the system.", + "prerequisites": "An account with the test email already exists.", + "stepsToPerform": "1. Open the application. 2. Click on 'Sign Up'. 3. Enter a unique username. 4. Enter the email address already registered in the system. 5. Enter a valid password. 6. Complete other required fields if any. 7. Submit the registration form. 8. Wait for server response. 9. Observe any error messages provided.", + "expectedResult": "System prevents registration and displays error indicating the email is already in use.", + "sourceCitation": { + "location": "Section 2.3.3, page 9", + "excerpt": "Registration must fail with a descriptive error if the email is already registered." + } + }, + { + "type": "state-transition", + "title": "Email not verified blocks login and triggers verification prompt", + "description": "Tests that a user cannot log in before verifying their email, and system provides verification prompt.", + "testId": "TC-014", + "testDescription": "A new user completes registration but does not verify the email, then tries to log in.", + "prerequisites": "Test email registered as a new user with a verification link sent but not clicked.", + "stepsToPerform": "1. Launch the application. 2. Complete account registration with a test email (do not click verification link). 3. Go to login page. 4. Enter registered email and password. 5. Submit login form. 6. Wait for authentication response. 7. Observe any displayed error or prompt. 8. Check that login is not successful. 9. Log into test email and verify if a new verification email is provided/resent.", + "expectedResult": "Login is blocked for unverified emails and system prompts user to verify email before first login.", + "sourceCitation": { + "location": "Section 2.3.4, page 9", + "excerpt": "Users must verify their email address before login is allowed; prompt must indicate verification is needed." + } + }, + { + "type": "functional", + "title": "Password reset with expired link", + "description": "Validates expired password reset link is rejected and user is notified appropriately.", + "testId": "TC-015", + "testDescription": "A user clicks a password reset link after the expiration period and attempts to set a new password.", + "prerequisites": "Password reset request initiated for an existing user; link expiration configured per requirement.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login' then 'Forgot Password'. 3. Enter registered email address and submit. 4. Wait for password reset email. 5. Wait for the link to expire (exceeding expiration duration per requirement). 6. Click the expired password reset link from the received email. 7. Attempt to enter and confirm a new password. 8. Submit the new password. 9. Observe application feedback.", + "expectedResult": "System informs the user that the password reset link has expired and does not allow password change.", + "sourceCitation": { + "location": "Section 2.2.5, page 7", + "excerpt": "Password reset links must expire after 30 minutes and cannot be used once expired." + } + }, + { + "type": "functional", + "title": "Registration with invalid email format", + "description": "Ensures registration fails when user inputs an email address not matching the format requirements.", + "testId": "TC-016", + "testDescription": "A user attempts to register with an email address lacking the '@' symbol or domain part, checks for inline validation errors and form submission blocking.", + "prerequisites": "No account exists for the entered email address.", + "stepsToPerform": "1. Launch the application. 2. Click 'Sign Up' to display the registration form. 3. Enter a valid username in the 'Username' field. 4. Enter an invalid email (e.g., 'userexample.com') in the 'Email' field. 5. Enter a valid password. 6. Fill in other required fields. 7. Attempt to submit the registration form. 8. Observe for any error or blocking on the email field. 9. Try with another invalid email (e.g., 'user@com').", + "expectedResult": "Registration is blocked and an error message displayed indicating email format is invalid.", + "sourceCitation": { + "location": "Section 2.3.5, page 9", + "excerpt": "Email addresses must be validated against standard format before allowing registration to proceed." + } + }, + { + "type": "negative", + "title": "Registration when password and confirm password do not match", + "description": "Validates that the registration form enforces matching password and confirm password fields before submission.", + "testId": "TC-017", + "testDescription": "A user enters a password and a different confirm password in the registration form, observing that the mismatch blocks registration and displays a specific error.", + "prerequisites": "No existing account with test username or email.", + "stepsToPerform": "1. Open the application. 2. Navigate to 'Sign Up' registration page. 3. Fill in valid username and valid email. 4. Enter 'Password123!' into password field. 5. Enter 'Password1234!' into confirm password field. 6. Fill all other required fields. 7. Submit the registration form. 8. Review inline validation or error message. 9. Correct the confirm password to match and submit for cleanup.", + "expectedResult": "System displays a specific error that passwords do not match and does not proceed with registration.", + "sourceCitation": { + "location": "Section 2.3.6, page 9", + "excerpt": "If the confirm password field does not match password, registration must be blocked with a mismatch error." + } + }, + { + "type": "boundary", + "title": "Password minimum complexity enforcement", + "description": "Checks if password meets all complexity rules before creation: uppercase, lowercase, digit, special character.", + "testId": "TC-018", + "testDescription": "A user attempts registration with valid length but passwords missing one or more complexity requirements, checking for form errors and enforcement.", + "prerequisites": "User registration page accessible with no existing account for test email.", + "stepsToPerform": "1. Launch the app and go to 'Sign Up'. 2. Fill username and email with valid values. 3. Enter a password with only lowercase letters (e.g., 'passwordabc'). 4. Confirm password to match. 5. Submit the form and note validation result. 6. Change password to 'Passwordabc' (upper and lower, still missing digit and symbol). 7. Submit again. 8. Change password to 'Password1' (missing symbol). 9. Submit and observe validation error.", + "expectedResult": "Password field enforces all required complexity rules, displaying specific error(s) per missing category.", + "sourceCitation": { + "location": "Section 2.2.2, page 7", + "excerpt": "Password policy: at least one uppercase, one lowercase, one digit, and one special character required." + } + }, + { + "type": "state-transition", + "title": "Automatic logout after session timeout", + "description": "Verifies the user is logged out automatically after the configured session inactivity period expires and access to secure pages is no longer possible.", + "testId": "TC-019", + "testDescription": "A user logs into the dashboard, remains inactive until session expires, and then attempts an action to check that re-authentication is now required.", + "prerequisites": "A valid user account exists.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login' and enter correct credentials. 3. Submit to access the dashboard. 4. Confirm dashboard is visible. 5. Leave the session inactive for the configured idle timeout (e.g., 15 minutes) without clicking or input. 6. After timeout, attempt to navigate to another secure page (e.g., 'Profile'). 7. Observe if access is blocked. 8. Attempt to reload the dashboard. 9. Verify redirection to login page.", + "expectedResult": "Session expires after the inactivity period, user is logged out and must log in again to access secure resources.", + "sourceCitation": { + "location": "Section 2.5.2, page 11", + "excerpt": "Sessions must automatically log out the user after 15 minutes of inactivity for security reasons." + } + }, + { + "type": "functional", + "title": "Successful password update from user profile", + "description": "Verifies that a logged-in user can update their password from the profile section using correct current and new password values.", + "testId": "TC-020", + "testDescription": "A logged-in user navigates to the profile area, initiates a password change, enters current and new passwords meeting all requirements, and confirms update.", + "prerequisites": "Test user is registered, email is verified, and login works.", + "stepsToPerform": "1. Launch the application. 2. Log in with valid credentials to access dashboard. 3. Click on 'Profile' or 'Account Settings'. 4. Select 'Change Password' option. 5. Enter current password in the required field. 6. Enter a new password that satisfies length and complexity requirements. 7. Confirm new password matches. 8. Submit the password change form. 9. Log out and attempt logging in with new password to confirm update.", + "expectedResult": "Password change is successful, confirmation message is displayed, and new password works for next login.", + "sourceCitation": { + "location": "Section 2.6, page 12", + "excerpt": "Logged-in users must be able to update their password from the profile settings area by providing the current password." + } + }, + { + "type": "boundary", + "title": "Username minimum length enforcement", + "description": "Ensures the registration form enforces the username minimum character requirement at its boundary condition.", + "testId": "TC-021", + "testDescription": "A user tries to register with a username of two characters (if the minimum is three), and verifies the form blocks submission and displays the correct validation error.", + "prerequisites": "No pre-existing account with the tested email or username.", + "stepsToPerform": "1. Launch the application. 2. Click 'Sign Up' for registration. 3. Enter valid email. 4. Enter a two-character username in the username field. 5. Enter a valid password meeting all complexity requirements. 6. Fill other mandatory fields if any. 7. Submit the registration form. 8. Observe the error message for minimum username length. 9. Update the username to meet the minimum length for cleanup.", + "expectedResult": "System rejects usernames below the minimum and displays a descriptive validation error, blocking registration.", + "sourceCitation": { + "location": "Section 2.3.1, page 8", + "excerpt": "Usernames must be at least 3 characters; shorter entries trigger a validation error." + } + }, + { + "type": "functional", + "title": "Resend email verification link from login prompt", + "description": "Verifies that a user blocked at login due to unverified email can request the verification link to be re-sent and successfully receives the email.", + "testId": "TC-022", + "testDescription": "After a failed login attempt with an unverified email, the user clicks a provided option to resend the verification link and confirms the reception of the email.", + "prerequisites": "Account registered, email not yet verified.", + "stepsToPerform": "1. Launch the application. 2. Go to 'Login' page. 3. Enter registered email and password (email unverified). 4. Submit credentials. 5. Observe login error indicating verification is required. 6. Click 'Resend Verification Link' option in the prompt. 7. Check the test email inbox for a new verification email. 8. Confirm receipt and verify that the link is correct. 9. Complete email verification for cleanup if required.", + "expectedResult": "A new verification email is sent, and user receives confirmation of re-sending within the UI.", + "sourceCitation": { + "location": "Section 2.3.4, page 9", + "excerpt": "If users have not verified their email, offer a prompt to resend verification email during login." + } + }, + { + "type": "functional", + "title": "Password reset notification email structure and logging", + "description": "Ensures the password reset email contains all specified fields and that the event is logged per audit requirements.", + "testId": "TC-023", + "testDescription": "A user initiates a password reset, receives the email, and validates required email content and that the reset event is recorded in the security audit log.", + "prerequisites": "Existing user account with accessible test email.", + "stepsToPerform": "1. Launch the application. 2. Click 'Login' > 'Forgot Password'. 3. Enter valid email and submit. 4. Wait for password reset email. 5. Open received email in the test inbox. 6. Review subject, sender, and ensure content includes reset link and expiration info. 7. Ensure no password is ever shown in email. 8. Access the application audit log/reporting module. 9. Check a log entry for the reset event with email, timestamp, and IP address.", + "expectedResult": "Reset email contains all required information; audit log entry exists documenting the reset request accurately.", + "sourceCitation": { + "location": "Section 2.2.6, page 7", + "excerpt": "Password reset emails must contain a reset link, expire time, and be logged for audit with user, timestamp, IP." + } + }, + { + "type": "negative", + "title": "Password change fails with incorrect current password", + "description": "Validates that users cannot change their password from the profile screen if they enter the wrong current password.", + "testId": "TC-024", + "testDescription": "A logged-in user tries to update their password but supplies an incorrect value in the 'current password' prompt, ensuring the form blocks the action and displays a specific error.", + "prerequisites": "Existing, logged-in test account; current valid password known.", + "stepsToPerform": "1. Launch the application and log in with valid credentials. 2. Access 'Profile' or 'Account Settings'. 3. Click to change password. 4. Enter an incorrect value in the 'current password' field. 5. Enter a new valid password and confirm password matching. 6. Submit the change password form. 7. Observe rejection message for incorrect current password. 8. Attempt to log in with both the old and new password to confirm no change occurred. 9. Repeat with correct current password for cleanup.", + "expectedResult": "Password update is denied with a clear error for wrong current password; password remains unchanged.", + "sourceCitation": { + "location": "Section 2.6.2, page 12", + "excerpt": "Password updates require the correct current password; incorrect entries must trigger a specific error." + } + }, + { + "type": "boundary", + "title": "Session timeout enforcement at exact threshold", + "description": "Checks automatic logout occurs precisely at the configured inactivity duration, no earlier or later.", + "testId": "TC-025", + "testDescription": "A user logs in and remains inactive, monitoring whether session expiry triggers exactly at the 15-minute mark.", + "prerequisites": "Registered active user account.", + "stepsToPerform": "1. Launch application and log in to access dashboard. 2. Confirm dashboard is loaded. 3. Remain completely inactive (no mouse/keyboard/clicks/touches). 4. Start a timer upon dashboard load. 5. Monitor for logout behavior. 6. At 14:59, verify user is still logged in. 7. At 15:00, attempt any action (e.g., view Profile). 8. Confirm the session has expired and redirection to login occurs. 9. Attempt access to any protected URL to confirm session is cleared.", + "expectedResult": "Session is valid until exactly 15 minutes of inactivity, then automatically logs out and requires a new login.", + "sourceCitation": { + "location": "Section 2.5.2, page 11", + "excerpt": "Sessions must automatically log out user after 15 minutes of inactivity." + } + }, + { + "type": "functional", + "title": "Registration with all special characters in password", + "description": "Verifies user registration is allowed when the password contains all special characters permitted by the policy.", + "testId": "TC-026", + "testDescription": "User completes the registration form and sets a password using all allowed special characters, confirming successful account creation.", + "prerequisites": "No pre-existing account with test username or email.", + "stepsToPerform": "1. Launch the application. 2. Click on 'Sign Up' to open registration page. 3. Enter a valid email in the 'Email' field. 4. Enter a valid username in the 'Username' field. 5. Enter a password with all allowed special characters (e.g., !@#$%^&*). 6. Confirm the password in the confirm password field. 7. Complete any other mandatory fields. 8. Submit the registration form. 9. Observe any inline validations or error messages. 10. Check for registration success notification.", + "expectedResult": "Registration succeeds with passwords containing all permitted special characters as per password policy.", + "sourceCitation": { + "location": "Section 2.2.2, page 7", + "excerpt": "Password policy: at least one uppercase, one lowercase, one digit, and one special character required." + } + }, + { + "type": "negative", + "title": "Registration attempt with whitespace in username", + "description": "Verifies that usernames containing spaces are rejected at registration as per username validation policy.", + "testId": "TC-027", + "testDescription": "User tries to register an account using a username containing leading, trailing, or mid-string whitespace and observes if registration is denied.", + "prerequisites": "No pre-existing account with the tested email.", + "stepsToPerform": "1. Launch application. 2. Click 'Sign Up' for the registration form. 3. Enter a valid email. 4. Enter a username with a space ('test user') in the username field. 5. Enter a valid password meeting all requirements. 6. Fill other required fields. 7. Submit the registration form. 8. Observe inline validation or blocking message for whitespace. 9. Repeat test with username having leading and trailing spaces.", + "expectedResult": "System displays a validation error and does not allow submission for usernames containing whitespace.", + "sourceCitation": { + "location": "Section 2.3.1, page 8", + "excerpt": "Usernames must be 3-32 characters, letters and numbers only, no whitespace allowed." + } + }, + { + "type": "functional", + "title": "Confirmation email contains correct verification link and expiry details", + "description": "Checks that the registration confirmation email contains the expected verification link and clearly states the expiry duration.", + "testId": "TC-028", + "testDescription": "User registers for an account and reviews the confirmation email to ensure the link is correct and expiry is present in the message body.", + "prerequisites": "No existing account for the test email; ability to access test email inbox.", + "stepsToPerform": "1. Launch the application. 2. Click 'Sign Up' and fill the registration form with valid data. 3. Submit the registration form. 4. Open the test email inbox. 5. Locate the new registration confirmation email. 6. Open the email and inspect the sender, subject, and body. 7. Confirm the presence of a verification link. 8. Check that the expiry information for the link is stated (e.g., 'Link expires in 24 hours'). 9. Attempt to copy the link to validate it is properly formed.", + "expectedResult": "Confirmation email contains correctly formatted verification link and explicit link expiry details.", + "sourceCitation": { + "location": "Section 2.3.7, page 10", + "excerpt": "Verification emails must include the activation link and inform user of expiration time for verification." + } + }, + { + "type": "negative", + "title": "Attempt login with deleted user account", + "description": "Ensures login is denied and an appropriate error message is displayed when attempting to log in with a deleted account.", + "testId": "TC-029", + "testDescription": "A user whose account was previously deleted tries to log in, ensuring system provides feedback and does not permit access.", + "prerequisites": "User account exists but is in 'deleted' state in the database.", + "stepsToPerform": "1. Launch the application. 2. Open 'Login' page. 3. Enter the username of a deleted account in the username field. 4. Enter the correct password. 5. Click 'Submit' to attempt login. 6. Wait for system response. 7. Observe if an error message is displayed. 8. Attempt a password reset with the deleted account email. 9. Confirm system reaction for password reset as well.", + "expectedResult": "System rejects login and password reset attempts for deleted accounts with appropriate feedback.", + "sourceCitation": { + "location": "Section 2.1.4, page 6", + "excerpt": "Deleted, disabled, or deactivated accounts must not permit login or password reset; display generic access denied error." + } + }, + { + "type": "functional", + "title": "Audit log records successful registration event", + "description": "Verifies that a successful user registration is properly logged in the audit system with timestamp and other specified fields.", + "testId": "TC-030", + "testDescription": "A user registers a new account and the test confirms a corresponding entry is recorded in the audit log per requirements.", + "prerequisites": "Audit log/reporting module access with proper permissions; no existing account for test email.", + "stepsToPerform": "1. Launch the application. 2. Go to 'Sign Up' to access the registration form. 3. Complete all required fields with valid data. 4. Submit the form to create an account. 5. Confirm registration success message is displayed. 6. Log in to the administrator/audit console. 7. Navigate to user registration audit log. 8. Search for recent registration event matching test user data. 9. Verify that log entry includes user, timestamp, IP, and event 'registration'.", + "expectedResult": "A successful registration event is present in the audit log with user, timestamp, IP address, and event type.", + "sourceCitation": { + "location": "Section 2.3.8, page 10", + "excerpt": "All user registration events must be recorded in the audit log, including user identifier, timestamp, and IP address." + } + } +] \ No newline at end of file diff --git a/functional_tests/test-big-pdf/test-big-pdf.xlsx b/functional_tests/test-big-pdf/test-big-pdf.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..e617d300cf491ac6a08de815d2fcbfa995d52a88 GIT binary patch literal 15935 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