Skip to content

Commit

Permalink
Add test helpers (#373)
Browse files Browse the repository at this point in the history
Add a test helpers file with `getByTextWithMarkup` and `waitForLoadingToFinish` helpers.
  • Loading branch information
denniskigen authored Sep 9, 2021
1 parent f1fb520 commit 67d817a
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import { fetchPatientRelationships } from './relationships.resource';
import ContactDetails from './contact-details.component';
import { waitForLoadingToFinish } from '../../../../tools/test-helpers';

const testProps = {
address: [
Expand Down Expand Up @@ -67,9 +68,3 @@ describe('ContactDetails: ', () => {
function renderContactDetails() {
render(<ContactDetails {...testProps} />);
}

function waitForLoadingToFinish() {
waitForElementToBeRemoved(() => [...screen.queryAllByRole(/progressbar/i, ...screen.queryAllByText(/loading/i))], {
timeout: 4000,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react';
import { delay } from 'rxjs/operators';
import { of } from 'rxjs/internal/observable/of';
import { throwError } from 'rxjs/internal/observable/throwError';
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import { attach, fhirBaseUrl, openmrsObservableFetch } from '@openmrs/esm-framework';
import { mockPatient } from '../../../../__mocks__/patient.mock';
import { mockFhirConditionsResponse } from '../../../../__mocks__/conditions.mock';
import userEvent from '@testing-library/user-event';
import ConditionsDetailedSummary from './conditions-detailed-summary.component';
import { waitForLoadingToFinish } from '../../../../tools/test-helpers';

const mockAttach = attach as jest.Mock;
const mockOpenmrsObservableFetch = openmrsObservableFetch as jest.Mock;
Expand All @@ -28,12 +29,6 @@ function renderConditionsDetailedSummary() {
render(<ConditionsDetailedSummary />);
}

function waitForLoadingToFinish() {
return waitForElementToBeRemoved(() => [...screen.queryAllByRole(/progressbar/i)], {
timeout: 4000,
});
}

it('renders an empty state view if conditions data is unavailable', async () => {
mockOpenmrsObservableFetch.mockReturnValueOnce(of({ data: [] }).pipe(delay(10)));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { searchedCondition } from '../../../../__mocks__/conditions.mock';
import { createErrorHandler, detach, showNotification, showToast } from '@openmrs/esm-framework';
import { createPatientCondition, searchConditionConcepts } from './conditions.resource';
import ConditionsForm from './conditions-form.component';
import { getByTextWithMarkup } from '../../../../tools/test-helpers';

const utc = require('dayjs/plugin/utc');
dayjs.extend(utc);
Expand Down Expand Up @@ -131,18 +132,7 @@ describe('ConditionsForm: ', () => {

expect(screen.queryByRole('menuitem', { name: /Post-acute sequelae of COVID-19/i })).not.toBeInTheDocument();
expect(screen.getByDisplayValue(/Post-acute sequelae of COVID-19/i)).toBeInTheDocument();

expect(
screen.getByText((content, node) => {
const textMatch = 'No results for "Post-acute sequelae of COVID-19"';
const hasText = (node: Element) => node.textContent === textMatch || node.textContent.match(textMatch);

const nodeHasText = hasText(node);
const childrenDontHaveText = Array.from(node.children).every((child) => !hasText(child));

return nodeHasText && childrenDontHaveText;
}),
).toBeInTheDocument();
expect(getByTextWithMarkup('No results for "Post-acute sequelae of COVID-19"')).toBeInTheDocument();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react';
import { delay } from 'rxjs/operators';
import { of } from 'rxjs/internal/observable/of';
import { throwError } from 'rxjs/internal/observable/throwError';
import { render, screen, waitForElementToBeRemoved } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import ConditionsOverview from './conditions-overview.component';
import { mockPatient } from '../../../../__mocks__/patient.mock';
import { attach, fhirBaseUrl, openmrsObservableFetch } from '@openmrs/esm-framework';
import { mockFhirConditionsResponse } from '../../../../__mocks__/conditions.mock';
import { waitForLoadingToFinish } from '../../../../tools/test-helpers';

const mockAttach = attach as jest.Mock;
const mockOpenmrsObservableFetch = openmrsObservableFetch as jest.Mock;
Expand All @@ -26,12 +27,6 @@ function renderConditionsOverview() {
render(<ConditionsOverview {...testProps} />);
}

function waitForLoadingToFinish() {
return waitForElementToBeRemoved(() => [...screen.queryAllByRole(/progressbar/i)], {
timeout: 4000,
});
}

it('renders an empty state view if conditions data is unavailable', async () => {
mockOpenmrsObservableFetch.mockReturnValueOnce(of({ data: [] }).pipe(delay(10)));

Expand Down
14 changes: 2 additions & 12 deletions packages/esm-patient-notes-app/src/notes/visit-notes-form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from '../../../../__mocks__/visit-note.mock';
import VisitNotesForm from './visit-notes-form.component';
import { mockSessionDataResponse } from '../../../../__mocks__/session.mock';
import { getByTextWithMarkup } from '../../../../tools/test-helpers';

jest.mock('lodash-es/debounce', () => jest.fn((fn) => fn));

Expand Down Expand Up @@ -113,18 +114,7 @@ describe('Visit notes form: ', () => {

const searchbox = screen.getByRole('searchbox');
userEvent.type(searchbox, 'COVID-21');

expect(
screen.getByText((content, node) => {
const textMatch = 'No diagnoses found matching "COVID-21"';
const hasText = (node: Element) => node.textContent === textMatch || node.textContent.match(textMatch);

const nodeHasText = hasText(node);
const childrenDontHaveText = Array.from(node.children).every((child) => !hasText(child));

return nodeHasText && childrenDontHaveText;
}),
).toBeInTheDocument();
expect(getByTextWithMarkup('No diagnoses found matching "COVID-21"')).toBeInTheDocument();
});

it('closes the form and the workspace when the cancel button is clicked', () => {
Expand Down
38 changes: 19 additions & 19 deletions tools/i18next-parser.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
module.exports = {
contextSeparator: "_",
contextSeparator: '_',
// Key separator used in your translation keys

createOldCatalogs: false,
// Save the \_old files

defaultNamespace: "translations",
defaultNamespace: 'translations',
// Default namespace used in your i18next config

defaultValue: "",
defaultValue: '',
// Default value to give to empty keys
// You may also specify a function accepting the locale, namespace, and key as arguments

Expand All @@ -18,43 +18,43 @@ module.exports = {
keepRemoved: false,
// Keep keys from the catalog that are no longer in code

keySeparator: ".",
keySeparator: '.',
// Key separator used in your translation keys
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.

// see below for more details
lexers: {
hbs: ["HandlebarsLexer"],
handlebars: ["HandlebarsLexer"],
hbs: ['HandlebarsLexer'],
handlebars: ['HandlebarsLexer'],

htm: ["HTMLLexer"],
html: ["HTMLLexer"],
htm: ['HTMLLexer'],
html: ['HTMLLexer'],

mjs: ["JavascriptLexer"],
js: ["JavascriptLexer"], // if you're writing jsx inside .js files, change this to JsxLexer
ts: ["JavascriptLexer"],
jsx: ["JsxLexer"],
tsx: ["JsxLexer"],
mjs: ['JavascriptLexer'],
js: ['JavascriptLexer'], // if you're writing jsx inside .js files, change this to JsxLexer
ts: ['JavascriptLexer'],
jsx: ['JsxLexer'],
tsx: ['JsxLexer'],

default: ["JavascriptLexer"],
default: ['JavascriptLexer'],
},

lineEnding: "auto",
lineEnding: 'auto',
// Control the line ending. See options at https://github.com/ryanve/eol

locales: ["en"],
locales: ['en'],
// An array of the locales in your applications

namespaceSeparator: ":",
namespaceSeparator: ':',
// Namespace separator used in your translation keys
// If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.

output: "$NAMESPACE/$LOCALE.json",
output: '$NAMESPACE/$LOCALE.json',
// Supports $LOCALE and $NAMESPACE injection
// Supports JSON (.json) and YAML (.yml) file formats
// Where to write the locale files relative to process.cwd()

pluralSeparator: "_",
pluralSeparator: '_',
// Plural separator used in your translation keys
// If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys.

Expand Down
16 changes: 16 additions & 0 deletions tools/test-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { screen, waitForElementToBeRemoved } from '@testing-library/react';

// Custom matcher that queries elements split up by multiple HTML elements by text
export function getByTextWithMarkup(text: RegExp | string) {
return screen.getByText((content, node) => {
const hasText = (node: Element) => node.textContent === text || node.textContent.match(text);
const childrenDontHaveText = Array.from(node.children).every((child) => !hasText(child as HTMLElement));
return hasText(node) && childrenDontHaveText;
});
}

export function waitForLoadingToFinish() {
return waitForElementToBeRemoved(() => [...screen.queryAllByRole(/progressbar/i)], {
timeout: 4000,
});
}

0 comments on commit 67d817a

Please sign in to comment.