vue-jest icon indicating copy to clipboard operation
vue-jest copied to clipboard

@vue/vue2-jest: Second script tag in components not loading

Open jaythomas opened this issue 3 years ago • 4 comments
trafficstars

vue: 2.7.10 jest: 29.2.1 @vue/vue2-jest: 29.1.1

My App.vue component has an options api script block and setup script block. It's apparent the second script block isn't picked up because it doesn't see any variables defined or components registered within the script block. The test completes with a failure and I see several [Vue warn] messages such as:

 console.error                                          
    [Vue warn]: Property or method "status" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring
-Reactive-Properties.                                                                                                                              
                                                                                                                                                   
    found in                                                                                                                                       
                                                                                                                                                   
    ---> <Anonymous>                                                                                                                               
           <Root>                                                      
                                                                                                                                                   
      73 |     throw e                                                                                                                             
      74 |   }
    > 75 | })
         |   ^
      76 | </script>
      77 |
      78 | <style lang="scss">

      at warn (node_modules/vue/dist/vue.runtime.common.dev.js:4516:21)
      at warnNonPresent (node_modules/vue/dist/vue.runtime.common.dev.js:5168:9)
      at Object.get (node_modules/vue/dist/vue.runtime.common.dev.js:5218:21)
      at Proxy.render (src/app-gizmos-main/App.vue:75:24)
    ....

Removing the first script block and leaving the <script setup> block the test runs as expected. In a perfect world I wouldn't have multiple script blocks sure, but since Vue supports this in the browser I would expect vue-jest to maintain feature parity.

App.vue
<template>
  <div id="app">
    <LoadingScreen v-show="status === 'loading'" />

    <Navbar v-show="status === 'success'" id="nav" data-test-id="app:navbar" />

    <div v-show="status === 'success'" id="content" data-test-id="app:content">
      <NotificationManager />
      <RouterView v-if="gizmoMetaDataLoaded" />
    </div>
  </div>
</template>

<script>
export default {
  metaInfo() {
    const canonicalURL = this.$urls.GIZMOS_ROOT + this.$route.path
    return {
      title: 'ExploreLearning Gizmos - Math & Science Simulations for Students',
      description:
        'Hundreds of online simulations with lesson materials, supporting research-based strategies to build deep conceptual understanding in math and science.',
      meta: [
        { property: 'og:url', content: canonicalURL },
        { property: 'twitter:url', content: canonicalURL }
      ],
      link: [{ rel: 'canonical', href: canonicalURL }]
    }
  },
}
</script>

<script setup>
import { computed, onBeforeMount, ref } from 'vue'
import { useRoute } from 'vue-router/composables'

import store from './state'
import ErrorScreen from './components/ErrorScreen'
import Navbar from './components/Navbar'

const $route = useRoute()
const status = ref('loading')
const gizmoMetaDataLoaded = computed(() => store.getters.gizmoMetaDataLoaded)

onBeforeMount(async () => {
  try {
    await store.dispatch('initializeApplication')
    status.value = 'success'
  } catch (e) {
    status.value = 'fail'
    throw e
  }
})
</script>

<style lang="scss">
#app {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
}
#content {
  margin-top: 2.5em;
  flex: 1 0 auto;
}
</style>
devDependencies
  "devDependencies": {
    "@babel/eslint-parser": "^7.18.9",
    "@playwright/test": "^1.22.2",
    "@rollup/plugin-alias": "^3.1.4",
    "@rollup/plugin-commonjs": "^17.1.0",
    "@rollup/plugin-node-resolve": "^11.2.0",
    "@vue/cli": "5.0.8",
    "@vue/cli-plugin-babel": "^3.12.1",
    "@vue/cli-service": "^3.0.4",
    "@vue/eslint-config-standard": "^4.0.0",
    "@vue/test-utils": "^1.2.0",
    "@vue/vue2-jest": "^29.1.1",
    "acorn": "^6.4.2",
    "axios-mock-adapter": "^1.21.2",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^29.1.2",
    "clipboard-copy": "^4.0.1",
    "dotenv-cli": "^6.0.0",
    "eslint": "^8.20.0",
    "eslint-import-resolver-jest": "^3.0.2",
    "eslint-import-resolver-webpack": "^0.13.2",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-vue": "^9.1.0",
    "flush-promises": "^1.0.2",
    "git-rev-sync": "^3.0.2",
    "jest": "^29.2.1",
    "jest-environment-jsdom": "^29.2.0",
    "jest-serializer-vue": "^2.0.2",
    "jest-watch-typeahead": "^2.2.0",
    "less": "3.13",
    "less-loader": "4.1",
    "node-sass": "^6.0.1",
    "prettier": "^2.3.0",
    "rollup": "^2.53.3",
    "rollup-plugin-scss": "^2.6.1",
    "rollup-plugin-vue": "^5.1.9",
    "sass": "^1.32.13",
    "sass-loader": "^10.2.0",
    "sinon": "^14.0.0",
    "start-server-and-test": "^1.14.0",
    "vue-jest": "^4.0.1",
    "vue-loader": "15.10.0",
    "vue-template-compiler": "2.7.10"
  }
jest.config.js
module.exports = {
  // Automatically clear mock calls and instances before every test.
  // Equivalent to calling jest.clearAllMocks() before each test.
  // This does not remove any mock implementation that may have been provided.
  clearMocks: true,
  // The directory where Jest should output its coverage files
  coverageDirectory: 'jest/coverage',
  // A list of reporter names that Jest uses when writing coverage reports
  coverageReporters: [
    // 'json'
    'html', // Check out coverage/lcov-report/index.html
    'lcov',
    'text'
  ],
  moduleFileExtensions: ['js', 'json', 'vue'],
  moduleNameMapper: {
    // Support the app's @ -> src alias mapping
    '^@/(.*)$': '<rootDir>/src/$1',
    '^~/(.*)$': '<rootDir>/$1',
    '^~helpers(.*)$': '<rootDir>/jest/helpers$1',
    '^~mocks(.*)$': '<rootDir>/jest/mocks$1',
    '\\.(css|less|scss)$': '<rootDir>/jest/helpers/asset-stub.js'
  },
  roots: ['<rootDir>/src/'],
  setupFilesAfterEnv: ['<rootDir>/jest/setup/index.js'],
  // Path to the helper that tells Jest where to fetch and retreive snapshot artifacts
  // https://jestjs.io/docs/en/configuration.html#snapshotresolver-string
  snapshotResolver: '<rootDir>/jest/helpers/snapshot-resolver.js',
  // De-facto snapshot serializer for vue2 components, but doesn't work with vue3
  snapshotSerializers: ['jest-serializer-vue'],
  testEnvironment: 'jsdom',
  testMatch: ['**/?(*.)+(spec|test).[jt]s'],
  transform: {
    '\\.js$': 'babel-jest',
    '\\.vue$': '@vue/vue2-jest'
  },
  // Indicates whether each individual test should be reported during the run
  verbose: null,
  watchPlugins: [
    require.resolve('jest-watch-typeahead/filename'),
    require.resolve('jest-watch-typeahead/testname')
  ]
}

I don't know how to use a code sandbox to reproduce, but if there is any further information I could provide let me know.

jaythomas avatar Oct 22 '22 02:10 jaythomas

I can confirm that vue 2.7 detection is happening in node_modules/@vue/vue2-jest/lib/process.js. The isVue27 boolean is flipped to true as expected. I assume none of the <script setup> syntax in any of my components' tests would work otherwise.

jaythomas avatar Oct 22 '22 02:10 jaythomas

I'm getting the same error, but I don't think it's because of multiple <script> tags. Here is my minimal reproduction: https://github.com/rudolfbyker/repro-vue-jest-issue-505

rudolfbyker avatar Oct 26 '22 07:10 rudolfbyker

Happening also to me with only

vate avatar Nov 04 '22 11:11 vate

Upgrading all jest-related packages from ^27 to ^29 solved this for me.

rudolfbyker avatar Nov 14 '22 10:11 rudolfbyker