Skip to content

test(analytics): migrate analytics to Vitest - #10375

Open
Manvi1203 wants to merge 7 commits into
mainfrom
feature/vitest-analytics
Open

Manvi1203 wants to merge 7 commits into
mainfrom
feature/vitest-analytics

Conversation

@Manvi1203

@Manvi1203 Manvi1203 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrates @firebase/analytics unit and integration tests from legacy Karma (Mocha / Chai / Sinon) to Vitest (Browser Chromium via Playwright).

Description

  • Runner & Config: Replaced karma.conf.js and karma.integration.conf.js with vitest.config.mjs and vitest.integration.config.mjs extending config/vitest.base.mjs. Configured browser runner targeting Chromium via Playwright with defensive project filtering (if (config.test?.projects)). Added test/types/vitest-globals.d.ts and configured test/setup.ts with global console/logger stubs to keep test logs clean.
  • Target Environment: @firebase/analytics relies on browser APIs (window, dataLayer, gtag, IndexedDB, DOM script injection). Both unit tests and integration tests run in the browser project via @vitest/browser-playwright.
  • Assertions & Lifecycle: Converted legacy Chai assertions (.to.equal, .to.deep.equal, .to.be.true, .to.throw) to native Vitest matchers (.toBe(), .toEqual(), .toBe(true), .toThrow()). Converted Mocha hooks (after, afterEach) to Vitest equivalents (afterAll, afterEach).
  • Mocks & Spies: Converted Sinon stubs and spies to native Vitest utilities (vi.fn(), vi.spyOn(), vi.mock()). Replaced fragile array index mock assertions with robust matcher assertions (toHaveBeenLastCalledWith(...)). Added internal _setWrappedGtagFunction helper to cleanly stub gtag calls in ESM environments.
  • Integration Tests: Migrated testing/integration-tests/integration.ts from Mocha's done callback to Promise-based execution. Excluded testing/** from rollup.config.js to ensure clean library builds in CI environments.
  • Package Scripts: Updated package.json scripts (test, test:all, test:browser, test:integration, test:ci, test:browser:debug) to use Vitest and cleaned up legacy Karma configs.

Performance

  • Baseline (Karma + Webpack): ~12–15s total duration
  • Vitest (Unit Tests): ~2.1s (6 test files, 86 tests passed)
  • Vitest (Integration Tests): ~12s (3 tests passed)

@Manvi1203
Manvi1203 requested review from a team and hsubox76 as code owners September 11, 2026 02:00
@changeset-bot

changeset-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 69adcca

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@firebase/analytics Patch
@firebase/analytics-compat Patch
firebase Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the @firebase/analytics test suite from Karma, Mocha, Chai, and Sinon to Vitest, updating package scripts, assertions, and mocking utilities across multiple test files. The review feedback points out that the test:integration script in package.json still references Karma despite the integration tests being migrated, and identifies a leftover asynchronous mock call in api.test.ts. Additionally, several test assertions directly accessing mock.calls are flagged as fragile and should be refactored to use safer Vitest matchers like toHaveBeenCalledWith or explicit call checks.

Comment thread packages/analytics/package.json Outdated
Comment thread packages/analytics/src/api.test.ts
Comment thread packages/analytics/src/get-config.test.ts Outdated
Comment thread packages/analytics/src/initialize-analytics.test.ts Outdated
Comment thread packages/analytics/src/index.test.ts Outdated
Comment thread packages/analytics/testing/integration-tests/integration.ts Outdated
@Manvi1203
Manvi1203 requested a review from a team as a code owner September 15, 2026 22:41
@Manvi1203
Manvi1203 requested a review from a team as a code owner September 16, 2026 22:57
@Manvi1203

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the @firebase/analytics test suite from Karma, Mocha, Chai, and Sinon to Vitest, updating configuration files, package scripts, and test assertions accordingly. The review feedback highlights a few important issues: first, the simplified test:all script in package.json skips integration tests, which should be restored; second, the app variable in api.test.ts should be reset to undefined in afterEach to prevent state leakage; and third, the console.warn mock in the integration tests should be made more robust by filtering for the expected warning message rather than asserting on the first warning received.

"dev": "rollup -c -w",
"test": "run-p --npm-path npm lint test:all",
"test:all": "run-p --npm-path npm test:browser test:integration",
"test:all": "vitest run",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The test:all script has been simplified to vitest run, which only runs the default unit tests. This means integration tests (configured in vitest.integration.config.mjs) are no longer executed as part of test:all or in CI (via test:ci). Please restore the execution of both unit and integration tests.

Suggested change
"test:all": "vitest run",
"test:all": "run-p --npm-path npm test:browser test:integration",

Comment on lines 64 to 66
if (app) {
return deleteApp(app);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The suite-level app variable is deleted in afterEach but not reset to undefined. Resetting it to undefined prevents potential state leakage or double-deletion attempts in subsequent tests.

    if (app) {
      await deleteApp(app);
      app = undefined as any;
    }

Comment on lines +60 to +63
vi.spyOn(console, 'warn').mockImplementation((_tag, message) => {
expect(message).toContain('does not match');
resolve();
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The mock implementation of console.warn asserts that the warning message contains 'does not match' on the very first warning received. If any other warning (such as a browser context or cookie warning) is logged first, the assertion will fail and the test will fail prematurely. Filtering the arguments to find the expected warning message makes the test much more robust.

        vi.spyOn(console, 'warn').mockImplementation((...args) => {
          const hasMatch = args.some(arg => typeof arg === 'string' && arg.includes('does not match'));
          if (hasMatch) {
            resolve();
          }
        });

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

Successfully merging this pull request may close these issues.

1 participant