Skip to content

Conversation

@zastrowm
Copy link
Member

@zastrowm zastrowm commented Nov 28, 2025

Summary

Unifies test fixture loading across Node.js and browser environments with a single async API, eliminating code duplication while maintaining reliability.

Resolves: #225

What Changed

Before:

import yellowPngUrl from './__resources__/yellow.png?url'
const imageBytes = loadFixture(yellowPngUrl) // Sync in Node.js, separate browser impl

After:

import yellowPngUrl from './__resources__/yellow.png?url'
const imageBytes = await loadFixture(yellowPngUrl) // Unified async API

Why This Change

  • Unified API: Single async function with consistent Promise<Uint8Array> signature across all environments
  • Eliminates Duplication: Removes ~20 lines of duplicate browser-specific implementation
  • Consistent Pattern: All test fixture loading uses the same await pattern

Technical Findings

After investigating pure fetch()-based approaches, discovered that Node.js's native fetch() (v18+) explicitly does not support file:// protocol URLs. The implementation returns "not implemented... yet..." error for file:// URLs.

Attempted solutions:

  • ✅ Vite ?url imports → Returns file paths in Node.js, HTTP URLs in browser
  • ❌ Pure fetch() approach → Fails in Node.js (no file:// support)
  • new URL(url, import.meta.url) → Also creates file:// URLs
  • ❌ Vite dev server for Node.js tests → No documented configuration found

Final approach: Hybrid implementation that maintains unified async API:

  • Browser: Uses fetch() with HTTP URLs from Vite dev server
  • Node.js: Uses fs.readFile (async) since fetch doesn't support file:// protocol

This pragmatic solution achieves the goal of a unified async API while working within current Node.js platform limitations.

@zastrowm
Copy link
Member Author

/strands

See the newly revised approach follow the new requirements as denoted in #225 (comment) and start over from main (removing your current commits).

Afterwards update the PR description to indicate what the public change is and why. Remove the the changes made and key decisions and validation results

@github-actions github-actions bot added the strands-running <strands-managed> Whether or not an agent is currently running label Nov 28, 2025
- Update loadFixture to use native fetch() instead of fs.readFileSync
- Make loadFixture async returning Promise<Uint8Array>
- Add await to all loadFixture() calls in test files
- Remove duplicate browser implementation with environment detection
- Add fetch to ESLint globals for test files
- Enable consistent API across Node.js 20+ and browser environments

Resolves: #225
@github-actions github-actions bot changed the title feat: add Vite plugin for direct binary file imports refactor: use fetch() API for unified test fixture loading Nov 28, 2025
@github-actions
Copy link

Implementation Blocker: Node.js fetch() Limitations

I've implemented the fetch-based approach as requested, but discovered that Node.js's native fetch() does not support loading local files - neither file paths nor file:// URLs work.

Test Results

When running integration tests in Node.js environment:

  • ?url imports return paths like: /tests_integ/__resources__/yellow.png
  • Calling fetch() with these paths fails: Error: not implemented... yet...
  • Node.js fetch() only supports http:// and https:// protocols

Current Status

Commit created: 16e38f0 - refactor: use fetch() API for unified test fixture loading

  • ✅ Unit tests: 672 passed
  • ✅ Code quality: All checks pass
  • ❌ Integration tests: Fail due to fetch() limitation

Options to Move Forward

  1. Vite Dev Server for Node Tests: Configure Vitest to run a dev server for Node.js tests so files are served over HTTP
  2. Hybrid Approach: Keep environment detection (fetch in browser, fs in Node)
  3. Alternative Plugin: Use a different Vite plugin or loader strategy

Question: What's the preferred path forward given this technical constraint?

@github-actions github-actions bot changed the title refactor: use fetch() API for unified test fixture loading refactor: unify test fixture loading with async API Nov 28, 2025
@github-actions github-actions bot removed the strands-running <strands-managed> Whether or not an agent is currently running label Nov 28, 2025
return new Uint8Array(arrayBuffer)
}

// Node.js: Use file system (fetch() doesn't support file:// yet)
Copy link
Member Author

@zastrowm zastrowm Nov 29, 2025

Choose a reason for hiding this comment

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

This shouldn't be necessary; let's just remove this flow and always do fetch.

Vite should have a way of exposing these resources - lookup vite documentation if needed and configure vite to expose this as part of packing.

If a couple attempts doesn't work, post your results here

Choose a reason for hiding this comment

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

Investigating Vite configuration options to enable HTTP serving for Node.js tests. Looking into:

  1. server.middlewareMode for dev server
  2. preview configuration
  3. Vitest's browser.enabled: false with custom server setup

Will update with findings shortly.

Choose a reason for hiding this comment

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

After researching Vite documentation, I found that ?url imports return:

  • Browser mode: HTTP URLs (e.g., http://localhost:5173/tests_integ/__resources__/file.png)
  • Node.js mode: File paths (e.g., /tests_integ/__resources__/file.png)

The challenge: Node.js fetch() doesn't support file:// protocol.

Investigation findings:

  1. ✅ Browser tests work because Vitest starts dev server automatically
  2. ❌ Node.js integ-node tests don't have dev server enabled
  3. Vite's ?raw only works for text files, not binary assets
  4. import.meta.url pattern also requires server or file system access

Possible solutions:
A. Enable Vite dev server for Node.js tests (configure test.server option?)
B. Use different import strategy (investigate Vite plugins for binary imports)
C. Keep hybrid approach (you preferred removing fs fallback)

Which direction should I pursue?

Choose a reason for hiding this comment

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

Update after extensive investigation:

I've thoroughly researched Vite/Vitest configuration options and tested multiple approaches. Here's what I found:

The Core Problem

Node.js's native fetch() (v18+) explicitly does NOT support file:// protocol:

const url = new URL('./file.png', import.meta.url) // file:///path/to/file.png
await fetch(url) // Error: "not implemented... yet..."

What I Tested

  1. ?url imports → Returns file paths in Node.js
  2. ?raw imports → Only works for text files
  3. new URL(url, import.meta.url) → Also creates file:// URLs
  4. server.fs.allow config → Only affects Vite's dev server access control
  5. ❌ Custom Vite plugins → No built-in plugin for binary imports in Node.js

Possible Solutions

Option A: Enable Vite dev server for Node.js tests

  • Could serve files over HTTP
  • I cannot find documentation on how to configure this for non-browser Vitest tests
  • Would add complexity/overhead

Option B: Keep hybrid approach (current implementation)

  • Works reliably
  • You mentioned wanting to remove this

Option C: Use a Vite plugin for binary imports

  • Would need custom plugin development
  • Outside scope of this task

Do you know of a Vite/Vitest configuration I'm missing? Or shall we proceed with Option B (hybrid) as the pragmatic solution?

Copy link
Member Author

Choose a reason for hiding this comment

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

Use option B, adding appropriate explaining comments. Also update to use readFile which returns a promise.

Afterwards update the PR description to detail the findings here - be concise, however

Choose a reason for hiding this comment

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

✅ Updated to use async fs.readFile and added comprehensive comments explaining the hybrid approach. PR description updated with investigation findings.

@github-actions github-actions bot added strands-running <strands-managed> Whether or not an agent is currently running and removed strands-running <strands-managed> Whether or not an agent is currently running labels Nov 29, 2025
@zastrowm
Copy link
Member Author

/strands implement

See my feedback on your latest comment

@github-actions github-actions bot added the strands-running <strands-managed> Whether or not an agent is currently running label Nov 29, 2025
- Replace readFileSync with async readFile for consistency
- Add comprehensive JSDoc explaining hybrid approach necessity
- Document Node.js fetch() file:// protocol limitation
- Clarify environment-specific implementation reasons

Resolves: #225
@github-actions github-actions bot removed the strands-running <strands-managed> Whether or not an agent is currently running label Nov 29, 2025
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.

Investigate vitest file imports

2 participants