- Tidak Ada Kontrol App - Tidak bisa mengecek atau meluncurkan app BCA secara otomatis
- Login Sederhana - Hanya menggunakan satu selector untuk tombol login
- REFF NO Bermasalah - Menggunakan nama + nominal + tanggal, jadi bisa duplikat
- Tidak Ada Retry - Kalau gagal, langsung error tanpa coba lagi
- Logging Berisik - LogLevel 'info' yang terlalu banyak output
- Tidak Deteksi Duplikat - Transaksi sama bisa diproses berulang kali
// SEBELUM: Tidak ada
// SESUDAH: Ada kontrol penuh
isBCAAppRunning() // Cek app jalan atau tidak
launchAppWithADB() // Launch app pakai ADB
ensureAppIsRunning() // Pastikan app jalan
restartApp() // Restart app kalau error
// SEBELUM: Cuma satu selector
const loginButton = await this.driver.$('//android.widget.TextView[@text="Masuk"]');
// SESUDAH: Multiple selectors + retry
const selectors = [
'//android.widget.ScrollView/android.view.View[6]',
'//android.widget.TextView[@text="Masuk"]',
'//android.view.View[@content-desc="Masuk"]',
'//android.widget.Button[contains(@text, "Masuk")]',
'//*[@text="Masuk"]'
];
// + findLoginButton() dengan 3x retry
// SEBELUM: Bermasalah
const key = `${name}_${amount}_${date}`; // Pakai tanggal
// SESUDAH: Konsisten
const key = `${name}_${amount}`; // Tanpa tanggal
// Reference number sekarang based on nama + nominal aja
// SEBELUM: Tidak ada
// SESUDAH: Ada pengecekan
const duplicateCheckStmt = this.db.prepare(`
SELECT COUNT(*) as count FROM transactions
WHERE description = ? AND amount = ? AND tanggal = ?
`);
// SEBELUM: Random order
const existingStmt = this.db.prepare("SELECT * FROM transactions");
// SESUDAH: Urutan waktu
const existingStmt = this.db.prepare("SELECT * FROM transactions ORDER BY timestamp ASC");
// SEBELUM: Logging berisik
logLevel: 'info'
// SESUDAH: Silent mode + debugging terstruktur
logLevel: 'silent'
console.log('Text values array:', textValues);
console.log('PEND Transaction:', {...});
console.log('Current reference counters:', refCounters);
// SEBELUM: Selector lama
'//o.r8lambdaBE22IXHLZLFTWxXTr9rzJPOX9g/android.view.View/android.view.View[3]/android.view.View[3]'
// SESUDAH: Selector baru
'//o.AFj1lSDK2/android.view.View/android.view.View[3]/android.view.View[3]'
Aspek
Sebelum
Sesudah
App Control
β Tidak ada
β Full ADB control
Login Retry
β Sekali gagal = error
β 3x retry + multiple selectors
REFF NO
β Nama+nominal+tanggal
β Nama+nominal (konsisten)
Duplikat
β Bisa duplikat
β Auto skip duplikat
Chronological
β Random order
β Timestamp-based order
Logging
β Berisik (info)
β Silent + structured debug
Error Recovery
β Crash = selesai
β Auto restart app
Transaction Type
β Basic
β Enhanced detection CR/DB
- β REFF NO Konsisten - A transfer 50k β REFF NO 1, 2, 3, 4... (tidak peduli urutan tampilan)
- β No More Crashes - App otomatis restart kalau error
- β Reliable Login - Multiple cara login + retry mechanism
- β No Duplicates - Transaksi sama tidak diproses 2x
- β Better Performance - Silent logging + efficient processing
- β Enhanced Stability - ADB control untuk app management
A transfer 50k (hari 1) β REFF NO 1
B transfer 30k (hari 1) β REFF NO 1
A transfer 50k (hari 2) β REFF NO 2 β Konsisten!
A transfer 50k (hari 3) β REFF NO 3 β Tetap berurutan!
Intinya: Dari scraper yang basic dan sering error, sekarang jadi scraper yang robust, reliable, dan intelligent! π