อะไรคือ Electron JS?

Electron JS คือ framework นึงที่ใช้ในการสร้าง Desktop Application ที่ทํางานได้บนทุก platform ด้วย Html5, JavaScript และ CSS

โดยเจ้า Electron JS ถูกสร้างด้วยเทคโนโลยียอดนิยมอย่าง Node.js และเจ้า Chromium นั้นเองงงง ดังนั้นพอนึกออกกันนะเหมือนเรารัน Web Application เรามันจะไปแสดงผลบน Chromium ดังนั้นพูดคร่าวๆได้ว่าเราเขียน Web App ครั้งเดียวสามารถรันได้บนทุก platform 🙂

แต่ในความเป็นจริง ไม่มีไรเขียนได้ครั้งเดียวจริงๆหรอก เมื่อไรก็ตามที่ใช้ tools ใดๆ เมื่อเรามี Native dependencies เราก็ต้องเขียนเพื่อให้มันทํางานบน OS เฉพาะๆนั้นอยู่ดี แต่อย่างน้อยเจ้า Electron JS ก็มี functionalities ที่ช่วยให้เราสามารถ access low-level ได้ในระดับนึง เช่น Keyboard Shortcuts เป็นต้น

ใครใช้ Electron JS บ้าง

จริงๆคนใช้ Electron JS นะมีหลายเจ้าเลยเลยสามารถดูได้ที่นี้ https://stackshare.io/slack/slack แต่ที่ดังที่สุดและกําลังจะเข้า ตลาดหุ้น คือ Slack Technologies Inc. นั้นเอง

พูดง่ายๆสมัยนี้ส่วนใหญ่ที่เป็น desktop app เอาไปทําเป็น Electron JS ซะส่วนใหญ่ละ นอกจากเค้าต้องการลง Natives จริงๆอาจจะเปลี่ยนไปเขียน Native ของ OS นั้นๆ

Electron JS Architecture

มาดูกันว่าเจ้า Electron JS มันถูกออกแบบมาให้ทํางานยังไง โดยต้องเข้าใจก่อนว่า Electron JS ถูกสร้างออกมาในรูปแบบแนวคิดของ Chromium คือ แยกแต่ละ process ออกมาเหมือนเวลาเราเปิด Tab ใน chrome มันก็จะสร้างอีก process ออกมา เพื่อที่เวลา tab ไหนตายจะได้ไม่ตายไปทั้งหมดนั้นเอง (resilience)

ด้วยความที่มันออกแบบออกมาอย่างงั้น Electron JS จึงมีสองอย่างที่สําคัญนั้นก็คือ

  1. Main Process
  2. Renderer Process

 

โดยเจ้า Main Process เนี่ยทําหน้าที่ก็คือ สร้างและจัดการ BrowserWindow instance และ event ต่างๆๆของโปรแกรมนั้นเอง โดยMain process จะรองรับการทํางานของพวก GUI และ Low-level เพื่อป้องกัน memory leak นั้นเอง

ส่วนเจ้า Renderer Process รับหน้าที่ในการจัดการรัน UI ของ App เราในแต่ละหน้า (ซึ่งก็คือเอา  html,css,js มาแสดงผลนั้นเอง)

ข้างล่างเป็นภาพอธิบายถึง 2 process ว่าเจ้า process ไหนรับหน้าที่ทําอะไรบ้าง และมีอะไรอยู่ตรงกลางและใช้ร่วมกันได้

https://medium.com/cameron-nokes/deep-dive-into-electrons-main-and-renderer-processes-7a9599d5c9e2

แล้วยังงี้ถ้า renderer ทํางานเสร็จแล้ว หรือ main process ต้องการให้ renderer ทํางานอะไรบางอย่าง มันคุยกันยังไง??? HTTP Request หรอ?

คําตอบคือ Inter-process communication (IPC)

ทีนี้เราอาจจะไม่เคยนึกว่า process จะคุยกันยัง แต่จริงๆแล้ว process จะคุยกันด้วย IPC หรือ Inter process communcation ซึ่งเป็นวิธีเดียวกับ Chromium นั้นเอง ในรูปแบบของ asynchronous โดยจะเป็นการคุยกันระหว่าง renderer กับ main process เท่านั้น มันไม่สามารถคุยข้ามไปมาระหว่าง renderer และ renderer ได้เอง

เราเอามาใช้ทําไรได้อีก? เราสามารถนําจุดนี้มาสร้าง debug mode ได้ เช่นสั่งให้ application ทํางานอะไรบางอย่างเพื่อเช็คโปรแกรมว่ายังตอบสนองอยู่ได้ด้วย เช่น เราสร้าง IPC เพื่อให้กด shortcut บน keyboard เป็นต้น

 

https://github.com/OKStateACM/ElectronCodelab/blob/master/04%20-%20Interprocess%20Communication.md

ตัวอย่าง IPC code

สิ่งที่ทําก็คือแค่เปิด channel ไว้รอรับ แล้วก็ส่งข้อมูลเมื่อ listener ถูก trigger นั้นเอง

https://coursetro.com/posts/code/122/Electron-IPC-Tutorial—Communication-within-your-Electron-App
https://coursetro.com/posts/code/122/Electron-IPC-Tutorial—Communication-within-your-Electron-App

เราจะเทส ElectronJs ยังไง

รู้จัก Electron JS framework ไปแบบ high level แล้วว่ามันคือ Node.js และ Chromium ที่ทําให้เราสามารถสร้าง Desktop Application ด้วย Html,JS และ CSS บน cross platform ได้

ทีนี้เมื่อเราทํา application เสร็จแล้วเราจะเขียนเทสยังไงละ ว่ามันทํางานได้ functionality ตามที่เราต้องการมั้ย?​ไม่ใช่ว่าส่งมอบไปแล้ว application พังซะงั้น

ซึ่งเจ้า Electron JS มีสิ่งนึงที่เรียกว่า Spectron ซึ่งเป็น electron module ที่ไว้ทํา E2E test …

จริงๆแล้วการทํา test electron js เราสามารถใช้ได้หลากหลายเพราะแค่เรา connect ไปที่ chromedriver debug port เราก็สามารถ access เข้าไปได้แล้ว แต่เหตุผลที่เราควรใช้ spectron ก็คือ มัน provide low-level ให้กับเราได้ เช่น access clipboard function เป็นต้น ซึ่งถ้าใช้ framework อื่นๆเราจะไม่สามารถ access พวกนี้ได้ และ จะไม่สามารถเทสได้ครบนั้นเอง

Spectron Architecture

ดังนั้นเราควรจะมารู้จัก Spectron กัน … Spectron สร้างขึ้นมาบน library ที่เรียกว่า WebdriverIO อีกที ซึ่งเป็น library ที่ไปจัดการกับ chromedriver ให้เราและก็ไปต่อกับ ElectronJS อีกที

ฟังแล้วอาจจะ งง ไปดู flow diagram ข้างล่างกันดีกว่า

จะเห็นว่า Spectron เรียกคําสั่งต่างๆไปที่ WebDriverIO แล้วหลังจากนั้นมันก็จะไปสั่งให้ Chromium ทํางานต่างๆๆตามที่เราต้องการผ่าน chromedriver อีกที 🙂

 

โดยถ้าดูจาก sequence diagram ข้างบนจะชัดเจนขึ้นคือ …. application.js ที่อยู่ใน Spectron ไป start chromedriver ก่อนแล้วก็เรียก WebdriverIO ไปต่อกับ chromedriver เพื่อได้ Browser Object ของ Webdrioverio กลับมา

ซึ่งเวลาเราเขียนเทสเนี้ย เราก็ต้องใช้ method ไหนทําไรก็คือต้องดูผ่านเจ้า browser object นี้นั้นแหละ ลิสคําสั่งของมันอยู่ที่นี้เลย

ปัญหาของ Spectron

ฟังดูดีทุกอย่างนะ แต่ทุกอย่างมี Pros กับ Cons เสมอ…

เวลาปกติที่เราเขียน test กันมาตลอดนะ เราใช้ผ่านสิ่งที่เรียกว่า Selenium Webdriver ที่นี้พวก function ต่างๆที่เราเรียกกันมาตลอดในนั้นนะ เจ้า selenium เป็นคนทําให้!

พอเราย้อนกลับขึ้นไปดู diagram ข้างบนทั้งสองภาพจะเห็นว่าไม่มี selenium เลย…. นั้นแปลว่าเราไปต่อ chromedriver ตรงๆๆจร้า (ในเคสของ spectron นะ ไม่ได้ใช้ test runner ของ wdio) … พอต่อตรงๆๆปัญหาคือ chromedriver ไม่ได้ support complex action หลายอย่างเลย เช่น การ mousemove mousedown rightclick บลาๆๆ เราสามารถสั่ง command ได้ แต่มันจะ errror แบบ action command not implemented yet !!! บ้ามากๆ

ซึ่งเจ้า webdriverio team บอกเองว่าเราไม่ได้รับผิดชอบทําส่วนนั้นนนให้ อยากใช้ให้รอ chromedriver team เอาน้าา ….. เอิ่มม ยังงี้ก็ได้หรอ

แปลว่าถ้าเรามาดู git log ของ chromedriver กันจะเห็นว่ามันพึ่งทําเสร็จใน

ChromeDriver 76.0.3809.12 (2019-06-07)
https://chromium.googlesource.com/chromium/src/+/master/docs/chromedriver_status.md

ครับ …. 🙁

ภาพข้างล่างคือ chromedriver status ของ spectron version 4.x.x จะเห็นว่าที่วงไว้ยังบอกว่าไม่เสร็จเลย

แต่ chromedriver พึ่งทําเสร็จตอนปี 2019 เอง….

แปลอีกอย่างก็คือ……ถ้าเราใช้ “Spectron” เราจะไม่สามารถใช้งาน “complex action” ใน test code เราได้นั้นเอง…. อึ้งกันไปเลย!!!

วิธีแก้ก็มีนะเราก็ต้องใน Selenium Webdriver ควบคู่ไปด้วยด้วยการขโมย session นั้นเอง 🙂 เทคนิคๆ

วิธี Debug ใน VS code

อันนี้เคยเขียนไปแล้ว บทความนี้เลย วิธีการ Debug ด้วย VS code ใช้วิธีนี้ตามได้เลย

มาถึงตอนจบด้วยการรันเทสด้วย spectron

เจ้า Spectron เนี่ยไม่ใชj test framework หรือ assertion framework ด้วย มันเพียงเป็นตัวจุด starter เพื่อให้ทําการเทสกับ electron ได้

ดังนั้นพอมาถึงการทําเทสจริงๆ เราก็จะมาใช้ JS test framework ยอดฮิตอย่าง mocha และ assertion library อย่าง chai นั้นเอง (และเนื่องจากเรา test JS ดังนั้นส่วนใหญ่จะเป็น asyc ดังนั้น assertion ยอดนิยมของเราก็ไม่พ้น chai-as-promised นั้นเอง)

จบด้วย report อย่าง allure report ตามแบบฉบับพื้นฐานเลย

แค่นี้ก็จบละการเขียน test กับ electron js หรือสรุปง่ายๆคือ เราเอา spectron มาสร้าง connection ไปที่ app แล้วก็ใช้พวก test framework, assertion framework & report เพื่อทําการเทสนั้นเอง

สรุปแล้วว

ภาพรวมของ electron js และ การทําเทสด้วย spectron ก็จะประมาณนี้ ที่เหลือก็แค่ลุยเขียนโค้ดเทส 🙂

ส่วนปัญหาที่ต้องเจอในการทําเทสแน่ๆก็จะตามด้านบนเลยคือเรื่องของ chromedriver แน่นอนนน

Leave a Reply

avatar

This site uses Akismet to reduce spam. Learn how your comment data is processed.