diff --git a/client/browser/src/shared/code-hosts/shared/codeHost.test.tsx b/client/browser/src/shared/code-hosts/shared/codeHost.test.tsx index bbf06c16e2d..b199ebd1a7f 100644 --- a/client/browser/src/shared/code-hosts/shared/codeHost.test.tsx +++ b/client/browser/src/shared/code-hosts/shared/codeHost.test.tsx @@ -1,9 +1,9 @@ import { nextTick } from 'process' import { promisify } from 'util' +import { RenderResult } from '@testing-library/react' import { Remote } from 'comlink' import { uniqueId, noop, isEmpty, pick } from 'lodash' -import renderer from 'react-test-renderer' import { BehaviorSubject, NEVER, of, Subject, Subscription } from 'rxjs' import { filter, take, first } from 'rxjs/operators' import { TestScheduler } from 'rxjs/testing' @@ -52,7 +52,7 @@ const notificationClassNames = { [NotificationType.Error]: 'error', } -const elementRenderedAtMount = (mount: Element): renderer.ReactTestRendererJSON | undefined => { +const elementRenderedAtMount = (mount: Element): RenderResult | undefined => { const call = RENDER.args.find(call => call[1] === mount) return call?.[0] } diff --git a/client/shared/src/actions/ActionItem.test.tsx b/client/shared/src/actions/ActionItem.test.tsx index c9d6071db1b..480b4154c3c 100644 --- a/client/shared/src/actions/ActionItem.test.tsx +++ b/client/shared/src/actions/ActionItem.test.tsx @@ -1,6 +1,7 @@ +import { render, screen, waitFor } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import * as H from 'history' import React from 'react' -import renderer from 'react-test-renderer' import { NEVER } from 'rxjs' import { createBarrier } from '../api/integration-test/testHelpers' @@ -16,7 +17,7 @@ describe('ActionItem', () => { const history = H.createMemoryHistory() test('non-actionItem variant', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('actionItem variant', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('noop command', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('pressed toggle actionItem', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('non-pressed actionItem', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('title element', () => { - const component = renderer.create( + const component = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(component.asFragment()).toMatchSnapshot() }) test('run command', async () => { const { wait, done } = createBarrier() - const component = renderer.create( + const { container, asFragment } = render( { ) // Run command and wait for execution to finish. - let tree = component.toJSON() - tree!.props.onClick({ preventDefault: () => undefined, currentTarget: { blur: () => undefined } }) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + userEvent.click(container) + expect(asFragment()).toMatchSnapshot() // Finish execution. (Use setTimeout to wait for the executeCommand resolution to result in the setState // call.) done() await new Promise(resolve => setTimeout(resolve)) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + expect(asFragment()).toMatchSnapshot() }) test('run command with showLoadingSpinnerDuringExecution', async () => { const { wait, done } = createBarrier() - const component = renderer.create( + const { asFragment } = render( { ) // Run command and wait for execution to finish. - let tree = component.toJSON() - tree!.props.onClick({ preventDefault: () => undefined, currentTarget: { blur: () => undefined } }) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + userEvent.click(screen.getByRole('button')) + + await waitFor(() => { + expect(screen.getByTestId('action-item-spinner')).toBeInTheDocument() + }) + + expect(asFragment()).toMatchSnapshot() // Finish execution. (Use setTimeout to wait for the executeCommand resolution to result in the setState // call.) done() await new Promise(resolve => setTimeout(resolve)) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + expect(asFragment()).toMatchSnapshot() }) test('run command with error', async () => { - const component = renderer.create( + const { asFragment } = render( { // Run command (which will reject with an error). (Use setTimeout to wait for the executeCommand resolution // to result in the setState call.) - let tree = component.toJSON() - tree!.props.onClick({ preventDefault: () => undefined, currentTarget: { blur: () => undefined } }) + userEvent.click(screen.getByRole('button')) + await new Promise(resolve => setTimeout(resolve)) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + + expect(asFragment()).toMatchSnapshot() }) test('run command with error with showInlineError', async () => { - const component = renderer.create( + const { asFragment } = render( { // Run command (which will reject with an error). (Use setTimeout to wait for the executeCommand resolution // to result in the setState call.) - let tree = component.toJSON() - tree!.props.onClick({ preventDefault: () => undefined, currentTarget: { blur: () => undefined } }) + userEvent.click(screen.getByRole('button')) + await new Promise(resolve => setTimeout(resolve)) - tree = component.toJSON() - expect(tree).toMatchSnapshot() + + expect(asFragment()).toMatchSnapshot() }) describe('"open" command', () => { it('renders as link', () => { jsdom.reconfigure({ url: 'https://example.com/foo' }) - const component = renderer.create( + const { asFragment } = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(asFragment()).toMatchSnapshot() }) it('renders as link with icon and opens a new tab for a different origin', () => { jsdom.reconfigure({ url: 'https://example.com/foo' }) - const component = renderer.create( + const { asFragment } = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(asFragment()).toMatchSnapshot() }) it('renders as link that opens in a new tab, but without icon for a different origin as the alt action and a primary action defined', () => { jsdom.reconfigure({ url: 'https://example.com/foo' }) - const component = renderer.create( + const { asFragment } = render( { platformContext={NOOP_PLATFORM_CONTEXT} /> ) - expect(component.toJSON()).toMatchSnapshot() + expect(asFragment()).toMatchSnapshot() }) }) }) diff --git a/client/shared/src/actions/ActionItem.tsx b/client/shared/src/actions/ActionItem.tsx index 3c1f44f88b2..db020e3c20b 100644 --- a/client/shared/src/actions/ActionItem.tsx +++ b/client/shared/src/actions/ActionItem.tsx @@ -277,7 +277,7 @@ export class ActionItem extends React.PureComponent { )} {showLoadingSpinner && ( -
+
)} diff --git a/client/shared/src/actions/__snapshots__/ActionItem.test.tsx.snap b/client/shared/src/actions/__snapshots__/ActionItem.test.tsx.snap index bedbf4d2d09..98b5dcd6bb8 100644 --- a/client/shared/src/actions/__snapshots__/ActionItem.test.tsx.snap +++ b/client/shared/src/actions/__snapshots__/ActionItem.test.tsx.snap @@ -1,307 +1,262 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`ActionItem "open" command renders as link 1`] = ` - - - - t - - + + + t + + `; exports[`ActionItem "open" command renders as link that opens in a new tab, but without icon for a different origin as the alt action and a primary action defined 1`] = ` - - - - primary - - + + + primary + + `; exports[`ActionItem "open" command renders as link with icon and opens a new tab for a different origin 1`] = ` - - - - t - - - + + + t + + + `; exports[`ActionItem actionItem variant 1`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem non-actionItem variant 1`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem non-pressed actionItem 1`] = ` - - b - - + + + b + + `; exports[`ActionItem noop command 1`] = ` - - d - - g: - t - + + + d + g: t + + `; exports[`ActionItem pressed toggle actionItem 1`] = ` - - b - - + + + b + + `; exports[`ActionItem run command 1`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem run command 2`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem run command with error 1`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem run command with error with showInlineError 1`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem run command with showLoadingSpinnerDuringExecution 1`] = ` - - d - - g: - t - -
+ -
-
-
+ g: t +
+
+
+ + `; exports[`ActionItem run command with showLoadingSpinnerDuringExecution 2`] = ` - - d - - g: - t - - + + + d + g: t + + `; exports[`ActionItem title element 1`] = ` - - - t2 - - - + + + + t2 + + + + `; diff --git a/client/web/src/enterprise/user/productSubscriptions/UserProductSubscriptionStatus.test.tsx b/client/web/src/enterprise/user/productSubscriptions/UserProductSubscriptionStatus.test.tsx index a074ff4fe66..30147951a7e 100644 --- a/client/web/src/enterprise/user/productSubscriptions/UserProductSubscriptionStatus.test.tsx +++ b/client/web/src/enterprise/user/productSubscriptions/UserProductSubscriptionStatus.test.tsx @@ -1,5 +1,6 @@ +import { render, screen } from '@testing-library/react' +import userEvent from '@testing-library/user-event' import React from 'react' -import renderer, { act } from 'react-test-renderer' import { UserProductSubscriptionStatus } from './UserProductSubscriptionStatus' @@ -9,7 +10,7 @@ jest.mock('../../../components/CopyableText', () => ({ CopyableText: 'CopyableTe describe('UserProductSubscriptionStatus', () => { test('toggle', () => { - const component = renderer.create( + const { asFragment } = render( { licenseKey="lk" /> ) - expect(component.toJSON()).toMatchSnapshot('license key hidden') + expect(asFragment()).toMatchSnapshot('license key hidden') // Click "Reveal license key" button. - act(() => component.root.findByType('button').props.onClick()) - expect(component.toJSON()).toMatchSnapshot('license key revealed') + const button = screen.getByRole('button') + userEvent.click(button) + expect(asFragment()).toMatchSnapshot('license key revealed') }) }) diff --git a/client/web/src/enterprise/user/productSubscriptions/__snapshots__/UserProductSubscriptionStatus.test.tsx.snap b/client/web/src/enterprise/user/productSubscriptions/__snapshots__/UserProductSubscriptionStatus.test.tsx.snap index 02612ac3430..bf951a65144 100644 --- a/client/web/src/enterprise/user/productSubscriptions/__snapshots__/UserProductSubscriptionStatus.test.tsx.snap +++ b/client/web/src/enterprise/user/productSubscriptions/__snapshots__/UserProductSubscriptionStatus.test.tsx.snap @@ -1,167 +1,159 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`UserProductSubscriptionStatus toggle: license key hidden 1`] = ` -
+
- Sourcegraph logo -
-

- P -

-

- 123-user - license, - - - expired on - - 1970-01-01 - - (36 years ago) - -

-
-
-
-
-
+
+ + `; diff --git a/client/web/src/site-admin/init/SiteInitPage.test.tsx b/client/web/src/site-admin/init/SiteInitPage.test.tsx index a2806e20475..8d99bbf2f9c 100644 --- a/client/web/src/site-admin/init/SiteInitPage.test.tsx +++ b/client/web/src/site-admin/init/SiteInitPage.test.tsx @@ -1,6 +1,7 @@ +import { render } from '@testing-library/react' +import { createMemoryHistory } from 'history' import React from 'react' -import { MemoryRouter, Redirect } from 'react-router' -import renderer from 'react-test-renderer' +import { Router } from 'react-router' import { EMPTY_FEATURE_FLAGS } from '../../featureFlags/featureFlags' @@ -18,8 +19,9 @@ describe('SiteInitPage', () => { }) test('site already initialized', () => { - const component = renderer.create( - + const history = createMemoryHistory({ initialEntries: ['/'] }) + render( + { context={{ authProviders: [], sourcegraphDotComMode: false }} featureFlags={EMPTY_FEATURE_FLAGS} /> - + ) - const redirect = component.root.findByType(Redirect) - expect(redirect).toBeDefined() - expect(redirect.props.to).toEqual('/search') + expect(history.location.pathname).toEqual('/search') }) test('unexpected authed user', () => expect( - renderer - .create( - - ) - .toJSON() + render( + + ).asFragment() ).toMatchSnapshot()) test('normal', () => expect( - renderer - .create( - - ) - .toJSON() + render( + + ).asFragment() ).toMatchSnapshot()) }) diff --git a/client/web/src/site-admin/init/__snapshots__/SiteInitPage.test.tsx.snap b/client/web/src/site-admin/init/__snapshots__/SiteInitPage.test.tsx.snap index e3af4b41dfe..a72450c9338 100644 --- a/client/web/src/site-admin/init/__snapshots__/SiteInitPage.test.tsx.snap +++ b/client/web/src/site-admin/init/__snapshots__/SiteInitPage.test.tsx.snap @@ -1,165 +1,160 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`SiteInitPage normal 1`] = ` -
+
- Sourcegraph logo -

- Welcome -

-

- Create an admin account to start using Sourcegraph. -

-
-
+

+ Welcome +

+

+ Create an admin account to start using Sourcegraph. +

+ -
- + +
+ +
-
-
-
- + +
+ +
-
-
-
- + +
+ +
+ + At least 12 characters +
- - At least 12 characters - -
-
- -
-
+ +
+ +
-
+ `; exports[`SiteInitPage unexpected authed user 1`] = ` -
+
- Sourcegraph logo -

- You're signed in as - - alice - - . A site admin must initialize Sourcegraph before you can continue. -

+
+ Sourcegraph logo +

+ You're signed in as + + alice + + . A site admin must initialize Sourcegraph before you can continue. +

+
-
+ `; diff --git a/client/web/src/site-admin/overview/SiteAdminOverviewPage.test.tsx b/client/web/src/site-admin/overview/SiteAdminOverviewPage.test.tsx index 2e4ef8fabdd..c5d192dae22 100644 --- a/client/web/src/site-admin/overview/SiteAdminOverviewPage.test.tsx +++ b/client/web/src/site-admin/overview/SiteAdminOverviewPage.test.tsx @@ -1,6 +1,6 @@ +import { render, waitFor } from '@testing-library/react' import * as H from 'history' import React from 'react' -import renderer from 'react-test-renderer' import { of } from 'rxjs' import sinon from 'sinon' @@ -21,8 +21,8 @@ describe('SiteAdminOverviewPage', () => { overviewComponents: [], } - test('activation in progress', done => { - const component = renderer.create( + test('activation in progress', async () => { + const component = render( { /> ) // ensure the hooks ran and the "API response" has been received - setTimeout(() => { - expect(component.toJSON()).toMatchSnapshot() - done() - }) + await waitFor(() => expect(component.asFragment()).toMatchSnapshot()) }) - test('< 2 users', done => { - const component = renderer.create( + test('< 2 users', async () => { + const component = render( @@ -101,12 +98,10 @@ describe('SiteAdminOverviewPage', () => { /> ) // ensure the hooks ran and the "API response" has been received - setTimeout(() => { - expect(component.toJSON()).toMatchSnapshot() - done() - }) + await waitFor(() => expect(component.asFragment()).toMatchSnapshot()) }) - test('>= 2 users', done => { + + test('>= 2 users', async () => { const usageStat: ISiteUsagePeriod = { __typename: 'SiteUsagePeriod', userCount: 10, @@ -115,7 +110,14 @@ describe('SiteAdminOverviewPage', () => { integrationUserCount: 0, startTime: new Date().toISOString(), } - const component = renderer.create( + + // Do this mock for resolving issue + // `Error: Uncaught [TypeError: tspan.node(...).getComputedTextLength is not a function` + // from `client/web/src/components/d3/BarChart.tsx` + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access + ;(window.SVGElement as any).prototype.getComputedTextLength = () => 500 + + const component = render( @@ -144,9 +146,6 @@ describe('SiteAdminOverviewPage', () => { /> ) // ensure the hooks ran and the "API response" has been received - setTimeout(() => { - expect(component.toJSON()).toMatchSnapshot() - done() - }) + await waitFor(() => expect(component.asFragment()).toMatchSnapshot()) }) }) diff --git a/client/web/src/site-admin/overview/__snapshots__/SiteAdminOverviewPage.test.tsx.snap b/client/web/src/site-admin/overview/__snapshots__/SiteAdminOverviewPage.test.tsx.snap index a0882f07f20..0630673fe0c 100644 --- a/client/web/src/site-admin/overview/__snapshots__/SiteAdminOverviewPage.test.tsx.snap +++ b/client/web/src/site-admin/overview/__snapshots__/SiteAdminOverviewPage.test.tsx.snap @@ -1,353 +1,452 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`SiteAdminOverviewPage < 2 users 1`] = ` -
+ + `; exports[`SiteAdminOverviewPage >= 2 users 1`] = ` -
+
-
- - 100 - - repositories - - - 1,825,299,556 - - bytes stored - - - 2,616,264 - - lines of code indexed - - - 10 - - users - - - 5 - - organizations - - - 100 - - user survey responses -
+
-
+ 100 repositories + + + 1,825,299,556 bytes stored + + + 2,616,264 lines of code indexed + + + 10 users + + + 5 organizations + + + 100 user survey responses + +
- - 10 - - active users - last week - - -
-
+
+ + + + + + + + + + + + + + + + 10 + + + 10 + + + - - - + + + + + + Tue, + + + Jan + + + 3 + + + + + + + + + GMT/UTC time + +
- - - - GMT/UTC time - -
-
+ `; exports[`SiteAdminOverviewPage activation in progress 1`] = ` -
+
- -
- Welcome to Sourcegraph -
-
-
- Complete the steps below to finish onboarding to Sourcegraph -
-
- -
-
-
-
+ +
+
+
+
+
-
- - - -
-
- -
+
- -
+ `; diff --git a/package.json b/package.json index 94bb8d8b014..452c1e21d44 100644 --- a/package.json +++ b/package.json @@ -296,7 +296,6 @@ "puppeteer-firefox": "^0.5.1", "react-refresh": "^0.10.0", "react-spring": "^9.0.0", - "react-test-renderer": "^16.14.0", "sass": "^1.32.4", "sass-loader": "^12.1.0", "shelljs": "^0.8.4", diff --git a/yarn.lock b/yarn.lock index d70189ce270..9089ea9a134 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19681,7 +19681,7 @@ react-syntax-highlighter@^13.5.3: prismjs "^1.21.0" refractor "^3.1.0" -react-test-renderer@^16.0.0-0, react-test-renderer@^16.14.0, "react-test-renderer@^16.8.0 || ^17.0.0": +react-test-renderer@^16.0.0-0, "react-test-renderer@^16.8.0 || ^17.0.0": version "16.14.0" resolved "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae" integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==