Tests not working upgrading node version 14 -> 16+

I have been building an app since Ionic/react v5. I updated to Ionic/react and the CLI required I use node v16 or higher. Unfortunately when I did the upgrade I noticed that my existing Jest/React Testing Library tests that all passed when I was using node 14 started to fail. It takes FOREVER to run my tests on node v16 and they fail with weird issues like:

var evt = document.createEvent('Event');
                         ^
TypeError: Cannot read properties of null (reading 'createEvent')

Or weird timeout issues. I am absolutely stumped as to why my tests only fail on node v16 or higher, and I am reaching out to the internet for help.

Here is my package.json

{
  "name": "",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "@aws-amplify/ui-react": "^4.6.1",
    "@aws-sdk/client-textract": "^3.131.0",
    "@aws-sdk/s3-request-presigner": "^3.267.0",
    "@capacitor-firebase/analytics": "^5.1.0",
    "@capacitor-firebase/messaging": "^5.0.0",
    "@capacitor-mlkit/barcode-scanning": "^5.1.0",
    "@capacitor/android": "^5.0.0",
    "@capacitor/app": "^5.0.0",
    "@capacitor/assets": "^1.0.10",
    "@capacitor/camera": "^5.0.0",
    "@capacitor/core": "^5.0.0",
    "@capacitor/filesystem": "^5.1.1",
    "@capacitor/haptics": "^5.0.0",
    "@capacitor/ios": "^5.0.0",
    "@capacitor/keyboard": "^5.0.0",
    "@capacitor/local-notifications": "^5.0.0",
    "@capacitor/preferences": "^5.0.0",
    "@capacitor/share": "^5.0.6",
    "@capacitor/status-bar": "^5.0.0",
    "@capawesome/capacitor-app-update": "^5.0.0",
    "@emotion/react": "^11.10.0",
    "@emotion/styled": "^11.10.0",
    "@ionic/react": "^6.4.1",
    "@ionic/react-router": "^6.4.1",
    "@ionic/react-test-utils": "^0.4.0",
    "@mui/icons-material": "^5.8.4",
    "@mui/material": "^5.10.1",
    "@stripe/react-stripe-js": "^1.16.4",
    "@stripe/stripe-js": "^1.46.0",
    "@tanstack/react-query": "^4.0.10",
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/react-hooks": "^8.0.1",
    "@testing-library/user-event": "^12.6.3",
    "@types/jest": "^26.0.20",
    "@types/node": "^12.19.15",
    "@types/react": "^17",
    "@types/react-dom": "^16.9.10",
    "@types/react-router": "^5.1.11",
    "@types/react-router-dom": "^5.1.7",
    "aws-amplify": "^5.2.1",
    "aws-sdk": "^2.1278.0",
    "axios": "^0.27.2",
    "buffer": "^6.0.3",
    "capacitor-rate-app": "^4.0.0",
    "chrono-node": "^2.3.8",
    "email-validator": "^2.0.4",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-plugin-prettier": "^4.2.1",
    "firebase": "^9.23.0",
    "html-react-parser": "^4.2.1",
    "ionicons": "^5.4.0",
    "luxon": "^3.0.1",
    "msw": "^0.49.1",
    "pdf-lib": "^1.17.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-helmet-async": "^1.3.0",
    "react-hook-form": "^7.34.2",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "^5.0.0",
    "stripe": "^11.6.0",
    "swiper": "^9.4.1",
    "typescript": "^4.1.3",
    "use-callback-ref": "^1.3.0",
    "uuid": "^8.3.2",
    "web-vitals": "^0.2.4",
    "workbox-background-sync": "^5.1.4",
    "workbox-broadcast-update": "^5.1.4",
    "workbox-cacheable-response": "^5.1.4",
    "workbox-core": "^5.1.4",
    "workbox-expiration": "^5.1.4",
    "workbox-google-analytics": "^5.1.4",
    "workbox-navigation-preload": "^5.1.4",
    "workbox-precaching": "^5.1.4",
    "workbox-range-requests": "^5.1.4",
    "workbox-routing": "^5.1.4",
    "workbox-strategies": "^5.1.4",
    "workbox-streams": "^5.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "start:android": "ionic caprun android --livereload --external",
    "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
    "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons|swiper|ssr-window)/)' --watchAll=false",
     "test:coverage": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons|swiper|ssr-window)/)' --coverage --watchAll=false",
    "test:csvBuilder": "cd amplify/backend/function/csvBuilder/src && npm run test",
    "test:email": "cd amplify/backend/function/email/src && npm run test",
    "test:monitorTextractUsage": "cd amplify/backend/function/monitorTextractUsage/src && npm run test",
    "test:moveReceiptsStorageTier": "cd amplify/backend/function/moveReceiptsStorageTier/src && npm run test",
    "test:notifications": "cd amplify/backend/function/notifications/src && npm run test",
    "test:successfulPayment": "cd amplify/backend/function/successfulPayment/src && npm run test",
    "test:textractUsageReset": "cd amplify/backend/function/textractUsageReset/src && npm run test",
    "test:stripePaymentIntent": "cd amplify/backend/function/stripePaymentIntent/src && npm run test",
    "test:taxRefundCalculation": "cd amplify/backend/function/taxRefundCalculation/src && npm run test",
    "test:lambdas": "npm run test:monitorTextractUsage && npm run test:textractUsageReset && npm run test:successfulPayment && npm run test:email && npm run test:stripePaymentIntent && npm run test:taxRefundCalculation && npm run test:csvBuilder && npm run test:notifications && npm run test:moveReceiptsStorageTier",
    "test:all": "npm run test && npm run test:lambdas",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@capacitor/cli": "^5.0.0",
    "@testing-library/dom": "^9.3.0",
    "@types/luxon": "^3.0.0",
    "@types/react-helmet": "^6.1.6",
    "@types/uuid": "^8.3.4",
    "eslint-config-prettier": "^8.5.0",
    "jest-watch-typeahead": "^0.6.5",
    "prettier": "^2.7.1"
  },
  "description": "An Ionic project",
  "jest": {
    "moduleNameMapper": {
      "\\.(css|less)$": "identity-obj-proxy"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!(@ionic|ionicons))"
    ]
  }
}

After trying what seemed like a million different things to speed up tests and reduce errors, I finally decided to just try the migration guide from Ionic v6 to Ionic v7. Following along in the instructions provided here:

https://ionicframework.com/docs/updating/7-0#browser-support

I did the following CLI commands:

  • npm install react@latest react-dom@latest
  • npm install @ionic/react@7 @ionic/react-router@7

After upgrading and making sure I had no breaking changes in my components, I used nvm to switch to node version 21. I ran npm run test and miraculously my year long bug has been solved! Tests are now working on node version 16 through node version 21.