Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions .changeset/cli_app-test-command.md

This file was deleted.

5 changes: 5 additions & 0 deletions .changeset/fusion-log_guard-process-env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@equinor/fusion-log": patch
---

Guard the `process.env` access used to detect the current log level so it no longer throws in environments without a Node-style `process` global (e.g. Vitest Browser Mode).
5 changes: 5 additions & 0 deletions .changeset/module-context_fix-empty-context-warning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@equinor/fusion-framework-module-context": patch
---

Fix `ContextModule.postInitialize` logging a `console.warn` for the valid "no initial context" case (no context in the path and no parent context). The default `resolveInitialContext` resolver used RxJS `first()` without a default value, so completing with no emissions threw an `EmptyError` that got logged as if resolution had actually failed. `first()` now falls back to `undefined`, so a genuinely empty result completes silently and only real resolution failures are logged.
5 changes: 5 additions & 0 deletions .changeset/msal_remove-debug-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@equinor/fusion-framework-module-msal": patch
---

Remove a stray `console.log` left in `resolveVersion`'s minor-version-mismatch warning path.
5 changes: 5 additions & 0 deletions .changeset/react-app_fix-remaining-vitest-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@equinor/fusion-framework-react-app": patch
---

Remove `docs/testing.md` and replace the README's testing section with a pointer to `@equinor/fusion-framework-vitest-plugin-react-app`, now that `renderAppHook`, `renderAppComponent`, `testApp`, and the `appTestVitePlugin` Vite plugin live in that separate package instead of this one. Both described the old `./vitest` entry-point as requiring `@testing-library/react` and returning a top-level `modules` field, which no longer applies now that the helpers are built on `vitest-browser-react` and return a nested `fusion: { framework, app }` object. The README's API-reference table no longer lists a `/vitest` entry-point.
Comment thread
odinr marked this conversation as resolved.
25 changes: 18 additions & 7 deletions .changeset/react-app_render-app-component-testing.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
---
"@equinor/fusion-framework-react-app": minor
"@equinor/fusion-framework-react-app": major
---

Add `renderAppComponent` to the `/testing` entry-point, a component-level counterpart to `renderAppHook` for testing components (not just hooks) against a real, mock-backed application module scope.
Remove the `./vitest` entry-point. `renderAppComponent` — a component-level counterpart to `renderAppHook` for testing components (not just hooks) against a real, mock-backed application module scope, built on `vitest-browser-react` instead of `@testing-library/react` — now lives in a separate package, `@equinor/fusion-framework-vitest-plugin-react-app`.

```tsx
import { renderAppComponent } from '@equinor/fusion-framework-react-app/testing';
import { waitFor } from '@testing-library/react';
import { renderAppComponent } from '@equinor/fusion-framework-vitest-plugin-react-app';
import { Apploader } from '../apploader/Apploader';

const { container } = await renderAppComponent(<Apploader appKey="child-app" />);
await waitFor(() => expect(container.textContent).toContain('mounted'));
const screen = await renderAppComponent(<Apploader appKey="child-app" />);
await expect.element(screen.getByText('mounted')).toBeVisible();
```

`renderAppComponent` wraps `@testing-library/react`'s `render` with the same `FrameworkProvider` + `ModuleProvider` nesting `renderAppHook` uses, backed by `mockFramework` and `mockAppModules` (`@equinor/fusion-framework-app/mock`), so tests can render a real component tree without hand-wiring those mocks.
`renderAppComponent` wraps `vitest-browser-react`'s `render` with the same `FrameworkProvider` + `ModuleProvider` nesting `renderAppHook` uses, backed by `mockFramework` and `mockAppModules` (`@equinor/fusion-framework-app/mock`), so tests can render a real component tree without hand-wiring those mocks.

The result also carries a nested `fusion` object (`fusion.framework`, `fusion.app`) — nested rather than spread directly onto the result so `vitest-browser-react`'s own return shape stays free to evolve without ever colliding with it — so a test can drive a module directly after the initial render and assert the component re-renders, instead of hand-wiring `mockAppModules`/`ModuleProvider` itself to reach the same instance:

```tsx
const { getByText, fusion } = await renderAppComponent<[ContextModule]>(<App />, {
configure: (configurator) => enableContextMock(configurator, (mock) => mock.setCurrentContext(projectA)),
});
await act(() => fusion.app.context.setCurrentContextByIdAsync(projectB.id));
await expect.element(getByText(/project-b/)).toBeVisible();
```

**Breaking change:** the `./vitest` entry-point is removed with no compatibility shim. Migrate by installing `@equinor/fusion-framework-vitest-plugin-react-app` and importing `renderAppComponent` from it instead, and replacing `@testing-library/react`'s `render`/`waitFor`/`act` with `vitest-browser-react`/`vitest`'s equivalents.
Comment thread
odinr marked this conversation as resolved.
18 changes: 12 additions & 6 deletions .changeset/react-app_render-app-hook-testing.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
---
"@equinor/fusion-framework-react-app": minor
"@equinor/fusion-framework-react-app": major
---

Add a `/testing` entry-point with `renderAppHook`, a pre-wrapped `renderHook` for testing app-scoped hooks (`useAppModule`, `useAccessToken`, etc.) against a real, mock-backed module and framework instance.
Remove the `./vitest` entry-point. `renderAppHook`a pre-wrapped `renderHook` for testing app-scoped hooks (`useAppModule`, `useAccessToken`, etc.) against a real, mock-backed module and framework instance, built on `vitest-browser-react` instead of `@testing-library/react` — now lives in a separate package, `@equinor/fusion-framework-vitest-plugin-react-app`.

```tsx
import { renderAppHook } from '@equinor/fusion-framework-react-app/testing';
import { waitFor } from '@testing-library/react';
import { renderAppHook } from '@equinor/fusion-framework-vitest-plugin-react-app';

const { result } = await renderAppHook(() => useAccessToken({ scopes: ['User.Read'] }));
await waitFor(() => expect(result.current.pending).toBe(false));
await vi.waitFor(() => expect(result.current.pending).toBe(false));
```

`renderAppHook` wraps the hook with the same `FrameworkProvider` + `ModuleProvider` nesting `renderApp` uses in production, backed by `mockFramework` and `mockAppModules` (`@equinor/fusion-framework-app/mock`), so app teams no longer need to hand-wire those mocks in every test.

Requires `@testing-library/react` (added as an optional peer dependency).
The result also carries a nested `fusion` object (`fusion.framework`, `fusion.app`) — the same instances the hook rendered against, for driving a module the hook itself doesn't return — nested rather than spread directly onto the result so the underlying `renderHook` return shape stays free to evolve without ever colliding with it.

**Breaking change:** the `./vitest` entry-point is removed with no compatibility shim. Migrate by installing `@equinor/fusion-framework-vitest-plugin-react-app` and importing `renderAppHook` from it instead, replacing `@testing-library/react`'s `render`/`waitFor`/`act` with `vitest-browser-react`/`vitest`'s equivalents, and reading `fusion.framework`/`fusion.app` instead of the old result shape.

```diff
-import { renderAppHook } from '@equinor/fusion-framework-react-app/vitest';
+import { renderAppHook } from '@equinor/fusion-framework-vitest-plugin-react-app';
Comment thread
odinr marked this conversation as resolved.
```
5 changes: 5 additions & 0 deletions .changeset/react_fix-usemodule-warning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@equinor/fusion-framework-react": patch
---

Fix `useFrameworkModule`'s console warning to name the actually-requested module key instead of always printing `undefined`.
22 changes: 22 additions & 0 deletions .changeset/vitest-plugin-react-app_initial-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@equinor/fusion-framework-vitest-plugin-react-app": minor
---

Add `@equinor/fusion-framework-vitest-plugin-react-app`: Vitest/`vitest-browser-react` helpers for testing a Fusion Framework React application inside a real, mock-backed application module scope — the same `FrameworkProvider` + `ModuleProvider` nesting `renderApp`/`createComponent` wire up in production, backed by `mockFramework` and `mockAppModules` (`@equinor/fusion-framework-app/mock`).

```tsx
import { renderAppHook } from '@equinor/fusion-framework-vitest-plugin-react-app';
import { useAccessToken } from '@equinor/fusion-framework-react-app/msal';

const { result } = await renderAppHook(() => useAccessToken({ scopes: ['User.Read'] }));
await vi.waitFor(() => expect(result.current.pending).toBe(false));
```

Highlights:

- `renderAppHook`/`renderAppComponent` — render a hook or component against the real `event`/`http`/`msal` module pipeline, with only the network boundary faked; the result carries a nested `fusion: { framework, app }` for driving a module directly after the initial render.
- `testApp` — a `vitest` `test` extended with `env`/`configure`/`app`/`render`/`renderHook` fixtures, for a test file whose cases share one mocked scope.
- `appTestVitePlugin` — a Vite plugin resolving an application's own manifest, config, and module-configurator (the same pipeline `ffc app build`/`ffc app dev` use) as virtual modules.
- A `/test` entry-point exporting `test`/`render`, pre-seeded from the resolved manifest/config/configure once `appTestVitePlugin` is registered — no per-test `env`/`configure` wiring.

This replaces `@equinor/fusion-framework-react-app`'s removed `./vitest` entry-point; see that package's changelog for migration notes.
Comment thread
odinr marked this conversation as resolved.
8 changes: 7 additions & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,13 @@ jobs:
- name: Check if build failed
if: steps.build.outcome == 'failure'
run: exit 1


- name: Install Playwright browsers
# `playwright` isn't a root dependency, so `pnpm exec` needs a --filter into a package that
# has it (react-app, vitest-plugin-react-app); the installed browser cache is shared, so
# this covers both packages' Vitest Browser Mode tests
run: pnpm --filter @equinor/fusion-framework-vitest-plugin-react-app exec playwright install --with-deps chromium

- name: Create Test Report
run: pnpm test run

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ typings/
# Optional eslint cache
.eslintcache

# Vitest browser mode failure screenshots
__screenshots__/
.vitest-attachments/

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
Expand Down
8 changes: 7 additions & 1 deletion CODEMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ search to rediscover it.

| Path | Contains | Published? |
| --- | --- | --- |
| `packages/*` | Framework libraries (59 packages) | Yes, via Changesets |
| `packages/*` | Framework libraries (60 packages) | Yes, via Changesets |
| `cookbooks/*` | Runnable example apps and portals | Yes (versioned, but examples) |
| `eds-content/`, `eds/` | EDS design-system content and token tooling | No |
| `vue-press/` | Documentation site | Partly |
Expand Down Expand Up @@ -130,6 +130,12 @@ Format: `package name` → path → role.
> cross-package import inside `packages/linting/*`, add the matching `references`
> entry to `tsconfig.json` or isolated `prepack` builds will fail during publish.

### Vitest plugins (`packages/vitest-plugin/*`)

| Package | Path | Role |
| --- | --- | --- |
| `@equinor/fusion-framework-vitest-plugin-react-app` | `packages/vitest-plugin/react-app` | Vite plugin and Vitest helpers (`renderAppComponent`, `renderAppHook`, `testApp`) for testing React apps in a real, mock-backed application module scope |

### Cookbooks (`cookbooks/*`)

`app-react`, `app-react-ag-grid`, `app-react-ai`, `app-react-apploader`, `app-react-assets`,
Expand Down
7 changes: 0 additions & 7 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@
"types": "./dist/types/lib/dev-server.d.ts",
"import": "./dist/esm/lib/dev-server.js"
},
"./vitest": {
"types": "./dist/types/lib/vitest/index.d.ts",
"import": "./dist/esm/lib/vitest/index.js"
},
"./bin": {
Comment thread
odinr marked this conversation as resolved.
"types": "./dist/types/bin/index.d.ts",
"import": "./bin/build/bin.mjs"
Expand Down Expand Up @@ -81,9 +77,6 @@
"dev-server": [
"dist/types/lib/dev-server.d.ts"
],
"vitest": [
"dist/types/lib/vitest/index.d.ts"
],
"bin": [
"dist/types/bin/index.d.ts"
],
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export { checkApp } from './check-app.js';
export { loadAppManifest } from './load-app-manifest.js';
export { uploadApplication } from './upload-application.js';
export { tagApplication } from './tag-application.js';
export { testApplication, type TestApplicationOptions } from './test-application.js';

export { startPortalDevServer } from './start-portal-dev-server.js';
export { servePortal, type ServePortalOptions } from './serve-portal.js';
Expand Down
162 changes: 0 additions & 162 deletions packages/cli/src/bin/test-application.ts

This file was deleted.

2 changes: 0 additions & 2 deletions packages/cli/src/cli/commands/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import configCommand from './config.command.js';
import tagCommand from './tag.command.js';
import devCommand from './dev.command.js';
import serveCommand from './serve.command.js';
import testCommand from './test.command.js';
import manifestCommand from './manifest.command.js';
import publishCommand from './publish.command.js';
import createAppCommand from '../create/create-app-command.js';
Expand Down Expand Up @@ -49,7 +48,6 @@ export const command = createCommand('app')
.addCommand(tagCommand)
.addCommand(devCommand)
.addCommand(serveCommand)
.addCommand(testCommand)
.addCommand(manifestCommand)
.addCommand(publishCommand)
.addCommand(createAppCommand('create'));
Expand Down
Loading
Loading