cloudscape-design / jest-preset

Jest presets for Cloudscape Design System
https://cloudscape.design/
Apache License 2.0
5 stars 1 forks source link

Make Jest preset work on Windows #33

Open Mythra opened 5 months ago

Mythra commented 5 months ago

Package version

2.0.28

Jest version

29.7.0

node-versions

20.9.0

npm-versions

10.2.3

Description

Hi đź‘‹ This is my first frontend project in quite awhile, I was able to get the UI & styling working in the way I wanted. However, I'm now running into an error upon trying to actually write tests for these react components. Specifically jest gets an unexpected token even though I have setup the project according to the documentation as far as I can tell.

The exact error I'm getting is:

 FAIL  source/ui/components/account-bar/__tests__/account-bar.tsx
  â—Ź Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. 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 be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.       
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your 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 docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    D:\github\<project-name>\packages\browser-extension\node_modules\@cloudscape-design\components\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as Alert } from './alert';
                                                                                      ^^^^^^

    SyntaxError: Unexpected token 'export'

      2 | import "./styles.css";
      3 |
    > 4 | import { TextContent } from "@cloudscape-design/components";
        | ^
      5 |
      6 | export default () => {
      7 |       return (

Source code

Although I can't share links directly to the code I can share the following snippets, please let me know if you need anymore:

pacakge.json ```json { "name": "", "private": true, "license": "UNLICENSED", "version": "0.1.0", "description": "", "author": "", "keywords": [ "aws", "", "aws accounts", "aws console", "aws credentials" ], "scripts": { "build": "cross-env TARGET=chromium,firefox webpack --config webpack/webpack.config.js", "format": "prettier . --write", "format:check": "prettier . --check", "package": "cross-env NODE_ENV=production TARGET=chromium,firefox PACKAGE_CRXS=true PACKAGE_XPIS=true webpack --config webpack/webpack.config.js", "package:chrome": "cross-env NODE_ENV=production TARGET=chromium PACKAGE_CRXS=true webpack --config webpack/webpack.config.js", "package:firefox": "cross-env NODE_ENV=production TARGET=firefox PACKAGE_CRXS=false PACKAGE_XPIS=true webpack --config webpack/webpack.config.js", "test": "jest --silent" }, "dependencies": { "@cloudscape-design/collection-hooks": "^1.0.36", "@cloudscape-design/components": "^3.0.529", "@cloudscape-design/design-tokens": "^3.0.34", "@cloudscape-design/global-styles": "^1.0.23", "react": "^18.2.0", "react-dom": "^18.2.0", "react-virtual": "^2.10.4" }, "devDependencies": { "@cloudscape-design/components-themeable": "^3.0.544", "@cloudscape-design/jest-preset": "^2.0.28", "@cloudscape-design/theming-build": "^1.0.51", "@types/chrome": "^0.0.260", "@types/firefox-webext-browser": "^120.0.0", "@types/jest": "^29.5.12", "@types/react": "^18.2.55", "@types/react-dom": "^18.2.19", "@types/react-test-renderer": "^18.0.7", "archiver": "^6.0.1", "copy-webpack-plugin": "^12.0.2", "cross-env": "^7.0.3", "crx": "^5.0.1", "css-loader": "^6.10.0", "git-revision-webpack-plugin": "^5.0.0", "jest": "^29.7.0", "merge": "^2.1.1", "mkdirp": "^3.0.1", "prettier": "3.2.5", "react-test-renderer": "^18.2.0", "sass": "^1.70.0", "sass-loader": "^14.1.0", "style-loader": "^3.3.4", "ts-jest": "^29.1.2", "ts-loader": "^9.5.1", "typescript": "^5.3.3", "webpack": "^5.90.1", "webpack-cli": "^5.1.4" }, "overrides": { "react-virtual": { "react": "$react" } } } ```
jest.config.js ```js const merge = require("merge"); const tsPreset = require("ts-jest/jest-preset"); const cloudscapePreset = require("@cloudscape-design/jest-preset"); module.exports = merge.recursive(tsPreset, cloudscapePreset, { globals: { GIT_SHORTHASH: "0000000", GIT_HASH: "0000000000000000000000000000000000000000", }, moduleNameMapper: { // As an explanation for this -- we have some "developer custom" components that are always rendered in night theme, these are generated as recommended in the render documentation -- but we're not using them for this test case, so we know it's not these that are an issue. // There may be a problem in the future but i'm not worried about that right now. "@//forced-night-theme/@cloudscape-design/components": "/build/cloudscape-devbar-theme/components", "@//forced-night-theme/@cloudscape-design/design-tokens": "/build/cloudscape-devbar-theme/design-tokens", "^.+\\.(css|scss|sass)$": "/webpack/css-stub.js", }, roots: ["/source"], testMatch: ["**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)"], }); ```
account-bar\index.tsx ```typescript import React from "react"; import "./styles.css"; import { TextContent } from "@cloudscape-design/components"; export default () => { return ( ); }; ```
account-bar\__tests__\account-bar.tsx ```typescript import React from "react"; import ReactTestRenderer from "react-test-renderer"; import AccountBar from "../"; it("can render the accountbar", () => { const renderer = ReactTestRenderer.create(); console.log(renderer.toJSON()); }); ```

Code of Conduct

just-boris commented 4 months ago

Everything looks as expected, except moduleNameMapper config.

It seems like you are using a custom themed package. Jest preset is only for the original components. For your themed package you need to configure this on your end

Mythra commented 4 months ago

Hi,

As I tried to mention in the original source code for jest.config.js, I'm not actually testing the mapped modules right now. To confirm this isn't an issue, I've removed that block entirely. So now I've got:

const merge = require("merge");
const tsPreset = require("ts-jest/jest-preset");
const cloudscapePreset = require("@cloudscape-design/jest-preset");

module.exports = merge.recursive(tsPreset, cloudscapePreset, {
    globals: {
        GIT_SHORTHASH: "0000000",
        GIT_HASH: "0000000000000000000000000000000000000000",
    },
    moduleNameMapper: {
        "^.+\\.(css|scss|sass)$": "<rootDir>/webpack/css-stub.js",
    },
    roots: ["<rootDir>/source"],
    testMatch: ["**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)"],
});

And I've still got the same error. If it's helpful, this seems to be the final module exports:

> node
Welcome to Node.js v20.9.0.       
Type ".help" for more information.
> const data = require("./jest.config.js");
undefined
> data
{
  transform: {
    '^.+\\.tsx?$': [ 'ts-jest', {} ],
    'node_modules/@cloudscape-design/.+\\.js$': 'D:\\github\\<project>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\js-transformer.js',
    'node_modules/@cloudscape-design/.+\\.css': 'D:\\github\\<project>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\css-transformer.js',
    'node_modules/(d3-.*|internmap)/.+\\.js$': 'D:\\github\\<project>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\js-transformer.js'
  },
  transformIgnorePatterns: [ '/node_modules/(?!(d3-.*|internmap|@cloudscape-design/)).+\\.js$' ],
  globals: {
    GIT_SHORTHASH: '0000000',
    GIT_HASH: '0000000000000000000000000000000000000000'
  },
  moduleNameMapper: { '^.+\\.(css|scss|sass)$': '<rootDir>/webpack/css-stub.js' },
  roots: [ '<rootDir>/source' ],
  testMatch: [
    '**/__tests__/**/*.+(ts|tsx|js)',
    '**/?(*.)+(spec|test).+(ts|tsx|js)'
  ]
}

And FWIW css-stub.js is just:

module.exports = {};
tannerbyers commented 4 months ago

Hey @Mythra, the cause of this issue is roots being set to <rootDir>/source but your npm modules are not in that directory so they're not being found & transformed to cjs. I tested myself (setting roots to a sub folder and node modules in another sub folder) and it fails for same reason as yours.

Could you add a roots route for node modules or removing roots from the config and updating the routes? Something like:

    roots: ["<rootDir>/source", "<rootDir>/node_modules"],
Mythra commented 4 months ago

Hi @tannerbyers ,

Thanks for that pointer! That certainly makes sense. I've gone ahead and remove that block because i don't think we ever really required it being set there -- probably got set without thinking. Good news is! Running this all in WSL (linux on windows), ran into a different error I was able to fix quickly, and tests now pass (specifically I had to switch the test environment to jsdom, and install jsdom as a development dependency).

Unfortunately, in WSL tests are relatively slow, and unfortunately the error is not fixed on Windows :( I did also try adding in explicitly <rootDir>/source, and <rootDir>/node_modules just incase but the error remained as well. I'm kind of unblocked here being able to run in WSL but it's certainly not ideal. The current jest configuration stands at:

const merge = require("merge");
const tsPreset = require("ts-jest/jest-preset");
const cloudscapePreset = require("@cloudscape-design/jest-preset");

module.exports = merge.recursive(tsPreset, cloudscapePreset, {
    globals: {
        GIT_SHORTHASH: "0000000",
        GIT_HASH: "0000000000000000000000000000000000000000",
    },
    moduleNameMapper: {
        "^.+\\.(css|scss|sass)$": "<rootDir>/webpack/css-stub.js",
    },
    testEnvironment: "jsdom",
    testMatch: ["**/__tests__/**/*.+(ts|tsx|js)", "**/?(*.)+(spec|test).+(ts|tsx|js)"],
});

Which translates to the following:

{
  transform: {
    '^.+\\.tsx?$': [ 'ts-jest', {} ],
    'node_modules/@cloudscape-design/.+\\.js$': 'D:\\github\\<project name>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\js-transformer.js',
    'node_modules/@cloudscape-design/.+\\.css': 'D:\\github\\<project name>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\css-transformer.js',
    'node_modules/(d3-.*|internmap)/.+\\.js$': 'D:\\github\\<project name>\\packages\\browser-extension\\node_modules\\@cloudscape-design\\jest-preset\\js-transformer.js'
  },
  transformIgnorePatterns: [ '/node_modules/(?!(d3-.*|internmap|@cloudscape-design/)).+\\.js$' ],
  globals: {
    GIT_SHORTHASH: '0000000',
    GIT_HASH: '0000000000000000000000000000000000000000'
  },
  moduleNameMapper: { '^.+\\.(css|scss|sass)$': '<rootDir>/webpack/css-stub.js' },
  testEnvironment: 'jsdom',
  testMatch: [
    '**/__tests__/**/*.+(ts|tsx|js)',
    '**/?(*.)+(spec|test).+(ts|tsx|js)'
  ]
}
just-boris commented 4 months ago

Closing as no actions required on our end. Feel free to reopen if you find anything needed from the preset.

Mythra commented 4 months ago

Hey @just-boris ,

To be clear I think there's still an open item here, where the preset isn't working out of the box on Windows for me? It's only working in Linux based environments, is Windows not supported? Was there something I missed I needed to do for Windows specifically?

Mythra commented 4 months ago

For what it’s worth I don’t seem to have permission to re-open the issue either, not sure if you expect folks to be able too, but at least I can’t right now.

just-boris commented 4 months ago

I can convert this to a feature request to support Windows environment in the preset, but it is a feature request only, not a bug, because it was not intended to work in the first place

Mythra commented 4 months ago

Hey @just-boris , That's really good to know that Windows development was not intended to be supported. I'll admit I said that almost a bit rhetorically not expecting that a major development platform wouldn't be supported without any mention of it in any Cloudscape docs. I realize this is a question a bit larger than just the jest preset, but I don't know quite where else to ask it... are there other parts of cloudscape that don't support windows explicitly? Can we document we don't support one of the major 3 OS's that folks may attempt to use these libraries with?

just-boris commented 4 months ago

This is briefly mentioned in the contribution instructions how to build our own package: https://github.com/cloudscape-design/components/blob/b8e8e21de3ee2e21ff62896df4af4adb7e3341d8/CONTRIBUTING.md?plain=1#L61

But the same applies also to our dev tooling, including this preset. Contributions are welcome, but our team has no plans doing any changes on that platform.