Skip to content
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

new driver for hint testing #2898

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/components/hint/Hint.driver.new.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
useComponentDriver,
ComponentProps,
usePressableDriver,
ViewDriver,
ImageDriver,
ModalDriver
} from '../../testkit';
import {ViewStyle, StyleSheet} from 'react-native';

export const HintDriver = (props: ComponentProps) => {
const driver = usePressableDriver(useComponentDriver(props));

const modalDriver = ModalDriver({
renderTree: props.renderTree,
testID: `${props.testID}.modal`
});

const contentDriver = ViewDriver({
renderTree: props.renderTree,
testID: `${props.testID}.message`
});

const overlayDriver = usePressableDriver(useComponentDriver({
renderTree: props.renderTree,
testID: `${props.testID}.overlay`
}));

const iconDriver = ImageDriver({
renderTree: props.renderTree,
testID: `${props.testID}.icon`
});

const getIcon = () => {
return iconDriver;
};

const getBackgroundColor = (): ViewStyle => {
return StyleSheet.flatten(contentDriver.getStyle()).backgroundColor as ViewStyle;
};

const isBackgroundExists = () => {
return overlayDriver.exists();
};

const isModalVisible = () => {
return modalDriver.isVisible();
};

const press = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

press is show? Or can it be both show and hide?

return driver.press();
};

const pressOnBackground = () => {
return overlayDriver.press();
};

return {
getBackgroundColor,
getIcon,
isBackgroundExists,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer isBackgroundVisible, WDYT?

pressOnBackground,
isModalVisible,
...driver,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the ...driver export, maybe export what is actually needed?

press
};
};
133 changes: 97 additions & 36 deletions src/components/hint/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,130 @@
import React from 'react';
import {Hint} from 'react-native-ui-lib';
import {Colors} from '../../../style';
import {findStyle} from '../../../uilib-test-renderer';
import {HintDriver} from '../Hint.driver';
import React, {useRef} from 'react';
import {waitFor, render} from '@testing-library/react-native';
import {Hint, Colors, Button} from '../../../';
import {HintDriver} from '../Hint.driver.new';

const TEST_ID = 'Hint';

const settingsIcon = require('../../../assets/icons/check.png');

const HintTestComponent = ({
showHint,
color
color,
onPress,
onBackgroundPress,
useTargetFrame = true,
useModal,
useIcon
}: {
showHint: boolean;
color?: string;
onPress?: Function;
onBackgroundPress?: Function;
useTargetFrame?: boolean;
useModal?: boolean;
useIcon?: boolean;
}) => {
const ref = useRef();
return (
<Hint
visible={showHint}
message={'Hint message to hint things'}
position={Hint.positions.TOP}
useSideTip
key={'1'}
targetFrame={{x: 1, y: 1, height: 1, width: 1}}
onBackgroundPress={() => {}}
targetFrame={useTargetFrame && {x: 1, y: 1, height: 1, width: 1}}
onBackgroundPress={onBackgroundPress}
onPress={onPress}
color={color}
removePaddings
enableShadow
testID={'Hint'}
/>
testID={TEST_ID}
useModal={useModal}
icon={useIcon ? settingsIcon : undefined}
ref={ref}
>
<Button round $backgroundDefault label="Hint Button"/>
</Hint>
);
};

describe('Hint Screen component test', () => {
afterEach(() => {
HintDriver.clear();
});
//TODO: Add test for Hint tip position
describe('Test Hint style:', () => {
it('Test Hint component background color', async () => {
const expectedColor = Colors.$backgroundPrimaryHeavy;
const renderTree = render(<HintTestComponent showHint/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
expect(await driver.getElement()).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'de change this to something else, what are we really testing here?


it('Test Hint component background color', async () => {
const expectedColor = Colors.$backgroundPrimaryHeavy;
const component = <HintTestComponent showHint/>;
let contentColor = await driver.getBackgroundColor();
expect(contentColor).toBe(expectedColor);

const driver = new HintDriver({component, testID: 'Hint'});
expect(await driver.getElement()).toBeTruthy();
const whiteHintRenderTree = render(<HintTestComponent showHint color={Colors.white}/>);
const whiteHintDriver = HintDriver({renderTree: whiteHintRenderTree, testID: TEST_ID});

const hintContent = await driver.getHintContent();
let color = findStyle('backgroundColor', hintContent);
contentColor = await whiteHintDriver.getBackgroundColor();
expect(contentColor).toBe(Colors.white);
});
});

expect(color).toBe(expectedColor);
expect(hintContent).toBeTruthy();
describe('Test Hint icon', () => {
it('Hint should include icon', async () => {
const renderTree = render(<HintTestComponent showHint useIcon/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
expect(driver.getIcon().exists()).toBeTruthy();
});

const WhiteHint = <HintTestComponent showHint color={Colors.white}/>;
const WhiteHintDriver = new HintDriver({component: WhiteHint, testID: 'Hint'});
it('Hint shouldn\'t include icon', async () => {
const renderTree = render(<HintTestComponent showHint/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
expect(driver.getIcon().exists()).toBeFalsy();
});
});

const WhiteHintContent = await WhiteHintDriver.getHintContent();
color = findStyle('backgroundColor', WhiteHintContent);
expect(color).toBe(Colors.white);
describe('Test Hint content', () => {
it('Hint should include message', async () => {
const renderTree = render(<HintTestComponent showHint/>);
const message = renderTree.getByTestId(`${TEST_ID}.message.text`).props.children;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be exported from the driver

expect(message).toBe('Hint message to hint things');
});
});

it('Test Hint modal is not visible when showHint is false', async () => {
const component = <HintTestComponent showHint={false}/>;
const driver = new HintDriver({component, testID: 'Hint'});
expect(await driver.getHintModal()).toBeFalsy();
describe('Test Hint visibility:', () => {
//Note: Cannot test Hint when showHint is false, the component isn't rendered and return null or the children.
it('Test Hint is visible when showHint is true', async () => {
const renderTree = render(<HintTestComponent showHint onBackgroundPress={() => {}}/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
expect(await driver.exists()).toBeTruthy();
expect(await driver.isModalVisible()).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want this or maybe just a generic isOpen? WDYT?

});
});

describe('Test Hint onPress', () => {
let onPressCallback: jest.Mock;
beforeEach(() => (onPressCallback = jest.fn()));
afterEach(() => onPressCallback.mockClear());

it('should trigger onPress callback', async () => {
const renderTree = render(<HintTestComponent showHint onPress={onPressCallback}/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
driver.press();
await waitFor(() => expect(onPressCallback).toHaveBeenCalledTimes(1));
});

it('should not trigger onPress callback when onPress isn\'t passed', async () => {
const renderTree = render(<HintTestComponent showHint/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
driver.press();
await waitFor(() => expect(onPressCallback).toHaveBeenCalledTimes(0));
});
});

it('Test Hint modal is visible when showHint is true', async () => {
const component = <HintTestComponent showHint/>;
const driver = new HintDriver({component, testID: 'Hint'});
expect(await driver.getElement()).toBeTruthy();
expect(await driver.getHintModal()).toBeTruthy();
describe('Test Hint onBackgroundPress', () => {
it('should not create touchable overlay driver when onBackgroundPress isn\'t passed', async () => {
const renderTree = render(<HintTestComponent showHint/>);
const driver = HintDriver({renderTree, testID: TEST_ID});
expect(driver.isBackgroundExists()).toBeFalsy();
});
});
});
12 changes: 7 additions & 5 deletions src/components/hint/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,13 @@ class Hint extends Component<HintProps, HintState> {
}
]}
pointerEvents="box-none"
testID={`${testID}.overlay`}
>
{onBackgroundPress && (
<TouchableWithoutFeedback style={StyleSheet.absoluteFillObject} onPress={onBackgroundPress}>
<TouchableWithoutFeedback
style={StyleSheet.absoluteFillObject}
onPress={onBackgroundPress}
testID={`${testID}.overlay`}
>
<View flex/>
</TouchableWithoutFeedback>
)}
Expand Down Expand Up @@ -481,7 +484,7 @@ class Hint extends Component<HintProps, HintState> {
ref={this.hintRef}
>
{customContent}
{!customContent && icon && <Image source={icon} style={[styles.icon, iconStyle]}/>}
{!customContent && icon && <Image source={icon} style={[styles.icon, iconStyle]} testID={`${testID}.icon`}/>}
{!customContent && (
<Text recorderTag={'unmask'} style={[styles.hintMessage, messageStyle]} testID={`${testID}.message.text`}>
{message}
Expand All @@ -507,9 +510,8 @@ class Hint extends Component<HintProps, HintState> {
this.getHintAnimatedStyle()
]}
pointerEvents="box-none"
testID={testID}
>
<TouchableOpacity activeOpacity={opacity} onPress={onPress}>
<TouchableOpacity activeOpacity={opacity} onPress={onPress} testID={testID}>
{this.renderContent()}
</TouchableOpacity>
{this.renderHintTip()}
Expand Down
1 change: 1 addition & 0 deletions src/testkit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {TextFieldDriver} from '../components/textField/TextField.driver.new';
export {ViewDriver} from '../components/view/View.driver.new';
export {ModalDriver} from '../components/modal/Modal.driver.new';
export {DialogDriver} from '../incubator/Dialog/Dialog.driver.new';
export {HintDriver} from '../components/hint/Hint.driver.new';
export {ButtonDriver} from '../components/button/Button.driver.new';
export {ImageDriver} from '../components/image/Image.driver.new';
export {SwitchDriver} from '../components/switch/switch.driver';
Expand Down