Heim >Web-Frontend >js-Tutorial >Implementieren Sie einen Pixelvergleichsdienst basierend auf casper.js und ähnelt.js

Implementieren Sie einen Pixelvergleichsdienst basierend auf casper.js und ähnelt.js

小云云
小云云Original
2018-01-11 09:04:051569Durchsuche

Dieses Mal teile ich einen Knotendienst, der einen Pixelvergleich zwischen Designentwürfen und Front-End-Seiten ermöglicht. Er soll einen Hilfstest für Tester oder Front-End-Mitarbeiter selbst durchführen. Glauben Sie mir, beim Vergleich auf Pixelebene wird sofort ersichtlich, wie gut der Designentwurf auf der Webseite wiederhergestellt ist. Im Folgenden gibt es nicht viel zu sagen. Werfen wir einen Blick auf die ausführliche Einführung. Ich hoffe, sie kann allen helfen.

Effektvorschau


Vorkenntnisse

Die folgenden zwei Bibliotheken werden dieses Mal als Hilfswerkzeuge verwendet:

  • casperjs: geschrieben basierend auf PhantomJS. Es stellt intern einen schnittstellenlosen Browser bereit, mit dem Sie den Vorgang der Simulation eines menschlichen Browsers in Form von Code durchführen können, der verschiedene Mausereignisse und viele andere Funktionen umfasst verfügt über eine Screenshot-Funktion.

  • resemble.js: Bildpixel-Vergleichstool. Das einfache Verständnis der aufrufenden Methode besteht darin, dass zwei Bilder übergeben werden und ein zusammengesetztes Bild mit Vergleichsparametern wie Differenz usw. zurückgegeben wird. Die Grundidee der Implementierung kann darin bestehen, das Bild in eine Leinwand umzuwandeln, seine Bildpixel zu erhalten und dann jedes Pixel zu vergleichen.

Wir sollten also bereits eine große Idee für den gesamten Dienst haben, die darin besteht, mit casperjs eine Website einzugeben, um eine Seite abzufangen, und sie dann mit der Entwurfszeichnung zu vergleichen, um die zu erhalten Ergebnis.

Gesamtidee

Aus dem obigen Bild sollten wir in der Lage sein, einen groben Prozess zu bestimmen:

  • Vom Frontend Die Seite empfängt die Designentwurfsbilder sowie die Website-Adresse und Knoteninformationen, die abgefangen werden müssen

  • Speichern Sie den Designentwurf im Bilderordner

  • Öffnen Sie den Unterprozess, starten Sie casperjs und schließen Sie das Abfangen der Zielwebsite ab

  • Fordern Sie nach dem Abfangen form.html auf, um die Bildadressinformationen einzugeben und erneut Übertragen Sie es zurück an den Server

  • Der Server erhält die Bildinformationen und vergleicht den Screenshot mit dem Entwurfsentwurf über ähnelnjs

  • Das Ergebnis wird gesendet zurück zur Startseite

Hier liegt ein Problem vor. Jemand hat es vielleicht bemerkt: Warum kann ich die Informationen nicht direkt an den Server zurücksenden, nachdem ich einen Screenshot des Ziels gemacht habe? Website in casperjs? Stattdessen öffne ich eine Formularseite, um die Informationen über das Formular zu übermitteln?

A: Erstens weiß ich nicht viel über casperjs und node. Erstens ist casperjs kein Knotenmodul, das ich noch nicht habe Ich habe herausgefunden, wie man in casperjs einen Link mit casperjs erstellt. Wenn es eine Möglichkeit gibt, mit dem Knotendienst zu kommunizieren, sagen Sie es mir bitte, da ich wirklich nicht viel über casper weiß! Zweitens kann ich, da keine Kommunikation hergestellt werden kann, nur auf die nächstbeste Lösung zurückgreifen: Öffnen Sie schnell eine Formularseite, die ich über Casper geschrieben habe, geben Sie die Bildinformationen ein und senden Sie sie an den Server zurück. Dadurch kann die ursprüngliche Anfrage abgeschlossen werden. Es gibt also die obige Operation from.html.

Implementierungsdetails

Implementierung eines einfachen statischen Servers

Da es sich um die Rückgabe von index.html- und form.html-Seiten handelt, ist dies erforderlich Implementieren Sie einen supereinfachen statischen Server. Der Code lautet wie folgt:

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)
    }
   })
  }
 })
}

Parsen Sie das Formular und speichern Sie die Bilder im Bilderordner

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))
   ...
  } 
 })

Lesen Sie den Dateiinhalt, indem Sie einen lesbaren Stream erstellen und dann Schreiben Sie es in die Die hochgeladenen Bilder können unter dem angegebenen Pfad gespeichert werden.

Casperjs ausführen

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

Sie können einen Unterprozess erstellen, um Casperjs über Spawn zu starten. Sie können auch Exec usw. verwenden.

Machen Sie einen Screenshot und senden Sie die Daten an 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()

Der Hauptvorgang besteht darin, eine Seite zu öffnen und dann Ihren Vorgang zu übergeben und schließlich Execute ausführen. Während dieses Vorgangs wusste ich nicht genau, wie ich mit dem Knotendienst kommunizieren sollte, also entschied ich mich, eine andere Seite zu öffnen. . Wenn Sie sich eingehend informieren möchten, können Sie sich die offizielle Website von casperjs ansehen, die sehr detailliert ist!

Pixelvergleich durchführen und Daten über ähnelt.js zurückgeben

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)

Dabei geht es um einen Punkt, das heißt, die Ergebnisse, die ich jetzt erhalte, müssen an die ursprüngliche Anfrage zurückgegeben werden. und ich wurde von der ersten Anfrage bis jetzt viele Male weitergeleitet, was dazu führte, dass ich meinen ursprünglichen Rückgabetext nicht mehr finden kann. Nachdem ich lange darüber nachgedacht habe, kann ich das globale Objekt nur vorübergehend festlegen, nachdem ich die erste Anfrage erhalten habe, die IP und den Zeitstempel des Anforderers als eindeutige ID festlegen und als Schlüssel des Objekts speichern, und der Wert ist der aktuelle res. Gleichzeitig wird die ID während des gesamten Übertragungsprozesses ständig übergeben, und schließlich werden der anfängliche Rückgabetext und die Daten durch Aufrufen von resObj[id] abgerufen. Ich glaube nicht, dass diese Methode die optimale Lösung ist, aber da mir jetzt keine gute Möglichkeit einfällt, muss ich sie machen, um den gesamten Dienst durchzugehen. . Wenn Sie neue Ideen haben, lassen Sie es uns bitte wissen! !

Bereitstellung

PhantomJS (osx) installieren

Offizieller Website-Download: phantomjs-2.1.1-macosx.zip

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

Umgebungsvariablen hinzufügen: Fügen Sie

export PATH="$PATH:/Users/xxx/phantomjs- im ~/ hinzu. bash_profile file 2.1.1-macosx/bin"

Terminaleingabe: phantomjs --version

Wenn Sie die Versionsnummer sehen können, ist die Installation erfolgreich

Casperjs installieren

brew update && brew install casperjs

Ähnliche.js installieren

cnpm i resemblejs //已写进packjson可不用安装
brew install pkg-config cairo libpng jpeg giflib
cnpm i canvas //node内运行canvas

Knotendienst

git clone https://github.com/Aaaaaaaty/gui-auto-test.git
cd gui-auto-test
cnpm i
cd pxdiff
nodemon server.js

Öffnen Sie http://localhost :3033/index.html

Verwandte Empfehlungen:

Zusammenfassung von Pixelanzeigeproblemen in Tutorials zur mobilen Entwicklung_Erfahrungen und Tipps_Webseitenproduktion

CSS-Beispielcode zur Implementierung eines 0,5-Pixel-Rahmens

Detaillierte Einführung in Auflösung, Pixel und PPI

Das obige ist der detaillierte Inhalt vonImplementieren Sie einen Pixelvergleichsdienst basierend auf casper.js und ähnelt.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn