diff --git a/packages/dom/src/lib/ElementAssertion.ts b/packages/dom/src/lib/ElementAssertion.ts index 2ae9b29..3b9bdc6 100644 --- a/packages/dom/src/lib/ElementAssertion.ts +++ b/packages/dom/src/lib/ElementAssertion.ts @@ -216,6 +216,50 @@ export class ElementAssertion extends Assertion { }); } + /** + * Asserts that the element has one or more of the specified CSS styles. + * + * @example + * ``` + * expect(component).toHaveSomeStyle({ color: 'green', display: 'block' }); + * ``` + * + * @param expected the expected CSS style/s. + * @returns the assertion instance. + */ + + public toHaveSomeStyle(expected: Partial): this { + + const [expectedStyle, elementProcessedStyle] = getExpectedAndReceivedStyles(this.actual, expected); + + if (!expectedStyle || !elementProcessedStyle) { + throw new Error("No available styles."); + } + + const hasSomeStyle = Object.entries(expectedStyle).some(([expectedProp, expectedValue]) => { + return Object.entries(elementProcessedStyle).some(([receivedProp, receivedValue]) => { + return equal(expectedProp, receivedProp) && equal(expectedValue, receivedValue); + }); + }); + + const error = new AssertionError({ + actual: this.actual, + message: `Expected the element to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`, + }); + + const invertedError = new AssertionError({ + actual: this.actual, + // eslint-disable-next-line max-len + message: `Expected the element NOT to match some of the following styles:\n${JSON.stringify(expectedStyle, null, 2)}`, + }); + + return this.execute({ + assertWhen: hasSomeStyle, + error, + invertedError, + }); + } + /** * Helper method to assert the presence or absence of class names. * diff --git a/packages/dom/test/unit/lib/ElementAssertion.test.tsx b/packages/dom/test/unit/lib/ElementAssertion.test.tsx index 1a77fe2..182ea34 100644 --- a/packages/dom/test/unit/lib/ElementAssertion.test.tsx +++ b/packages/dom/test/unit/lib/ElementAssertion.test.tsx @@ -368,4 +368,47 @@ describe("[Unit] ElementAssertion.test.ts", () => { }); }); }); + + describe(".toHaveSomeStyle", () => { + context("when the element contains one or more expected styles", () => { + it("returns the assertion instance", () => { + const { getByTestId } = render( +
, + ); + const divTest = getByTestId("test-div"); + const test = new ElementAssertion(divTest); + + expect(test.toHaveSomeStyle({ color: "red", display: "flex", height: "3rem", width: "2rem" })).toBeEqual(test); + + expect(() => test.not.toHaveSomeStyle({ color: "blue" })) + .toThrowError(AssertionError) + // eslint-disable-next-line max-len + .toHaveMessage("Expected the element NOT to match some of the following styles:\n{\n \"color\": \"rgb(0, 0, 255)\"\n}"); + }); + }); + + context("when the element does not contain any of the expected styles", () => { + it("throws an assertion error", () => { + const { getByTestId } = render( +
, + ); + const divTest = getByTestId("test-div"); + const test = new ElementAssertion(divTest); + + expect(() => test.toHaveSomeStyle({ color: "red", display: "flex" })) + .toThrowError(AssertionError) + // eslint-disable-next-line max-len + .toHaveMessage("Expected the element to match some of the following styles:\n{\n \"color\": \"rgb(255, 0, 0)\",\n \"display\": \"flex\"\n}"); + + expect(test.not.toHaveSomeStyle({ border: "1px solid blue", color: "red", display: "flex" })).toBeEqual(test); + }); + }); + }); });