All work
Professional work · PT. Cazh Teknologi Inovasi

CARDS School V3 - QA & Test Automation

Professional QA on a school-management platform

CypressPage Object ModelData-driven fixturescy.interceptcy.sessionMochawesomeJira & Zephyr
847+
Automated test cases
64
Spec files
700+
Institutions using CARDS

Overview

CARDS is a school-management ecosystem used by 700+ educational institutions: a web dashboard, a parents app, a school app, and a POS app together with its own web dashboard. As the sole QA engineer on the team, I own test coverage and bug-reporting standards across all of it.

My role here spans test design, manual testing, regression, exploratory testing, and UAT, plus bug validation, end-to-end automation, and coordinating QA interns. Automation focuses on the latest major releases and stays traceable to the test case documentation.

To respect confidentiality, this case study contains no internal URLs, credentials, user data, or code from the company repository. The code below is illustrative - rewritten generically to show the patterns I use, not production source.

Objective

Keep the CARDS ecosystem release-ready across web, mobile, and POS through test design, manual testing, and automation that maps one-to-one to the test case documentation.

Testing scope

  • CARDS School V3 - automation (847+ cases, 64 specs)

    • Onboarding and authentication
    • Academic Year settings
    • Subject settings
    • Grade Level settings
    • Tag settings
  • Cazh POS web dashboard - CPA V2 (86 cases)

    • Login
    • Dashboard
    • Employee
  • Manual testing across the ecosystem

    • Finance: student admissions, invoices, arrears, donations, savings, balance top-up & withdrawal
    • Attendance module
    • Regression, UI, exploratory, and responsive testing on web, mobile & POS
    • UAT scenarios prepared and executed before release

Test strategy

  • Page Object Model separates selectors and actions from the assertions.
  • Data-driven fixtures feed each scenario its own inputs.
  • cy.intercept verifies request and response behaviour, not just the rendered UI.
  • cy.session establishes the login once instead of repeating it per test.
  • Every test carries its own test case ID, so the suite stays traceable to Zephyr.
  • Mochawesome produces the run report. The suite is executed locally, not in CI.

Architecture

  1. Test case docs (Zephyr)each case has an ID
  2. Spec + Page ObjectID in the test name
  3. Application under testweb / POS dashboard
  4. Mochawesome reportrun locally

Implementation

A Page Object with generic selectors keeps specs readable and stable.Illustrative example - not production code
class SettingsPage {
  elements = {
    createButton: () => cy.get('[data-testid="create"]'),
    nameField:    () => cy.get('[data-testid="name"]'),
    saveButton:   () => cy.get('[data-testid="save"]'),
    toast:        () => cy.get('[data-testid="toast"]'),
  };
  visit() { cy.visit(`${Cypress.env('baseUrl')}/settings`); return this; }
  create(name) {
    this.elements.createButton().click();
    this.elements.nameField().type(name);
    this.elements.saveButton().click();
    return this;
  }
  assertSaved() { this.elements.toast().should('contain', 'Saved'); }
}
cy.session logs in once; the test name carries its test case ID for traceability.Illustrative example - not production code
beforeEach(() => {
  cy.session('qa-user', () => {
    cy.request('POST', '/api/login', Cypress.env('creds'))
      .its('body.token')
      .then((t) => window.localStorage.setItem('token', t));
  });
});

it('TC-AY-012 create a new academic year', () => {
  cy.intercept('POST', '/api/academic-years').as('create');
  settingsPage.visit().create('2026/2027');
  cy.wait('@create').its('response.statusCode').should('eq', 201);
});
A fixture drives positive and negative cases from one data table.Illustrative example - not production code
// fixtures/subjects.json
// [ { "id": "TC-SUB-001", "name": "Mathematics", "valid": true },
//   { "id": "TC-SUB-002", "name": "",            "valid": false } ]

cy.fixture('subjects').then((rows) => {
  rows.forEach((row) => {
    it(`${row.id} ${row.valid ? 'accepts' : 'rejects'} the name`, () => {
      subjectPage.create(row.name);
      row.valid ? subjectPage.assertSaved() : subjectPage.assertError();
    });
  });
});

Results

847+

Automated test cases

CARDS School V3, 64 spec files

86

Automated test cases

Cazh POS web dashboard (CPA V2)

700+

Institutions on the platform

60+

QA interns coordinated