Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Percy Local Report Generation #5

Merged
merged 4 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,5 @@ dist

Report/
.DS_Store
Summary/
Summary/
.vscode
3 changes: 2 additions & 1 deletion bin/cli.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env node
require('dotenv').config()
const { Command } = require('commander');
const { ar } = require('date-fns/locale');
const { Generate,Summary } = require('../src');
Expand All @@ -7,7 +8,7 @@ const {endOfDay,startOfDay} = require('date-fns')

program.name('percy-report')
.description('Generate Percy Reports & Download Images Locally')
.version('0.0.1')
.version('0.0.2')

program.command('generate')
.description('Genetate Report')
Expand Down
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "percy-report",
"version": "0.0.1",
"version": "0.0.2",
"description": "Percy Report Generator",
"main": "index.js",
"scripts": {},
Expand All @@ -26,6 +26,7 @@
"chromedriver": "^105.0.0",
"commander": "^9.4.0",
"date-fns": "^2.29.3",
"dotenv": "^16.0.3",
"ejs": "^3.1.8"
},
"devDependencies": {
Expand Down
55 changes: 38 additions & 17 deletions src/generate.js
ansel2000 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

const { Parser } = require('./response-parser')
const { Axios } = require('axios')
const fs = require('fs')
Expand Down Expand Up @@ -27,6 +28,7 @@ module.exports.Generate = async function (config) {
throw res.data
}
})
const isApp = buildDetails['data']['attributes']['type'] == 'app'
while (buildDetails.data && buildDetails.data.attributes.state !== 'finished') {
console.log("Waiting for build to complete on Percy...")
await wait(30000)
Expand All @@ -41,6 +43,7 @@ module.exports.Generate = async function (config) {
throw new Error("Build Failed with an Error on Percy Server. Please check your percy dashboard for more information.")
}
}

console.log(`Generating report for Build ID ${buildId}`)
let snapshotsData = await axios.get(`/snapshots?build_id=${buildId}`, { responseType: 'json' }).then((res) => {
if (res.status == 200) {
Expand All @@ -64,7 +67,8 @@ module.exports.Generate = async function (config) {
unreviewedSnapshots: 0,
widths: [],
browsers: [],
projectURL : projectURL,
devices: [],
projectURL: projectURL,
buildNumber: buildDetails['data']['attributes']['build-number'],
projectName: projectName
}
Expand All @@ -79,13 +83,29 @@ module.exports.Generate = async function (config) {
let base = images['base'] = getComparisonImage(comp, 'base-screenshot')
let head = images['head'] = getComparisonImage(comp, 'head-screenshot')
let diff = images['diff'] = getComparisonImage(comp, 'diff-image')
let browser = getComparisonBrowser(comp)
let compTag;
if (isApp) {
let device = getComparisonDevice(comp)
compTag = device.name
if(!report.devices.includes(device.name)){
report.devices.push(device.name)
}
} else {
let browser = getComparisonBrowser(comp)
compTag = device.nam
if (!report.browsers.includes(browser.name)) {
report.browsers.push(browser.name)
}
if (!report.widths.includes(comparison['width'])) {
report.widths.push(comparison['width'])
}
}
if (downloadImages) {
['base', 'head', 'diff'].forEach((val) => {
if (images[val]) {
images[val].file = downloadImage({
name: String(snapshot?.['attributes'].name).replace('/', '-'),
browser: browser.name,
compTag,
width: images[val].width,
type: val,
baseDir,
Expand All @@ -102,13 +122,9 @@ module.exports.Generate = async function (config) {
report['unreviewedScreenshots']++
flagChanged = true
}
Object.assign(comparison, comp.attributes, { images }, { browser: browser.name || '' })
if (!report.browsers.includes(browser.name)) {
report.browsers.push(browser.name)
}
if (!report.widths.includes(comparison['width'])) {
report.widths.push(comparison['width'])
}
Object.assign(comparison, comp.attributes, { images }, isApp?{ device:compTag }:{browser:compTag})


comparison['diff-percentage'] = (comparison['diff-ratio'] * 100).toFixed(2)
comparison['diff-color'] = "yellow"
if (comparison['diff-percentage'] > diffThreshold) {
Expand All @@ -122,11 +138,12 @@ module.exports.Generate = async function (config) {
return formattedSnapshot
})
fs.writeFileSync(`${baseDir}/report.json`, JSON.stringify(report, undefined, 2))
HtmlReportGenerator(config, report)
HtmlReportGenerator(config, report, isApp)
console.log("Build Report Generated.")
return report
}


function getComparisonImage(comparison, key) {
let screenshot = comparison.relationships[key]
if (!screenshot) return;
Expand All @@ -141,20 +158,24 @@ function getComparisonBrowser(comparison) {
return comparison.relationships['browser']?.relationships['browser-family']?.attributes
}

function getComparisonDevice(comparison) {
return comparison.relationships['comparison-tag']?.attributes
}

function downloadImage(options) {
let { name, browser, width, type, baseDir, url } = options
if(!fs.existsSync(`${baseDir}/${type}`)){
fs.mkdirSync(`${baseDir}/${type}`,{recursive:true})
let { name, width, type, baseDir, url,compTag } = options
if (!fs.existsSync(`${baseDir}/${type}`)) {
fs.mkdirSync(`${baseDir}/${type}`, { recursive: true })
}
let path = `${baseDir}/${type}/${name}-${browser}-${width}.png`
let path = `${baseDir}/${type}/${name}-${compTag}-${width}.png`
try {
new Axios({ responseType: 'arraybuffer',url:url }).get(url).then((file) => {
new Axios({ responseType: 'arraybuffer', url: url }).get(url).then((file) => {
console.log("Download Complete:" + path)
fs.writeFileSync(path, file.data)
}).catch((err) => {
console.error("Failed to Download: " + path)
})
return `./${type}/${name}-${browser}-${width}.png`;
return `file:./${type}/${name}-${compTag}-${width}.png`;
} catch {

}
Expand Down
70 changes: 55 additions & 15 deletions src/html-render.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
const fs = require('fs')
const ejs = require('ejs');
const path = require('path')
function HtmlReportGenerator(config,jsonReport){
let { buildId, downloadPath } = config
let template_path = path.resolve(__dirname,'template/report.html')
const template = fs.readFileSync(template_path,{encoding:'utf-8'}).toString()
let htmlReport = ejs.render(template,{buildId,...jsonReport})
fs.writeFileSync(`${downloadPath}/${buildId}/report.html`,htmlReport)

function HtmlReportGenerator(config, jsonReport, isApp) {
if (isApp) {
let {
buildId,
downloadPath
} = config
let template_path = path.resolve(__dirname, 'template/app-report.html')
const template = fs.readFileSync(template_path, {
encoding: 'utf-8'
}).toString()
let htmlReport = ejs.render(template, {
buildId,
...jsonReport
})
fs.writeFileSync(`${downloadPath}/${buildId}/app-report.html`, htmlReport)
} else {
let {
buildId,
downloadPath
} = config
let template_path = path.resolve(__dirname, 'template/report.html')
const template = fs.readFileSync(template_path, {
encoding: 'utf-8'
}).toString()
let htmlReport = ejs.render(template, {
buildId,
...jsonReport
})
fs.writeFileSync(`${downloadPath}/${buildId}/report.html`, htmlReport)
}
}

function HtmlSummary(summary,filename){
let template_path = path.resolve(__dirname,'template/summary.html')
const template = fs.readFileSync(template_path,{encoding:"utf-8"}).toString()
try{
let htmlSummary = ejs.render(template,summary)
fs.writeFileSync(filename,htmlSummary)
}catch(err){
console.log(err)
function HtmlSummary(summary, filename, isApp) {
if (isApp) {
let template_path = path.resolve(__dirname, 'template/app-summary.html')
const template = fs.readFileSync(template_path, {
encoding: "utf-8"
}).toString()
try {
let htmlSummary = ejs.render(template, summary)
fs.writeFileSync(filename, htmlSummary)
} catch (err) {
console.log(err)
}
} else {
let template_path = path.resolve(__dirname, 'template/summary.html')
const template = fs.readFileSync(template_path, {
encoding: "utf-8"
}).toString()
try {
let htmlSummary = ejs.render(template, summary)
fs.writeFileSync(filename, htmlSummary)
} catch (err) {
console.log(err)
}
}

}

module.exports.HtmlReportGenerator = HtmlReportGenerator
Expand Down
3 changes: 2 additions & 1 deletion src/summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports.Summary = async function (opts) {
throw res.data
}
})
const isApp = project['data']['attributes']['type'] == 'app'
let projectId = project.data.id
let projectURL = "https://percy.io/"+project.data.attributes['full-slug']
let projectName = project.data.attributes.name
Expand Down Expand Up @@ -130,7 +131,7 @@ module.exports.Summary = async function (opts) {
fs.mkdirSync('Summary',{recursive:true})
}
fs.writeFileSync(`Summary/${summary.projectName}-${Date.now()}.json`,JSON.stringify(summary,undefined,2))
HtmlSummary(summary,`Summary/${summary.projectName}-${Date.now()}.html`)
HtmlSummary(summary,`Summary/${summary.projectName}-${Date.now()}.html`, isApp)
console.log("Summary report generated")
return summary;

Expand Down
Loading