inertia-laravel icon indicating copy to clipboard operation
inertia-laravel copied to clipboard

Vitest + Inertia.js errors when running tests on Page/Components

Open alisanie opened this issue 3 years ago • 2 comments

Hi I had a plan to use Vitest with Inertia js but there is a problem.After running below test

import { mount } from '@vue/test-utils'
import Register from '@/Pages/Auth/Register.vue';

it('Register Contains Register', () => {
    const wrapper = mount(Register);
    expect(wrapper.text()).toCaintain('Register');
})

I git this error:

TypeError: Cannot read properties of undefined (reading 'createProvider')

There is also a threat on laracast: https://laracasts.com/discuss/channels/inertia/vitest-inertiajs-errors-when-running-tests-on-pagecomponents

alisanie avatar Oct 18 '22 12:10 alisanie

Hi I had the same error following code.

// Welcome.test.js
// @vitest-environment happy-dom
import { mount } from '@vue/test-utils'
import { describe, expect, test } from 'vitest'
import Welcome from './Welcome.vue'

describe('Screen Display', () => {
  test('Display `Welcome` message', () => {
    const wrapper = mount(Welcome)
    expect(wrapper.text()).toContain('Welcome')
  })
})
// Welcome.vue
<script setup>
  import { onMounted } from "vue";
  import { Head } from "@inertiajs/inertia-vue3";
  onMounted(() => {
    console.log("Welcome Page mounted");
  });
</script>

<template>
  <Head>
    <title>Welcome</title>
  </Head>
  <h1>Welcome Inertia.js</h1>
</template>

in details of the error message, it seemed that the error was caused by Head from @inertiajs/inertia-vue3. So I split it into Layout.vue file and Welcome.vue file. Then Welcome.vue file test worked.

// Welcome.vue
<script setup>
  import { onMounted } from "vue";
  onMounted(() => {
    console.log("Welcome Page mounted");
  });
</script>

<script>
  import Layout from "./Layout.vue";
  export default {
    layout: Layout,
  }
</script>

<template>
  <h1>Welcome Inertia.js</h1>
</template>
// Layout.vue
<script>
  import { Head } from "@inertiajs/inertia-vue3";
  export default {
    components: {
      Head,
    }
  }
</script>

<template>
  <Head>
    <title>Welcome</title>
  </Head>
  <main>
    <slot />
  </main>
</template>

ryu022304 avatar Oct 29 '22 16:10 ryu022304

@alisanie In my React & TypeScript case, I was able to test a component that included a Head component. I referenced this issue comment. https://github.com/vercel/next.js/discussions/11060#discussioncomment-33628

// Title.tsx
import React from 'react';
import { Head } from '@inertiajs/inertia-react';

type TitlePrpps = {
  title: string;
};

function Title(props: TitlePrpps) {
  const { title } = props;
  return (
    <Head>
      <title>{title ? `${title} - MyPage` : 'MyPage'}</title>
    </Head>
  );
}

export default Title;
// Title.test.tsx
// @vitest-environment happy-dom
import React from 'react';
import '@testing-library/jest-dom';
import { render } from '@testing-library/react';
import { describe, expect, test, vi } from 'vitest';
import Title from '@/Components/Layout/Title';

vi.mock('@inertiajs/inertia-react', () => ({
  Head: ({ children }: { children: Array<React.ReactElement> }) => (
    <>{children}</>
  )
}));

describe('Screen Display', () => {
  test('Display `title - MyPage` title', async () => {
    render(<Title title="test" />, {
      container: document.head
    });
    expect(document.head.querySelector('title')?.innerHTML).toEqual(
      'test - MyPage'
    );
  });
});

I hope this helps you.

ryu022304 avatar Nov 05 '22 06:11 ryu022304

Hey folks, this isn't really related to the Laravel adapter, so I'm going to close this one.

Probably best discussed on our Discord channel or GitHub Discussions.

reinink avatar Jan 17 '23 01:01 reinink