skip to Main Content

I’m working on a project that utilizes Next.js, TypeScript, and Jest. I’m attempting to create a test using a component returned by the withTheme function from the RJSF (React JSONSchema Form) library. My intention is to use this component in the render function from @testing-library/react during a specific test. However, I’m encountering the following error:

FAIL src/common/components/JsonSchemaForm/ArrayFieldTemplate/SelectableArrayFieldTemplate/SelectableArrayField.test.tsx
  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box, Jest supports Babel, which will transform your files into valid JS based on your Babel configuration.

    By default, the "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see [link to Jest ECMAScript Modules documentation].
     • If you are trying to use TypeScript, see [link to Jest TypeScript documentation].
     • To transform some of your "node_modules" files, you can specify a custom "transformIgnorePatterns" in your Jest config.
     • If you need a custom transformation, specify a "transform" option in your config.
     • If you simply want to mock non-JS modules (e.g., binary assets), you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the Jest documentation:
    [link to Jest configuration docs]
    For information about custom transformations, see:
    [link to Jest code transformation docs]

    Details:

    /Users/jusbrasil/dg_dev/theodora-belisarius/node_modules/nanoid/index.browser.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { urlAlphabet } from './url-alphabet/index.js'
                                                                                      ^^^^^^

    SyntaxError: Cannot use an import statement outside a module

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1773:14)
      at Object.<anonymous> (node_modules/@rjsf/core/src/components/fields/ArrayField.js:21:1)

I’m using the following libraries with the specified versions:

@rjsf/antd: "^4.2.0"
@rjsf/core: "^4.2.0"
jest: "^28.0.3"
jest-axe: "^6.0.0"
jest-environment-jsdom: "^28.0.2"
antd: "^4.20.2"
@testing-library/jest-dom: "^5.16.4"
@testing-library/react: "12.1.5"
@testing-library/user-event: "^14.1.1"
typescript: "^4.4.3"

My Jest configuration file:

/* eslint-disable @typescript-eslint/no-var-requires */
const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './'
});

const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/setupTests.ts'],
  testEnvironment: 'jest-environment-jsdom',
  modulePaths: ['<rootDir>/src/', '<rootDir>/.jest'],
  testPathIgnorePatterns: ['/node_modules/', '/.next/'],
  collectCoverage: true,
  collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/pages/**/*.{js,jsx,ts,tsx}', '!**/*.d.ts', '!**/index.ts'],
  coverageThreshold: {
    global: {
      branches: 3.5,
      functions: 2.9,
      lines: 5.2,
      statements: 6.4
    }
  },
  moduleNameMapper: {
    '~/components/(.+)': '<rootDir>/src/components/$1',
    '__mocks__/(.+)': '<rootDir>/__mocks__/$1'
  }
};

module.exports = createJestConfig(customJestConfig);

My test file:

import { withTheme, FormProps } from '@rjsf/core';
import { render } from '@testing-library/react';
import type { JSONSchema7Object } from 'json-schema';

type SchemaFormOwnProps<T> = {
  formLabelPosition?: 'top' | 'side';
  customErrors?: any;
  formRef?: any;
  shouldDebounceInput?: boolean;
};

type SchemaFormProps<T> = FormProps<T> & SchemaFormOwnProps<T>;

const Theme = {
  ...AntDTheme,
  FieldTemplate,
  ArrayFieldTemplate,
  fields: {
    StringField
  }
};

const ThemedForm = withTheme(Theme);

const SchemaForm = <T extends object>({
  liveValidate = false,
  showErrorList = false,
  transformErrors = defaultTransformErrors,
  formLabelPosition = 'top',
  id = 'schema-form',
  shouldDebounceInput = true,
  schema,
  idPrefix,
  idSeparator = '_',
  children,
  onChange,
  onSubmit,
  onError,
  formRef: forwardRef,
  widgets = {},
  disabled,
  ...props
}: SchemaFormProps<T>) => {
  return (
    <ThemedForm
      {...props}
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      ref={formRef}
      id={id}
      idSeparator={idSeparator}
      className={formLabelPosition === 'top' ? 'ant-form-vertical' : 'ant-form-horizontal'}
      schema={schema}
      transformErrors={transformErrors}
      showErrorList={showErrorList}
      liveValidate={false}
      disabled={disabled}
    >
      {children}
    </ThemedForm>
  );
};

const schema: JSONSchema7Object = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      title: 'Name'
    }
  }
};

function renderComponent() {
  return render(<SchemaForm schema={schema} />);
}

describe('SelectableArrayFieldTemplate component', () => {
  it('should check if search bar is in the field', () => {
    const { container } = renderComponent();

    const elementWithFormItemControl = container.querySelector('.ant-form-item-control');
    const elementWithCard = elementWithFormItemControl?.querySelector('.ant-card');

    expect(elementWithCard).toBeInTheDocument();
  });
});

2

Answers


  1. Chosen as BEST ANSWER

    What worked for me, based on this answer:

    // jest.config.js
    /* eslint-disable @typescript-eslint/no-var-requires */
    const nextJest = require('next/jest');
    
    const createJestConfig = nextJest({
      dir: './'
    });
    
    const customJestConfig = {
      setupFilesAfterEnv: ['<rootDir>/setupTests.ts'],
      testEnvironment: 'jest-environment-jsdom',
      modulePaths: ['<rootDir>/src/', '<rootDir>/.jest'],
      testPathIgnorePatterns: ['/node_modules/', '/.next/'],
      collectCoverage: true,
      collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/pages/**/*.{js,jsx,ts,tsx}', '!**/*.d.ts', '!**/index.ts'],
      coverageThreshold: {
        global: {
          branches: 3.5,
          functions: 2.9,
          lines: 5.2,
          statements: 6.4
        }
      },
      moduleNameMapper: {
        '~/components/(.+)': '<rootDir>/src/components/$1',
        '__mocks__/(.+)': '<rootDir>/__mocks__/$1'
      }
    };
    
    module.exports = async () => ({
      ...(await createJestConfig(customJestConfig)()),
      transformIgnorePatterns: [
        'node_modules/(?!(nanoid|uuid)/)',
      ]
    })
    

  2. It seems that the Jest has problem with nanoid package.
    Try updating transformIgnorePatterns in the Jest configuration.

     transformIgnorePatterns: [
        "/node_modules/(?!nanoid).+\.js$"
      ],
    

    Also check your .babelrc config

    {
        "presets": ["next/babel"]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search