OrangeHRM Web Automation
Suite end-to-end Cypress UI + API
- 105
- Test end-to-end
- 100%
- Pass rate
- 4
- Suite spec
Ringkasan
Suite automation end-to-end untuk demo open-source OrangeHRM, mencakup alur autentikasi dan directory yang pertama kali ditemui pengguna, ditambah lapisan API terpisah yang diuji terhadap Platzi Fake Store API publik.
Suite ini dibangun di atas Page Object Model supaya selector dan action terpisah dari assertion, dan berjalan otomatis di GitHub Actions dengan laporan Mochawesome yang bisa diakses publik.
Tujuan
Menutup alur Login, Forgot Password, dan Directory secara end-to-end - termasuk pemeriksaan UI, responsive, negatif, dan waktu respons - serta memvalidasi REST API publik untuk status code, struktur response, dan tipe data.
Cakupan pengujian
Login (22 test)
- Redirect ke login saat membuka dashboard tanpa autentikasi
- Elemen UI, placeholder, dan penyamaran password
- Login valid lewat klik dan lewat tombol Enter
- Username / password / keduanya salah memunculkan error
- Validasi field kosong dan karakter spesial
- Layout responsive dan waktu respons login di bawah threshold
- Klik ganda hanya mengirim satu request
Forgot Password (30 test)
- Navigasi dari login ke halaman reset dan kembali lewat cancel
- Elemen form, placeholder, dan teks copyright
- Submit dengan username valid, tidak terdaftar, dan berkarakter spesial
- Isi halaman konfirmasi setelah submit
- Username kosong dan hanya berisi spasi ditolak
- Layout responsive dan waktu proses
Directory (28 test)
- Redirect autentikasi dan label kartu filter
- Pencarian dengan nama karyawan valid dan tidak terdaftar
- Mengosongkan lalu mengisi ulang field nama
- Reset mengembalikan data dan nilai awal dropdown
- Layout responsive dengan tombol tidak terpotong di mobile
- Pemuatan halaman dan hasil pencarian di bawah batas waktu
API - Platzi Fake Store (25 test)
- GET categories: array, tidak kosong, skema (id, name, image)
- Pemeriksaan Content-Type dan waktu respons
- GET category by ID: assertion nilai dan tipe data
- PUT update: status 200, nama berubah, ID tetap, image ikut diperbarui
- DELETE category dan GET products by category
- Negatif: ID tidak valid dan POST tanpa nama mengembalikan error
Strategi pengujian
- Page Object Model memisahkan selector dan action dari assertion.
- Fixture data-driven menampung varian kredensial, bukan ditulis langsung di spec.
- cy.intercept memastikan status HTTP navigasi sebelum UI diperiksa.
- Kasus negatif dan boundary: field kosong, spasi, dan karakter spesial.
- Pemeriksaan responsive di berbagai viewport, plus batas waktu respons.
- GitHub Actions menjalankan suite dan menerbitkan laporan Mochawesome.
Arsitektur
- File specdescribe / it, test case ID
- Page Objectselector + action
- OrangeHRM demo / Platzi APIsistem yang diuji
- GitHub ActionsCypress berjalan saat push
- Mochawesome → GitHub Pageslaporan yang dipublikasikan
Implementasi
class LoginPage {
// Selectors
get usernameInput() { return cy.get('input[name="username"]') }
get passwordInput() { return cy.get('input[name="password"]') }
get submitButton() { return cy.get('button[type="submit"]') }
get alertMessage() { return cy.get('.oxd-alert-content-text') }
// Actions
login(username, password) {
this.usernameInput.type(username)
this.passwordInput.type(password)
this.submitButton.click()
}
// Assertions
assertInvalidCredentials() {
this.alertMessage.should('be.visible').and('contain', 'Invalid credentials')
}
}
export default LoginPageit('login page returns 200 before UI checks', () => {
cy.intercept('GET', '**/auth/login').as('loginPage')
loginPage.visitLogin()
cy.wait('@loginPage').then((interception) => {
expect(interception.response.statusCode).to.eq(200)
})
loginPage.assertBrandingVisible()
}){
"validUser": { "username": "Admin", "password": "admin123" },
"invalidUsername": { "username": "admintesting", "password": "admin123" },
"invalidPassword": { "username": "Admin", "password": "123" },
"specialChar": { "username": "@@$$*&$", "password": "@@$$*&$" }
}it('GET categories returns a non-empty array', () => {
cy.request('GET', `${BASE_URL}/categories`).then((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.be.an('array')
expect(response.body.length).to.be.greaterThan(0)
expect(response.body[0]).to.have.all.keys('id', 'name', 'image')
})
})Hasil
105
Test
di 4 suite spec
105
Lulus
0
Gagal
100%
Pass rate