QA Practice Portal

Test data and selectors

Demo accounts
EmailPasswordRoleUse it for
student@qa.testPassword123student The main happy path. Seeded with 4 enrolments, 3 tickets and 5 notifications.
admin@qa.testAdmin@123admin Unlocks the three admin screens.
instructor@qa.testTeach@123instructor A signed-in role that must not see the admin area.
suspended@qa.testPassword123student Correct password, but sign-in is always refused.
dana@qa.test, miguel@qa.testPassword123 studentExtra rows for admin list filtering.
Locator conventions

Every interactive element carries a data-testid. Prefer it over CSS classes or XPath position - the styling will change, the test ids will not.

// Playwright
await page.getByTestId('input-email').fill('student@qa.test');
await page.getByTestId('btn-login').click();

// Selenium (Java)
driver.findElement(By.cssSelector("[data-testid='input-email']")).sendKeys("student@qa.test");

// Cypress
cy.get('[data-testid=btn-login]').click();

Naming pattern

  • input-*, select-*, textarea-*, checkbox-*, radio-*, range-* - form controls
  • btn-* - buttons; row-level buttons end with the record id, e.g. btn-enroll-3
  • link-*, nav-*, tab-*, filter-* - navigation
  • *-row, *-card, *-item - repeating elements
  • error-<field> - the inline validation message for that field
  • flash-success / flash-danger / flash-warning / flash-info - page-level messages, with the text in flash-message
  • toast - transient message, auto-hides after 4 seconds
  • empty-state - shown by every list when there is nothing to display

Synchronisation hooks

  • body[data-app-ready="true"] - set on window load
  • [data-testid="results-summary"] carries data-total, data-page and data-total-pages
  • [data-testid="pagination-*"] carries data-current-page / data-total-pages
  • Rows expose their business key: data-course-code, data-ticket-ref, data-user-email
  • Forms with client validation set data-validation="passed|failed" on submit
Page map
PathPageWhat there is to test
login.php Sign in Valid / invalid credentials, suspended account, lockout after 5 failures
register.php Registration Field validation, duplicate email, password rules, terms checkbox
forgot-password.php Forgot password Generates a reset link on screen (no mail server needed)
reset-password.php Reset password Valid token, expired token, mismatched passwords
dashboard.php Dashboard Stat cards, progress bar, quick enrol, activity timeline
courses.php Course catalog Search, category / level / price filters, sorting, paging, grid vs table
course.php?id=1 Course detail Enrol, drop with a confirm modal, progress slider, seat counting
my-courses.php My courses Status tabs, progress updates, drop, re-enrol, certificate
certificate.php Certificate Only for completed courses; has a real file download
tickets.php Support tickets Create in a modal, search, filter, sort, page, delete with confirm
ticket.php?id=1 Ticket detail Replies, status workflow, permission rules, delete
notifications.php Notifications Mark read / unread, mark all, delete, clear all, unread badge
profile.php Profile Tabs, validation, avatar upload, change password
playground.php QA playground Alerts, waits, frames, drag and drop, shadow DOM, status codes
admin/users.php Admin: users Search, role change, suspend, create, delete (admin only)
admin/courses.php Admin: courses Create / edit in one modal, publish toggle, delete guard
admin/tickets.php Admin: tickets Bulk status changes with select-all checkbox
Deliberate behaviours worth a test
  • Five failed sign-ins lock the form for 60 seconds, and the message counts down the attempts left.
  • suspended@qa.test gets a different message from a wrong password - assert on both.
  • Registering with an existing email is rejected server-side even if the client check is bypassed.
  • Enrolling twice is refused; dropping and re-enrolling keeps the old progress.
  • Setting progress to 100% flips the enrolment to completed and unlocks the certificate.
  • A certificate request for an unfinished course redirects back with a warning.
  • Resolved and closed tickets refuse new replies.
  • A student can only move a ticket to Open or Closed; the other states need an admin.
  • Opening another user's ticket by id redirects with a permission error.
  • A non-admin hitting admin/* is bounced to the dashboard with a message.
  • Admins cannot suspend, delete or demote their own account.
  • A course with active enrolments cannot be deleted - unpublish it instead.
  • Every destructive action goes through a confirm modal, and cancelling really does cancel.
  • Every form is CSRF-protected: a stale token produces a visible "session expired" message.
Resetting the data

Put the database back to its seeded state before a suite run:

php C:\xampp\htdocs\theme\app\install.php

Or open install.php in a browser. It only touches the qa_practice database, and it is disabled on the live host unless QA_INSTALL_KEY is set. The terms and conditions for this sandbox are simple: it is a practice target, so nothing you do here matters.

Back to sign in

A sandbox built for practising UI test automation · Test data & selectors