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

[MNT] Implemented component tests #31

Merged
merged 26 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e841532
Bumped Cypress
rmanaem Feb 19, 2024
9226eba
Implemented `CategoricalField` component test
rmanaem Feb 19, 2024
4fa9955
Implemented `ContinuousField` component test
rmanaem Feb 19, 2024
9b163dd
Implemented `DownloadResultButton` component test
rmanaem Feb 19, 2024
98409dc
Implemented `NBDialog` component test
rmanaem Feb 19, 2024
4097cb7
Added `component-test` workflow
rmanaem Feb 19, 2024
01a1a34
Fixed the indentation of `component-test` workflow config file
rmanaem Feb 19, 2024
1ea24b5
Fixed typos
rmanaem Feb 19, 2024
2e6888b
Cleaned up `component-test` workflow config file
rmanaem Feb 19, 2024
f90e64a
Implemented `Navbar` component test
rmanaem Feb 20, 2024
24368c9
Updated .gitignore
rmanaem Feb 20, 2024
1a05871
Implemented a test case for `QueryForm` component
rmanaem Feb 20, 2024
ea85108
Implemented logic for disabling Diagnosis field
rmanaem Feb 20, 2024
933a87c
Implemented test cases for `QueryForm` event handlers
rmanaem Feb 20, 2024
7eccb58
Imported styles into cypress component tests
rmanaem Feb 20, 2024
5f75929
Implemented `ResultCard` component test
rmanaem Feb 20, 2024
2293066
Aligned types with API response model
rmanaem Feb 20, 2024
b7a28f4
Implemented `ResultContainer` component test
rmanaem Feb 20, 2024
f7679a0
Fixed the issue with displaying error for an empty continuous field
rmanaem Feb 21, 2024
2bedd0f
Implemented `Form` e2e test
rmanaem Feb 21, 2024
0a5d1fb
Updated `component-test` workflow trigger event
rmanaem Feb 21, 2024
c09bfa8
Ran prettier
rmanaem Feb 21, 2024
481fdcc
Updated `ResultsTSV` e2e test
rmanaem Feb 21, 2024
d8d4565
Refactored tests
rmanaem Feb 23, 2024
45dc8fd
Updated `Form` e2e test
rmanaem Feb 23, 2024
c312006
Update `Navbar` component test
rmanaem Feb 26, 2024
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
27 changes: 27 additions & 0 deletions .github/workflows/component-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: component tests

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
component-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Create .env file
run: |
echo -e "NB_API_QUERY_URL=${{ vars.NB_API_QUERY_URL }}\nNB_IS_FEDERATION_API=${{ vars.NB_IS_FEDERATION_API }}" > .env
surchs marked this conversation as resolved.
Show resolved Hide resolved

- name: build
run: npm install && npm run build

- name: Run component tests
uses: cypress-io/github-action@v6
with:
component: true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ dist-ssr

# Environment files
.env

# Cypress
cypress/screenshots
cypress/downloads
71 changes: 71 additions & 0 deletions cypress/component/CategoricalField.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import CategoricalField from '../../src/components/CategoricalField';

const props = {
label: 'Categorical Field',
options: [
{ id: '1', label: 'Option 1' },
{ id: '2', label: 'Option 2' },
{ id: '3', label: 'Option 3' },
],
onFieldChange: () => {},
multiple: false,
inputValue: null,
};

describe('CategoricalField', () => {
it('Displays a MUI Autocomplete with the label and options passed as props', () => {
cy.mount(
<CategoricalField
label={props.label}
options={props.options}
onFieldChange={props.onFieldChange}
inputValue={props.inputValue}
/>
);
cy.get('[data-cy="Categorical Field-categorical-field"]').should('be.visible');
cy.get('[data-cy="Categorical Field-categorical-field"] label').should(
'contain',
'Categorical Field'
);
props.options.forEach((option) => {
cy.get('[data-cy="Categorical Field-categorical-field"]').type(
`${option.label}{downarrow}{enter}`
);
cy.get('[data-cy="Categorical Field-categorical-field"] input').should(
'have.value',
option.label
);
cy.get('[data-cy="Categorical Field-categorical-field"]').clear();
});
});
it('Displays the input value passed as props', () => {
cy.mount(
<CategoricalField
label={props.label}
options={props.options}
onFieldChange={props.onFieldChange}
inputValue={props.options[0]}
/>
);
cy.get('[data-cy="Categorical Field-categorical-field"] input').should(
'have.value',
'Option 1'
);
});
it('Fires onFieldChange event handler with the appropriate payload when a value is selected', () => {
const onFieldChangeSpy = cy.spy().as('onFieldChangeSpy');
cy.mount(
<CategoricalField
label={props.label}
options={props.options}
onFieldChange={onFieldChangeSpy}
inputValue={props.inputValue}
/>
);
cy.get('[data-cy="Categorical Field-categorical-field"]').type('Option 1{downarrow}{enter}');
cy.get('@onFieldChangeSpy').should('have.been.calledWith', 'Categorical Field', {
id: '1',
label: 'Option 1',
});
});
});
42 changes: 42 additions & 0 deletions cypress/component/ContinuousField.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ContinuousField from '../../src/components/ContinuousField';

const props = {
helperText: 'This is a helper text',
label: 'Continuous Field',
onFieldChange: () => {},
};

describe('ContinuousField', () => {
it('Displays a MUI Textfield and a label as passed via prop', () => {
cy.mount(<ContinuousField label={props.label} onFieldChange={props.onFieldChange} />);
cy.get('[data-cy="Continuous Field-continuous-field"]').should('be.visible');
cy.get('[data-cy="Continuous Field-continuous-field"] label').should(
'contain',
'Continuous Field'
);
cy.get('[data-cy="Continuous Field-continuous-field"] label').should(
'not.have.class',
'Mui-error'
);
});
it('Displays a MUI Textfield in error state when the helper text is not empty', () => {
cy.mount(
<ContinuousField
label={props.label}
onFieldChange={props.onFieldChange}
helperText={props.helperText}
/>
);
cy.get('[data-cy="Continuous Field-continuous-field"] p').should(
'contain',
'This is a helper text'
);
cy.get('[data-cy="Continuous Field-continuous-field"] label').should('have.class', 'Mui-error');
});
it('Fires onFieldChange event handler with the appropriate payload when a value is entered', () => {
const onFieldChangeSpy = cy.spy().as('onFieldChangeSpy');
cy.mount(<ContinuousField label={props.label} onFieldChange={onFieldChangeSpy} />);
cy.get('[data-cy="Continuous Field-continuous-field"]').type('10');
cy.get('@onFieldChangeSpy').should('have.been.calledWith', 'Continuous Field', 10);
});
});
45 changes: 45 additions & 0 deletions cypress/component/DownloadResultButton.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import DownloadResultButton from '../../src/components/DownloadResultButton';

const props = {
identifier: 'test',
disabled: false,
handleClick: () => {},
};

describe('DownloadResultButton', () => {
it('Displays an enabled MUI Button with the identifier passed as prop', () => {
cy.mount(
<DownloadResultButton
identifier={props.identifier}
disabled={props.disabled}
handleClick={props.handleClick}
/>
);
cy.get('[data-cy="test-download-results-button"]').should('be.visible');
cy.get('[data-cy="test-download-results-button"]').should('contain', 'Download test Result');
cy.get('[data-cy="test-download-results-button"]').should('not.be', 'disabled');
});
it('Displays a disabled MUI Button and a tooltip when the button is hovered over', () => {
cy.mount(
<DownloadResultButton
identifier={props.identifier}
disabled
handleClick={props.handleClick}
/>
);
cy.get('[data-cy="test-download-results-button"]').trigger('mouseover', { force: true });
cy.get('.MuiTooltip-tooltip').should('contain', 'Please select at least one dataset');
});
it('Fires the handleClick event handler with the appropriate payload when the button is clicked', () => {
const handleClickSpy = cy.spy().as('handleClickSpy');
cy.mount(
<DownloadResultButton
identifier={props.identifier}
disabled={props.disabled}
handleClick={handleClickSpy}
/>
);
cy.get('[data-cy="test-download-results-button"]').click();
cy.get('@handleClickSpy').should('have.been.calledWith', 'test');
});
});
28 changes: 28 additions & 0 deletions cypress/component/NBDialog.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import NBDialog from '../../src/components/NBDialog';

const props = {
open: true,
onClose: () => {},
};

describe('NBDialog', () => {
it('Displays a MUI Diaglog with the title and content', () => {
cy.mount(<NBDialog open={props.open} onClose={props.onClose} />);
cy.get('[data-cy="nb-dialog"]').should('be.visible');
cy.get('[data-cy="nb-dialog"] h2').should('contain', 'Example usage');
cy.get('[data-cy="nb-dialog"] p').should(
'contain',
'The command for automatically getting the data currently only applies to datasets available through datalad.'
);
});
it("Doesn't display the dialog when open prop is set to false", () => {
cy.mount(<NBDialog open={false} onClose={props.onClose} />);
cy.get('[data-cy="nb-dialog"]').should('not.exist');
});
it('Fires onClose event handler when the close button is clicked', () => {
const onCloseSpy = cy.spy().as('onCloseSpy');
cy.mount(<NBDialog open={props.open} onClose={onCloseSpy} />);
cy.get('[data-cy="nb-dialog"] button').click();
cy.get('@onCloseSpy').should('have.been.called');
});
});
21 changes: 21 additions & 0 deletions cypress/component/Navbar.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Navbar from '../../src/components/Navbar';

describe('Navbar', () => {
it('Displays a MUI Toolbar with logo, title, subtitle, documentation link, and GitHub link', () => {
cy.mount(<Navbar />);
cy.get("[data-cy='navbar']").should('be.visible');
cy.get("[data-cy='navbar'] img").should('exist');
cy.get("[data-cy='navbar'] h5").should('contain', 'Neurobagel Query');
cy.get("[data-cy='navbar'] p").should(
'contain',
'Define and find cohorts at the subject level'
);
cy.get("[data-cy='navbar'] a")
.should('contain', 'Documentation')
.should('have.attr', 'href', 'https://neurobagel.org/query_tool/');
cy.get("[data-cy='navbar'] a").eq(1).find('svg').should('be.visible');
cy.get("[data-cy='navbar'] a")
.eq(1)
.should('have.attr', 'href', 'https://github.com/neurobagel/react-query-tool/');
});
});
Loading