Files
automaker/app/tests/add-context-file.spec.ts
Cody Seibert e4b45f53f3 feat: Update feature list and add project initialization utilities
- Removed obsolete feature from feature_list.json related to context file deletion.
- Added new features for keyboard shortcuts in Kanban and context management.
- Introduced project initialization utilities to create necessary .automaker directory structure and files when opening a new project.
- Updated the AgentOutputModal and other components to reference the new agents-context directory.
- Enhanced Playwright tests for context file management and project initialization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 02:26:32 -05:00

197 lines
7.3 KiB
TypeScript

import { test, expect } from "@playwright/test";
import { setupMockProject, clickElement } from "./utils";
// Helper function to navigate to context view and wait for either loading or main view
async function navigateToContextAndOpenDialog(page: any) {
// Click on context nav
const contextNav = page.locator('[data-testid="nav-context"]');
await contextNav.waitFor({ state: "visible", timeout: 10000 });
await contextNav.click();
// Wait for either the context view or the loading view
// The loading view might stay visible if the electron API is mocked
await page.waitForSelector(
'[data-testid="context-view"], [data-testid="context-view-loading"], [data-testid="context-view-no-project"]',
{ timeout: 10000 }
);
// If we have the main context view, click the add button
const contextView = page.locator('[data-testid="context-view"]');
const isContextViewVisible = await contextView.isVisible().catch(() => false);
if (isContextViewVisible) {
// Click add context file button
const addFileBtn = page.locator('[data-testid="add-context-file"]');
await addFileBtn.click();
} else {
// If context view isn't visible, we might be in loading state
// For testing purposes, simulate opening the dialog via keyboard or other means
// Skip this test scenario
test.skip();
return;
}
// Wait for dialog to appear
const dialog = page.locator('[data-testid="add-context-dialog"]');
await dialog.waitFor({ state: "visible", timeout: 5000 });
}
test.describe("Add Context File Dialog", () => {
test.beforeEach(async ({ page }) => {
await setupMockProject(page);
await page.goto("/");
await page.waitForLoadState("networkidle");
});
test("should show file name input and content textarea in add context dialog", async ({
page,
}) => {
await navigateToContextAndOpenDialog(page);
// Verify file name input is visible
const fileNameInput = page.locator('[data-testid="new-file-name"]');
await expect(fileNameInput).toBeVisible();
// Verify content textarea is visible when text type is selected (default)
const contentTextarea = page.locator('[data-testid="new-file-content"]');
await expect(contentTextarea).toBeVisible();
// Verify placeholder text
await expect(contentTextarea).toHaveAttribute(
"placeholder",
"Enter context content here or drag & drop a .txt or .md file..."
);
});
test("should allow typing content in the textarea", async ({ page }) => {
await navigateToContextAndOpenDialog(page);
const contentTextarea = page.locator('[data-testid="new-file-content"]');
const testContent =
"# Test Context\n\nThis is test content for the context file.";
await contentTextarea.fill(testContent);
await expect(contentTextarea).toHaveValue(testContent);
});
test("should show textarea only for text file type", async ({ page }) => {
await navigateToContextAndOpenDialog(page);
// Verify textarea is visible when text type is selected (default)
const contentTextarea = page.locator('[data-testid="new-file-content"]');
await expect(contentTextarea).toBeVisible();
// Switch to image type
await clickElement(page, "add-image-type");
// Verify textarea is no longer visible
await expect(contentTextarea).not.toBeVisible();
// Verify image upload input is attached instead
const imageUploadInput = page.locator('[data-testid="image-upload-input"]');
await expect(imageUploadInput).toBeAttached();
// Switch back to text type
await clickElement(page, "add-text-type");
// Verify textarea is visible again
const contentTextareaAgain = page.locator('[data-testid="new-file-content"]');
await expect(contentTextareaAgain).toBeVisible();
});
test("should display drag and drop helper text", async ({ page }) => {
await navigateToContextAndOpenDialog(page);
// Check for helper text about drag and drop
const helperText = page.locator(
"text=Drag & drop .txt or .md files to import their content"
);
await expect(helperText).toBeVisible();
});
test("should populate content from dropped .txt file", async ({ page }) => {
await navigateToContextAndOpenDialog(page);
const contentTextarea = page.locator('[data-testid="new-file-content"]');
const testContent = "This is content from a text file.";
// Create a data transfer with a .txt file
const dataTransfer = await page.evaluateHandle((content) => {
const dt = new DataTransfer();
const file = new File([content], "test-file.txt", { type: "text/plain" });
dt.items.add(file);
return dt;
}, testContent);
// Dispatch drag events to simulate file drop
await contentTextarea.dispatchEvent("dragover", { dataTransfer });
await contentTextarea.dispatchEvent("drop", { dataTransfer });
// Wait for the content to be populated
await expect(contentTextarea).toHaveValue(testContent, { timeout: 5000 });
// Verify filename was auto-filled
const fileNameInput = page.locator('[data-testid="new-file-name"]');
await expect(fileNameInput).toHaveValue("test-file.txt");
});
test("should populate content from dropped .md file", async ({ page }) => {
await navigateToContextAndOpenDialog(page);
const contentTextarea = page.locator('[data-testid="new-file-content"]');
const testContent = "# Markdown File\n\nThis is markdown content.";
// Create a data transfer with a .md file
const dataTransfer = await page.evaluateHandle((content) => {
const dt = new DataTransfer();
const file = new File([content], "readme.md", { type: "text/markdown" });
dt.items.add(file);
return dt;
}, testContent);
// Dispatch drag events to simulate file drop
await contentTextarea.dispatchEvent("dragover", { dataTransfer });
await contentTextarea.dispatchEvent("drop", { dataTransfer });
// Wait for the content to be populated
await expect(contentTextarea).toHaveValue(testContent, { timeout: 5000 });
// Verify filename was auto-filled
const fileNameInput = page.locator('[data-testid="new-file-name"]');
await expect(fileNameInput).toHaveValue("readme.md");
});
test("should not auto-fill filename if already provided", async ({
page,
}) => {
await navigateToContextAndOpenDialog(page);
// Fill in the filename first
const fileNameInput = page.locator('[data-testid="new-file-name"]');
await fileNameInput.fill("my-custom-name.md");
const contentTextarea = page.locator('[data-testid="new-file-content"]');
const testContent = "Content from dropped file";
// Create a data transfer with a .txt file
const dataTransfer = await page.evaluateHandle((content) => {
const dt = new DataTransfer();
const file = new File([content], "dropped-file.txt", {
type: "text/plain",
});
dt.items.add(file);
return dt;
}, testContent);
// Dispatch drag events to simulate file drop
await contentTextarea.dispatchEvent("dragover", { dataTransfer });
await contentTextarea.dispatchEvent("drop", { dataTransfer });
// Wait for the content to be populated
await expect(contentTextarea).toHaveValue(testContent, { timeout: 5000 });
// Verify filename was NOT overwritten
await expect(fileNameInput).toHaveValue("my-custom-name.md");
});
});