-
Notifications
You must be signed in to change notification settings - Fork 493
Refactor e2e Tests #221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor e2e Tests #221
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| name: Release Build | ||
|
|
||
| on: | ||
| release: | ||
| types: [published] | ||
|
|
||
| jobs: | ||
| build: | ||
| strategy: | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest, windows-latest] | ||
| runs-on: ${{ matrix.os }} | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Extract version from tag | ||
| id: version | ||
| shell: bash | ||
| run: | | ||
| # Remove 'v' prefix if present (e.g., "v1.2.3" -> "1.2.3") | ||
| VERSION="${{ github.event.release.tag_name }}" | ||
| VERSION="${VERSION#v}" | ||
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | ||
| echo "Extracted version: ${VERSION}" | ||
|
|
||
| - name: Update package.json version | ||
| shell: bash | ||
| run: | | ||
| node apps/ui/scripts/update-version.mjs "${{ steps.version.outputs.version }}" | ||
|
|
||
| - name: Setup project | ||
| uses: ./.github/actions/setup-project | ||
| with: | ||
| check-lockfile: 'true' | ||
|
|
||
| - name: Build Electron app (macOS) | ||
| if: matrix.os == 'macos-latest' | ||
| shell: bash | ||
| run: npm run build:electron:mac --workspace=apps/ui | ||
| env: | ||
| CSC_IDENTITY_AUTO_DISCOVERY: false | ||
|
|
||
| - name: Build Electron app (Windows) | ||
| if: matrix.os == 'windows-latest' | ||
| shell: bash | ||
| run: npm run build:electron:win --workspace=apps/ui | ||
|
|
||
| - name: Build Electron app (Linux) | ||
| if: matrix.os == 'ubuntu-latest' | ||
| shell: bash | ||
| run: npm run build:electron:linux --workspace=apps/ui | ||
|
|
||
| - name: Upload macOS artifacts | ||
| if: matrix.os == 'macos-latest' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: macos-builds | ||
| path: apps/ui/release/*.{dmg,zip} | ||
| retention-days: 30 | ||
|
|
||
| - name: Upload Windows artifacts | ||
| if: matrix.os == 'windows-latest' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: windows-builds | ||
| path: apps/ui/release/*.exe | ||
| retention-days: 30 | ||
|
|
||
| - name: Upload Linux artifacts | ||
| if: matrix.os == 'ubuntu-latest' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: linux-builds | ||
| path: apps/ui/release/*.{AppImage,deb} | ||
| retention-days: 30 | ||
|
|
||
| upload: | ||
| needs: build | ||
| runs-on: ubuntu-latest | ||
| if: github.event.release.draft == false | ||
|
|
||
| steps: | ||
| - name: Download macOS artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: macos-builds | ||
| path: artifacts/macos-builds | ||
|
|
||
| - name: Download Windows artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: windows-builds | ||
| path: artifacts/windows-builds | ||
|
|
||
| - name: Download Linux artifacts | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: linux-builds | ||
| path: artifacts/linux-builds | ||
|
|
||
| - name: Upload to GitHub Release | ||
| uses: softprops/action-gh-release@v2 | ||
| with: | ||
| files: | | ||
| artifacts/macos-builds/* | ||
| artifacts/windows-builds/* | ||
| artifacts/linux-builds/* | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #!/usr/bin/env node | ||
| /** | ||
| * Updates the version in apps/ui/package.json | ||
| * Usage: node scripts/update-version.mjs <version> | ||
| * Example: node scripts/update-version.mjs 1.2.3 | ||
| */ | ||
|
|
||
| import { readFileSync, writeFileSync } from 'fs'; | ||
| import { fileURLToPath } from 'url'; | ||
| import { dirname, join } from 'path'; | ||
|
|
||
| const __filename = fileURLToPath(import.meta.url); | ||
| const __dirname = dirname(__filename); | ||
|
|
||
| const version = process.argv[2]; | ||
|
|
||
| if (!version) { | ||
| console.error('Error: Version argument is required'); | ||
| console.error('Usage: node scripts/update-version.mjs <version>'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| // Remove 'v' prefix if present (e.g., "v1.2.3" -> "1.2.3") | ||
| const cleanVersion = version.startsWith('v') ? version.slice(1) : version; | ||
|
|
||
| // Validate version format (basic semver check) | ||
| if (!/^\d+\.\d+\.\d+/.test(cleanVersion)) { | ||
| console.error(`Error: Invalid version format: ${cleanVersion}`); | ||
| console.error('Expected format: X.Y.Z (e.g., 1.2.3)'); | ||
| process.exit(1); | ||
| } | ||
|
Comment on lines
+26
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strengthen semver validation to reject invalid suffixes. The regex 🔎 Proposed fix // Validate version format (basic semver check)
-if (!/^\d+\.\d+\.\d+/.test(cleanVersion)) {
+if (!/^\d+\.\d+\.\d+$/.test(cleanVersion)) {
console.error(`Error: Invalid version format: ${cleanVersion}`);
console.error('Expected format: X.Y.Z (e.g., 1.2.3)');
process.exit(1);
}🤖 Prompt for AI Agents |
||
|
|
||
| const packageJsonPath = join(__dirname, '..', 'package.json'); | ||
|
|
||
| try { | ||
| const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); | ||
| const oldVersion = packageJson.version; | ||
| packageJson.version = cleanVersion; | ||
|
|
||
| writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf8'); | ||
|
|
||
| console.log(`Updated version from ${oldVersion} to ${cleanVersion}`); | ||
| } catch (error) { | ||
| console.error(`Error updating version: ${error.message}`); | ||
| process.exit(1); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| /** | ||
| * Start New Chat Session E2E Test | ||
| * | ||
| * Happy path: Start a new agent chat session | ||
| */ | ||
|
|
||
| import { test, expect } from '@playwright/test'; | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
| import { | ||
| createTempDirPath, | ||
| cleanupTempDir, | ||
| setupRealProject, | ||
| waitForNetworkIdle, | ||
| navigateToAgent, | ||
| clickNewSessionButton, | ||
| waitForNewSession, | ||
| countSessionItems, | ||
| } from '../utils'; | ||
|
|
||
| const TEST_TEMP_DIR = createTempDirPath('agent-session-test'); | ||
|
|
||
| test.describe('Agent Chat Session', () => { | ||
| let projectPath: string; | ||
| const projectName = `test-project-${Date.now()}`; | ||
|
|
||
| test.beforeAll(async () => { | ||
| if (!fs.existsSync(TEST_TEMP_DIR)) { | ||
| fs.mkdirSync(TEST_TEMP_DIR, { recursive: true }); | ||
| } | ||
|
|
||
| projectPath = path.join(TEST_TEMP_DIR, projectName); | ||
| fs.mkdirSync(projectPath, { recursive: true }); | ||
|
|
||
| fs.writeFileSync( | ||
| path.join(projectPath, 'package.json'), | ||
| JSON.stringify({ name: projectName, version: '1.0.0' }, null, 2) | ||
| ); | ||
|
|
||
| const automakerDir = path.join(projectPath, '.automaker'); | ||
| fs.mkdirSync(automakerDir, { recursive: true }); | ||
| fs.mkdirSync(path.join(automakerDir, 'features'), { recursive: true }); | ||
| fs.mkdirSync(path.join(automakerDir, 'context'), { recursive: true }); | ||
| fs.mkdirSync(path.join(automakerDir, 'sessions'), { recursive: true }); | ||
|
|
||
| fs.writeFileSync( | ||
| path.join(automakerDir, 'categories.json'), | ||
| JSON.stringify({ categories: [] }, null, 2) | ||
| ); | ||
|
|
||
| fs.writeFileSync( | ||
| path.join(automakerDir, 'app_spec.txt'), | ||
| `# ${projectName}\n\nA test project for e2e testing.` | ||
| ); | ||
| }); | ||
|
Comment on lines
+27
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
|
|
||
| test.afterAll(async () => { | ||
| cleanupTempDir(TEST_TEMP_DIR); | ||
| }); | ||
|
|
||
| test('should start a new agent chat session', async ({ page }) => { | ||
| await setupRealProject(page, projectPath, projectName, { setAsCurrent: true }); | ||
|
|
||
| await page.goto('/'); | ||
| await waitForNetworkIdle(page); | ||
|
|
||
| // Navigate to agent view | ||
| await navigateToAgent(page); | ||
|
|
||
| // Verify we're on the agent view | ||
| await expect(page.locator('[data-testid="agent-view"]')).toBeVisible({ timeout: 10000 }); | ||
|
|
||
| // Click new session button | ||
| await clickNewSessionButton(page); | ||
|
|
||
| // Wait for new session to appear in the list | ||
| await waitForNewSession(page, { timeout: 10000 }); | ||
|
|
||
| // Verify at least one session exists | ||
| const sessionCount = await countSessionItems(page); | ||
| expect(sessionCount).toBeGreaterThanOrEqual(1); | ||
|
|
||
| // Verify the message list is visible (indicates a session is selected) | ||
| await expect(page.locator('[data-testid="message-list"]')).toBeVisible({ timeout: 5000 }); | ||
|
|
||
| // Verify the agent input is visible | ||
| await expect(page.locator('[data-testid="agent-input"]')).toBeVisible(); | ||
| }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current regex
/^\d+\.\d+\.\d+/for version validation is a bit loose as it only checks the beginning of the string. This would incorrectly validate versions like1.2.3.4or1.2.3-and-more. To ensure the version string strictly follows theX.Y.Zformat, you should anchor the regex to the end of the string as well.