Detailed description of a pixel comparison Service Based on casperjs and resemble. js,

Source: Internet
Author: User
Tags install brew

Detailed description of a pixel comparison Service Based on casperjs and resemble. js,

Preface

This article shares a node service that provides pixel comparison between the design draft and the front-end page. It aims to complete an auxiliary test for the testing or front-end personnel. Believe me, in the pixel-level comparison, the restoration degree of the design draft on the webpage will be highlighted at once. I won't talk much about it below. Let's take a look at the detailed introduction.

Effect Preview


Prerequisites

The following two libraries are used as auxiliary tools:

  • Casperjs: Based on PhantomJS. It provides a non-interface browser. In simple terms, you can use it to perform operations on the browser by simulating people in the form of code, which involves various mouse events and many other functions, this time, we mainly use the features that come with it.
  • Resemble. js: image pixel comparison tool. The calling method is simply to pass in two graphs, return a synthetic diagram with comparison parameters such as the degree of difference. The basic idea is to convert an image into a canvas, get its image pixels, and then compare each pixel.

Therefore, we should already have the idea of accessing a website through casperjs to intercept a page, and then compare it with the design drawing to get the result.

Overall Thinking

We should be able to organize a rough process:

  • Receiving design draft images and the website addresses and node information to be captured from the front-end page
  • Save the design draft to the images folder
  • Start the sub-process, start casperjs, and complete the interception of the target website
  • After receiving the screenshot, request form.html to fill in the image address information and return it back to the server.
  • The server obtains image information and compares the screenshot with the design draft through resemblejs.
  • Result returned to front-end page

One of these problems may be noticed: Why can't the target website be directly transmitted back to the server in casperjs, instead, I chose to open a form page and submit information in the form of a form?

A: First of all, I don't know much about casperjs and node. I understand that casperjs is not a node module and runs in the operating system, I still haven't found out how to establish communication with the node service in casperjs. If you have any way, please let me know, because I really don't know casper! Secondly, because communication cannot be established, I can only go back to the next step. By using casper, I can quickly open a form page that I have written and fill in the image information and send it back to the server. In this way, I can fulfill my initial appeal. In this case, the from.html operation is performed.

Implementation Details

Implement a simple static Server

To return the index.html and form.html pages, you need to implement a super simple static server. The Code is as follows:

Const MIME_TYPE = {"css": "text/css", "gif": "image/gif", "html": "text/html", "ico ": "image/x-icon", "jpeg": "image/jpeg", "jpg": "image/jpg", "js": "text/javascript ", "json": "application/json", "pdf": "application/pdf", "png": "image/png", "svg ": "image/svg + xml", "swf": "application/x-shockwave-flash", "tiff": "image/tiff", "txt ": "text/plain", "wav": "audio/x-wav", "wma": "audio/x-ms-wma", "wm V ":" video/x-ms-wmv "," xml ":" text/xml "} function sendFile (filePath, res) {fs. open (filePath, 'r + ', function (err) {// open the file if (err) {send404 (res)} else {let ext = path according to the path. extname (filePath) ext = ext? Ext. slice (1): 'unknown 'let contentType = MIME_TYPE [ext] | "text/plain" // matches the file type fs. readFile (filePath, function (err, data) {if (err) {send500 (res)} else {res. writeHead (200, {'content-type': contentType}) res. end (data )}})}})}

Parse the form and store the image in the images folder

Const multiparty = require ('multiparty ') // parse the form let form = new multiparty. form () form. parse (req, function (err, fields, files) {let filename = files ['file'] [0]. originalFilename, targetPath = _ dirname + '/images/' + filename, if (filename) {fs. createReadStream (files ['file'] [0]. path ). pipe (fs. createWriteStream (targetPath ))...}})

You can create a readable stream to read the file content, and write it to the specified path through pipe to save the uploaded image.

Run casperjs

const { spawn } = require('child_process')spawn('casperjs', ['casper.js', filename, captureUrl, selector, id])casperjs.stdout.on('data', (data) => { ...}) 

Through spawn, you can create sub-processes to start casperjs, and you can also use exec.

Submit data to form.html

Const system = require ('system') const host = 'HTTP: // 10.2.45.110: 3033 'const casper = require ('casper '). create ({// browser window size viewportSize: {width: 1920, height: 4080}) const fileName = decodeURIComponent (system. args [4]) const url = decodeURIComponent (system. args [5]) const selector = decodeURIComponent (system. args [6]) const id = decodeURIComponent (system. args [7]) const time = new Date (). getTime () casper. start (url) casper. then (function () {console. log ('Please wait a while later ') this. captureSelector ('. /images/casper '+ id + time interval '.png', selector)}) casper. then (function () {casper. start (host + '/form.html', function () {this. fill ('form # contact-form', {'dir ':'. /images/casper '+ id + time interval '.png', 'point ':'. /images/'+ fileName, 'id': id}, true)}) casper. run ()

The code is still relatively simple. The main process is to open a page, input your operations in then, and finally execute run. In this process, I do not know how to communicate with the node service, so I chose to open another page .. For more information, see the official casperjs website!

Use resemble. js to compare pixels and return data

Function complete (data) {let imgName = 'diff '+ new Date (). getTime () pai'.png ', imgUrl, analysisTime = data. analysisTime, misMatchPercentage = data. misMatchPercentage, resultUrl = '. /images/'+ imgName fs. writeFileSync (resultUrl, data. getBuffer () imgObj = {...} let resEnd = resObj [id] // retrieve the initial res and return it to the page data resEnd. writeHead (200, {'content-type': 'application/json'}) resEnd. end (JSON. stringify (imgObj)} let result = resemble (diff ). compareTo (point ). ignoreColors (). onComplete (complete)

This involves a point, that is, the results I get now are returned to the initial request, and I have transitioned many times from the beginning to now, as a result, I cannot find my initial returned body res. After thinking for a long time, you can only temporarily use a set global object. After receiving the initial request, set the requester's ip address and timestamp to a unique id and save it as the key of the object, value is the current res. At the same time, the id is passed during the entire transfer process, and the first response body is returned by calling resObj [id. I don't think this method is the optimal solution, but since I cannot come up with a good method, I have .. If you have any new ideas, please be sure to inform us !!

Deployment

Install PhantomJS (osx)

Download: phantomjs-2.1.1-macosx.zip

Unzip path:/User/xxx/phantomjs-2.1.1-macosx

Add environment variable :~ /Add to the. bash_profile File

Export PATH = "$ PATH:/Users/xxx/phantomjs-2.1.1-macosx/bin"

Terminal input: phantomjs -- version

The version number is successfully installed.

Install casperjs

brew update && brew install casperjs

Install resemble. js

Cnpm I resemblejs // you do not need to install brew install pkg-config cairo libpng jpeg giflibcnpm I canvas/node to run canvas

Node service

git clone https://github.com/Aaaaaaaty/gui-auto-test.gitcd gui-auto-testcnpm icd pxdiffnodemon server.js

Open http: // localhost: 3033/index.html

The blog of the author of po is updated from time to time --

References

  • Install PhantomJS
  • Casperjs document
  • Resemble. js document

Summary

The above is all the content of this article. I hope the content of this article has some reference and learning value for everyone's learning or work. If you have any questions, please leave a message to us, thank you for your support.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.