diff --git a/packages/components/src/color-picker/test/index.tsx b/packages/components/src/color-picker/test/index.tsx
index f531455f734e7e..8d584d626487a4 100644
--- a/packages/components/src/color-picker/test/index.tsx
+++ b/packages/components/src/color-picker/test/index.tsx
@@ -1,49 +1,14 @@
/**
* External dependencies
*/
-import { render, fireEvent, waitFor } from '@testing-library/react';
+import { screen, render } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
/**
* Internal dependencies
*/
import { ColorPicker } from '..';
-/**
- * Ordinarily we'd try to select the component by role but the slider role appears
- * on several elements and we'd end up encoding assumptions about order when
- * trying to select the appropriate element. We might as well just use the class name
- * on the container which will be more durable if, for example, the order changes.
- */
-function getSaturation( container: HTMLElement ) {
- return container.querySelector(
- '.react-colorful__saturation .react-colorful__interactive'
- );
-}
-
-type PageXPageY = { pageX: number; pageY: number };
-
-// Fix to pass `pageX` and `pageY`
-// See https://github.com/testing-library/react-testing-library/issues/268
-class FakeMouseEvent extends MouseEvent {
- constructor( type: MouseEvent[ 'type' ], values?: PageXPageY ) {
- super( type, { buttons: 1, bubbles: true, ...values } );
-
- Object.assign( this, {
- pageX: values?.pageX ?? 0,
- pageY: values?.pageY ?? 0,
- } );
- }
-}
-
-function moveReactColorfulSlider(
- sliderElement: Element,
- from: PageXPageY,
- to: PageXPageY
-) {
- fireEvent( sliderElement, new FakeMouseEvent( 'mousedown', from ) );
- fireEvent( sliderElement, new FakeMouseEvent( 'mousemove', to ) );
-}
-
const hslaMatcher = expect.objectContaining( {
h: expect.any( Number ),
s: expect.any( Number ),
@@ -73,99 +38,134 @@ const legacyColorMatcher = {
describe( 'ColorPicker', () => {
describe( 'legacy props', () => {
it( 'should fire onChangeComplete with the legacy color format', async () => {
+ const user = userEvent.setup();
const onChangeComplete = jest.fn();
- const color = '#fff';
+ const color = '#000';
- const { container } = render(
+ render(
);
- const saturation = getSaturation( container );
-
- if ( saturation === null ) {
- throw new Error( 'The saturation slider could not be found' );
- }
+ const formatSelector = screen.getByRole( 'combobox' );
+ expect( formatSelector ).toBeVisible();
- expect( saturation ).toBeInTheDocument();
+ await user.selectOptions( formatSelector, 'hex' );
- moveReactColorfulSlider(
- saturation,
- { pageX: 0, pageY: 0 },
- { pageX: 10, pageY: 10 }
- );
+ const hexInput = screen.getByRole( 'textbox' );
+ expect( hexInput ).toBeVisible();
- await waitFor( () =>
- expect( onChangeComplete ).toHaveBeenCalled()
- );
+ await user.clear( hexInput );
+ await user.type( hexInput, '1ab' );
- expect( onChangeComplete ).toHaveBeenCalledWith(
+ expect( onChangeComplete ).toHaveBeenCalledTimes( 3 );
+ expect( onChangeComplete ).toHaveBeenLastCalledWith(
legacyColorMatcher
);
} );
} );
+ describe( 'Hex input', () => {
+ it( 'should fire onChange with the correct value from the hex input', async () => {
+ const user = userEvent.setup();
+ const onChange = jest.fn();
+ const color = '#000';
+
+ render(
+
+ );
+
+ const formatSelector = screen.getByRole( 'combobox' );
+ expect( formatSelector ).toBeVisible();
+
+ await user.selectOptions( formatSelector, 'hex' );
- it( 'should fire onChange with the string value', async () => {
- const onChange = jest.fn();
- const color = 'rgba(1, 1, 1, 0.5)';
+ const hexInput = screen.getByRole( 'textbox' );
+ expect( hexInput ).toBeVisible();
- const { container } = render(
-
- );
+ await user.clear( hexInput );
+ await user.type( hexInput, '1ab' );
- const saturation = getSaturation( container );
+ expect( onChange ).toHaveBeenCalledTimes( 3 );
+ expect( onChange ).toHaveBeenLastCalledWith( '#11aabb' );
+ } );
+ } );
- if ( saturation === null ) {
- throw new Error( 'The saturation slider could not be found' );
- }
+ describe.each( [
+ [ 'red', 'Red', '#7dffff' ],
+ [ 'green', 'Green', '#ff7dff' ],
+ [ 'blue', 'Blue', '#ffff7d' ],
+ ] )( 'RGB inputs', ( colorInput, inputLabel, expected ) => {
+ it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
+ const user = userEvent.setup();
+ const onChange = jest.fn();
+ const color = '#fff';
- expect( saturation ).toBeInTheDocument();
+ render(
+
+ );
- moveReactColorfulSlider(
- saturation,
- { pageX: 0, pageY: 0 },
- { pageX: 10, pageY: 10 }
- );
+ const formatSelector = screen.getByRole( 'combobox' );
+ expect( formatSelector ).toBeVisible();
- await waitFor( () => expect( onChange ).toHaveBeenCalled() );
+ await user.selectOptions( formatSelector, 'rgb' );
- expect( onChange ).toHaveBeenCalledWith(
- expect.stringMatching( /^#([a-fA-F0-9]{8})$/ )
- );
- } );
+ const inputElement = screen.getByRole( 'spinbutton', {
+ name: inputLabel,
+ } );
+ expect( inputElement ).toBeVisible();
- it( 'should fire onChange with the HSL value', async () => {
- const onChange = jest.fn();
- const color = 'hsla(125, 20%, 50%, 0.5)';
+ await user.clear( inputElement );
+ await user.type( inputElement, '125' );
- const { container } = render(
-
- );
+ expect( onChange ).toHaveBeenCalledTimes( 4 );
+ expect( onChange ).toHaveBeenLastCalledWith( expected );
+ } );
+ } );
- const saturation = getSaturation( container );
+ describe.each( [
+ [ 'hue', 'Hue', '#aad52a' ],
+ [ 'saturation', 'Saturation', '#20dfdf' ],
+ [ 'lightness', 'Lightness', '#95eaea' ],
+ ] )( 'HSL inputs', ( colorInput, inputLabel, expected ) => {
+ it( `should fire onChange with the correct value when the ${ colorInput } value is updated`, async () => {
+ const user = userEvent.setup();
+ const onChange = jest.fn();
+ const color = '#2ad5d5';
+
+ render(
+
+ );
- if ( saturation === null ) {
- throw new Error( 'The saturation slider could not be found' );
- }
+ const formatSelector = screen.getByRole( 'combobox' );
+ expect( formatSelector ).toBeVisible();
- expect( saturation ).toBeInTheDocument();
+ await user.selectOptions( formatSelector, 'hsl' );
- moveReactColorfulSlider(
- saturation,
- { pageX: 0, pageY: 0 },
- { pageX: 10, pageY: 10 }
- );
+ const inputElement = screen.getByRole( 'spinbutton', {
+ name: inputLabel,
+ } );
+ expect( inputElement ).toBeVisible();
- await waitFor( () => expect( onChange ).toHaveBeenCalled() );
+ await user.clear( inputElement );
+ await user.type( inputElement, '75' );
- expect( onChange ).toHaveBeenCalledWith(
- expect.stringMatching( /^#([a-fA-F0-9]{6})$/ )
- );
+ expect( onChange ).toHaveBeenCalledTimes( 3 );
+ expect( onChange ).toHaveBeenLastCalledWith( expected );
+ } );
} );
} );