diff --git a/packages/next/build/jest/jest.ts b/packages/next/build/jest/jest.ts index 844afc8e22308..1dbd27da10374 100644 --- a/packages/next/build/jest/jest.ts +++ b/packages/next/build/jest/jest.ts @@ -1,6 +1,7 @@ import { loadEnvConfig } from '@next/env' import { resolve, join } from 'path' import loadConfig from '../../server/config' +import { NextConfigComplete } from '../../server/config-shared' import { PHASE_TEST } from '../../shared/lib/constants' import loadJsConfig from '../load-jsconfig' import * as Log from '../output/log' @@ -27,6 +28,16 @@ function loadClosestPackageJson(dir: string, attempts = 1): any { } } +/** Loads dotenv files and sets environment variables based on next config. */ +function setUpEnv(dir: string, nextConfig: NextConfigComplete) { + const dev = false + loadEnvConfig(dir, dev, Log) + + if (nextConfig.experimental.newNextLinkBehavior) { + process.env.__NEXT_NEW_LINK_BEHAVIOR = 'true' + } +} + /* // Usage in jest.config.js const nextJest = require('next/jest'); @@ -61,7 +72,7 @@ export default function nextJest(options: { dir?: string } = {}) { isEsmProject = packageConfig.type === 'module' nextConfig = await getConfig(resolvedDir) - loadEnvConfig(resolvedDir, false, Log) + setUpEnv(resolvedDir, nextConfig) // TODO: revisit when bug in SWC is fixed that strips `.css` const result = await loadJsConfig(resolvedDir, nextConfig) jsConfig = result.jsConfig diff --git a/test/production/jest/new-link-behavior.test.ts b/test/production/jest/new-link-behavior.test.ts new file mode 100644 index 0000000000000..f088713a443a8 --- /dev/null +++ b/test/production/jest/new-link-behavior.test.ts @@ -0,0 +1,86 @@ +import { createNext } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' + +describe('next/jest', () => { + let next: NextInstance + + if (process.env.NEXT_TEST_REACT_VERSION === '^17') { + // react testing library is specific to react version + it('should bail on react v17', () => {}) + return + } + + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.jsx': ` + import Link from 'next/link' + + export default function Page() { + return Hello World! + } + `, + 'test/index.test.jsx': ` + import { render, screen, act } from '@testing-library/react' + import Page from '../pages/index' + + it('Link', () => { + act(() => { + render() + + const link = screen.getByRole('link', { name: 'Hello World!' }) + expect(link.getAttribute('href')).toBe('https://example.com') + }) + }) + `, + 'jest.config.js': ` + const nextJest = require('next/jest') + const createJestConfig = nextJest({ dir: './' }) + module.exports = createJestConfig({ + testEnvironment: 'jest-environment-jsdom', + }) + `, + }, + dependencies: { + jest: '27.4.7', + '@testing-library/react': '12.1.2', + }, + packageJson: { + scripts: { + build: 'next build && yarn jest --forceExit test/index.test.jsx', + }, + }, + skipStart: true, + buildCommand: `yarn build`, + }) + }) + + afterAll(() => next.destroy()) + + it(`should use normal Link behavior when newNextLinkBehavior is unset`, async () => { + await next.start() + }) + + it(`should use new link behavior when newNextLinkBehavior is true`, async () => { + await next.stop() + + await next.patchFile( + 'pages/index.jsx', + ` + import Link from 'next/link' + + export default function Page() { + return
Hello World!
+ } + ` + ) + await next.patchFile( + 'next.config.js', + ` + module.exports = { experimental: { newNextLinkBehavior: true } } + ` + ) + + await next.start() + }) +})