Puppeteer ควบคุมและบันทึกการใช้งาน chrome สำหรับ UI testing

Puppeteer เป็น Node library ที่มีชุดของ API สำหรับการควบคุม Google Chrome หรือ Chromium ผ่าน DevTool protocol ทำงานในรูปแบบ headless โดย default แต่สามารถกำหนดให้ทำงานแบบ full (non-headless) Chrome ได้  ที่สำคัญไม่ต้องทำงานผ่าน Web Driver อีกต่อไป puppeteer สามารถทำงานได้ทุกอย่างที่สามารถทำได้โดย manual บน browser เช่น สร้าง screenshots และ PDFs ของ page Automate form submission UI testing keyboard input การติดตั้ง Puppeteer การติดตั้ง Puppeteer เพื่อใช้งานใน project สามารถทำได้ผ่านทาง NPM โดยใช้คำสั่ง npm i puppeteer เมื่อทำการติดตั้ง Puppeteer จะทำการ downloads Chromium version ล่าสุดซึ่งสามารถทำงานร่วมกับ api ได้อย่างสมบูรณ์ (ประมาณ 170 Mb สำหรับ Mac, 282 Mb สำหรับ Linux และ 280 Mb สำหรับ Windows) ถ้าไม่ต้องการ download Chromium ในระหว่างการติดตั้ง สามารถยกเลิกได้โดยการกำหนดค่า “PUPPETEER_SKIP_CHROMIUM_DOWNLOAD”  environment variables การใช้งาน Puppeteer Puppeteer API ให้ความสามารถในการสร้าง instance ของ  browser, เปิด webpage และบันทึก screenshot โดยสร้าง file ชื่อ example.js และเขียน code ดังนี้ เรียกใช้งาน script  บน command line โดยใช้คำสั่ง node example.js Puppeteer กำหนด default ขนาดของ page ที่ 800 x 600px  และสามารถเปลี่ยน page size โดยใช้ page.setViewport() ซึ่งสามารถศึกษาเพิ่มเติมการใช้งาน Puppeteer API ได้ที่ https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md ผลของการ run script  จะทำการบันทึก screenshot ของ https://example.com ไปที่ file “example.png” จะเห็นว่าในระหว่างการ run script ไม่ได้ปรากฎ browser ขึ้นมาให้เห็น เนื่องจากโดยค่า default จะทำงานเป็น headless mode แต่สามารถเปลี่ยนการทำงานได้โดยกำหนด headless = false หากต้องการดูการทำงาน const browser = await puppeteer.launch({ headless: true }); // default is true   อ้างอิง https://github.com/GoogleChrome/puppeteer/

Read More »

Visual test automation : Appraise test page

จากบทความ Visual test automation ที่ได้กล่าวถึง Appraise ที่ใช้สำหรับทำการทดสอบการแสดงผลแบบอัตโนมัติในเบื้องต้น ตั้งแต่การติดตั้ง ตัวอย่าง test page, test fixture การเรียกใช้งานการทดสอบ และผลการทดสอบ บทความนี้จะมาลงรายละเอียดในการสร้าง test page Creating test pages Appraise สามารถกำหนดรูปแบบข้อกำหนดการทดสอบสำหรับการทดสอบส่วนแสดงผลได้ไม่ยุ่งยาก โดย Appraise จะทำการอ่านข้อมูลนำเข้า และ ผลลัพธ์ที่คาดหวัง จาก file ที่เขียนในรูปแบบ Markdown แล้วส่งต่อให้กับระบบทำการทดสอบ จากนั้นจะบันทึกภาพการแสดงผลที่เกิดขึ้น เปรียบเทียบภาพการแสดงผลที่ได้จริงกับผลลัพธ์ที่คาดหวัง โดยมีสิ่งที่จำเป็นที่จะต้องกำหนดสำหรับการทดสอบ 3 ส่วน คือ input expect output fixture Input (parameters ของ example) input parameters อยู่ในรูปแบบ text JSON หรือ YAML  ในการกำนด input parameters สำหรับแต่ละการทดสอบหรือ example จะต้องกำหนด block ของ example และกำหนดชื่อให้กับ example ในส่วนเริ่มต้น block ในรูปแบบ example=”ชื่อ” จากรูปข้างต้น จะเห็นว่ามี example ชื่อ “first” ถูกกำหนดรูปแบบเป็น YAML ซึ่ง Appraise จะรู้ว่าจะนำข้อมูลไปได้อย่างไร ในแต่ละ test page สามารถมี eaxmple ได้มากกว่าหนึ่ง example โดยที่แต่ละ example จะต้องมีชื่อที่ไม่ซ้ำกัน ซึ่งจำเป็นในการใช้สำหรับเปรียบเทียบกับผลลัพธ์ที่คาดหวังด้วย Expect output ecpect output – ผลลัพธ์ที่คาดหวัง ซึ่งอยู่ในรูปแบบ file รูปภาพ .png  การกำหนดผลลัพธ์ที่คาดหวังใน test page ทำได้โดยระบุ ![ชื่อ example](ชื่อ file รูปภาพ .png ที่เป็นผลลัพธ์ที่คาดหวัง) ซึ่งจะอยู่ส่วนใดๆใน test page ก็ได้ ไม่ว่าจะอยู่ก่อน example input ก็ได้ โดยที่ความเชื่อมโยงระหว่าง input กับ expect output ก็คือชื่อของ example ที่กำหนดใน [] ในการสร้าง test page อาจจะไม่ต้องกำหนด expect output ก่อนก็ได้เช่นกัน เมื่อทำการ run test ครั้งแรก ผลที่ออกมาจะ failed เนื่องจากไม่ได้ระบุ expect output แต่สามารถที่จะบันทึกผลที่ได้จากการ run test ใช้เป็น expect output สำหรับการ run test ครั้งต่อไปได้ Fixture fixture คือส่วนของ code ที่ Apprise ใช้ในการเชื่อมต่อกับระบบที่จะทดสอบ รวมทั้งกำหนดการใช้งานและการประมวลผล input ในการทดสอบ โดยทั่วไป examples ที่เชื่อมโยงกันจะใช้ fixture เดียวกัน การกำหนด fixture ทำโดยการระบุ fixture =”ชื่อ fixture” ในส่วนของ header ของ example block จากรูปข้างต้น จะเห็นว่ามี example ชื่อ “first” มีการกำหนด fixture คือ “hello.js” จากตัวอย่าง fixture ด้านบน เป็น fixture ที่มีการสร้าง output page ออกมาโดยตรงโดยไม่ได้เชื่อมต่อกับระบบใดๆ ซึ่งในการใช้งานจริง จะต้องเชื่อมต่อกับระบบหรือส่วนที่จะทำการทดสอบจริงที่ทำการ render ผลลัพธ์ออกมา input

Read More »

Stencil : Decorators

Component Decorator แต่ละ Stencil component จะต้องขึ้นต้นด้วย @Component() decorator เสมอ โดย import มาจาก @stencil.core package ซึ่งภายใต้ @Component() decorator สามารถกำหนด tag name และ styleUrl ของ component import { Component } from ‘@stencil/core’; @Component({ tag: ‘todo-list’, styleUrl: ‘todo-list.scss’ }) export class TodoList { … } @Component() decorator ให้ความสามารถในการกำหนด CSS classes และ attributes บน componnet ที่สร้างโดยใช้ host option ดังนี้ import { Component } from ‘@stencil/core’; @Component({ tag: ‘todo-list’, styleUrl: ‘todo-list.scss’, host: { theme: ‘todo’, role: ‘list’ } }) เมื่อใช้งาน component ตัวนี้ ก็จะมีการกำหนดค่า class เป็น todo และกำหนด role attribute ให้อัตโนมัติ <todo-list class=’todo’ role=’list’></todo-list>   Prop Decorator @Prop() decorator ใช้ระบุ attribute หรือ properties สำหรับ element ที่ผู้พัฒนาสามารถกำหนดค่าให้กับ component นั้นได้  เนื่องจาก Children component จะไม่สามารถเข้าถึง properties หรือ reference ของ parent component ได้จึงใช้ Props ในการผ่านข้อมูลจาก parent มาสู่ child และเมื่อใดก็ตามที่ค่าของ Props เปลี่ยนแปลงจะทำให้ component ทำการ re-render type ของ Props ที่รองรับมีหลากหลาย ไม่ว่าจะเป็น number, string, boolean หรือแม้กระทั่ง Object หรือ Array import { Prop } from ‘@stencil/core’; … export class TodoList { @Prop() color: string; @Prop() favoriteNumber: number; @Prop() isSelected: boolean; @Prop() myHttpService: MyHttpService; } ภายใน function ใน TodoList class สามารถเรียกใช้งาน Props ผ่าน this operator logColor() { console.log(this.color) } สำหรับการใช้ภายนอก ใน HTML การกำหนดค่าทำได้โดย set ค่าให้ attributes ของ component tag โดยใช้ dash-case  เช่น Prop favoriteNumber ใช้ attribute favorite-number <todo-list color=”blue” favorite-number=”24″ is-selected=”true”></todo-list> สำหรับการใช้ใน JSX การกำหนดค่าทำได้โดย set ค่าให้ attributes ของ component tag โดยใช้

Read More »

Visual test automation

ในการพัฒนา software นั้น เรื่อง Look and Feel เป็นสิ่งที่สำคัญมาก ๆ software ที่ทำงานได้ดียังไม่พอ ต้องดูดีสวยงามและใช้งานง่ายอีกด้วย คำถามที่น่าสนใจคือ จะทำการทดสอบในส่วนของการแสดงผลอย่างไรบ้าง โดยปกติในการทำการทดสอบการแสดงผล จะใช้คนเป็นผู้ทดสอบ มานั่งดู มาใช้งาน แล้วพิจารณาและตัดสินว่า ถูกหรือไม่ ทำให้ต้องใช้เวลาและกำลังคนในการทดสอบค่อยข้างมาก เพราะว่าในส่วนของการแสดงผลนั้นมันยากมาก ๆ สำหรับการทดสอบ มีหลายสิ่งอย่างให้พิจารณา ยกตัวอย่างเช่น ในแต่ละ element แต่ละส่วนงานทำงานและแสดงผลได้อย่างถูกต้องแต่เมื่อนำมารวมกัน กลับทำงานไม่ถูกต้อง หรือ แสดงผลผิดพลาด การลดเวลาและต้นทุนในการทดสอบลงโดยใช้การทดสอบแบบอัตโนมัติ เป็นสิ่งจำเป็น และต้องมีเครื่องมือช่วย ในบทความนี้ขอแนะนำ Appraise ซึ่ง Appraise นั้นได้นำแนวทางของ Specification by Example มาใช้ นั่นหมายความว่า ในแต่ละ test case ต้องมี concrete example ที่ชัดเจน นำ test case เหล่านี้ไปทดสอบแบบอัตโนมัติ ทำการทดสอบด้วย Google Chrome Headless ซึ่งจะทำการ snapshot ส่วนที่ต้องการเป็นรูปภาพและเปรียบเทียบกับผลที่คาดหวังหรือไม่ ถ้าผลออกมาไม่ตรงกับที่คาดหวัง Appraise จะแสดงผลที่แตกต่างออกมาให้เห็น จากนั้นจะให้คนมา approve ว่าผลที่แตกต่างถูกหรือไม่ต่อไป ถ้าทำการยอมรับความแตกต่างก็จะบันทึกผลใหม่ให้ทันที ซึ่งง่ายต่อการดูแลรักษา test case อย่างมาก เริ่มต้นการใช้งาน Appraise ทำการติดตั้ง Appraise ด้วย NPM npm install appraise -g จะทำการติดตั้ง Appraise เป็น global command line uitlity อย่างไรก็ตาม สามารถติตั้งเป็นแบบ NPM package dependency โดยใช้ NPM script เรียกใช้ commamd line ก็ได้เช่นกัน สร้าง test page เริ่มต้นสร้าง folder “examples” เป็นที่เก็บ test page  (default folder สำหรับเก็บ test page ของ Appraise คือ “examples”)  Appraise ใช้  Github-flavoured Markdown syntax  ในการประมวลผล test page สร้าง file : hello-world.md ใน folder “examples” และเพิ่มข้อความดังนี้ This paragraph is just an intro, it will be ignored for testing ~~~yaml example=”first” fixture=”hello.js” color: blue ~~~ สร้าง test fixture test fixture ใช้สำหรับ Appraise สำหรับประมวลผล example ไปเป็น test result โดยสร้าง file : hello.js ใน folder “examples”และเพิ่ม code ดังนี้ ทำการ run ทดสอบ ทดสอบโดยใช้คำสั่ง appraise run ซึ่งจะได้ผลดังนี้ Appraise บันทึกผลการทดสอบไว้ใน folder “results” ซึ่งได้ผลการทดสอบ file : result/hello-world.htm ดังนี้ จะเห็นได้ว่าผลการทดสอบ failed เนื่องจาก test case นี้ยังไม่ได้กำหนด expected result หรือผลที่คาดหวัง อย่างไรก็ตาม ถ้าพิจารณาผลการทำงานว่าใช้ได้ Appraise มีทางเลือกให้สามารถ capture ผลเพื่อใช้ในการทดสอบครั้งต่อไป โดยทำการ approve ผลการทำงานนี้ก่อนเพื่อทำการยอมรับผลนี้ ด้วยคำสั่ง appraise approve –page “hello-world” Appraise จะทำการบันทึกผลเป็นรูปภาพลงใน 

Read More »

Stencil : Web component compiler

Stencil เป็น compiler ที่ทำหน้าที่สร้าง standards-based web component (custom element) ซึ่งรวบรวมแนวคิดที่ดีของ framework ต่างๆที่ได้รับความนิยมสูง มาไว้ใน component โดย build-time tool ที่ใช้งานง่าย เช่น Virtual DOM Async rendering (inspired by React Fiber) Reactive data-binding TypeScript JSX web component ที่ได้จาก Stencil เป็น standards-based web component ทำให้สามารถใช้งานร่วมกับ framework ต่างๆที่ได้รับความนิยม และสามารถใช้ได้โดยไม่มี framework ก็ได้ จากเดิมเมื่อพัฒนาด้วย framework หนึ่งแล้ว ไม่สามารถนำไปใช้ร่วมกับ framework อื่นได้ Stencil มี APIs เช่น Virtual DOM, JSX, และ async rendering  ที่ทำให้สามารถพัฒนา web component ที่ทำงานได้เร็ว มีประสิทธิภาพดีกว่า และสร้างได้ง่ายกว่าเมื่อเปรียบเทียบกับการเขียน custom element โดยตรงโดยไม่ใช้ Stencil  และใน Stencil ยังมี small dev server พร้อมความสามารถ live reload อยู่ด้วย เริ่มต้นสร้าง project กับ Stencil การสร้าง component ทำได้โดยเริ่มต้นจาก component starter ดังนี้ git clone https://github.com/ionic-team/stencil-component-starter my-component cd my-component git remote rm origin npm install จากนั้น ถ้าต้องการ start  live-reload server สำหรับการพัฒนา ให้ใช้คำสั่ง npm start Updating Stencil ถ้าต้องการ update Stencil เป็น version ล่าสุดให้ใช้คำสั่ง npm install @stencil/core@latest –save-exact Stencil components component ถูกสร้างโดยการสร้าง file .tsx ใน “src/components” directory เขียน component ด้วย JSX และ Typescript  ซึ่ง component ที่สร้างมาจาก component starter คือ my-component.tsx import { Component, Prop } from ‘@stencil/core’; @Component({ tag: ‘my-first-component’, styleUrl: ‘my-first-component.scss’ }) export class MyComponent { @Prop() name: string; render() { return (My name is {this.name}); } } เมื่อ compile แล้วเสร็จ สามารถนำ component ไปใช้ใน HTML page ได้เช่นเดียวกับ tag อื่นๆ Web Components จะต้องมี “-” ภายใน tag (“myFirstComponent” เป็นชื่อที่ไม่สามารถใช้งานได้) <my-first-component name=”Max”></my-first-component> เมื่อเปิดผ่าน browser จะแสดงผล My name is Max

Read More »