Skip to content

Instantly share code, notes, and snippets.

@NicholasBoll
Last active November 8, 2023 15:50
Show Gist options
  • Save NicholasBoll/e584991b36986a85acf0e95101752bc0 to your computer and use it in GitHub Desktop.
Save NicholasBoll/e584991b36986a85acf0e95101752bc0 to your computer and use it in GitHub Desktop.
Cypress assertion to compare colors
const compareColor = (color, property) => (targetElement) => {
const tempElement = document.createElement('div');
tempElement.style.color = color;
tempElement.style.display = 'none'; // make sure it doesn't actually render
document.body.appendChild(tempElement); // append so that `getComputedStyle` actually works
const tempColor = getComputedStyle(tempElement).color;
const targetColor = getComputedStyle(targetElement[0])[property];
document.body.removeChild(tempElement); // remove it because we're done with it
expect(tempColor).to.equal(targetColor);
};
Cypress.Commands.overwrite('should', (originalFn, subject, expectation, ...args) => {
const customMatchers = {
'have.backgroundColor': compareColor(args[0], 'backgroundColor'),
'have.color': compareColor(args[0], 'color'),
};
// See if the expectation is a string and if it is a member of Jest's expect
if (typeof expectation === 'string' && customMatchers[expectation]) {
return originalFn(subject, customMatchers[expectation]);
}
return originalFn(subject, expectation, ...args);
});
const compareColor = (color: string, property: keyof CSSStyleDeclaration) => (
targetElement: JQuery
) => {
const tempElement = document.createElement('div');
tempElement.style.color = color;
tempElement.style.display = 'none'; // make sure it doesn't actually render
document.body.appendChild(tempElement); // append so that `getComputedStyle` actually works
const tempColor = getComputedStyle(tempElement).color;
const targetColor = getComputedStyle(targetElement[0])[property];
document.body.removeChild(tempElement); // remove it because we're done with it
expect(tempColor).to.equal(targetColor);
};
Cypress.Commands.overwrite('should', (originalFn: Function, subject: any, expectation: any, ...args: any[]) => {
const customMatchers = {
'have.backgroundColor': compareColor(args[0], 'backgroundColor'),
'have.color': compareColor(args[0], 'color'),
};
// See if the expectation is a string and if it is a member of Jest's expect
if (typeof expectation === 'string' && customMatchers[expectation]) {
return originalFn(subject, customMatchers[expectation]);
}
return originalFn(subject, expectation, ...args);
});
@NicholasBoll
Copy link
Author

NicholasBoll commented Mar 31, 2020

Add the contents into your cypress/support/index.js/ts or cypress/support/commands.js/ts file.

After that, you should be able to do the following:

cy.get('button').should('have.color', 'black')
cy.get('button').should('have.color', '#000000')
cy.get('button').should('have.color', 'rgba(0, 0, 0)')

cy.get('button').should('have.backgroundColor', '#cccccc')

@Gurumoorthyb
Copy link

Gurumoorthyb commented Nov 8, 2023

Hey, I have added the above ts code in my space, my concern is the color that is coming from the Atlas library is hex I just want to assert in cypress.
My result: I have sent this color #455D82, the above comment returned this color #5d7599

@NicholasBoll
Copy link
Author

Are you able to verify on a simpler test case? The snippet was made to solve the problem where the browser might force a different color return than the one you enter. For example, you may set the color to a hex, but get back an rgba from getComputedStyle. So the function creates a temporary element and sets the color and uses getComputedStyle so you're using the browser`s color space preference instead of your own. A color difference is unexpected. Is Atlas changing incoming colors to meet accessible contrast requirements?

@Gurumoorthyb
Copy link

No, We haven't changed the atlas incoming color for ex: #455D82 if this is the color in the atlas in UI it will render as same RGB(69, 93, 130)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment