Kembali ketika pertama kali saya belajar Web Development, saya tidak mengenal tools atau library yang digunakan untuk keperluan testing. Saya melakukan semua manual dari browser, yah cukup primitif dan tidak efisien memang. Kemudian saya mengenal beberapa testing tools yang sangat bermanfaat, benar-benar membuat pekerjaan menjadi efesien dan ngga buang-buang waktu.
Ada macam-macam tipe testing tools, bentuk dan kegunaannya juga beragam. Kali ini kita akan membahas Puppeteer yang dikembangkan oleh Google.
Jadi, apa sih Puppeteer itu ? No, kita ngga akan bermain boneka eropa yang memegang pisau. Puppeteer adalah node library yang dapat digunakan untuk mengontrol Chrome atau Chromium. Pada dasarnya Puppeteer berjalan headless atau tanpa antar muka. Jadi dia bisa control browser tapi ngga ada GUI-nya, macam jalan diterminal atau command line gitu. Ini berguna banget kalau dipakai di server, kita tau lah mayoritas server berbasis text. Yah yah tapi apa hubungannya dengan Testing ?
Apa aja sih yang bisa kita lakukan dengan Puppeteer ini ? Apapun yang bisa kita lakukan pada browser Chrome/Chromium bisa kita lakukan di Puppeteer. Contohnya nih:
- Ambil screenshot dari web
- Generate pdf dari web, oke siapa yang capek generate pdf, tapi library yang dipakai ngga support semua fitur html & css ? Bikin frustasi ? Sama saya juga, semenjak ada Puppeteer semua jadi lebih mudah, Hampir semua html & css bisa dipakai.
- Crawl website, bahkan bisa juga crawl SPA loh (pada dasarnya memang browser, secara logis memang bisa)
- Task Automation, ini yang paling menarik. Jadi kita bisa ngisi otomatis form di website kita. Bisa submit juga, jadi bagus dipakai testing, ga perlu capek-capek ngisi form terus submit cuma buat test. Ini punya potensi besar untuk membuat bot loh, udah ada banyak samplenya.
- dll
Puppeteer menggunakan Javascript atau lebih tepatnya Nodejs. Kalau belum familiar dengan javascript ngga perlu sedih, cara pakainya ngga susah loh. Bisa kok pakai Puppeteer tanpa jago javascript, menurut saya Puppeteer bisa digunakan hanya dengan copy-paste dari code-example.
Installation
Cara install Puppeteer cukup mudah. Pertama pastikan NodeJS sudah terinstall, minimal versi v7.6.0.
Bikin 1 folder baru, buka terminal kemudian masukin perintahnpm i puppeteer
Screenshot
Pertama kita akan mencoba mengambil screenshot dari sebuah website. Bikin 1 file baru dengan nama screenshot.js
1 | const puppeteer = require('puppeteer'); |
Buka terminal jalankan perintah node screenshot.js
. Kemudian cek hasilnya, cari file test.png.
Nama methodnya sangat mudah dimengerti kan ? Bahkan tanpa paham javascript kita bisa tahu apa maksud dari code di atas. Pada dasarnya seperti mengoperasikan browser pada umumnya.
- Pertama buka browser
const browser = await puppeteer.launch();
- Kemudian buka 1 tab/page baru
const page = await browser.newPage();
- Navigasikan ke url tertentu
await page.goto('https://mythinbooks.gitlab.io/');
- Dan ambil screenshot
await page.screenshot({path: 'test.png'});
. - Langkah terakhir tutup browsernya.
await browser.close();
Generate PDF
Contoh berikutnya kita akan mencoba generate pdf. Banyak banget library untuk generate pdf di luar sana, tapi menurut saya Puppeteer adalah yang paling MANTAP :)
Cara pemakaiannya hampir mirip dengan mengambil screenshot.
1 | const puppeteer = require('puppeteer'); |
Cukup identik bukan ?
Perbedaan pertama ada di method goto()
. Ada tambahan option waitUntil
. Apa sih kegunaannya ? Sederhana-nya waitUntil
akan menunggu sampai semua komponen pada semua website selesai diload (sebenarnya penjelasan cukup kompleks nanti lihat footnotes yah), jadi harus dipastikan semua selesai diload kemudian baru diprint. Kan ngga lucu kalau diprint cuma setengah halaman.
await page.pdf({path: 'test.pdf', format: 'A4'});
Ini perbedaan yang terakhir, jelas banget ini method buat generate pdfnya. Cukup definisikan path & format kertasnya.
Crawl website
Ini salah satu fitur menarik dari Puppeteer, bisa dipakai untuk crawl website, bahkan bisa juga mengcrawl website SPA, atau yg dirender menggunakan javascript.
Kali ini kita akan mencoba mengcrawl Twitter. Target kita https://twitter.com/search?q=laravel&src=typed_query&f=live.
Sebelum kita mulai, ada hal yang perlu dipastikan. Ketika kita menavigasikan Puppeteer ke suatu website, semua komponen pada web tersebut tidak langsung muncul segera, ada semacam interval waktu. Penyebabnya bermacam-macam, seperti internet lambat, server lambat, kemudian ada client-side rendering dan sebagainya. Nah, sebelum kita memulai aksi, harus pastikan elemen yang kita butuhkan sudah muncul. Pada contoh sebelumnya kita menggunakan waitUntil
. Ada banyak option dan method untuk mengatasi masalah tersebut, lalu bagaimana jika kita mengabaikan hal ini ? Kalau kita mengabaikan hal ini kita akan mendapatkan hasil yang tidak diinginkan, misalnya saja ketika ingin print pdf, tapi tidak menunggu sampai semua halaman diload maka hasil print pdf-nya akan berantakan atau hanya beberapa halaman yg berhasil diprint. Atau saat kita mengcrawl web SPA yang biasanya dirender pada sisi client, dan langsung melakukan eksekusi tanpa menunggu semua elemen selesai dirender maka kita tidak akan mendapatkan data yang diinginkan. Ada macam-macam options dan methods untuk menunggu elemen yang diperlukan muncul, silahkan buka dokumentasi resminya.
sā , gēmu o hajimeyō
Buat 1 file baru tweets.js
Kemudian jalankan perintah node tweets.js
1 | const puppeteer = require('puppeteer'); |
Saya menambahkan option {headless:false}
pada method launch()
. Ini berguna untuk debugging, jadi nanti akan muncul browser beneran. Pastikan ketika masuk production atau mode serius hapus option tersebut.
Oke yang perlu diperhatikan pertama adalah await page.waitFor(() => !!document.querySelector('.js-stream-tweet'));
. Seperti yang kita bahas tadi kita harus menunggu elemen yang dibutuhkan muncul lebih dahulu. Disini method waitFor menunggu elemen ".js-stream-tweet"
muncul. Elemen ini adalah container, di dalamnya ada text, image ,profil user dll. Untuk selector bisa menggunakan selector css/js pada umumnya.
Setelah elemen yang kita perlukan muncul, sekarang kita tinggal mengambil elemen tersebut let tweets = await page.$$(".js-stream-tweet");
. Method $$
mengambil semua elemen sesuai dengan selector yang kita masukan dan mengembalikannya dalam bentuk Array, disini kita mengambil tweet dari setiap orang tentu hasilnya akan banyak. Jika ingin mengambil 1 elemen pertama gunakan method $
.
Kita sudah mendapatkan container elemen. Kemudian kita hanya perlu memprosesnya saja. Yang perlu diambil adalah tweet dari tiap user. Karena class "js-stream-tweet"
adalah container, kita harus mencari child yang mengandung tweet. Disini method $eval
beraksi, dia mencari child berdasarkan selector, parameter pertama adalah selector/target kita, kemudian parameter kedua adalah function untuk memproses elemen yang ditemukan. Seperti yang kita lihat, function tersebut mendapatkan parameter element. Ini adalah elemen yang kita cari, hal apa saja yang dimiliki element bisa lihat di https://developer.mozilla.org/en-US/docs/Web/API/element.
Bonus crawl tokopedia products
1 | const puppeteer = require('puppeteer'); |
Jika web kita crawl menggunakan API yang diload lewat ajax misal, kita bisa langsung mengambil responsenya. Jadi tidak perlu repot-repot menunggu sampai semua dirender. Cara ini juga lebih efisien. Ada method bernama waitForResponse
silahkan dilihat di https://github.com/GoogleChrome/puppeteer/blob/v1.18.1/docs/api.md#pagewaitforresponseurlorpredicate-options. Kita akan membahas fitur ini lain kali.
Task Automation
Menurut saya ini merupakan fitur Puppeteer yang paling menarik, bisa dipakai buat bot, dipakai testing website, dsb.
Kali ini kita akan membuat auto-tweet. Flownya login ke twitter kemudian post 1 tweet, simple.
Buat 1 file baru auto-tweet.js, kemudian jalankan node auto-tweet.js
1 | const puppeteer = require('puppeteer'); |
Ini ngga terlalu susah loh, cuma modal method type & click.
- Kita buka halaman login twitter, kemudian tunggu selesai navigasinya.
await page.type('.email-input', 'YourEmailGoesHere')
Perkenalkan methodtype
, dia bertugas untuk melakukan input pada textbox,textarea atau apapun yang bisa diketik user, sesuai namanya memang fungsinya. Parameter pertama adalah selector target element. Parameter kedua adalah nilai yang ingin kita ketik/masukan.- Click button login
await page.click('#page-container > div > div.signin-wrapper > form > div.clearfix > button')
, methodclick
membuat debutnya disini. Dia memiliki 1 parameter wajib yaitu selector elemen yang ingin diclick. - Selesai sudah, sisanya sama seperti sebelumnya, cuma perlu cari selector kemudian type & click
Terkadang kita susah untuk mencari selector yang tepat, gunakan fitur dari google chrome devtools
Yang saya tulis hanyalah sedikit dari banyak fitur yang dimiliki oleh Puppeteer. Silahkan buka repo resmi Puppeteer https://github.com/GoogleChrome/puppeteer. Untuk hal yang belum dimengerti silahkan coret-coret komen di bawah ini atau langsung aja buka dokumentasi resmi puppeteer https://github.com/GoogleChrome/puppeteer/blob/v1.18.1/docs/api.md. Ah mau lihat project lain yg dibuat dengan Puppeteer bisa buka ini https://github.com/transitive-bullshit/awesome-puppeteer.
Semua code pada artikel ini bisa kalian temukan di repo kami https://github.com/MyThinBooks/Puppeteer.
Comments