mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 08:33:36 +00:00
feat: enhance ESLint configuration and improve component error handling
- Updated ESLint configuration to include support for `.mjs` and `.cjs` file types, adding necessary global variables for Node.js and browser environments. - Introduced a new `vite-env.d.ts` file to define environment variables for Vite, improving type safety. - Refactored error handling in `file-browser-dialog.tsx`, `description-image-dropzone.tsx`, and `feature-image-upload.tsx` to omit error parameters, simplifying the catch blocks. - Removed unused bug report button functionality from the sidebar, streamlining the component structure. - Adjusted various components to improve code readability and maintainability, including updates to type imports and component props. These changes aim to enhance the development experience by improving linting support and simplifying error handling across components.
This commit is contained in:
@@ -15,11 +15,11 @@
|
||||
* so it doesn't make real API calls during CI/CD runs.
|
||||
*/
|
||||
|
||||
import { test, expect } from "@playwright/test";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { test, expect } from '@playwright/test';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
|
||||
import {
|
||||
waitForNetworkIdle,
|
||||
@@ -29,15 +29,14 @@ import {
|
||||
setupProjectWithPathNoWorktrees,
|
||||
waitForBoardView,
|
||||
clickAddFeature,
|
||||
fillAddFeatureDialog,
|
||||
confirmAddFeature,
|
||||
dragAndDropWithDndKit,
|
||||
} from "./utils";
|
||||
} from './utils';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
// Create unique temp dir for this test run
|
||||
const TEST_TEMP_DIR = createTempDirPath("feature-lifecycle-tests");
|
||||
const TEST_TEMP_DIR = createTempDirPath('feature-lifecycle-tests');
|
||||
|
||||
interface TestRepo {
|
||||
path: string;
|
||||
@@ -45,9 +44,9 @@ interface TestRepo {
|
||||
}
|
||||
|
||||
// Configure all tests to run serially
|
||||
test.describe.configure({ mode: "serial" });
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.describe("Feature Lifecycle Tests", () => {
|
||||
test.describe('Feature Lifecycle Tests', () => {
|
||||
let testRepo: TestRepo;
|
||||
let featureId: string;
|
||||
|
||||
@@ -76,7 +75,7 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
});
|
||||
|
||||
// this one fails in github actions for some reason
|
||||
test.skip("complete feature lifecycle: create -> in_progress -> waiting_approval -> commit -> verified -> archive -> restore -> delete", async ({
|
||||
test.skip('complete feature lifecycle: create -> in_progress -> waiting_approval -> commit -> verified -> archive -> restore -> delete', async ({
|
||||
page,
|
||||
}) => {
|
||||
// Increase timeout for this comprehensive test
|
||||
@@ -87,7 +86,7 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// ==========================================================================
|
||||
// Use no-worktrees setup to avoid worktree-related filtering/initialization issues
|
||||
await setupProjectWithPathNoWorktrees(page, testRepo.path);
|
||||
await page.goto("/");
|
||||
await page.goto('/');
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
|
||||
@@ -98,18 +97,15 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await clickAddFeature(page);
|
||||
|
||||
// Fill in the feature details - requesting a file with "yellow" content
|
||||
const featureDescription =
|
||||
"Create a file named yellow.txt that contains the text yellow";
|
||||
const descriptionInput = page
|
||||
.locator('[data-testid="add-feature-dialog"] textarea')
|
||||
.first();
|
||||
const featureDescription = 'Create a file named yellow.txt that contains the text yellow';
|
||||
const descriptionInput = page.locator('[data-testid="add-feature-dialog"] textarea').first();
|
||||
await descriptionInput.fill(featureDescription);
|
||||
|
||||
// Confirm the feature creation
|
||||
await confirmAddFeature(page);
|
||||
|
||||
// Debug: Check the filesystem to see if feature was created
|
||||
const featuresDir = path.join(testRepo.path, ".automaker", "features");
|
||||
const featuresDir = path.join(testRepo.path, '.automaker', 'features');
|
||||
|
||||
// Wait for the feature to be created in the filesystem
|
||||
await expect(async () => {
|
||||
@@ -131,18 +127,14 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
featureId = featureDirs[0];
|
||||
|
||||
// Now get the actual card element by testid
|
||||
const featureCardByTestId = page.locator(
|
||||
`[data-testid="kanban-card-${featureId}"]`
|
||||
);
|
||||
const featureCardByTestId = page.locator(`[data-testid="kanban-card-${featureId}"]`);
|
||||
await expect(featureCardByTestId).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// ==========================================================================
|
||||
// Step 2: Drag feature to in_progress and wait for agent to finish
|
||||
// ==========================================================================
|
||||
const dragHandle = page.locator(`[data-testid="drag-handle-${featureId}"]`);
|
||||
const inProgressColumn = page.locator(
|
||||
'[data-testid="kanban-column-in_progress"]'
|
||||
);
|
||||
const inProgressColumn = page.locator('[data-testid="kanban-column-in_progress"]');
|
||||
|
||||
// Perform the drag and drop using dnd-kit compatible method
|
||||
await dragAndDropWithDndKit(page, dragHandle, inProgressColumn);
|
||||
@@ -151,13 +143,10 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// This helps diagnose if the drag-drop is working or not
|
||||
await expect(async () => {
|
||||
const featureData = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(featuresDir, featureId, "feature.json"),
|
||||
"utf-8"
|
||||
)
|
||||
fs.readFileSync(path.join(featuresDir, featureId, 'feature.json'), 'utf-8')
|
||||
);
|
||||
// Feature should be either in_progress (agent running) or waiting_approval (agent done)
|
||||
expect(["in_progress", "waiting_approval"]).toContain(featureData.status);
|
||||
expect(['in_progress', 'waiting_approval']).toContain(featureData.status);
|
||||
}).toPass({ timeout: 15000 });
|
||||
|
||||
// The mock agent should complete quickly (about 1.3 seconds based on the sleep times)
|
||||
@@ -165,12 +154,9 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// The status changes are: in_progress -> waiting_approval after agent completes
|
||||
await expect(async () => {
|
||||
const featureData = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(featuresDir, featureId, "feature.json"),
|
||||
"utf-8"
|
||||
)
|
||||
fs.readFileSync(path.join(featuresDir, featureId, 'feature.json'), 'utf-8')
|
||||
);
|
||||
expect(featureData.status).toBe("waiting_approval");
|
||||
expect(featureData.status).toBe('waiting_approval');
|
||||
}).toPass({ timeout: 30000 });
|
||||
|
||||
// Refresh page to ensure UI reflects the status change
|
||||
@@ -181,19 +167,17 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// ==========================================================================
|
||||
// Step 3: Verify feature is in waiting_approval (manual review) column
|
||||
// ==========================================================================
|
||||
const waitingApprovalColumn = page.locator(
|
||||
'[data-testid="kanban-column-waiting_approval"]'
|
||||
);
|
||||
const waitingApprovalColumn = page.locator('[data-testid="kanban-column-waiting_approval"]');
|
||||
const cardInWaitingApproval = waitingApprovalColumn.locator(
|
||||
`[data-testid="kanban-card-${featureId}"]`
|
||||
);
|
||||
await expect(cardInWaitingApproval).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify the mock agent created the yellow.txt file
|
||||
const yellowFilePath = path.join(testRepo.path, "yellow.txt");
|
||||
const yellowFilePath = path.join(testRepo.path, 'yellow.txt');
|
||||
expect(fs.existsSync(yellowFilePath)).toBe(true);
|
||||
const yellowContent = fs.readFileSync(yellowFilePath, "utf-8");
|
||||
expect(yellowContent).toBe("yellow");
|
||||
const yellowContent = fs.readFileSync(yellowFilePath, 'utf-8');
|
||||
expect(yellowContent).toBe('yellow');
|
||||
|
||||
// ==========================================================================
|
||||
// Step 4: Click commit and verify git status shows committed changes
|
||||
@@ -207,18 +191,18 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Verify git status shows clean (changes committed)
|
||||
const { stdout: gitStatus } = await execAsync("git status --porcelain", {
|
||||
const { stdout: gitStatus } = await execAsync('git status --porcelain', {
|
||||
cwd: testRepo.path,
|
||||
});
|
||||
// After commit, the yellow.txt file should be committed, so git status should be clean
|
||||
// (only .automaker directory might have changes)
|
||||
expect(gitStatus.includes("yellow.txt")).toBe(false);
|
||||
expect(gitStatus.includes('yellow.txt')).toBe(false);
|
||||
|
||||
// Verify the commit exists in git log
|
||||
const { stdout: gitLog } = await execAsync("git log --oneline -1", {
|
||||
const { stdout: gitLog } = await execAsync('git log --oneline -1', {
|
||||
cwd: testRepo.path,
|
||||
});
|
||||
expect(gitLog.toLowerCase()).toContain("yellow");
|
||||
expect(gitLog.toLowerCase()).toContain('yellow');
|
||||
|
||||
// ==========================================================================
|
||||
// Step 5: Verify feature moved to verified column after commit
|
||||
@@ -228,21 +212,15 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
|
||||
const verifiedColumn = page.locator(
|
||||
'[data-testid="kanban-column-verified"]'
|
||||
);
|
||||
const cardInVerified = verifiedColumn.locator(
|
||||
`[data-testid="kanban-card-${featureId}"]`
|
||||
);
|
||||
const verifiedColumn = page.locator('[data-testid="kanban-column-verified"]');
|
||||
const cardInVerified = verifiedColumn.locator(`[data-testid="kanban-card-${featureId}"]`);
|
||||
await expect(cardInVerified).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// ==========================================================================
|
||||
// Step 6: Archive (complete) the feature
|
||||
// ==========================================================================
|
||||
// Click the Complete button on the verified card
|
||||
const completeButton = page.locator(
|
||||
`[data-testid="complete-${featureId}"]`
|
||||
);
|
||||
const completeButton = page.locator(`[data-testid="complete-${featureId}"]`);
|
||||
await expect(completeButton).toBeVisible({ timeout: 5000 });
|
||||
await completeButton.click();
|
||||
|
||||
@@ -254,39 +232,28 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
|
||||
// Verify feature status is completed in filesystem
|
||||
const featureData = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(featuresDir, featureId, "feature.json"),
|
||||
"utf-8"
|
||||
)
|
||||
fs.readFileSync(path.join(featuresDir, featureId, 'feature.json'), 'utf-8')
|
||||
);
|
||||
expect(featureData.status).toBe("completed");
|
||||
expect(featureData.status).toBe('completed');
|
||||
|
||||
// ==========================================================================
|
||||
// Step 7: Open archive modal and restore the feature
|
||||
// ==========================================================================
|
||||
// Click the completed features button to open the archive modal
|
||||
const completedFeaturesButton = page.locator(
|
||||
'[data-testid="completed-features-button"]'
|
||||
);
|
||||
const completedFeaturesButton = page.locator('[data-testid="completed-features-button"]');
|
||||
await expect(completedFeaturesButton).toBeVisible({ timeout: 5000 });
|
||||
await completedFeaturesButton.click();
|
||||
|
||||
// Wait for the modal to open
|
||||
const completedModal = page.locator(
|
||||
'[data-testid="completed-features-modal"]'
|
||||
);
|
||||
const completedModal = page.locator('[data-testid="completed-features-modal"]');
|
||||
await expect(completedModal).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Verify the archived feature is shown in the modal
|
||||
const archivedCard = completedModal.locator(
|
||||
`[data-testid="completed-card-${featureId}"]`
|
||||
);
|
||||
const archivedCard = completedModal.locator(`[data-testid="completed-card-${featureId}"]`);
|
||||
await expect(archivedCard).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Click the restore button
|
||||
const restoreButton = page.locator(
|
||||
`[data-testid="unarchive-${featureId}"]`
|
||||
);
|
||||
const restoreButton = page.locator(`[data-testid="unarchive-${featureId}"]`);
|
||||
await expect(restoreButton).toBeVisible({ timeout: 5000 });
|
||||
await restoreButton.click();
|
||||
|
||||
@@ -294,47 +261,34 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Close the modal - use first() to select the footer Close button, not the X button
|
||||
const closeButton = completedModal
|
||||
.locator('button:has-text("Close")')
|
||||
.first();
|
||||
const closeButton = completedModal.locator('button:has-text("Close")').first();
|
||||
await closeButton.click();
|
||||
await expect(completedModal).not.toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Verify the feature is back in the verified column
|
||||
const restoredCard = verifiedColumn.locator(
|
||||
`[data-testid="kanban-card-${featureId}"]`
|
||||
);
|
||||
const restoredCard = verifiedColumn.locator(`[data-testid="kanban-card-${featureId}"]`);
|
||||
await expect(restoredCard).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Verify feature status is verified in filesystem
|
||||
const restoredFeatureData = JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(featuresDir, featureId, "feature.json"),
|
||||
"utf-8"
|
||||
)
|
||||
fs.readFileSync(path.join(featuresDir, featureId, 'feature.json'), 'utf-8')
|
||||
);
|
||||
expect(restoredFeatureData.status).toBe("verified");
|
||||
expect(restoredFeatureData.status).toBe('verified');
|
||||
|
||||
// ==========================================================================
|
||||
// Step 8: Delete the feature and verify it's removed
|
||||
// ==========================================================================
|
||||
// Click the delete button on the verified card
|
||||
const deleteButton = page.locator(
|
||||
`[data-testid="delete-verified-${featureId}"]`
|
||||
);
|
||||
const deleteButton = page.locator(`[data-testid="delete-verified-${featureId}"]`);
|
||||
await expect(deleteButton).toBeVisible({ timeout: 5000 });
|
||||
await deleteButton.click();
|
||||
|
||||
// Wait for the confirmation dialog
|
||||
const confirmDialog = page.locator(
|
||||
'[data-testid="delete-confirmation-dialog"]'
|
||||
);
|
||||
const confirmDialog = page.locator('[data-testid="delete-confirmation-dialog"]');
|
||||
await expect(confirmDialog).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Click the confirm delete button
|
||||
const confirmDeleteButton = page.locator(
|
||||
'[data-testid="confirm-delete-button"]'
|
||||
);
|
||||
const confirmDeleteButton = page.locator('[data-testid="confirm-delete-button"]');
|
||||
await confirmDeleteButton.click();
|
||||
|
||||
// Wait for the delete action to complete
|
||||
@@ -361,7 +315,7 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// Step 1: Setup and create a feature in backlog
|
||||
// ==========================================================================
|
||||
await setupProjectWithPathNoWorktrees(page, testRepo.path);
|
||||
await page.goto("/");
|
||||
await page.goto('/');
|
||||
await waitForNetworkIdle(page);
|
||||
await waitForBoardView(page);
|
||||
await page.waitForTimeout(1000);
|
||||
@@ -370,17 +324,15 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await clickAddFeature(page);
|
||||
|
||||
// Fill in the feature details
|
||||
const featureDescription = "Create a file named test-restart.txt";
|
||||
const descriptionInput = page
|
||||
.locator('[data-testid="add-feature-dialog"] textarea')
|
||||
.first();
|
||||
const featureDescription = 'Create a file named test-restart.txt';
|
||||
const descriptionInput = page.locator('[data-testid="add-feature-dialog"] textarea').first();
|
||||
await descriptionInput.fill(featureDescription);
|
||||
|
||||
// Confirm the feature creation
|
||||
await confirmAddFeature(page);
|
||||
|
||||
// Wait for the feature to be created in the filesystem
|
||||
const featuresDir = path.join(testRepo.path, ".automaker", "features");
|
||||
const featuresDir = path.join(testRepo.path, '.automaker', 'features');
|
||||
await expect(async () => {
|
||||
const dirs = fs.readdirSync(featuresDir);
|
||||
expect(dirs.length).toBeGreaterThan(0);
|
||||
@@ -396,36 +348,26 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
await waitForBoardView(page);
|
||||
|
||||
// Wait for the feature card to appear
|
||||
const featureCard = page.locator(
|
||||
`[data-testid="kanban-card-${testFeatureId}"]`
|
||||
);
|
||||
const featureCard = page.locator(`[data-testid="kanban-card-${testFeatureId}"]`);
|
||||
await expect(featureCard).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// ==========================================================================
|
||||
// Step 2: Drag feature to in_progress (first start)
|
||||
// ==========================================================================
|
||||
const dragHandle = page.locator(
|
||||
`[data-testid="drag-handle-${testFeatureId}"]`
|
||||
);
|
||||
const inProgressColumn = page.locator(
|
||||
'[data-testid="kanban-column-in_progress"]'
|
||||
);
|
||||
const dragHandle = page.locator(`[data-testid="drag-handle-${testFeatureId}"]`);
|
||||
const inProgressColumn = page.locator('[data-testid="kanban-column-in_progress"]');
|
||||
|
||||
await dragAndDropWithDndKit(page, dragHandle, inProgressColumn);
|
||||
|
||||
// Verify feature file still exists and is readable
|
||||
const featureFilePath = path.join(
|
||||
featuresDir,
|
||||
testFeatureId,
|
||||
"feature.json"
|
||||
);
|
||||
const featureFilePath = path.join(featuresDir, testFeatureId, 'feature.json');
|
||||
expect(fs.existsSync(featureFilePath)).toBe(true);
|
||||
|
||||
// First verify that the drag succeeded by checking for in_progress status
|
||||
await expect(async () => {
|
||||
const featureData = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
const featureData = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
// Feature should be either in_progress (agent running) or waiting_approval (agent done)
|
||||
expect(["in_progress", "waiting_approval"]).toContain(featureData.status);
|
||||
expect(['in_progress', 'waiting_approval']).toContain(featureData.status);
|
||||
}).toPass({ timeout: 15000 });
|
||||
|
||||
// ==========================================================================
|
||||
@@ -433,19 +375,14 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// ==========================================================================
|
||||
// The mock agent completes quickly, so we wait for it to finish
|
||||
await expect(async () => {
|
||||
const featureData = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
expect(featureData.status).toBe("waiting_approval");
|
||||
const featureData = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
expect(featureData.status).toBe('waiting_approval');
|
||||
}).toPass({ timeout: 30000 });
|
||||
|
||||
// Verify feature file still exists after completion
|
||||
expect(fs.existsSync(featureFilePath)).toBe(true);
|
||||
const featureDataAfterComplete = JSON.parse(
|
||||
fs.readFileSync(featureFilePath, "utf-8")
|
||||
);
|
||||
console.log(
|
||||
"Feature status after first run:",
|
||||
featureDataAfterComplete.status
|
||||
);
|
||||
const featureDataAfterComplete = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
console.log('Feature status after first run:', featureDataAfterComplete.status);
|
||||
|
||||
// Reload to ensure clean state
|
||||
await page.reload();
|
||||
@@ -457,12 +394,8 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// ==========================================================================
|
||||
// Feature is in waiting_approval, drag it back to backlog
|
||||
const backlogColumn = page.locator('[data-testid="kanban-column-backlog"]');
|
||||
const currentCard = page.locator(
|
||||
`[data-testid="kanban-card-${testFeatureId}"]`
|
||||
);
|
||||
const currentDragHandle = page.locator(
|
||||
`[data-testid="drag-handle-${testFeatureId}"]`
|
||||
);
|
||||
const currentCard = page.locator(`[data-testid="kanban-card-${testFeatureId}"]`);
|
||||
const currentDragHandle = page.locator(`[data-testid="drag-handle-${testFeatureId}"]`);
|
||||
|
||||
await expect(currentCard).toBeVisible({ timeout: 10000 });
|
||||
await dragAndDropWithDndKit(page, currentDragHandle, backlogColumn);
|
||||
@@ -470,8 +403,8 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
|
||||
// Verify feature is in backlog
|
||||
await expect(async () => {
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
expect(data.status).toBe("backlog");
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
expect(data.status).toBe('backlog');
|
||||
}).toPass({ timeout: 10000 });
|
||||
|
||||
// Reload to ensure clean state
|
||||
@@ -482,55 +415,45 @@ test.describe("Feature Lifecycle Tests", () => {
|
||||
// ==========================================================================
|
||||
// Step 5: Restart the feature (drag to in_progress again)
|
||||
// ==========================================================================
|
||||
const restartCard = page.locator(
|
||||
`[data-testid="kanban-card-${testFeatureId}"]`
|
||||
);
|
||||
const restartCard = page.locator(`[data-testid="kanban-card-${testFeatureId}"]`);
|
||||
await expect(restartCard).toBeVisible({ timeout: 10000 });
|
||||
|
||||
const restartDragHandle = page.locator(
|
||||
`[data-testid="drag-handle-${testFeatureId}"]`
|
||||
);
|
||||
const inProgressColumnRestart = page.locator(
|
||||
'[data-testid="kanban-column-in_progress"]'
|
||||
);
|
||||
const restartDragHandle = page.locator(`[data-testid="drag-handle-${testFeatureId}"]`);
|
||||
const inProgressColumnRestart = page.locator('[data-testid="kanban-column-in_progress"]');
|
||||
|
||||
// Listen for console errors to catch "Feature not found"
|
||||
const consoleErrors: string[] = [];
|
||||
page.on("console", (msg) => {
|
||||
if (msg.type() === "error") {
|
||||
page.on('console', (msg) => {
|
||||
if (msg.type() === 'error') {
|
||||
consoleErrors.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
// Drag to in_progress to restart
|
||||
await dragAndDropWithDndKit(
|
||||
page,
|
||||
restartDragHandle,
|
||||
inProgressColumnRestart
|
||||
);
|
||||
await dragAndDropWithDndKit(page, restartDragHandle, inProgressColumnRestart);
|
||||
|
||||
// Verify the feature file still exists
|
||||
expect(fs.existsSync(featureFilePath)).toBe(true);
|
||||
|
||||
// First verify that the restart drag succeeded by checking for in_progress status
|
||||
await expect(async () => {
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
// Feature should be either in_progress (agent running) or waiting_approval (agent done)
|
||||
expect(["in_progress", "waiting_approval"]).toContain(data.status);
|
||||
expect(['in_progress', 'waiting_approval']).toContain(data.status);
|
||||
}).toPass({ timeout: 15000 });
|
||||
|
||||
// Verify no "Feature not found" errors in console
|
||||
const featureNotFoundErrors = consoleErrors.filter(
|
||||
(err) => err.includes("not found") || err.includes("Feature")
|
||||
(err) => err.includes('not found') || err.includes('Feature')
|
||||
);
|
||||
expect(featureNotFoundErrors).toEqual([]);
|
||||
|
||||
// Wait for the mock agent to complete and move to waiting_approval
|
||||
await expect(async () => {
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, "utf-8"));
|
||||
expect(data.status).toBe("waiting_approval");
|
||||
const data = JSON.parse(fs.readFileSync(featureFilePath, 'utf-8'));
|
||||
expect(data.status).toBe('waiting_approval');
|
||||
}).toPass({ timeout: 30000 });
|
||||
|
||||
console.log("Feature successfully restarted after stop!");
|
||||
console.log('Feature successfully restarted after stop!');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user