이번에는 테스터나 프런트엔드 직원이 직접 보조 테스트를 완료할 수 있도록 디자인 초안과 프런트엔드 페이지 간의 픽셀 비교를 제공하는 노드 서비스를 공유합니다. 저를 믿으십시오. 픽셀 수준의 비교를 통해 웹 페이지의 디자인 초안이 복원된 정도는 즉시 명백해집니다. 아래에서는 별로 할 말이 없지만, 자세한 소개를 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.
효과 미리보기
Pre-knowledge
이번에는 다음 두 라이브러리가 보조 도구로 사용됩니다.
casperjs: PhantomJS를 기반으로 작성되었습니다. 내부적으로는 인터페이스가 없는 브라우저를 제공하는데, 간단히 말해서 다양한 마우스 이벤트와 기타 여러 기능이 포함된 브라우저를 코드 형태로 시뮬레이션하는 작업을 완료하는 데 사용할 수 있습니다. 스크린샷 기능이 제공됩니다.
resemble.js: 이미지 픽셀 비교 도구. 호출 방법을 간단히 이해하면 두 개의 이미지가 전달되고 차이 등의 비교 매개변수와 함께 합성 이미지가 반환된다는 것입니다. 기본 구현 아이디어는 이미지를 캔버스로 변환하고 이미지 픽셀을 얻은 다음 각 픽셀을 비교하는 것으로 이해될 수 있습니다.
그래서 우리는 이미 전체 서비스에 대한 큰 아이디어를 가지고 있어야 합니다. 즉, casperjs를 사용하여 웹 사이트에 들어가 특정 페이지를 가로채고 이를 디자인 도면과 비교하여 결과를 얻는 것입니다.
전체적인 아이디어
위의 그림을 통해 대략적인 과정을 정리할 수 있을 것입니다.
디자인 초안 이미지와 프론트 엔드에서 가로채야 할 웹 사이트 주소 및 노드 정보를 받습니다. page
디자인 초안 저장 이미지 폴더로 이동
하위 프로세스 시작, casperjs 시작, 대상 웹 사이트 차단 완료
차단 후 form.html을 요청하여 이미지 주소 정보를 다시 서버로 전송
서버에서 이미지를 받아 Likejs
결과를 프런트엔드 페이지로 다시 전송
일부 사람들이 알아차릴 수 있는 문제가 있습니다. 정보를 casperjs에서 대상 웹사이트의 스크린샷에 직접 복사할 수 없는 이유는 무엇입니까? 서버에 다시 전달하지만 양식을 통해 정보를 제출하기 위해 양식 페이지를 열도록 선택합니까?
A: 우선 저는 casperjs와 node에 대해 잘 모릅니다. 우선 casperjs는 운영 체제에서 실행되는 노드 모듈이 아니라는 점입니다. casperjs에서 노드 서비스와 통신을 설정합니다. 방법이 있으면 알려주시기 바랍니다. 왜냐하면 저는 캐스퍼에 대해 잘 모르기 때문입니다! 둘째, 통신이 이루어지지 않기 때문에 차선책으로 캐스퍼를 통해 작성한 양식 페이지를 빠르게 열고 이미지 정보를 입력한 후 서버로 다시 전송하면 초기 요청이 완료됩니다. 따라서 .html에서 위의 작업이 있습니다.
구현 내용
간단한 정적 서버 구현
index.html 및 form.html 페이지를 반환해야 하기 때문에 초간단 정적 서버 구현이 필요합니다. 코드는 다음과 같습니다.
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) } }) } }) }
양식을 구문 분석하고 이미지 폴더에 이미지를 저장합니다
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)) ... } })
읽을 수 있는 스트림을 생성하여 파일 내용을 읽은 다음 파이프를 통해 지정된 경로에 작성하여 업로드된 이미지를 저장합니다.
Run casperjs
const { spawn } = require('child_process') spawn('casperjs', ['casper.js', filename, captureUrl, selector, id]) casperjs.stdout.on('data', (data) => { ... })
spawn을 통해 casperjs를 시작하는 하위 프로세스를 만들 수 있고 exec 등을 사용할 수도 있습니다.
스크린샷을 찍어 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()
에 데이터를 제출하세요. 코드는 비교적 간단합니다. 주요 프로세스는 페이지를 연 다음 작업을 전달하고 마지막으로 실행을 실행하는 것입니다. 이 과정에서 노드 서비스와 통신하는 방법을 잘 몰라서 다른 페이지를 열기로 했습니다. . 더 깊이 있게 공부하고 싶다면 casperjs 공식 웹사이트를 방문해보세요. 매우 자세하게 설명되어 있습니다!
like.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로 설정하여 객체의 키로 저장하면 그 값이 현재 값이 됩니다. 입술. 동시에 전체 전송 과정에서 항상 id가 전달되며, 마지막으로 resObj[id]를 호출하여 초기 반환 본문과 데이터를 가져옵니다. 이 방법이 최적의 솔루션은 아니라고 생각하지만, 현재는 좋은 방법이 생각나지 않아서 전체 서비스를 실행하려면 이 방법을 해야만 합니다. . 새로운 아이디어가 있으면 알려주세요! !
Deployment
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"을 추가하세요
터미널 입력: phantomjs --version
버전 번호가 보이면, 설치가 성공적이었습니다
Casperjs 설치
brew update && brew install casperjs
like.js 설치
cnpm i resemblejs //已写进packjson可不用安装 brew install pkg-config cairo libpng jpeg giflib cnpm i canvas //node内运行canvas
node service
git clone https://github.com/Aaaaaaaty/gui-auto-test.git cd gui-auto-test cnpm i cd pxdiff nodemon server.js
http://localhost:3033/index.html
열기 관련 권장 사항:
모바일 개발 튜토리얼의 픽셀 표시 문제 요약_경험 및 팁_웹 페이지 제작
위 내용은 casper.js 및 like.js를 기반으로 픽셀 비교 서비스 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!