diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4d69335a..5a559a2b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -32,7 +32,7 @@ jobs:
node-version: "14.x"
- uses: c-hive/gha-yarn-cache@v1
- run: yarn install --frozen-lockfile
- - run: yarn test --coverage
+ - run: yarn test --coverage --runInBand
- name: Coveralls
uses: coverallsapp/github-action@master
with:
@@ -69,7 +69,7 @@ jobs:
node-version: "14.x"
- uses: c-hive/gha-yarn-cache@v1
- run: yarn install --frozen-lockfile
- - run: yarn test --coverage --forceExit
+ - run: yarn test --coverage --forceExit --runInBand
- name: Coveralls
uses: coverallsapp/github-action@master
with:
@@ -104,7 +104,7 @@ jobs:
node-version: "14.x"
- uses: c-hive/gha-yarn-cache@v1
- run: yarn install --frozen-lockfile
- - run: yarn test --coverage
+ - run: yarn test --coverage --runInBand
- name: Coveralls
uses: coverallsapp/github-action@master
with:
diff --git a/spotlight-client/src/App-auth.test.tsx b/spotlight-client/src/App-auth.test.tsx
index e95b1be2..7db57834 100644
--- a/spotlight-client/src/App-auth.test.tsx
+++ b/spotlight-client/src/App-auth.test.tsx
@@ -77,14 +77,12 @@ afterEach(() => {
cleanup();
});
-// TODO (#353) async specs fail intermittently
-test.skip("no auth required", async () => {
+test("no auth required", async () => {
const App = await getApp();
render();
// site home redirects to the ND home
- const websiteName = await screen.findByRole("heading", {
- name: authenticatedTextMatch,
- });
+ const websiteName = await screen.findByTestId("PageTitle");
+ expect(websiteName).toHaveTextContent(authenticatedTextMatch);
expect(websiteName).toBeInTheDocument();
});
@@ -112,8 +110,7 @@ test("requires authentication", async () => {
});
});
-// TODO (#353) async specs fail intermittently
-test.skip("requires email verification", async () => {
+test("requires email verification", async () => {
// configure environment for valid authentication
process.env.REACT_APP_AUTH_ENABLED = "true";
process.env.REACT_APP_AUTH_ENV = "development";
@@ -126,12 +123,10 @@ test.skip("requires email verification", async () => {
render();
await waitFor(() => {
// application contents should not have been rendered without verification
- expect(
- screen.queryByRole("heading", { name: authenticatedTextMatch })
- ).not.toBeInTheDocument();
+ expect(screen.queryByTestId("PageTitle")).not.toBeInTheDocument();
// there should be a message about the verification requirement
expect(
- screen.getByRole("heading", { name: /verification/i })
+ screen.getByRole("heading", { name: /verification/i, hidden: true })
).toBeInTheDocument();
});
});
diff --git a/spotlight-client/src/App.test.tsx b/spotlight-client/src/App.test.tsx
index 32ceeea1..60b01f38 100644
--- a/spotlight-client/src/App.test.tsx
+++ b/spotlight-client/src/App.test.tsx
@@ -107,8 +107,7 @@ describe("navigation", () => {
expect(screen.getByRole(...lookupArgs)).toBeInTheDocument();
});
- // TODO (#353) async specs fail intermittently
- test.skip("links", async () => {
+ test("links", async () => {
renderNavigableApp();
const inNav = within(screen.getByRole("navigation"));
@@ -120,38 +119,41 @@ describe("navigation", () => {
});
fireEvent.click(sentencingLink);
- expect(
- await screen.findByRole("heading", { name: "Sentencing", level: 1 })
- ).toBeInTheDocument();
+ // NOTE: *ByRole queries can be too expensive to run async with this much DOM,
+ // so we are using *ByTestId queries here instead
+ await waitFor(async () =>
+ expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
+ "Sentencing"
+ )
+ );
fireEvent.click(tenantLink);
- expect(
- await screen.findByRole("heading", {
- name: "Explore correctional data from North Dakota.",
- level: 1,
- })
- ).toBeInTheDocument();
+ await waitFor(async () =>
+ expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
+ "Explore correctional data from North Dakota."
+ )
+ );
const disparitiesLink = screen.getByRole("link", {
name: "Racial Disparities",
});
fireEvent.click(disparitiesLink);
- expect(
- await screen.findByRole("heading", {
- name: "Racial Disparities",
- level: 1,
- })
- ).toBeInTheDocument();
+ await waitFor(async () =>
+ expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
+ "Racial Disparities"
+ )
+ );
fireEvent.click(homeLink);
// home redirect to ND
- expect(
- await screen.findByRole("heading", { name: /North Dakota/, level: 1 })
- ).toBeInTheDocument();
+ await waitFor(async () =>
+ expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
+ "North Dakota"
+ )
+ );
});
- // TODO (#353) async specs fail intermittently
- test.skip("pageview tracking", async () => {
+ test("pageview tracking", async () => {
segmentMock.page.mockReset();
const {
@@ -168,10 +170,6 @@ describe("navigation", () => {
);
expect(segmentMock.page).toHaveBeenCalledTimes(2);
- // in-page navigation doesn't trigger additional pageviews
- await act(() => navigate(`/us-nd/${NarrativesSlug}/prison/2`));
- expect(segmentMock.page).toHaveBeenCalledTimes(2);
-
await act(() => navigate(`/us-nd/${NarrativesSlug}/sentencing`));
expect(document.title).toBe(
diff --git a/spotlight-client/src/Loading/Loading.tsx b/spotlight-client/src/Loading/Loading.tsx
index 0b276316..4ef10abc 100644
--- a/spotlight-client/src/Loading/Loading.tsx
+++ b/spotlight-client/src/Loading/Loading.tsx
@@ -53,7 +53,7 @@ const LoadingSpinnerText = styled.div`
export default function Loading(): JSX.Element {
return (
-
+
Data is loading
diff --git a/spotlight-client/src/ModelHydrator/ModelHydrator.test.tsx b/spotlight-client/src/ModelHydrator/ModelHydrator.test.tsx
index e4e03890..721ed7d7 100644
--- a/spotlight-client/src/ModelHydrator/ModelHydrator.test.tsx
+++ b/spotlight-client/src/ModelHydrator/ModelHydrator.test.tsx
@@ -56,14 +56,13 @@ test("hydration in progress", () => {
expect(screen.queryByText("hydrated")).not.toBeInTheDocument();
});
-// TODO (#353) async specs fail intermittently
-test.skip("hydrated", async () => {
+test("hydrated", async () => {
runInAction(() => {
mockModel.isLoading = false;
});
await waitFor(() => {
- expect(screen.queryByRole("status")).not.toBeInTheDocument();
+ expect(screen.queryByTestId("LoadingIndicator")).not.toBeInTheDocument();
expect(screen.getByText("hydrated")).toBeInTheDocument();
});
});
diff --git a/spotlight-client/src/RacialDisparitiesNarrativePage/RacialDisparitiesNarrativePage.test.tsx b/spotlight-client/src/RacialDisparitiesNarrativePage/RacialDisparitiesNarrativePage.test.tsx
index 7f4d6065..b5caf97a 100644
--- a/spotlight-client/src/RacialDisparitiesNarrativePage/RacialDisparitiesNarrativePage.test.tsx
+++ b/spotlight-client/src/RacialDisparitiesNarrativePage/RacialDisparitiesNarrativePage.test.tsx
@@ -32,9 +32,9 @@ beforeEach(() => {
});
test("renders all the sections", async () => {
- expect(
- await screen.findByRole("heading", { name: "Racial Disparities", level: 1 })
- ).toBeInTheDocument();
+ expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
+ "Racial Disparities"
+ );
return Promise.all(
Object.values(narrativeContent.sections).map(async (section) => {
diff --git a/spotlight-client/src/UiLibrary/PageTitle.ts b/spotlight-client/src/UiLibrary/PageTitle.ts
index 94632218..94b573c9 100644
--- a/spotlight-client/src/UiLibrary/PageTitle.ts
+++ b/spotlight-client/src/UiLibrary/PageTitle.ts
@@ -20,7 +20,7 @@ import styled from "styled-components/macro";
import breakpoints from "./breakpoints";
import { typefaces } from "./typography";
-export default styled.h1`
+export default styled.h1.attrs({ "data-testid": "PageTitle" })`
font-family: ${typefaces.display};
font-size: ${rem(32)};
letter-spacing: -0.04em;
diff --git a/spotlight-client/src/VizPopulationBreakdownByLocation/VizPopulationBreakdownByLocation.test.tsx b/spotlight-client/src/VizPopulationBreakdownByLocation/VizPopulationBreakdownByLocation.test.tsx
index 83906ad3..f2ceb1cb 100644
--- a/spotlight-client/src/VizPopulationBreakdownByLocation/VizPopulationBreakdownByLocation.test.tsx
+++ b/spotlight-client/src/VizPopulationBreakdownByLocation/VizPopulationBreakdownByLocation.test.tsx
@@ -54,12 +54,11 @@ test("loading", () => {
expect(screen.getByText(/loading/i)).toBeInTheDocument();
});
-// TODO (#353) async specs fail intermittently
-test.skip("total counts", async () => {
+test("total counts", async () => {
renderWithStore();
await waitFor(() => {
- const stat = screen.getByRole("figure", { name: "Total people in prison" });
+ const stat = screen.getByLabelText("Total people in prison");
expect(stat).toBeVisible();
expect(within(stat).getByText("2,041")).toBeVisible();
});
@@ -140,8 +139,7 @@ test.skip("total counts", async () => {
).toHaveStyle(`fill: ${colors.dataViz[1]}`);
});
-// TODO (#353) async specs fail intermittently
-test.skip("counts filtered by locality", async () => {
+test("counts filtered by locality", async () => {
renderWithStore();
await when(() => !metric.isLoading);
@@ -158,7 +156,7 @@ test.skip("counts filtered by locality", async () => {
fireEvent.click(option);
await waitFor(() => {
- const stat = screen.getByRole("figure", { name: "Total people in prison" });
+ const stat = screen.getByLabelText("Total people in prison");
expect(within(stat).getByText("413")).toBeVisible();
});
diff --git a/spotlight-client/src/VizRecidivismRateCumulative/VizRecidivismRateCumulative.test.tsx b/spotlight-client/src/VizRecidivismRateCumulative/VizRecidivismRateCumulative.test.tsx
index d9d71260..3cc7b07d 100644
--- a/spotlight-client/src/VizRecidivismRateCumulative/VizRecidivismRateCumulative.test.tsx
+++ b/spotlight-client/src/VizRecidivismRateCumulative/VizRecidivismRateCumulative.test.tsx
@@ -88,8 +88,7 @@ test("total chart", async () => {
}
});
-// TODO (#353) async specs fail intermittently
-test.skip("demographic charts", async () => {
+test("demographic charts", async () => {
renderWithStore();
await when(() => !metric.isLoading);
@@ -110,10 +109,6 @@ test.skip("demographic charts", async () => {
name: "5 lines in a line chart",
});
- await waitFor(() => {
- expect(lineChart).toBeVisible();
- });
-
expect(
within(lineChart).getAllByRole("img", {
name: /^3 point line starting value 0% at 0 ending value \d+% at 2/,
@@ -127,10 +122,6 @@ test.skip("demographic charts", async () => {
name: "2 lines in a line chart",
});
- await waitFor(() => {
- expect(lineChart).toBeVisible();
- });
-
expect(
within(lineChart).getAllByRole("img", {
name: /^3 point line starting value 0% at 0 ending value \d+% at 2/,
@@ -146,8 +137,6 @@ test.skip("demographic charts", async () => {
});
});
- expect(lineChart).toBeVisible();
-
expect(
within(lineChart).getAllByRole("img", {
name: /^3 point line starting value 0% at 0 ending value \d+% at 2/,
diff --git a/spotlight-client/src/VizRecidivismRateSingleFollowup/VizRecidivismRateSingleFollowup.test.tsx b/spotlight-client/src/VizRecidivismRateSingleFollowup/VizRecidivismRateSingleFollowup.test.tsx
index 961237f1..f00770f8 100644
--- a/spotlight-client/src/VizRecidivismRateSingleFollowup/VizRecidivismRateSingleFollowup.test.tsx
+++ b/spotlight-client/src/VizRecidivismRateSingleFollowup/VizRecidivismRateSingleFollowup.test.tsx
@@ -102,8 +102,7 @@ test("total chart", async () => {
).toBeInTheDocument();
});
-// TODO (#353) async specs fail intermittently
-test.skip("demographic charts", async () => {
+test("demographic charts", async () => {
renderWithStore();
await when(() => !metric.isLoading);
@@ -159,8 +158,9 @@ test("followup period filter", async () => {
fireEvent.click(menuButton);
fireEvent.click(screen.getByRole("option", { name: "1 Year" }));
- const oneYearChart = screen.getByRole("group", {
+ const oneYearChart = await screen.findByRole("group", {
name: "10 bars in a bar chart",
+ hidden: true,
});
expect(oneYearChart).toBeVisible();