-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
155 lines (126 loc) · 4.1 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
const { Cluster } = require("puppeteer-cluster");
const pixelmatch = require("pixelmatch");
const fs = require("fs");
const dayjs = require("dayjs");
const PNG = require("pngjs").PNG;
const chalk = require("chalk");
const cliProgress = require("cli-progress");
const log = console.log;
const config = require("./config");
// Setup our progress bars
const screenshotProgress = new cliProgress.SingleBar(
{},
cliProgress.Presets.rect
);
const diffProgress = new cliProgress.SingleBar({}, cliProgress.Presets.rect);
// Create a timestamp for file and folder names
const date = dayjs().format("YYYY_MM_DD__HH-mm-ss");
(async () => {
// Setup the batch jobs for Puppeteer crawling
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_CONTEXT,
maxConcurrency: config.maxConcurrency,
});
// We don't define a task and instead use own functions
const screenshot = async ({ page, data }) => {
// Create the directory for the given image
fs.mkdirSync(`screenshots/${date}/${data.item}`, { recursive: true });
// Generate screenshots of the A and B URLs using our specified viewport size
await page.setViewport(config.viewport);
await page.goto(data.url);
// Load in any custom CSS that we have defined
await page.evaluate((data) => {
let style = document.createElement("style");
style.innerHTML = data.css;
document.getElementsByTagName("head")[0].appendChild(style);
}, data);
await page.screenshot({
path: `screenshots/${date}/${data.item}/${data.test}.png`,
});
// Update the progress
screenshotProgress.increment();
};
// Initiate the progress bar
log(chalk.blue("\nGenerating images from your URLs..."));
screenshotProgress.start(config.urls.length * 2, 0);
// Add each page in our settings to a queue
config.urls.forEach((data, i) => {
// Add the "A" test to our queue
cluster.queue(
{ url: data.a, css: data.css, test: "a", item: i + 1 },
screenshot
);
// Add the "B" test to our queue
cluster.queue(
{ url: data.b, css: data.css, test: "b", item: i + 1 },
screenshot
);
});
await cluster.idle();
await cluster.close();
// Stop the progress bar
screenshotProgress.stop();
/**
* Generate diffs for each captured image
*/
log(chalk.blue("\nDiffing images and creating report..."));
diffProgress.start(config.urls.length, 0);
// Append data to a CSV file
fs.appendFileSync(
`screenshots/${date}/audit.csv`,
`URL A, URL B, Path to diff file, # of pixels difference, Status, Notes\n`
);
// Create an array that holds the pages that have non-acceptable differences
let nonacceptableDiffs = [];
for (let i = 0; i < config.urls.length; i++) {
const url = config.urls[i];
const img1 = PNG.sync.read(
fs.readFileSync(`screenshots/${date}/${i + 1}/a.png`)
);
const img2 = PNG.sync.read(
fs.readFileSync(`screenshots/${date}/${i + 1}/b.png`)
);
const { width, height } = img1;
const diff = new PNG({ width, height });
const diffAmount = pixelmatch(
img1.data,
img2.data,
diff.data,
width,
height,
{
threshold: config.diffThreshold,
}
);
if (diffAmount >= config.nonacceptableDiff) {
nonacceptableDiffs.push(`screenshots/${date}/${i + 1}/diff.png`);
}
// Append data to a CSV file
fs.appendFileSync(
`screenshots/${date}/audit.csv`,
`${url.a},${url.b},${i + 1}/diff.png,${diffAmount},${
diffAmount <= config.nonacceptableDiff ? "Pass" : "Fail"
},""\n`
);
fs.writeFileSync(
`screenshots/${date}/${i + 1}/diff.png`,
PNG.sync.write(diff)
);
// Update the progress
diffProgress.increment();
}
// Exit progress bar
diffProgress.stop();
log(
`\n\n⚠️ A total of ${nonacceptableDiffs.length} page(s) had non-acceptable differences.`
);
nonacceptableDiffs.forEach((diff) => {
log(chalk.red(`- ${diff}`));
});
log(`\n\n🎉 Audit complete!`);
log(
`You can view a full report of this audit at ${chalk.green(
`screenshots/${date}/audit.csv`
)}`
);
})();