Cet article vous présente principalement les informations pertinentes sur la mise en œuvre d'un service de comparaison de pixels basé sur casperjs et similar.js. L'article le présente en détail à travers un exemple de code. Il a une certaine valeur d'apprentissage de référence pour l'étude ou le travail de chacun. est nécessaire Amis, étudions ensemble.
Avant-propos
Cette fois, je partage un service de nœud qui fournit une comparaison de pixels entre les brouillons de conception et les pages frontales, dans le but de fournir des tests ou le personnel de première ligne passe lui-même un test auxiliaire. Croyez-moi, lors de la comparaison au niveau des pixels, le degré de restauration du projet de conception sur la page Web deviendra immédiatement apparent. Pas grand chose à dire ci-dessous, jetons un œil à l’introduction détaillée.
Aperçu de l'effet
Connaissances pré-requises
Les deux bibliothèques suivantes sont utilisées cette fois comme outils auxiliaires :
casperjs : écrit sur la base de PhantomJS. Il fournit un navigateur sans interface en interne. En termes simples, vous pouvez l'utiliser pour compléter l'opération de simulation d'un humain pour faire fonctionner le navigateur sous forme de code, ce qui implique divers événements de souris et de nombreuses autres fonctions. Cette fois, il est principalement utilisé. est livré avec une fonction de capture d'écran.
resemble.js : outil de comparaison de pixels d'image. La simple compréhension de la méthode appelante est que deux images sont transmises et qu'une image composite est renvoyée avec des paramètres de comparaison tels que la différence, etc. L'idée de base de la mise en œuvre peut être comprise comme la conversion de l'image en toile, l'obtention de ses pixels d'image, puis la comparaison de chaque pixel.
Nous devrions donc déjà avoir une grande idée pour l'ensemble du service, qui consiste à utiliser casperjs pour accéder à un site Web afin d'intercepter une page, puis à la comparer avec le dessin de conception pour obtenir le résultat.
Idée générale
À partir de l'image ci-dessus, nous devrions être en mesure de trier un processus approximatif :
Recevoir le brouillon de l'image de conception ainsi que l'adresse du site Web et les informations sur le nœud qui doivent être interceptées depuis le page frontale
Enregistrez le brouillon de conception dans le dossier images
Ouvrez le sous-processus, démarrez casperjs et terminez l'interception de le site Web cible
Après l'interception, demandez au form.html de remplir les informations d'adresse de l'image et de les retransmettre au serveur
Le serveur obtient les informations sur l'image et compare l'image interceptée avec le brouillon de conception via similarjs
Les résultats sont renvoyés à la page frontale
L'un des problèmes que certaines personnes peuvent remarquer est le suivant : pourquoi les informations ne peuvent-elles pas être directement récupérées lors de la prise d'une capture d'écran du site Web cible dans casperjs ? via le formulaire ?
R : Tout d'abord, je ne connais pas grand-chose à Casperjs et à Node. Ce que je comprends, c'est que tout d'abord, Casperjs n'est pas un module de noeud, il s'exécute dans le système d'exploitation que je n'ai pas encore. J'ai découvert comment créer un lien avec Casperjs dans Casperjs. S'il existe un moyen de communiquer avec le service de nœud, dites-le-moi, car je ne connais vraiment pas grand-chose à Casper ! Deuxièmement, comme la communication ne peut pas être établie, je ne peux que recourir à la meilleure solution, ouvrir rapidement une page de formulaire que j'ai écrite via Casper, remplir les informations de l'image et la renvoyer au serveur. Cela peut compléter la demande initiale. Il y a donc l’opération ci-dessus from.html.
Détails d'implémentation
Implémentation d'un serveur statique simple
Parce que cela implique le retour de index.html et form.html pages , nous devons donc implémenter un serveur statique super simple. Le code est le suivant :
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", "wmv": "video/x-ms-wmv", "xml": "text/xml" } function sendFile(filePath, res) { fs.open(filePath, 'r+', function(err){ //根据路径打开文件 if(err){ send404(res) }else{ let ext = path.extname(filePath) ext = ext ? ext.slice(1) : 'unknown' let contentType = MIME_TYPE[ext] || "text/plain" //匹配文件类型 fs.readFile(filePath,function(err,data){ if(err){ send500(res) }else{ res.writeHead(200,{'content-type':contentType}) res.end(data) } }) } }) }
Analysez le formulaire et stockez l'image dans le dossier images
const multiparty = require('multiparty') //解析表单 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)) ... } })
Lisez le contenu du fichier en créant un flux lisible, puis écrivez-le dans le chemin spécifié à travers le tuyau L'image téléchargée sera enregistrée.
Exécuter casperjs
const { spawn } = require('child_process') spawn('casperjs', ['casper.js', filename, captureUrl, selector, id]) casperjs.stdout.on('data', (data) => { ... })
Vous pouvez créer un sous-processus pour démarrer casperjs via spawn, vous pouvez également utiliser exec, etc.
Prenez une capture d'écran et soumettez les données à form.html
const system = require('system') const host = 'http://10.2.45.110:3033' const casper = require('casper').create({ // 浏览器窗口大小 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('正在截图请稍后') this.captureSelector('./images/casper'+ id + time +'.png', selector) }) casper.then(function() { casper.start(host + '/form.html', function() { this.fill('form#contact-form', { 'diff': './images/casper'+ id + time +'.png', 'point': './images/' + fileName, 'id': id }, true) }) }) casper.run()
Le code est relativement simple. Le processus principal consiste à ouvrir une page puis à la transmettre. votre opération, et enfin exécutez run. Au cours de ce processus, je ne savais pas trop comment communiquer avec le service de nœud, j'ai donc choisi d'ouvrir une autre page. . Si vous souhaitez étudier en profondeur, vous pouvez consulter le site officiel de casperjs qui est très détaillé !
Effectuez une comparaison de pixels et renvoyez des données via similar.js
function complete(data) { let imgName = 'diff'+ new Date().getTime() +'.png', imgUrl, analysisTime = data.analysisTime, misMatchPercentage = data.misMatchPercentage, resultUrl = './images/' + imgName fs.writeFileSync(resultUrl, data.getBuffer()) imgObj = { ... } let resEnd = resObj[id] // 找回最开始的res返回给页面数据 resEnd.writeHead(200, {'Content-type':'application/json'}) resEnd.end(JSON.stringify(imgObj)) } let result = resemble(diff).compareTo(point).ignoreColors().onComplete(complete)
这其中涉及到了一个点,即我现在所得到的结果要返回给最初的请求里,而从一开始的请求到现在我已经中转了多次,导致我现在找不到我最初的返回体res了。想了很久只能暂时采用了设定全局对象,在接收最初的请求后将请求者的ip和时间戳设定为唯一id存为该对象的key,value为当前的res。同时整个中转流程中时刻传递id,最后通过调用resObj[id]来得到一开始的返回体,返回数据。这个方法我不认为是最优解,但是鉴于我现在想不出来好方法为了跑通整个服务不得已。。如果有新的思路请务必告知!!
部署
安装PhantomJS(osx)
官网下载: phantomjs-2.1.1-macosx.zip
解压路径:/User/xxx/phantomjs-2.1.1-macosx
添加环境变量:~/.bash_profile 文件中添加
export PATH="$PATH:/Users/xxx/phantomjs-2.1.1-macosx/bin"
terminal输入:phantomjs --version
能看到版本号即安装成功
安装casperjs
brew update && brew install casperjs
安装resemble.js
cnpm i resemblejs //已写进packjson可不用安装 brew install pkg-config cairo libpng jpeg giflib cnpm i canvas //node内运行canvas
node服务
git clone https://github.com/Aaaaaaaty/gui-auto-test.git cd gui-auto-test cnpm i cd pxdiff nodemon server.js
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!