-
Notifications
You must be signed in to change notification settings - Fork 1
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
US152247 & US152272 - Add pixelmatch and handle images of different sizes #46
Conversation
Co-authored-by: Dave Lockhart <[email protected]>
…spaceUI/testing into US152271_Cleanup_Folders_Option_2
# Conflicts: # src/server/visual-diff-plugin.js # src/server/wtr-config.js
…ncrease_timeout # Conflicts: # src/browser/vdiff.js # src/server/visual-diff-plugin.js # test/browser/element.vdiff.js
expect.fail(message); | ||
let result = await executeServerCommand('brightspace-visual-diff-compare', { name, rect, opts }); | ||
if (result.resizeRequired) { | ||
this.test.timeout(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.test.timeout(0); | |
this.test.timeout(100000); |
If we're worried about turning off the timeout, we could also pick a large number. We'll only get to this point after the screenshot is taken, so we don't need to worry about bad tests timing out - those will fail properly. It'd only be if pixelmatch or the file operations never completed that we'd be stuck.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not worried about it -- if we run into these cases we should be able to handle them separately anyway.
|
||
const isCI = !!env['CI']; | ||
const DEFAULT_MARGIN = 10; | ||
const DEFAULT_TOLERANCE = 0; // TODO: Support tolerance override? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We currently allow this to be overridden and a few places have, but I don't think we have a story for it
{ name: 'right', coord: newSize.width - original.width } | ||
].forEach(x => { // TODO: position added for reports, remove/adjust as needed | ||
if (original.width === newSize.width && original.height === newSize.height) { | ||
resizedPNGs.push({ png: original, position: `${y.name}-${x.name}` }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The position can be adjusted to whatever if we want to use it for the report, I don't actually use it anywhere. I used it for testing, and because it made these nested for
s a lot easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the reports are going to need it, since they're going to use the resized images anyway which will always both be the same size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it was only if we wanted to call it out for extra clarity. I could remove this and switch to just comments for each value, like
[
0, // top
Math.floor((newSize.height - original.height) / 2), // center
newSize.height - original.height // bottom
].forEach(y => {
[
0, // left
Math.floor((newSize.width - original.width) / 2), // center
newSize.width - original.width // right
].forEach(x => {
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess keep it for now and I'll see if it can be used in a useful way. Your TODO can remind us to remove it later if not!
const screenshotFileName = `${screenshotFile}.png`; | ||
|
||
if (command === 'brightspace-visual-diff-compare') { | ||
if (!isCI) { // CI will be a fresh .vdiff folder each time and only one run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about putting this whole cleanup in it's own command to make this cleaner, but then we're running
testing/src/server/visual-diff-plugin.js
Lines 136 to 143 in 9723915
const browser = session.browser.name.toLowerCase(); | |
const { dir, newName } = extractTestPartsFromName(payload.name); | |
const testPath = dirname(session.testFile).replace(rootDir, ''); | |
const newPath = join(rootDir, PATHS.VDIFF_ROOT, testPath, dir); | |
const goldenFileName = `${join(newPath, PATHS.GOLDEN, browser, newName)}.png`; | |
const passFileName = `${join(newPath, PATHS.PASS, browser, newName)}.png`; | |
const screenshotFile = join(newPath, PATHS.FAIL, browser, newName); | |
const screenshotFileName = `${screenshotFile}.png`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... was thinking we could also refactor this a bit at this point to be like:
if (command === 'brightspace-visual-diff-compare') {
doCompare();
} else if (command === 'brightspace-visual-diff-compare-resize') {
doCompareResize();
}
At the very least that'd reduce a lot of the nesting, and would also let us move things out into separate files if that made sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I started doing that and then there were way too many things I was passing around as parameters without knowing what you'd need and where, so I figured that might be better once the skeleton of the report stuff is in
@@ -0,0 +1 @@ | |||
import '../element.vdiff.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've found having this second nested test file was really helpful for all the file manipulation testing, so figured I'd just add it. Could also help with the deleting/creating/rolling up reports testing!
{ name: 'slimer-taller', action: elem => { | ||
elem.style.width = '200px'; | ||
elem.style.height = '70px'; | ||
elem.style.textAlign = 'end'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding these text-align
changes make these last two tests have interesting best positions chosen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good! I think we'll want to refactor it at some point, but that can wait.
The tricky part is that we need to add extra data for the report before each of the return
statements, which happen all over the place haha.
expect.fail(message); | ||
let result = await executeServerCommand('brightspace-visual-diff-compare', { name, rect, opts }); | ||
if (result.resizeRequired) { | ||
this.test.timeout(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not worried about it -- if we run into these cases we should be able to handle them separately anyway.
{ name: 'right', coord: newSize.width - original.width } | ||
].forEach(x => { // TODO: position added for reports, remove/adjust as needed | ||
if (original.width === newSize.width && original.height === newSize.height) { | ||
resizedPNGs.push({ png: original, position: `${y.name}-${x.name}` }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the reports are going to need it, since they're going to use the resized images anyway which will always both be the same size.
const screenshotFileName = `${screenshotFile}.png`; | ||
|
||
if (command === 'brightspace-visual-diff-compare') { | ||
if (!isCI) { // CI will be a fresh .vdiff folder each time and only one run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... was thinking we could also refactor this a bit at this point to be like:
if (command === 'brightspace-visual-diff-compare') {
doCompare();
} else if (command === 'brightspace-visual-diff-compare-resize') {
doCompareResize();
}
At the very least that'd reduce a lot of the nesting, and would also let us move things out into separate files if that made sense.
src/server/visual-diff-plugin.js
Outdated
if (screenshotImage.width === goldenImage.width && screenshotImage.height === goldenImage.height) { | ||
const diff = new PNG({ width: screenshotImage.width, height: screenshotImage.height }); | ||
const pixelsDiff = pixelmatch( | ||
screenshotImage.data, goldenImage.data, diff.data, screenshotImage.width, screenshotImage.height, { threshold: DEFAULT_TOLERANCE } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you pass the diffMask
option so that they're transparent? I've added it my branch but it keeps getting conflicts/blown away each time I rebase.
🎉 This PR is included in version 0.13.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Ok, most of the work here was around testing and the resulting code is pretty small. I'll add more comments inline, but at a high-level this PR:
Other diffing libraries were investigated but in the end pixelmatch was the simplest and gave us what we needed with minimal code.