CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vitest--browser

Browser runner for Vitest enabling tests to run in actual browser environments with real DOM APIs and browser-specific features

Pending
Overview
Eval results
Files

commands.mddocs/

File System Commands

Server-side file operations accessible from browser context for reading configuration files, test fixtures, and writing test outputs, bridging browser and server file systems.

Capabilities

File Reading

Read files from the server file system during browser tests.

/**
 * Read file from server filesystem
 * @param path - File path relative to server working directory
 * @param options - Encoding or file system options
 * @returns Promise resolving to file content as string
 */
readFile(path: string, options?: BufferEncoding | FsOptions): Promise<string>;

Usage Examples:

import { commands } from "@vitest/browser/context";

// Read configuration files
const configContent = await commands.readFile("./config.json");
const config = JSON.parse(configContent);

// Read test fixtures
const fixtureData = await commands.readFile("./fixtures/test-data.json");
const testData = JSON.parse(fixtureData);

// Read with specific encoding
const textContent = await commands.readFile("./data.txt", "utf8");
const binaryContent = await commands.readFile("./image.png", "base64");

// Read with file system options
const content = await commands.readFile("./file.txt", {
  encoding: "utf8",
  flag: "r"
});

// Handle different file types
const csvData = await commands.readFile("./data.csv");
const csvRows = csvData.split('\n').map(row => row.split(','));

const xmlData = await commands.readFile("./config.xml");
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlData, "text/xml");

File Writing

Write files to the server file system from browser tests.

/**
 * Write file to server filesystem
 * @param path - File path relative to server working directory
 * @param content - Content to write to file
 * @param options - Encoding or file system options with optional mode
 * @returns Promise that resolves when file is written
 */
writeFile(path: string, content: string, options?: BufferEncoding | (FsOptions & { mode?: number | string })): Promise<void>;

Usage Examples:

import { commands } from "@vitest/browser/context";

// Write test results
const testResults = {
  passed: 15,
  failed: 2,
  timestamp: new Date().toISOString()
};
await commands.writeFile("./test-results.json", JSON.stringify(testResults, null, 2));

// Write logs
const logEntry = `${new Date().toISOString()}: Test completed\n`;
await commands.writeFile("./test.log", logEntry, { flag: "a" }); // append mode

// Write CSV data
const csvData = [
  ["Name", "Age", "City"],
  ["John", "30", "New York"],
  ["Jane", "25", "Boston"]
];
const csvContent = csvData.map(row => row.join(',')).join('\n');
await commands.writeFile("./output.csv", csvContent);

// Write with specific encoding and permissions
await commands.writeFile("./config.txt", "sensitive data", {
  encoding: "utf8",
  mode: 0o600 // Read/write for owner only
});

// Write binary data (base64 encoded)
const imageBase64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==";
const imageData = imageBase64.split(',')[1]; // Remove data URL prefix
await commands.writeFile("./test-image.png", imageData, "base64");

File Removal

Delete files from the server file system.

/**
 * Remove file from server filesystem
 * @param path - File path relative to server working directory
 * @returns Promise that resolves when file is deleted
 */
removeFile(path: string): Promise<void>;

Usage Examples:

import { commands } from "@vitest/browser/context";

// Clean up test files
await commands.removeFile("./temp-test-file.txt");
await commands.removeFile("./output.json");

// Conditional cleanup
const fileExists = await commands.readFile("./optional-file.txt")
  .then(() => true)
  .catch(() => false);

if (fileExists) {
  await commands.removeFile("./optional-file.txt");
}

// Bulk cleanup
const testFiles = [
  "./temp1.txt",
  "./temp2.json", 
  "./temp3.csv"
];

for (const file of testFiles) {
  try {
    await commands.removeFile(file);
  } catch (error) {
    console.warn(`Could not remove ${file}:`, error);
  }
}

Advanced File Operations

Complex file manipulation patterns for testing scenarios.

Configuration Management:

import { commands } from "@vitest/browser/context";

// Read, modify, and write config
const configPath = "./test-config.json";
const originalConfig = JSON.parse(await commands.readFile(configPath));

const testConfig = {
  ...originalConfig,
  testMode: true,
  apiUrl: "http://localhost:3001"
};

await commands.writeFile(configPath, JSON.stringify(testConfig, null, 2));

// Test with modified config...

// Restore original config
await commands.writeFile(configPath, JSON.stringify(originalConfig, null, 2));

Test Data Generation:

// Generate test data files
const generateTestData = async (userCount: number) => {
  const users = Array.from({ length: userCount }, (_, i) => ({
    id: i + 1,
    name: `User ${i + 1}`,
    email: `user${i + 1}@example.com`
  }));
  
  await commands.writeFile("./test-users.json", JSON.stringify(users, null, 2));
  
  // Generate CSV version
  const csvHeader = "id,name,email\n";
  const csvRows = users.map(u => `${u.id},${u.name},${u.email}`).join('\n');
  await commands.writeFile("./test-users.csv", csvHeader + csvRows);
};

await generateTestData(100);

Log Analysis:

// Analyze test logs
const logContent = await commands.readFile("./application.log");
const logLines = logContent.split('\n');

const errors = logLines.filter(line => line.includes('ERROR'));
const warnings = logLines.filter(line => line.includes('WARN'));

const logSummary = {
  totalLines: logLines.length,
  errors: errors.length,
  warnings: warnings.length,
  errorMessages: errors.slice(0, 10) // First 10 errors
};

await commands.writeFile("./log-summary.json", JSON.stringify(logSummary, null, 2));

File Upload Testing:

// Create test files for upload scenarios
const createTestFiles = async () => {
  // Text file
  await commands.writeFile("./upload-test.txt", "This is a test file for upload");
  
  // JSON file
  const jsonData = { test: true, data: [1, 2, 3] };
  await commands.writeFile("./upload-test.json", JSON.stringify(jsonData));
  
  // CSV file
  const csvContent = "name,value\ntest1,100\ntest2,200";
  await commands.writeFile("./upload-test.csv", csvContent);
};

await createTestFiles();

// Test file upload functionality
const fileInput = page.getByLabelText("Upload file");
await userEvent.upload(fileInput, ["./upload-test.txt"]);

// Cleanup after test
await commands.removeFile("./upload-test.txt");
await commands.removeFile("./upload-test.json");
await commands.removeFile("./upload-test.csv");

Error Handling

Handle file system errors gracefully in browser tests.

import { commands } from "@vitest/browser/context";

// Safe file reading with fallback
const readConfigSafely = async (configPath: string, defaultConfig: object) => {
  try {
    const content = await commands.readFile(configPath);
    return JSON.parse(content);
  } catch (error) {
    console.warn(`Could not read config from ${configPath}, using default`);
    return defaultConfig;
  }
};

// Ensure directory exists (by writing a marker file)
const ensureTestDir = async () => {
  try {
    await commands.writeFile("./test-output/.gitkeep", "");
  } catch (error) {
    console.error("Could not create test output directory");
    throw error;
  }
};

// Atomic file operations
const writeFileSafely = async (path: string, content: string) => {
  const tempPath = `${path}.tmp`;
  
  try {
    // Write to temporary file first
    await commands.writeFile(tempPath, content);
    
    // Remove original file
    try {
      await commands.removeFile(path);
    } catch {
      // Original file might not exist
    }
    
    // Move temp file to final location (rename not available, so re-write)
    const tempContent = await commands.readFile(tempPath);
    await commands.writeFile(path, tempContent);
    await commands.removeFile(tempPath);
  } catch (error) {
    // Cleanup temp file on error
    try {
      await commands.removeFile(tempPath);
    } catch {
      // Ignore cleanup errors
    }
    throw error;
  }
};

Path Handling

File paths are relative to the server's working directory (where the test runner is executed).

// Examples of valid paths:
await commands.readFile("./config.json");           // Current directory
await commands.readFile("../parent-config.json");   // Parent directory
await commands.readFile("subdir/file.txt");         // Subdirectory
await commands.readFile("fixtures/test-data.json"); // Test fixtures

// Absolute paths work but are not recommended:
// await commands.readFile("/absolute/path/file.txt");

// Path construction for cross-platform compatibility
const configPath = "./config.json";
const logPath = "./logs/test.log";
const fixturePath = "./fixtures/user-data.json";

Types

File system operation types and options:

/**
 * Buffer encoding options for file operations
 */
type BufferEncoding = 
  | 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' 
  | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' 
  | 'latin1' | 'binary' | 'hex';

/**
 * File system operation options
 */
interface FsOptions {
  /** Text encoding for file content */
  encoding?: BufferEncoding;
  /** File system flag (e.g., 'r', 'w', 'a') */
  flag?: string | number;
}

/**
 * Browser commands interface
 */
interface BrowserCommands {
  readFile(path: string, options?: BufferEncoding | FsOptions): Promise<string>;
  writeFile(path: string, content: string, options?: BufferEncoding | (FsOptions & { mode?: number | string })): Promise<void>;
  removeFile(path: string): Promise<void>;
}

Install with Tessl CLI

npx tessl i tessl/npm-vitest--browser

docs

assertions.md

commands.md

context.md

index.md

interactions.md

locators.md

providers.md

server.md

utilities.md

tile.json