mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
Implement initial project structure and features for Automaker application, including environment setup, auto mode services, and session management. Update port configurations to 3007 and add new UI components for enhanced user interaction.
This commit is contained in:
398
app/tests/interview.spec.ts
Normal file
398
app/tests/interview.spec.ts
Normal file
@@ -0,0 +1,398 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
test.describe("Interactive New Project Interview", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto("/");
|
||||
});
|
||||
|
||||
test("Step 1: Click 'New Project' -> 'Interactive Mode' navigates to interview view", async ({ page }) => {
|
||||
// Click the Create Project dropdown button
|
||||
await page.getByTestId("create-new-project").click();
|
||||
|
||||
// Wait for dropdown to appear and click Interactive Mode option
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Verify the header shows "New Project Interview"
|
||||
await expect(page.getByText("New Project Interview")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Step 2: Chat interface appears asking 'What do you want to build?'", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Verify the first question is displayed
|
||||
await expect(page.getByTestId("interview-messages")).toBeVisible();
|
||||
await expect(page.getByText("What do you want to build?")).toBeVisible();
|
||||
|
||||
// Verify input field is available
|
||||
await expect(page.getByTestId("interview-input")).toBeVisible();
|
||||
await expect(page.getByTestId("interview-send")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Step 3: User can reply 'A todo app'", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Type the answer in the input field
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
|
||||
// Click send button
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Verify user message appears in the chat
|
||||
await expect(page.getByTestId("interview-messages").getByText("A todo app")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Step 4: Agent asks clarifying questions (tech stack)", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Wait for interview view
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Answer first question
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for the next question to appear (tech stack question)
|
||||
await expect(page.getByText("What tech stack would you like to use?")).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Verify progress text shows question 2 of 4
|
||||
await expect(page.getByText("Question 2 of 4")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Step 5: Agent generates draft app_spec.txt based on conversation", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Wait for interview view
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Answer first question - project description
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for tech stack question
|
||||
await expect(page.getByText("What tech stack would you like to use?")).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Answer tech stack question
|
||||
await page.getByTestId("interview-input").fill("React, Next.js, TypeScript");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for features question
|
||||
await expect(page.getByText("What are the core features you want to include?")).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Answer features question
|
||||
await page.getByTestId("interview-input").fill("Add tasks, Mark complete, Delete tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for additional requirements question
|
||||
await expect(page.getByText("Any additional requirements or preferences?")).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Answer additional requirements
|
||||
await page.getByTestId("interview-input").fill("Dark mode support");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for spec generation to complete
|
||||
await expect(page.getByTestId("project-setup-form")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify spec preview is visible with generated content
|
||||
await expect(page.getByTestId("spec-preview")).toBeVisible();
|
||||
|
||||
// Verify the generated spec contains the project description
|
||||
const specPreview = page.getByTestId("spec-preview");
|
||||
await expect(specPreview).toContainText("A todo app");
|
||||
|
||||
// Verify it contains tech stack information
|
||||
await expect(specPreview).toContainText("React");
|
||||
|
||||
// Verify it contains features
|
||||
await expect(specPreview).toContainText("Add tasks");
|
||||
});
|
||||
|
||||
test("Interview shows progress indicator with correct number of steps", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Verify progress text shows question 1 of 4
|
||||
await expect(page.getByText("Question 1 of 4")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Send button is disabled when input is empty", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify send button is disabled when input is empty
|
||||
await expect(page.getByTestId("interview-send")).toBeDisabled();
|
||||
|
||||
// Type something
|
||||
await page.getByTestId("interview-input").fill("Test");
|
||||
|
||||
// Now button should be enabled
|
||||
await expect(page.getByTestId("interview-send")).toBeEnabled();
|
||||
|
||||
// Clear input
|
||||
await page.getByTestId("interview-input").fill("");
|
||||
|
||||
// Button should be disabled again
|
||||
await expect(page.getByTestId("interview-send")).toBeDisabled();
|
||||
});
|
||||
|
||||
test("Can submit answer by pressing Enter", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Type answer and press Enter
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
await page.getByTestId("interview-input").press("Enter");
|
||||
|
||||
// Verify user message appears
|
||||
await expect(page.getByTestId("interview-messages").getByText("A todo app")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Back button returns to welcome view", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// Click back button
|
||||
await page.getByTestId("interview-back-button").click();
|
||||
|
||||
// Verify we're back on welcome view
|
||||
await expect(page.getByTestId("welcome-view")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Project setup form appears after completing interview", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Complete all questions
|
||||
await page.getByTestId("interview-input").fill("A simple todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What tech stack would you like to use?")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("React");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What are the core features")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Add, edit, delete tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("Any additional requirements")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("None");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for project setup form
|
||||
await expect(page.getByTestId("project-setup-form")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify form has name input
|
||||
await expect(page.getByTestId("interview-project-name-input")).toBeVisible();
|
||||
|
||||
// Verify form has path input
|
||||
await expect(page.getByTestId("interview-project-path-input")).toBeVisible();
|
||||
|
||||
// Verify browse directory button
|
||||
await expect(page.getByTestId("interview-browse-directory")).toBeVisible();
|
||||
|
||||
// Verify create project button
|
||||
await expect(page.getByTestId("interview-create-project")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Create project button is disabled without name and path", async ({ page }) => {
|
||||
// Navigate to interview view and complete interview
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Complete all questions quickly
|
||||
await page.getByTestId("interview-input").fill("A simple todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What tech stack")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("React");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("core features")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("additional requirements")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("None");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for project setup form
|
||||
await expect(page.getByTestId("project-setup-form")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Create button should be disabled without name and path
|
||||
await expect(page.getByTestId("interview-create-project")).toBeDisabled();
|
||||
|
||||
// Enter project name
|
||||
await page.getByTestId("interview-project-name-input").fill("my-todo-app");
|
||||
|
||||
// Still disabled (no path)
|
||||
await expect(page.getByTestId("interview-create-project")).toBeDisabled();
|
||||
|
||||
// Enter path
|
||||
await page.getByTestId("interview-project-path-input").fill("/Users/test/projects");
|
||||
|
||||
// Now should be enabled
|
||||
await expect(page.getByTestId("interview-create-project")).toBeEnabled();
|
||||
});
|
||||
|
||||
test("Creates project and navigates to board view after interview", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Complete all questions
|
||||
await page.getByTestId("interview-input").fill("A simple todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What tech stack")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("React");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("core features")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("additional requirements")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("None");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for project setup form
|
||||
await expect(page.getByTestId("project-setup-form")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Fill in project details
|
||||
await page.getByTestId("interview-project-name-input").fill("interview-test-project");
|
||||
await page.getByTestId("interview-project-path-input").fill("/Users/test/projects");
|
||||
|
||||
// Click create
|
||||
await page.getByTestId("interview-create-project").click();
|
||||
|
||||
// Should navigate to board view
|
||||
await expect(page.getByTestId("board-view")).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Project name should be visible
|
||||
await expect(page.getByTestId("board-view").getByText("interview-test-project")).toBeVisible();
|
||||
});
|
||||
|
||||
test("Interview messages have timestamps", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Verify interview view is displayed
|
||||
await expect(page.getByTestId("interview-view")).toBeVisible();
|
||||
|
||||
// The welcome message should have a timestamp displayed
|
||||
// Timestamps are in format like "10:30:45 AM" or similar
|
||||
const messagesArea = page.getByTestId("interview-messages");
|
||||
await expect(messagesArea).toBeVisible();
|
||||
|
||||
// The welcome message should contain the first question
|
||||
await expect(messagesArea.getByText("What do you want to build?")).toBeVisible();
|
||||
|
||||
// The message area should contain timestamp text (time format like "10:30:45 AM")
|
||||
// We verify by checking that the welcome message exists and has content
|
||||
await expect(messagesArea.locator("p.text-sm").first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("Input field is hidden after interview completes", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Complete all questions
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What tech stack")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("React");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("core features")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("additional requirements")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("None");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for project setup form (interview complete)
|
||||
await expect(page.getByTestId("project-setup-form")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Input field should no longer be visible
|
||||
await expect(page.getByTestId("interview-input")).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("Generated spec contains proper XML structure", async ({ page }) => {
|
||||
// Navigate to interview view
|
||||
await page.getByTestId("create-new-project").click();
|
||||
await page.getByTestId("interactive-mode-option").click();
|
||||
|
||||
// Complete all questions
|
||||
await page.getByTestId("interview-input").fill("A todo app");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("What tech stack")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("React, TypeScript");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("core features")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Add tasks, Delete tasks");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
await expect(page.getByText("additional requirements")).toBeVisible({ timeout: 5000 });
|
||||
await page.getByTestId("interview-input").fill("Mobile responsive");
|
||||
await page.getByTestId("interview-send").click();
|
||||
|
||||
// Wait for spec preview
|
||||
await expect(page.getByTestId("spec-preview")).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify XML structure elements
|
||||
const specPreview = page.getByTestId("spec-preview");
|
||||
await expect(specPreview).toContainText("<project_specification>");
|
||||
await expect(specPreview).toContainText("<overview>");
|
||||
await expect(specPreview).toContainText("<technology_stack>");
|
||||
await expect(specPreview).toContainText("<core_capabilities>");
|
||||
await expect(specPreview).toContainText("<development_guidelines>");
|
||||
});
|
||||
|
||||
test("Quick Setup option still works from dropdown", async ({ page }) => {
|
||||
// Click the Create Project dropdown button
|
||||
await page.getByTestId("create-new-project").click();
|
||||
|
||||
// Click Quick Setup option
|
||||
await page.getByTestId("quick-setup-option").click();
|
||||
|
||||
// Verify dialog appears (not interview view)
|
||||
await expect(page.getByTestId("new-project-dialog")).toBeVisible();
|
||||
await expect(page.getByText("Create New Project")).toBeVisible();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user