Skip to content

Commit

Permalink
add more screenshot tests (oncokb#341)
Browse files Browse the repository at this point in the history
 add more screenshot tests
  • Loading branch information
bprize15 authored Jun 6, 2024
1 parent ec1250c commit cfbdbf8
Show file tree
Hide file tree
Showing 19 changed files with 346 additions and 3,885 deletions.
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ To launch your application's tests, run:
./mvnw verify
```
### Client tests
### Unit tests
#### Set up
Expand Down Expand Up @@ -282,34 +282,46 @@ npx firebase init
- Enter when prompted for the project name so it defaulted to your project
- Select Authentication Emulator, Database Emulator when asked which emulators to setup
#### Screenshot test
#### Run unit tests
1. Start up just the local client
Unit tests are run by [Jest](https://jestjs.io/docs/getting-started). They're
located in [src/test/javascript/](src/test/javascript/) and can be run with:

```sh
yarn test
```

### End-to-end tests

We use the [WebDriverIO](https://webdriver.io/) framework for our end-to-end testing, allowing us to test interactions like a user and take screenshots. We provide two options for running these tests: locally and in docker.

**IMPORTANT**: Expect the screenshot tests to fail if ran locally due to resolution issues. Local development for screenshot tests is only recommended during development for faster iteration. To update screenshots, wait for the [GitHub action](.github/workflows/webdriver-test.yml) after pushing your changes and retrieve the updated screenshots from the `actual` folder.

#### Run tests locally

1. Follow the [Set up](#set-up) instructions

2. Start up just the local client

```sh
yarn start
```

2. Start the firebase emulator
3. Start the firebase emulator

```sh
yarn run firebase-emulator
```

3. Run web driver IO
4. Run web driver IO

```sh
yarn run wdio
```

#### Unit test
#### Run tests in Docker

Unit tests are run by [Jest](https://jestjs.io/docs/getting-started). They're
located in [src/test/javascript/](src/test/javascript/) and can be run with:

```sh
yarn test
```
Run `docker compose up` to build and run the tests. Make sure to update the images after making changes to the project.

## Build production docker image

Expand Down
17 changes: 12 additions & 5 deletions src/main/webapp/app/pages/curation/collapsible/BaseCollapsible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ export interface BaseCollapsibleProps {
showLoadingSpinner?: boolean;
}

function getDataTestid(dataTestid: string, identifier: React.ReactNode) {
if (typeof identifier === 'string') {
return `${identifier}-${dataTestid}`;
}
return dataTestid;
}

export default function BaseCollapsible({
children,
title,
Expand Down Expand Up @@ -64,7 +71,7 @@ export default function BaseCollapsible({
const infoComponent = useMemo(() => {
if (!displayOptions?.hideInfo) {
return (
<div className="d-flex" data-testid="collapsible-info">
<div className="d-flex" data-testid={getDataTestid('collapsible-info', title)}>
{info}
</div>
);
Expand All @@ -77,7 +84,7 @@ export default function BaseCollapsible({
return (
<>
<div className={classNames(styles.divider)} />
<div className={'collapsible-action all-children-margin'} data-testid="collapsible-action">
<div className={'collapsible-action all-children-margin'} data-testid={getDataTestid('collapsible-action', title)}>
{action}
</div>
</>
Expand All @@ -103,21 +110,21 @@ export default function BaseCollapsible({
};

return (
<div className={classNames('card', collapsibleClassName, styles.main)}>
<div className={classNames('card', collapsibleClassName, styles.main)} data-testid={getDataTestid('collapsible', title)}>
<div
className={classNames(
'd-flex align-items-center p-1 bg-transparent pe-2',
styles.header,
colorOptions?.hideLeftBorder ? styles.hiddenHeaderLeftBorder : undefined,
)}
ref={collapsibleRef}
data-testid="collapsible-card"
data-testid={getDataTestid('collapsible-card', title)}
>
<div style={{ flexGrow: 1 }} className="d-flex align-items-center">
<div
className={classNames(styles.collapsibleTitleWrapper, displayOptions?.disableCollapsible && styles.disabledCollapsible)}
onClick={handleToggle}
data-testid="collapsible-title-wrapper"
data-testid={getDataTestid('collapsible-title-wrapper', title)}
>
<button
disabled={displayOptions?.disableCollapsible || displayOptions?.hideToggle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import Collapsible, { CollapsibleProps } from './Collapsible';
import { DANGER } from 'app/config/colors';
import { DISABLED_COLLAPSIBLE_COLOR } from 'app/config/constants/constants';

const DEFAULT_TITLE = 'Default Title';

function buildCollapsible(props?: Partial<CollapsibleProps>) {
return (
<Collapsible title={'Default Title'} {...props}>
<Collapsible title={DEFAULT_TITLE} {...props}>
<div>Default content</div>
</Collapsible>
);
}

function assertToggleDisabled() {
expect(screen.getByRole('button')).toBeDisabled();
fireEvent.click(screen.getByTestId('collapsible-title-wrapper'));
fireEvent.click(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-title-wrapper`));
expect(screen.queryByText('Default content')).toBeNull();
}

Expand All @@ -24,10 +26,10 @@ describe('Collapsible tests', () => {
render(buildCollapsible());

expect(screen.queryByText('Default content')).toBeNull();
fireEvent.click(screen.getByTestId('collapsible-title-wrapper'));
fireEvent.click(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-title-wrapper`));
expect(screen.getByText('Default content')).toBeInTheDocument();

fireEvent.click(screen.getByTestId('collapsible-title-wrapper'));
fireEvent.click(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-title-wrapper`));
expect(screen.queryByText('Default content')).toBeNull();
});

Expand All @@ -48,7 +50,7 @@ describe('Collapsible tests', () => {
});

it('should have grey border', () => {
expect(screen.getByTestId('collapsible-card')).toHaveStyle(`border-left-color: ${DISABLED_COLLAPSIBLE_COLOR}`);
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-card`)).toHaveStyle(`border-left-color: ${DISABLED_COLLAPSIBLE_COLOR}`);
});

it('toggle button should be disabled', () => {
Expand All @@ -67,7 +69,7 @@ describe('Collapsible tests', () => {
});

it('should have red left border', () => {
expect(screen.getByTestId('collapsible-card')).toHaveStyle(`border-left-color: ${DANGER}`);
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-card`)).toHaveStyle(`border-left-color: ${DANGER}`);
});

it('toggle button should be disabled', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import '@testing-library/jest-dom';
import { RemovableCollapsible } from './RemovableCollapsible';
import { Review } from 'app/shared/model/firebase/firebase.model';

const DEFAULT_TITLE = 'Default Title';

function buildCollapsible(review: Review) {
return (
<RemovableCollapsible title={'Default Title'} review={review} info={<div>Info section</div>} action={<div>Action section</div>}>
<RemovableCollapsible title={DEFAULT_TITLE} review={review} info={<div>Info section</div>} action={<div>Action section</div>}>
<div>Default content</div>
</RemovableCollapsible>
);
Expand All @@ -23,11 +25,11 @@ describe('Removable Collapsible', () => {
});

it('should hide actions when pending deletion', () => {
expect(screen.queryByTestId('collapsible-action')).toBeNull();
expect(screen.queryByTestId(`${DEFAULT_TITLE}-collapsible-action`)).toBeNull();
});

it('should have info section', () => {
expect(screen.getByTestId('collapsible-info')).toBeInTheDocument();
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-info`)).toBeInTheDocument();
});
});

Expand All @@ -41,11 +43,11 @@ describe('Removable Collapsible', () => {
});

it('should hide actions when pending deletion', () => {
expect(screen.queryByTestId('collapsible-action')).toBeNull();
expect(screen.queryByTestId(`${DEFAULT_TITLE}-collapsible-action`)).toBeNull();
});

it('should have info section', () => {
expect(screen.getByTestId('collapsible-info')).toBeInTheDocument();
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-info`)).toBeInTheDocument();
});
});

Expand All @@ -58,11 +60,11 @@ describe('Removable Collapsible', () => {
});

it('should have action section', () => {
expect(screen.getByTestId('collapsible-action')).toBeInTheDocument();
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-action`)).toBeInTheDocument();
});

it('should have info section', () => {
expect(screen.getByTestId('collapsible-info')).toBeInTheDocument();
expect(screen.getByTestId(`${DEFAULT_TITLE}-collapsible-info`)).toBeInTheDocument();
});
});
});
6 changes: 3 additions & 3 deletions src/main/webapp/app/pages/curation/header/GeneHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,21 @@ const GeneHeader = ({
if (geneMetaReviewHasUuids(metaReview)) {
if (isReviewing || isReviewFinished) {
button = (
<Button color="primary" onClick={handleReviewButtonClick}>
<Button color="primary" onClick={handleReviewButtonClick} data-testid="review-complete-button">
Review Complete
</Button>
);
} else {
button = (
<Button outline color="primary" onClick={handleReviewButtonClick}>
<Button outline color="primary" onClick={handleReviewButtonClick} data-testid="review-button">
Review
</Button>
);
}
} else {
if (isReviewFinished) {
button = (
<Button color="primary" onClick={handleReviewButtonClick}>
<Button color="primary" onClick={handleReviewButtonClick} data-testid="review-complete-button">
Review Complete
</Button>
);
Expand Down
1 change: 1 addition & 0 deletions src/main/webapp/app/pages/curation/list/TherapiesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const TherapiesList = ({
);
})}
<Button
data-testid="add-therapy"
className={txObjects.length > 0 ? `mt-2` : null}
outline
color="primary"
Expand Down
4 changes: 2 additions & 2 deletions src/main/webapp/app/pages/curation/review/ReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const ReviewPage = (props: IReviewPageProps) => {
};

return (
<>
<div data-testid="review-page">
<Row className={`${getSectionClassName()} justify-content-between`}>
<Col>
{props.reviewFinished ? (
Expand Down Expand Up @@ -171,7 +171,7 @@ const ReviewPage = (props: IReviewPageProps) => {
</Col>
</Row>
) : undefined}
</>
</div>
);
};

Expand Down
48 changes: 25 additions & 23 deletions src/main/webapp/app/shared/modal/SimpleConfirmModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,31 @@ export const SimpleConfirmModal: React.FunctionComponent<{
};
return (
<Modal style={props.style} isOpen={props.show} toggle={() => onCancel()}>
<ModalHeader toggle={() => onCancel()}>{props.title || 'Please confirm'}</ModalHeader>
<ModalBody>{props.body ? props.body : 'Are you sure?'}</ModalBody>
<ModalFooter>
<Button color={props.cancelColor || 'secondary'} onClick={(event: any) => onCancel(event)}>
{props.cancelIcon && (
<>
<FontAwesomeIcon icon={props.cancelIcon} /> &nbsp;
</>
)}{' '}
{props.cancelText || 'Cancel'}
</Button>
<AsyncSaveButton
disabled={props.confirmDisabled}
color={props.confirmColor || 'primary'}
onClick={(event: any) => {
event.preventDefault();
if (props.onConfirm) props.onConfirm();
}}
icon={props.confirmIcon}
confirmText={props.confirmText}
isSavePending={props.showConfirmLoader}
/>
</ModalFooter>
<div data-testid="simple-confirm-modal-content">
<ModalHeader toggle={() => onCancel()}>{props.title || 'Please confirm'}</ModalHeader>
<ModalBody>{props.body ? props.body : 'Are you sure?'}</ModalBody>
<ModalFooter>
<Button color={props.cancelColor || 'secondary'} onClick={(event: any) => onCancel(event)}>
{props.cancelIcon && (
<>
<FontAwesomeIcon icon={props.cancelIcon} /> &nbsp;
</>
)}{' '}
{props.cancelText || 'Cancel'}
</Button>
<AsyncSaveButton
disabled={props.confirmDisabled}
color={props.confirmColor || 'primary'}
onClick={(event: any) => {
event.preventDefault();
if (props.onConfirm) props.onConfirm();
}}
icon={props.confirmIcon}
confirmText={props.confirmText}
isSavePending={props.showConfirmLoader}
/>
</ModalFooter>
</div>
</Modal>
);
};
5 changes: 3 additions & 2 deletions src/main/webapp/app/shared/table/VusTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const VusTable = ({
),
id: LAST_EDITED_AT,
accessor: 'time.value',
width: 250,
width: 300,
Cell(cell: { original: VusTableData }) {
const time = cell.original.time.value;
const color = getVusTimestampClass(time);
Expand Down Expand Up @@ -175,6 +175,7 @@ const VusTable = ({
{
id: 'actions',
Header: 'Actions',
width: 150,
sortable: false,
Cell(cell: { original: VusTableData }) {
return (
Expand Down Expand Up @@ -213,7 +214,7 @@ const VusTable = ({
return (
<>
{vusData ? (
<div className={'justify-content-between align-items-center mt-5'}>
<div className={'justify-content-between align-items-center mt-5'} data-testid="vus-table">
<div className={'d-flex align-items-center mb-2'}>
<span style={{ fontSize: '1.25rem' }}>Variants of Unknown Significance (Investigated and data not found)</span>
<AddButton className="ms-2" onClickHandler={() => setShowAddVusModal(true)} />
Expand Down
Loading

0 comments on commit cfbdbf8

Please sign in to comment.