nuxt-modules / plausible

🎟️ Plausible Analytics integration for Nuxt
https://plausible.io
MIT License
102 stars 5 forks source link

Encountered Issue with Plausible Analytics Integration in Nuxt 3 during Testing #16

Open nesimtunc opened 5 months ago

nesimtunc commented 5 months ago

We've encountered an issue integrating Plausible Analytics in a Nuxt 3 application, specifically during testing with vitest. Despite following documentation and trying various mocking strategies, we're unable to successfully mock useTrackPageview and related functionalities for our unit tests. This results in tests failing due to Nuxt instance availability errors or incorrect mock implementations.

Steps to Reproduce

Expected Behavior

Mocks for Plausible's useTrackPageview and useTrackEvent should correctly simulate their functionalities, allowing for successful execution of unit tests without encountering Nuxt instance availability errors.

Actual Behavior

Tests fail with errors related to Nuxt instance availability or incorrect mock implementations. Specifically, we encountered errors like [nuxt] instance unavailable when trying to mock useTrackPageview. Tried Solutions

Mocking @nuxtjs/plausible and #app (for useNuxtApp) globally in our Vitest setup file.
Adjusting mock implementations to closely match the signatures and behaviors of Plausible's functions.
Ensuring mocks for $plausible are included as part of the object returned by useNuxtApp.

Despite these efforts, the issue persists, indicating a potential gap in documentation or support for this specific use case. Additional Context

Nuxt 3 version: 3.4.14
Vitest version: 1.2.2
@nuxtjs/plausible version: 0.2.4

Relevant configuration snippets and code samples:
// @vitest-environment happy-dom
import { describe, it, expect, vi } from "vitest";
import { mount } from "@vue/test-utils";
import { useHead } from "@unhead/vue";
import NewMessage from "@/pages/m/new.vue";
import type { PlausibleOptions, EventOptions } from "plausible-tracker";

// Mock Nuxt 3 app
vi.mock("#app", () => ({
  useNuxtApp: vi.fn(() => ({
    $config: {},
    $plausible: {
      trackLocalhost: false,
      autoPageviews: false,
      autoOutboundTracking: true,
      trackPageview: vi.fn(
        (eventData?: PlausibleOptions, options?: EventOptions) => {}
      ),
      trackEvent: vi.fn(
        (
          eventName: string,
          options?: EventOptions,
          eventData?: PlausibleOptions
        ) => {}
      ),
    },
  })),
}));

// Mock for @nuxtjs/plausible
vi.mock("@nuxtjs/plausible", () => ({
  useTrackPageview: vi.fn(
    (eventData?: PlausibleOptions, options?: EventOptions) => {}
  ),
  useTrackEvent: vi.fn(
    (
      eventName: string,
      options?: EventOptions,
      eventData?: PlausibleOptions
    ) => {}
  ),
}));

// Mock for useHead
vi.mock("@unhead/vue");
vi.mocked(useHead).mockImplementation(vi.fn());

describe("Creating NewMessage", () => {
  const wrapper = mount(NewMessage);

  it("renders without crashing", () => {
    expect(wrapper.exists()).toBe(true);
  });

  it("displays warning message when the textarea max limits reach", async () => {
    const textarea = wrapper.find("textarea");
    await textarea.setValue("0".repeat(256));
    expect(wrapper.find(".warning").exists()).toBe(true);
    expect(wrapper.find(".warning").text()).toBe("0 characters left.");
  });
});

Test Result:

 FAIL  tests/pages/m/new.spec.ts [ tests/pages/m/new.spec.ts ]
Error: [nuxt] instance unavailable
 ❯ Module.useNuxtApp node_modules/nuxt/dist/app/nuxt.js:218:13
    216|   Object.defineProperty(obj, key, { get: () => val });
    217| }
    218| export function defineAppConfig(config) {
       |             ^
    219|   return config;
    220| }
 ❯ Module.useTrackPageview node_modules/@nuxtjs/plausible/dist/runtime/composables/useTrackPageview.mjs:6:27

Request

Guidance on correctly mocking Plausible Analytics for unit tests in a Nuxt 3 application, or any updates to the documentation or package that could help address this issue.

Thank you