Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It can't be tested when a library is dynamically loaded through the script tag. #481

Closed
zouyaoji opened this issue Mar 27, 2021 · 7 comments

Comments

@zouyaoji
Copy link

zouyaoji commented Mar 27, 2021

Hi~

My component uses the following way to load a JS library:

// part of HelloWorld.vue
setup () {
    console.log('Cesium loading~ ')
    const $script = document.createElement('script')
    document.body.appendChild($script)
    $script.src = 'https://unpkg.com/cesium/Build/Cesium/Cesium.js'
    const createPromise = new Promise((resolve, reject) => {
      $script.onload = () => {
        console.log('Cesium loaded~ ')
        resolve(true)
      }
    })

    return {
      createPromise
    }
  }

and the test code is:

//example.spec.js
import { shallowMount, mount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  test('renders props.msg when passed', async () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      props: { msg }
    })
    console.log(wrapper.vm.createPromise)
    // It can pass in a few seconds in the browser, but it will always time out during testing.
    await wrapper.vm.createPromise
    expect(wrapper.text()).toMatch(msg)
  }, 25000)
})

In my case, the business logic was processed after $script.onload. But I found that this logic cannot be tested with @vue/test-utils. Is it not supported or am I using it incorrectly? The attachment can reproduce the problem I described.

test.zip

Best wish

@nandi95
Copy link
Contributor

nandi95 commented Mar 27, 2021

I'm not sure if that is supported in your choice of dom implementation.
I think it would be odd if a unit test is downloading some script from outside.
Check the documentation of your dom environment. One of the most common one is jsdom

This doesn't sounds like it has anything to do with the test utils.

@zouyaoji
Copy link
Author

well, the reason is that from the beginning of the project, the js library was introduced through script tag, instead of NPM, I have other considerations.

I think the render api in version 2 seems to meet my needs, but version 3 does not seem to have this api?

@lmiller1990
Copy link
Member

lmiller1990 commented Mar 30, 2021

I don't think that'll work in jsdom. Best try it in a more minimal environment (w/o test utils).

We have not implemented a render function yet for V2... now that Vue 3 (and compiler-ssr) is stable, we should definitely implement this.

We need to determine if this is a test utils problem, or jsdom problem. Then we can proceed with how to test this.

@lmiller1990
Copy link
Member

#507

@zouyaoji
Copy link
Author

zouyaoji commented Apr 8, 2021

@lmiller1990
Hello, I just try it in a more minimal environment of jsdom. According to the test result, I think it works in jsdom.

import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

const jsdom = require('jsdom')
const { JSDOM } = jsdom

describe('HelloWorld.vue', () => {
  test('renders props.msg when passed', async () => {
    const dom = new JSDOM(
      `
    <body>
      <script src="https://unpkg.com/cesium/Build/Cesium/Cesium.js"></script>
    </body>`,
      { runScripts: 'dangerously', resources: 'usable' }
    )
    console.log(dom.window.Cesium) // undefined
    setTimeout(() => {
      console.log(dom.window.Cesium.VERSION) // 1.80
    }, 5000)
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      props: { msg }
    })
    console.log(wrapper.vm.createPromise)
    // It can pass in a few seconds in the browser, but it will always time out during testing.
    await wrapper.vm.createPromise
    expect(wrapper.text()).toMatch(msg)
  }, 10000)
})

image

@zouyaoji
Copy link
Author

zouyaoji commented Apr 8, 2021

I studied the documentation of jsdom and found that adding this option in jest.config.js then the CesiumJS loaded successfully.

module.exports = {
  preset: '@vue/cli-plugin-unit-jest',
  transform: {
    '^.+\\.vue$': 'vue-jest'
  },
  testEnvironmentOptions: {
    resources: 'usable'
  }
}

But I encountered a new problem, jsdom does not support webgl...

@zouyaoji zouyaoji closed this as completed Apr 8, 2021
@zouyaoji
Copy link
Author

zouyaoji commented Apr 9, 2021

I have tested almost all testEnvironment of jest, and finally only jest-electron can meet my testing needs, hoping to help people with similar needs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants