LiveVue v0.7.0 - seamless File Uploads & E2E testing for the whole library

LiveVue 0.7.0 - File Upload Composable & Comprehensive Testing Suite!

Hey everyone! :waving_hand:

I’m excited to announce the release of LiveVue v0.7.0! This release focuses on making file uploads seamless and establishing a robust testing foundation for the library. If you’ve been waiting for better file upload support or wondering about LiveVue’s reliability, this release addresses both! :rocket:

What’s New?

:file_folder: New useLiveUpload Composable

The biggest new feature in this release is the new useLiveUpload() composable that makes Phoenix LiveView file uploads feel native in Vue! Let’s take a look at how it works:

Backend (LiveView):

defmodule MyAppWeb.UploadLive do
  use MyAppWeb, :live_view

  def render(assigns) do
    ~H"""
    <.vue
      upload={@uploads.documents}
      uploaded_files={@uploaded_files}
      v-component="FileUploader"
      v-socket={@socket}
    />
    """
  end

  def mount(_params, _session, socket) do
    {:ok,
     socket
     |> assign(:uploaded_files, [])
     |> allow_upload(:documents,
       accept: ~w(.pdf .txt .jpg .png),
       max_entries: 3,
       auto_upload: true
     )}
  end

  def handle_event("validate", _params, socket), do: {:noreply, socket}

  def handle_event("save", _params, socket) do
    uploaded_files =
      consume_uploaded_entries(socket, :documents, fn %{path: path}, entry ->
        dest = Path.join("uploads", entry.client_name)
        File.cp!(path, dest)
        {:ok, %{name: entry.client_name, size: entry.client_size}}
      end)

    {:noreply, update(socket, :uploaded_files, &(&1 ++ uploaded_files))}
  end
end

Frontend (Vue):

<template>
  <div>
    <button @click="showFilePicker">Select Files</button>
    <button v-if="entriesCount > 0" @click="cancel()">Cancel All</button>

    <div v-for="entry in entries" :key="entry.ref">
      <span>{{ entry.client_name }} ({{ entry.client_size }} bytes)</span>
      <span>{{ entry.progress || 0 }}%</span>
      <span>{{ entry.done ? 'done' : 'pending' }}</span>
      <button @click="cancel(entry.ref)">×</button>
    </div>

    <div v-if="uploadedFiles.length">
      <h3>Uploaded Files</h3>
      <div v-for="file in uploadedFiles" :key="file.name">
        {{ file.name }} ({{ file.size }} bytes)
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from "vue"
import { useLiveUpload, UploadConfig } from "live_vue"

interface Props {
  upload: UploadConfig
  uploadedFiles: { name: string; size: number }[]
}

const props = defineProps<Props>()

const { entries, showFilePicker, submit, cancel } = useLiveUpload(() => props.upload, {
  changeEvent: "validate",
  submitEvent: "save"
})

const entriesCount = computed(() => entries.value?.length || 0)
</script>

Key features:

  • Reactive upload state - Progress tracking, metadata, and validation status
  • Automatic DOM management - File inputs are handled seamlessly
  • Drag-and-drop support - Built-in drag-and-drop file handling
  • LiveView integration - Works perfectly with Phoenix’s upload validation and submission
  • Full TypeScript support - Complete type definitions for all upload configurations
  • Declarative API - Vue-friendly approach to complex upload workflows

:test_tube: Comprehensive Testing Foundation

This release establishes LiveVue as a thoroughly tested library with multiple testing layers:

Frontend Test Suite with Vitest:

  • 36 test cases covering JSON Patch functionality with edge cases
  • Tests for escaped characters, deep cloning, and complex patch sequences
  • jsdom environment for DOM testing
  • Full coverage of the TypeScript codebase

End-to-End Testing with Playwright:

  • 5 comprehensive test suites covering all major functionality
  • Tests for Vue component rendering, props passing, event emission
  • LiveView/Vue synchronization testing
  • File upload workflow testing
  • Navigation and prop diffing validation

Improved CI/CD:

  • E2E CI: Automatically runs E2E tests on every PR
  • Frontend CI: Tests across Node.js 20, 22, and 24 (LTS and current)
  • Elixir CI: Focused Elixir/OTP matrix testing

New Mix Commands:

mix assets.test          # Run frontend tests
npm test                 # Run tests once
npm run test:watch       # Run tests in watch mode
npm run test:ui          # Interactive test UI
npm run e2e:test         # E2E tests
npm run e2e:test:headed  # E2E with browser UI
npm run e2e:test:debug   # E2E debug mode

Why This Matters

File uploads have always been one of the trickier aspects of web development, especially when bridging server-side frameworks like Phoenix with client-side reactive frameworks. The useLiveUpload composable eliminates this complexity entirely, giving you a Vue-native way to handle uploads while leveraging all of Phoenix LiveView’s powerful upload features.

The comprehensive testing suite ensures LiveVue’s reliability and gives confidence for production use. With both unit tests for the TypeScript code and E2E tests covering real-world scenarios, you can trust that LiveVue will work as expected.

What’s Next?

With file uploads now seamlessly integrated and a solid testing foundation in place, LiveVue continues to mature as the go-to solution for Vue + Phoenix LiveView applications. The testing infrastructure also sets us up for more confident development of future features.

Next step: useLiveForm() composable for seamless form handling :purple_heart:

As always, I’d love to hear your feedback and experiences with the new release! And if you find LiveVue useful, a :star: on the GitHub repo would be much appreciated :blush:


Full Release Notes

:rocket: New Composable: useLiveUpload

  • File Upload Composable: Added useLiveUpload() composable for seamless Vue integration with Phoenix LiveView file uploads
    • Provides reactive upload state management with progress tracking and metadata
    • Automatic DOM element management for file inputs
    • Built-in support for drag-and-drop file handling
    • Integration with LiveView’s upload validation and submission system
    • TypeScript support with full type definitions for upload configurations
    • Simplifies complex upload workflows with a declarative Vue-friendly API

:test_tube: Testing Improvements

  • Frontend Test Suite: Added comprehensive test suite for frontend TypeScript code using Vitest framework
    • Tests for JSON Patch functionality with 36 test cases covering all operations
    • Test configuration with jsdom environment for DOM testing
    • Coverage includes edge cases like escaped characters, deep cloning, and complex patch sequences
  • End-to-End Test Suite: Added comprehensive E2E test suite using Playwright framework
    • Tests for Vue component rendering, props passing, event emission, and LiveView/Vue synchronization
    • 5 test suites covering basic functionality, navigation, events, prop diffs, and file uploads
    • Test server setup with dedicated Phoenix endpoint for isolated testing
    • Utilities for LiveView/Vue synchronization and server-side code execution
  • Separate CI Workflows: Split testing into dedicated workflows for better separation of concerns
    • Frontend CI: Tests TypeScript code across Node.js versions 20, 22, and 24 (LTS and current stable)
    • Elixir CI: Focused purely on Elixir/OTP matrix testing without redundant frontend test runs
  • New Mix Commands: Added mix assets.test alias for running frontend tests alongside existing npm scripts
    • npm test - Run tests once
    • npm run test:watch - Run tests in watch mode
    • npm run test:ui - Run tests with interactive UI
    • npm run e2e:test - Run E2E tests
    • npm run e2e:test:headed - Run E2E tests with browser UI
    • npm run e2e:test:debug - Run E2E tests in debug mode

Happy coding! :rocket:

6 Likes