Skip to content

Commit

Permalink
chore: Removes dependencies on React <19 in test utils
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-kot committed Feb 5, 2025
1 parent 89612ae commit d311907
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 11 deletions.
18 changes: 16 additions & 2 deletions src/autosuggest/__tests__/autosuggest.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import * as React from 'react';
import React, { useState } from 'react';
import { render } from '@testing-library/react';

import { warnOnce } from '@cloudscape-design/component-toolkit/internal';
Expand Down Expand Up @@ -28,6 +28,20 @@ const defaultProps: AutosuggestProps = {
options: defaultOptions,
};

function StatefulAutosuggest(props: AutosuggestProps) {
const [value, setValue] = useState(props.value);
return (
<Autosuggest
{...props}
value={value}
onChange={event => {
props.onChange?.(event);
setValue(event.detail.value);
}}
/>
);
}

function renderAutosuggest(jsx: React.ReactElement) {
const { container, rerender } = render(jsx);
const wrapper = createWrapper(container).findAutosuggest()!;
Expand Down Expand Up @@ -114,7 +128,7 @@ test('option with special characters can be selected by value', () => {
test('should display entered text option/label', () => {
const enteredTextLabel = jest.fn(value => `Custom function with ${value} placeholder`);
const { wrapper } = renderAutosuggest(
<Autosuggest enteredTextLabel={enteredTextLabel} value="1" options={defaultOptions} />
<StatefulAutosuggest enteredTextLabel={enteredTextLabel} value="" options={defaultOptions} />
);
wrapper.setInputValue('1');
expect(enteredTextLabel).toBeCalledWith('1');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ describe('extended operators', () => {
expect(wrapper.findDropdown()?.findOpenDropdown()).toBeFalsy();

// Reopen dropdown
wrapper.setInputValue('index >');
wrapper.setInputValue('index > ');
expect(wrapper.find('[data-testid="change+"]')!.getElement()).toHaveTextContent('0');
});

Expand Down
22 changes: 20 additions & 2 deletions src/test-utils/dom/input/base-input.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { Simulate } from 'react-dom/test-utils';

import { ComponentWrapper, ElementWrapper, usesDom } from '@cloudscape-design/test-utils-core/dom';
import { act } from '@cloudscape-design/test-utils-core/utils-dom';
Expand Down Expand Up @@ -45,7 +44,9 @@ export default abstract class BaseInputWrapper extends ComponentWrapper {
@usesDom setInputValue(value: string): void {
const element = this.findNativeInput().getElement();
act(() => {
Simulate.change(element, { target: { value } as unknown as EventTarget });
const event = new Event('change', { bubbles: true, cancelable: false });
setNativeValue(element, value);
element.dispatchEvent(event);
});
}

Expand All @@ -54,3 +55,20 @@ export default abstract class BaseInputWrapper extends ComponentWrapper {
return this.findNativeInput().getElement().hasAttribute('disabled');
}
}

// Copied from @testing-library/dom/dist/events.js
function setNativeValue(element: Element, value: string): void {
const { set: valueSetter } = Object.getOwnPropertyDescriptor(element, 'value') || {};
const prototype = Object.getPrototypeOf(element);
const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};

if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {

Check warning on line 67 in src/test-utils/dom/input/base-input.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/input/base-input.ts#L67

Added line #L67 was not covered by tests
if (valueSetter) {
valueSetter.call(element, value);
} else {
throw new Error('The given element does not have a value setter');

Check warning on line 71 in src/test-utils/dom/input/base-input.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/input/base-input.ts#L69-L71

Added lines #L69 - L71 were not covered by tests
}
}
}
24 changes: 21 additions & 3 deletions src/test-utils/dom/prompt-input/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { Simulate } from 'react-dom/test-utils';

import { ComponentWrapper, ElementWrapper, usesDom } from '@cloudscape-design/test-utils-core/dom';
import { act } from '@cloudscape-design/test-utils-core/utils-dom';
Expand Down Expand Up @@ -41,9 +40,28 @@ export default class PromptInputWrapper extends ComponentWrapper {
* @param value value to set the textarea to.
*/
@usesDom setTextareaValue(value: string): void {
const element: HTMLTextAreaElement = this.findNativeTextarea().getElement();
const element = this.findNativeTextarea().getElement();
act(() => {
Simulate.change(element, { target: { value } as unknown as EventTarget });
const event = new Event('change', { bubbles: true, cancelable: false });
setNativeValue(element, value);
element.dispatchEvent(event);
});
}
}

// Copied from @testing-library/dom/dist/events.js
function setNativeValue(element: Element, value: string): void {
const { set: valueSetter } = Object.getOwnPropertyDescriptor(element, 'value') || {};
const prototype = Object.getPrototypeOf(element);
const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};

if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {

Check warning on line 60 in src/test-utils/dom/prompt-input/index.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/prompt-input/index.ts#L60

Added line #L60 was not covered by tests
if (valueSetter) {
valueSetter.call(element, value);
} else {
throw new Error('The given element does not have a value setter');

Check warning on line 64 in src/test-utils/dom/prompt-input/index.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/prompt-input/index.ts#L62-L64

Added lines #L62 - L64 were not covered by tests
}
}
}
24 changes: 21 additions & 3 deletions src/test-utils/dom/textarea/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { Simulate } from 'react-dom/test-utils';

import { ComponentWrapper, ElementWrapper, usesDom } from '@cloudscape-design/test-utils-core/dom';
import { act } from '@cloudscape-design/test-utils-core/utils-dom';
Expand Down Expand Up @@ -29,9 +28,28 @@ export default class TextareaWrapper extends ComponentWrapper<HTMLTextAreaElemen
* @param value value to set the textarea to.
*/
@usesDom setTextareaValue(value: string): void {
const element: HTMLTextAreaElement = this.findNativeTextarea().getElement();
const element = this.findNativeTextarea().getElement();
act(() => {
Simulate.change(element, { target: { value } as unknown as EventTarget });
const event = new Event('change', { bubbles: true, cancelable: false });
setNativeValue(element, value);
element.dispatchEvent(event);
});
}
}

// Copied from @testing-library/dom/dist/events.js
function setNativeValue(element: Element, value: string): void {
const { set: valueSetter } = Object.getOwnPropertyDescriptor(element, 'value') || {};
const prototype = Object.getPrototypeOf(element);
const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, 'value') || {};

if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {

Check warning on line 48 in src/test-utils/dom/textarea/index.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/textarea/index.ts#L48

Added line #L48 was not covered by tests
if (valueSetter) {
valueSetter.call(element, value);
} else {
throw new Error('The given element does not have a value setter');

Check warning on line 52 in src/test-utils/dom/textarea/index.ts

View check run for this annotation

Codecov / codecov/patch

src/test-utils/dom/textarea/index.ts#L50-L52

Added lines #L50 - L52 were not covered by tests
}
}
}

0 comments on commit d311907

Please sign in to comment.