aat-devqa 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aat_devqa-1.0.0/.claude/settings.local.json +19 -0
- aat_devqa-1.0.0/.github/PULL_REQUEST_TEMPLATE.md +15 -0
- aat_devqa-1.0.0/.github/workflows/ci.yml +50 -0
- aat_devqa-1.0.0/.gitignore +64 -0
- aat_devqa-1.0.0/.pre-commit-config.yaml +7 -0
- aat_devqa-1.0.0/CONTRIBUTING.ko.md +286 -0
- aat_devqa-1.0.0/CONTRIBUTING.md +225 -0
- aat_devqa-1.0.0/LICENSE +21 -0
- aat_devqa-1.0.0/Makefile +29 -0
- aat_devqa-1.0.0/PKG-INFO +405 -0
- aat_devqa-1.0.0/README.ko.md +337 -0
- aat_devqa-1.0.0/README.md +348 -0
- aat_devqa-1.0.0/awt-skill/.claude-plugin/marketplace.json +28 -0
- aat_devqa-1.0.0/awt-skill/CONTRIBUTING.md +66 -0
- aat_devqa-1.0.0/awt-skill/LICENSE +669 -0
- aat_devqa-1.0.0/awt-skill/README.md +215 -0
- aat_devqa-1.0.0/awt-skill/awt/SKILL.md +300 -0
- aat_devqa-1.0.0/awt-skill/awt/references/cli-reference.md +140 -0
- aat_devqa-1.0.0/awt-skill/awt/references/config-reference.md +98 -0
- aat_devqa-1.0.0/awt-skill/awt/references/scenario-schema.md +116 -0
- aat_devqa-1.0.0/awt-skill/awt/templates/config-template.yaml +25 -0
- aat_devqa-1.0.0/awt-skill/awt/templates/scenario-template.yaml +30 -0
- aat_devqa-1.0.0/awt-skill/package.json +17 -0
- aat_devqa-1.0.0/blog_Img/awt_devto_cover.png +0 -0
- aat_devqa-1.0.0/cloud/BACKUP_RECOVERY.md +91 -0
- aat_devqa-1.0.0/cloud/Dockerfile +40 -0
- aat_devqa-1.0.0/cloud/README.md +235 -0
- aat_devqa-1.0.0/cloud/aat_cloud.db +0 -0
- aat_devqa-1.0.0/cloud/app/__init__.py +0 -0
- aat_devqa-1.0.0/cloud/app/auth.py +171 -0
- aat_devqa-1.0.0/cloud/app/auth_patterns.py +821 -0
- aat_devqa-1.0.0/cloud/app/config.py +89 -0
- aat_devqa-1.0.0/cloud/app/crawler.py +2072 -0
- aat_devqa-1.0.0/cloud/app/crypto.py +59 -0
- aat_devqa-1.0.0/cloud/app/database.py +26 -0
- aat_devqa-1.0.0/cloud/app/docparse.py +109 -0
- aat_devqa-1.0.0/cloud/app/executor.py +960 -0
- aat_devqa-1.0.0/cloud/app/fast_mode.py +229 -0
- aat_devqa-1.0.0/cloud/app/fix_guide_ai.py +385 -0
- aat_devqa-1.0.0/cloud/app/health.py +110 -0
- aat_devqa-1.0.0/cloud/app/main.py +197 -0
- aat_devqa-1.0.0/cloud/app/middleware.py +163 -0
- aat_devqa-1.0.0/cloud/app/models.py +311 -0
- aat_devqa-1.0.0/cloud/app/routers/__init__.py +0 -0
- aat_devqa-1.0.0/cloud/app/routers/ai_config.py +300 -0
- aat_devqa-1.0.0/cloud/app/routers/billing.py +212 -0
- aat_devqa-1.0.0/cloud/app/routers/documents.py +157 -0
- aat_devqa-1.0.0/cloud/app/routers/fix_guides.py +268 -0
- aat_devqa-1.0.0/cloud/app/routers/github.py +393 -0
- aat_devqa-1.0.0/cloud/app/routers/keys.py +85 -0
- aat_devqa-1.0.0/cloud/app/routers/scan.py +2390 -0
- aat_devqa-1.0.0/cloud/app/routers/tests.py +1609 -0
- aat_devqa-1.0.0/cloud/app/routers/v1.py +80 -0
- aat_devqa-1.0.0/cloud/app/scan_diff.py +197 -0
- aat_devqa-1.0.0/cloud/app/scenario_builder.py +588 -0
- aat_devqa-1.0.0/cloud/app/scenario_utils.py +2349 -0
- aat_devqa-1.0.0/cloud/app/schemas.py +398 -0
- aat_devqa-1.0.0/cloud/app/test_patterns.py +447 -0
- aat_devqa-1.0.0/cloud/app/worker.py +356 -0
- aat_devqa-1.0.0/cloud/app/ws.py +51 -0
- aat_devqa-1.0.0/cloud/docs/CI_CD_GUIDE.md +123 -0
- aat_devqa-1.0.0/cloud/docs/DEPLOYMENT.md +198 -0
- aat_devqa-1.0.0/cloud/frontend/.gitignore +41 -0
- aat_devqa-1.0.0/cloud/frontend/README.md +56 -0
- aat_devqa-1.0.0/cloud/frontend/eslint.config.mjs +18 -0
- aat_devqa-1.0.0/cloud/frontend/messages/en.json +731 -0
- aat_devqa-1.0.0/cloud/frontend/messages/ko.json +731 -0
- aat_devqa-1.0.0/cloud/frontend/next-env.d.ts +6 -0
- aat_devqa-1.0.0/cloud/frontend/next.config.ts +10 -0
- aat_devqa-1.0.0/cloud/frontend/package-lock.json +7384 -0
- aat_devqa-1.0.0/cloud/frontend/package.json +31 -0
- aat_devqa-1.0.0/cloud/frontend/postcss.config.mjs +7 -0
- aat_devqa-1.0.0/cloud/frontend/public/demo.gif +0 -0
- aat_devqa-1.0.0/cloud/frontend/public/demo.mp4 +0 -0
- aat_devqa-1.0.0/cloud/frontend/public/file.svg +1 -0
- aat_devqa-1.0.0/cloud/frontend/public/globe.svg +1 -0
- aat_devqa-1.0.0/cloud/frontend/public/llms-full.txt +369 -0
- aat_devqa-1.0.0/cloud/frontend/public/llms.txt +25 -0
- aat_devqa-1.0.0/cloud/frontend/public/logo-dark.png +0 -0
- aat_devqa-1.0.0/cloud/frontend/public/next.svg +1 -0
- aat_devqa-1.0.0/cloud/frontend/public/og-image.png +0 -0
- aat_devqa-1.0.0/cloud/frontend/public/robots.txt +7 -0
- aat_devqa-1.0.0/cloud/frontend/public/vercel.svg +1 -0
- aat_devqa-1.0.0/cloud/frontend/public/window.svg +1 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/auth/callback/route.ts +38 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/billing/layout.tsx +10 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/billing/page.tsx +145 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/dashboard/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/dashboard/page.tsx +1553 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/favicon.ico +0 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/forgot-password/page.tsx +99 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/globals.css +38 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/layout.tsx +93 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/login/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/login/page.tsx +117 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/opengraph-image.tsx +68 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/page.tsx +636 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/pricing/layout.tsx +10 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/pricing/page.tsx +128 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/privacy/page.tsx +281 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/settings/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/settings/page.tsx +686 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/signup/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/signup/page.tsx +172 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/sitemap.ts +32 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/status/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/status/page.tsx +180 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/terms/page.tsx +260 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/tests/[id]/page.tsx +1453 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/tests/layout.tsx +13 -0
- aat_devqa-1.0.0/cloud/frontend/src/app/tests/page.tsx +212 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/AuthProvider.tsx +63 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/FileUpload.tsx +137 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/Footer.tsx +62 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/Header.tsx +165 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/HeroAnimation.tsx +161 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/LanguageToggle.tsx +25 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/ScenarioEditor.tsx +113 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/ScenarioReview.tsx +396 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/ScenarioViewer.tsx +244 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/ServerWarmup.tsx +60 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/SocialLoginButtons.tsx +89 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/StepIndicator.tsx +86 -0
- aat_devqa-1.0.0/cloud/frontend/src/components/TestProgress.tsx +517 -0
- aat_devqa-1.0.0/cloud/frontend/src/i18n/request.ts +28 -0
- aat_devqa-1.0.0/cloud/frontend/src/lib/api.ts +784 -0
- aat_devqa-1.0.0/cloud/frontend/src/lib/errorMessages.ts +75 -0
- aat_devqa-1.0.0/cloud/frontend/src/lib/supabase.ts +8 -0
- aat_devqa-1.0.0/cloud/frontend/src/middleware.ts +72 -0
- aat_devqa-1.0.0/cloud/frontend/tsconfig.json +34 -0
- aat_devqa-1.0.0/cloud/frontend/tsconfig.tsbuildinfo +1 -0
- aat_devqa-1.0.0/cloud/frontend/vercel.json +5 -0
- aat_devqa-1.0.0/cloud/requirements.txt +33 -0
- aat_devqa-1.0.0/cloud/scripts/backup.sh +76 -0
- aat_devqa-1.0.0/cloud/scripts/capture_fixture.py +132 -0
- aat_devqa-1.0.0/cloud/scripts/restore.sh +92 -0
- aat_devqa-1.0.0/cloud/tests/__init__.py +0 -0
- aat_devqa-1.0.0/cloud/tests/conftest.py +108 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/automation_exercise.json +162 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/demoqa.json +168 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/expand_testing.json +144 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/sample_scan_data.json +142 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/saucedemo.json +179 -0
- aat_devqa-1.0.0/cloud/tests/fixtures/the_internet.json +141 -0
- aat_devqa-1.0.0/cloud/tests/output/.gitignore +3 -0
- aat_devqa-1.0.0/cloud/tests/output/automation_exercise_postproc_fixed.yaml +254 -0
- aat_devqa-1.0.0/cloud/tests/output/automation_exercise_postproc_raw.yaml +254 -0
- aat_devqa-1.0.0/cloud/tests/output/automation_exercise_run_single.yaml +254 -0
- aat_devqa-1.0.0/cloud/tests/output/demoqa_postproc_fixed.yaml +458 -0
- aat_devqa-1.0.0/cloud/tests/output/demoqa_postproc_raw.yaml +458 -0
- aat_devqa-1.0.0/cloud/tests/output/demoqa_run_single.yaml +429 -0
- aat_devqa-1.0.0/cloud/tests/output/expand_testing_postproc_fixed.yaml +262 -0
- aat_devqa-1.0.0/cloud/tests/output/expand_testing_postproc_raw.yaml +262 -0
- aat_devqa-1.0.0/cloud/tests/output/expand_testing_run_single.yaml +289 -0
- aat_devqa-1.0.0/cloud/tests/output/plan_ab_results.json +580 -0
- aat_devqa-1.0.0/cloud/tests/output/postproc_fixed.yaml +347 -0
- aat_devqa-1.0.0/cloud/tests/output/postproc_raw.yaml +347 -0
- aat_devqa-1.0.0/cloud/tests/output/run_001.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/run_002.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/run_003.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/run_004.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/run_005.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/run_single.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_postproc_fixed.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_postproc_raw.yaml +335 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_001.yaml +343 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_002.yaml +344 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_003.yaml +340 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_004.yaml +384 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_005.yaml +340 -0
- aat_devqa-1.0.0/cloud/tests/output/sample_scan_data_run_single.yaml +341 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_postproc_fixed.yaml +452 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_postproc_raw.yaml +452 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_run_single.yaml +451 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_scenarios/SC-001.yaml +81 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_scenarios/SC-002.yaml +140 -0
- aat_devqa-1.0.0/cloud/tests/output/saucedemo_scenarios/SC-003.yaml +230 -0
- aat_devqa-1.0.0/cloud/tests/output/the_internet_postproc_fixed.yaml +212 -0
- aat_devqa-1.0.0/cloud/tests/output/the_internet_postproc_raw.yaml +212 -0
- aat_devqa-1.0.0/cloud/tests/output/the_internet_run_single.yaml +288 -0
- aat_devqa-1.0.0/cloud/tests/test_api_key_auth.py +98 -0
- aat_devqa-1.0.0/cloud/tests/test_api_keys.py +80 -0
- aat_devqa-1.0.0/cloud/tests/test_auth.py +154 -0
- aat_devqa-1.0.0/cloud/tests/test_daily_limit.py +47 -0
- aat_devqa-1.0.0/cloud/tests/test_e2e_cloud.py +511 -0
- aat_devqa-1.0.0/cloud/tests/test_executor.py +67 -0
- aat_devqa-1.0.0/cloud/tests/test_health.py +51 -0
- aat_devqa-1.0.0/cloud/tests/test_patterns.py +191 -0
- aat_devqa-1.0.0/cloud/tests/test_phase_c.py +136 -0
- aat_devqa-1.0.0/cloud/tests/test_plan_ab.py +626 -0
- aat_devqa-1.0.0/cloud/tests/test_rate_limit.py +68 -0
- aat_devqa-1.0.0/cloud/tests/test_scenario_builder.py +218 -0
- aat_devqa-1.0.0/cloud/tests/test_schema.py +62 -0
- aat_devqa-1.0.0/cloud/tests/test_tests_api.py +353 -0
- aat_devqa-1.0.0/cloud/tests/test_v1_api.py +56 -0
- aat_devqa-1.0.0/cloud/tests/test_worker.py +366 -0
- aat_devqa-1.0.0/docs/API_REFERENCE.md +521 -0
- aat_devqa-1.0.0/docs/AWT_Agent_Skill_/341/204/214/341/205/251/341/206/274/341/204/222/341/205/241/341/206/270/341/204/200/341/205/241/341/204/213/341/205/265/341/204/203/341/205/263.md +572 -0
- aat_devqa-1.0.0/docs/AWT_Cost_Optimization_Plan.md +110 -0
- aat_devqa-1.0.0/docs/COMPARISON.md +102 -0
- aat_devqa-1.0.0/docs/FAQ.md +121 -0
- aat_devqa-1.0.0/docs/MAINTENANCE.md +65 -0
- aat_devqa-1.0.0/docs/QUICK_START.md +112 -0
- aat_devqa-1.0.0/docs/assets/demo.gif +0 -0
- aat_devqa-1.0.0/docs/assets/demo.mp4 +0 -0
- aat_devqa-1.0.0/docs/assets/logo-dark.png +0 -0
- aat_devqa-1.0.0/docs/assets/logo-light.png +0 -0
- aat_devqa-1.0.0/docs/check_sync.sh +141 -0
- aat_devqa-1.0.0/llms-full.txt +369 -0
- aat_devqa-1.0.0/llms.txt +25 -0
- aat_devqa-1.0.0/pyproject.toml +123 -0
- aat_devqa-1.0.0/render.yaml +30 -0
- aat_devqa-1.0.0/src/aat/__init__.py +3 -0
- aat_devqa-1.0.0/src/aat/adapters/__init__.py +24 -0
- aat_devqa-1.0.0/src/aat/adapters/base.py +84 -0
- aat_devqa-1.0.0/src/aat/adapters/claude.py +340 -0
- aat_devqa-1.0.0/src/aat/adapters/deepseek.py +61 -0
- aat_devqa-1.0.0/src/aat/adapters/gemini.py +72 -0
- aat_devqa-1.0.0/src/aat/adapters/ollama.py +337 -0
- aat_devqa-1.0.0/src/aat/adapters/openai_adapter.py +563 -0
- aat_devqa-1.0.0/src/aat/cli/__init__.py +0 -0
- aat_devqa-1.0.0/src/aat/cli/commands/__init__.py +0 -0
- aat_devqa-1.0.0/src/aat/cli/commands/analyze_cmd.py +132 -0
- aat_devqa-1.0.0/src/aat/cli/commands/config_cmd.py +76 -0
- aat_devqa-1.0.0/src/aat/cli/commands/cost_cmd.py +113 -0
- aat_devqa-1.0.0/src/aat/cli/commands/dashboard_cmd.py +47 -0
- aat_devqa-1.0.0/src/aat/cli/commands/doctor_cmd.py +273 -0
- aat_devqa-1.0.0/src/aat/cli/commands/generate_cmd.py +201 -0
- aat_devqa-1.0.0/src/aat/cli/commands/init_cmd.py +52 -0
- aat_devqa-1.0.0/src/aat/cli/commands/learn_cmd.py +141 -0
- aat_devqa-1.0.0/src/aat/cli/commands/learned_cmd.py +23 -0
- aat_devqa-1.0.0/src/aat/cli/commands/loop_cmd.py +418 -0
- aat_devqa-1.0.0/src/aat/cli/commands/report_cmd.py +25 -0
- aat_devqa-1.0.0/src/aat/cli/commands/run_cmd.py +363 -0
- aat_devqa-1.0.0/src/aat/cli/commands/serve_cmd.py +52 -0
- aat_devqa-1.0.0/src/aat/cli/commands/setup_cmd.py +145 -0
- aat_devqa-1.0.0/src/aat/cli/commands/start_cmd.py +442 -0
- aat_devqa-1.0.0/src/aat/cli/commands/validate_cmd.py +58 -0
- aat_devqa-1.0.0/src/aat/cli/main.py +68 -0
- aat_devqa-1.0.0/src/aat/core/__init__.py +0 -0
- aat_devqa-1.0.0/src/aat/core/config.py +143 -0
- aat_devqa-1.0.0/src/aat/core/connection.py +131 -0
- aat_devqa-1.0.0/src/aat/core/cost.py +231 -0
- aat_devqa-1.0.0/src/aat/core/events.py +207 -0
- aat_devqa-1.0.0/src/aat/core/exceptions.py +62 -0
- aat_devqa-1.0.0/src/aat/core/git_ops.py +146 -0
- aat_devqa-1.0.0/src/aat/core/loop.py +555 -0
- aat_devqa-1.0.0/src/aat/core/models.py +557 -0
- aat_devqa-1.0.0/src/aat/core/scenario_loader.py +166 -0
- aat_devqa-1.0.0/src/aat/dashboard/__init__.py +1 -0
- aat_devqa-1.0.0/src/aat/dashboard/app.py +1850 -0
- aat_devqa-1.0.0/src/aat/dashboard/events_ws.py +191 -0
- aat_devqa-1.0.0/src/aat/dashboard/static/index.html +2057 -0
- aat_devqa-1.0.0/src/aat/dashboard/subprocess_manager.py +186 -0
- aat_devqa-1.0.0/src/aat/engine/__init__.py +9 -0
- aat_devqa-1.0.0/src/aat/engine/base.py +104 -0
- aat_devqa-1.0.0/src/aat/engine/comparator.py +204 -0
- aat_devqa-1.0.0/src/aat/engine/desktop.py +363 -0
- aat_devqa-1.0.0/src/aat/engine/executor.py +684 -0
- aat_devqa-1.0.0/src/aat/engine/humanizer.py +209 -0
- aat_devqa-1.0.0/src/aat/engine/waiter.py +59 -0
- aat_devqa-1.0.0/src/aat/engine/web.py +350 -0
- aat_devqa-1.0.0/src/aat/learning/__init__.py +0 -0
- aat_devqa-1.0.0/src/aat/learning/matcher.py +65 -0
- aat_devqa-1.0.0/src/aat/learning/store.py +481 -0
- aat_devqa-1.0.0/src/aat/matchers/__init__.py +28 -0
- aat_devqa-1.0.0/src/aat/matchers/base.py +49 -0
- aat_devqa-1.0.0/src/aat/matchers/feature.py +190 -0
- aat_devqa-1.0.0/src/aat/matchers/hybrid.py +145 -0
- aat_devqa-1.0.0/src/aat/matchers/ocr.py +207 -0
- aat_devqa-1.0.0/src/aat/matchers/template.py +202 -0
- aat_devqa-1.0.0/src/aat/matchers/vision_ai.py +51 -0
- aat_devqa-1.0.0/src/aat/parsers/__init__.py +13 -0
- aat_devqa-1.0.0/src/aat/parsers/base.py +31 -0
- aat_devqa-1.0.0/src/aat/parsers/markdown_parser.py +61 -0
- aat_devqa-1.0.0/src/aat/reporters/__init__.py +9 -0
- aat_devqa-1.0.0/src/aat/reporters/base.py +40 -0
- aat_devqa-1.0.0/src/aat/reporters/markdown.py +207 -0
- aat_devqa-1.0.0/test-site/README.md +34 -0
- aat_devqa-1.0.0/test-site/app.py +78 -0
- aat_devqa-1.0.0/test-site/config.yaml +18 -0
- aat_devqa-1.0.0/test-site/docs/AWT_Demo_/341/204/200/341/205/265/341/204/222/341/205/254/341/206/250/341/204/211/341/205/245.md +77 -0
- aat_devqa-1.0.0/test-site/docs/AWT_Demo_/341/204/200/341/205/265/341/204/222/341/205/254/341/206/250/341/204/211/341/205/245_/341/204/200/341/205/241/341/206/253/341/204/205/341/205/243/341/206/250.md +15 -0
- aat_devqa-1.0.0/test-site/docs//352/270/260/355/232/215/354/204/234.md +85 -0
- aat_devqa-1.0.0/test-site/templates/base.html +217 -0
- aat_devqa-1.0.0/test-site/templates/index.html +15 -0
- aat_devqa-1.0.0/test-site/templates/login.html +22 -0
- aat_devqa-1.0.0/test-site/templates/main.html +15 -0
- aat_devqa-1.0.0/test-site/templates/register.html +26 -0
- aat_devqa-1.0.0/tests/__init__.py +0 -0
- aat_devqa-1.0.0/tests/conftest.py +1 -0
- aat_devqa-1.0.0/tests/integration/__init__.py +0 -0
- aat_devqa-1.0.0/tests/integration/test_loop_e2e.py +735 -0
- aat_devqa-1.0.0/tests/integration/test_matchers_real.py +466 -0
- aat_devqa-1.0.0/tests/test_abc_interfaces.py +183 -0
- aat_devqa-1.0.0/tests/test_adapters/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_adapters/test_claude.py +306 -0
- aat_devqa-1.0.0/tests/test_adapters/test_ollama.py +419 -0
- aat_devqa-1.0.0/tests/test_adapters/test_openai.py +447 -0
- aat_devqa-1.0.0/tests/test_cli/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_cli/test_analyze_cmd.py +131 -0
- aat_devqa-1.0.0/tests/test_cli/test_config_cmd.py +115 -0
- aat_devqa-1.0.0/tests/test_cli/test_generate_cmd.py +255 -0
- aat_devqa-1.0.0/tests/test_cli/test_init_cmd.py +160 -0
- aat_devqa-1.0.0/tests/test_cli/test_learn_cmd.py +168 -0
- aat_devqa-1.0.0/tests/test_cli/test_loop_cmd.py +52 -0
- aat_devqa-1.0.0/tests/test_cli/test_run_cmd.py +23 -0
- aat_devqa-1.0.0/tests/test_cli/test_serve_cmd.py +33 -0
- aat_devqa-1.0.0/tests/test_cli/test_start_cmd.py +32 -0
- aat_devqa-1.0.0/tests/test_cli/test_validate_cmd.py +107 -0
- aat_devqa-1.0.0/tests/test_config.py +224 -0
- aat_devqa-1.0.0/tests/test_core/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_core/test_connection.py +348 -0
- aat_devqa-1.0.0/tests/test_core/test_events.py +265 -0
- aat_devqa-1.0.0/tests/test_core/test_git_ops.py +193 -0
- aat_devqa-1.0.0/tests/test_dashboard/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_dashboard/test_app.py +556 -0
- aat_devqa-1.0.0/tests/test_dashboard/test_events_ws.py +146 -0
- aat_devqa-1.0.0/tests/test_dashboard/test_subprocess_manager.py +174 -0
- aat_devqa-1.0.0/tests/test_engine/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_engine/test_comparator.py +211 -0
- aat_devqa-1.0.0/tests/test_engine/test_desktop.py +418 -0
- aat_devqa-1.0.0/tests/test_engine/test_executor.py +715 -0
- aat_devqa-1.0.0/tests/test_engine/test_humanizer.py +129 -0
- aat_devqa-1.0.0/tests/test_engine/test_waiter.py +66 -0
- aat_devqa-1.0.0/tests/test_engine/test_web_engine.py +187 -0
- aat_devqa-1.0.0/tests/test_exceptions.py +61 -0
- aat_devqa-1.0.0/tests/test_learning/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_learning/test_matcher.py +120 -0
- aat_devqa-1.0.0/tests/test_learning/test_store.py +136 -0
- aat_devqa-1.0.0/tests/test_loop.py +478 -0
- aat_devqa-1.0.0/tests/test_matchers/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_matchers/test_feature.py +139 -0
- aat_devqa-1.0.0/tests/test_matchers/test_hybrid.py +256 -0
- aat_devqa-1.0.0/tests/test_matchers/test_ocr.py +223 -0
- aat_devqa-1.0.0/tests/test_matchers/test_template.py +172 -0
- aat_devqa-1.0.0/tests/test_matchers/test_vision_ai.py +25 -0
- aat_devqa-1.0.0/tests/test_models.py +742 -0
- aat_devqa-1.0.0/tests/test_parsers/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_parsers/test_markdown_parser.py +143 -0
- aat_devqa-1.0.0/tests/test_reporters/__init__.py +0 -0
- aat_devqa-1.0.0/tests/test_reporters/test_markdown.py +224 -0
- aat_devqa-1.0.0/tests/test_scenario_loader.py +266 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(TOKEN=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0LXVzZXItMDAxIiwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiaWF0IjoxNzcxNzc1MTY2LCJleHAiOjE3NzE3Nzg3NjZ9.hqqiwgpS0gSexiMWixcsTrlaVMGhNJO-BBNSmRsoRkk\")",
|
|
5
|
+
"Bash(__NEW_LINE_235143f4d0a68954__ curl -s -X POST http://127.0.0.1:8000/api/scans -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
6
|
+
"Bash(python3:*)",
|
|
7
|
+
"Bash(__NEW_LINE_d2d54d808ebacd0a__ curl -s -X POST http://127.0.0.1:8000/api/scan -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
8
|
+
"Bash(__NEW_LINE_64300031d61389f5__ curl -s -X POST http://127.0.0.1:8000/api/scan -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
9
|
+
"Bash(__NEW_LINE_f039b8502301214b__ curl -v -X POST http://127.0.0.1:8000/api/scan -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
10
|
+
"Bash(source:*)",
|
|
11
|
+
"Bash(python -m uvicorn:*)",
|
|
12
|
+
"Bash(curl:*)",
|
|
13
|
+
"Bash(__NEW_LINE_a05475a8b0e3beb7__ curl -s -X POST http://127.0.0.1:8000/api/scan -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
14
|
+
"Bash(__NEW_LINE_a439d22f4994d432__ curl -s -X POST http://127.0.0.1:8000/api/scan -H \"Authorization: Bearer $TOKEN\" -H \"Content-Type: application/json\" -d '{\"\"target_url\"\": \"\"https://errcode.co.kr\"\", \"\"max_pages\"\": 3}')",
|
|
15
|
+
"Bash(git add:*)",
|
|
16
|
+
"Bash(sleep:*)"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Changes
|
|
2
|
+
|
|
3
|
+
-
|
|
4
|
+
|
|
5
|
+
## Documentation Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] `README.md` updated (if features/install/usage changed)
|
|
8
|
+
- [ ] `docs/API_REFERENCE.md` updated (if endpoints changed)
|
|
9
|
+
- [ ] `docs/QUICK_START.md` updated (if setup/usage changed)
|
|
10
|
+
- [ ] `docs/FAQ.md` updated (if user-facing behavior changed)
|
|
11
|
+
- [ ] `cloud/docs/CI_CD_GUIDE.md` updated (if API auth/endpoints changed)
|
|
12
|
+
- [ ] `en.json` updated (if UI text added/changed)
|
|
13
|
+
- [ ] `ko.json` structure synced with `en.json`
|
|
14
|
+
- [ ] `cloud/BACKUP_RECOVERY.md` updated (if DB schema changed)
|
|
15
|
+
- [ ] No docs update needed (explain why):
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint-and-test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.11", "3.12"]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Install system dependencies
|
|
26
|
+
run: |
|
|
27
|
+
sudo apt-get update
|
|
28
|
+
sudo apt-get install -y tesseract-ocr
|
|
29
|
+
|
|
30
|
+
- name: Setup Python ${{ matrix.python-version }}
|
|
31
|
+
uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
cache: pip
|
|
35
|
+
cache-dependency-path: pyproject.toml
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: |
|
|
39
|
+
python -m pip install --upgrade pip
|
|
40
|
+
pip install -e ".[dev]"
|
|
41
|
+
playwright install --with-deps chromium
|
|
42
|
+
|
|
43
|
+
- name: Lint with Ruff
|
|
44
|
+
run: ruff check src/ tests/
|
|
45
|
+
|
|
46
|
+
- name: Type check with Mypy
|
|
47
|
+
run: mypy src/aat/
|
|
48
|
+
|
|
49
|
+
- name: Run tests with Pytest
|
|
50
|
+
run: pytest tests/ --tb=short -q
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# PM documents (internal)
|
|
2
|
+
PM/
|
|
3
|
+
|
|
4
|
+
# Project config (may contain API keys)
|
|
5
|
+
aat.config.yaml
|
|
6
|
+
|
|
7
|
+
# Claude Code project guide (internal)
|
|
8
|
+
CLAUDE.md
|
|
9
|
+
|
|
10
|
+
# AAT runtime data (config, learned DB, screenshots, uploaded docs)
|
|
11
|
+
.aat/
|
|
12
|
+
|
|
13
|
+
# Reports (large files)
|
|
14
|
+
reports/
|
|
15
|
+
|
|
16
|
+
# Python
|
|
17
|
+
__pycache__/
|
|
18
|
+
*.pyc
|
|
19
|
+
*.pyo
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
htmlcov/
|
|
24
|
+
dist/
|
|
25
|
+
build/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
|
|
28
|
+
# IDE
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
|
|
32
|
+
# OS
|
|
33
|
+
.DS_Store
|
|
34
|
+
Thumbs.db
|
|
35
|
+
|
|
36
|
+
# Environment
|
|
37
|
+
.env
|
|
38
|
+
.venv/
|
|
39
|
+
venv/
|
|
40
|
+
|
|
41
|
+
# Cloud backend local DB + screenshots
|
|
42
|
+
awt_cloud.db
|
|
43
|
+
cloud/screenshots/
|
|
44
|
+
cloud/cloud/
|
|
45
|
+
cloud/uploads/
|
|
46
|
+
cloud/sample_spec.md
|
|
47
|
+
|
|
48
|
+
# Frontend
|
|
49
|
+
cloud/frontend/node_modules/
|
|
50
|
+
cloud/frontend/.next/
|
|
51
|
+
cloud/frontend/.env.local
|
|
52
|
+
.next/
|
|
53
|
+
|
|
54
|
+
# Uploads (runtime)
|
|
55
|
+
uploads/
|
|
56
|
+
|
|
57
|
+
# Scenarios (local test files)
|
|
58
|
+
scenarios/
|
|
59
|
+
|
|
60
|
+
# AAT data
|
|
61
|
+
.aat/config.yaml
|
|
62
|
+
.aat/learned.db
|
|
63
|
+
.aat/screenshots/
|
|
64
|
+
reports/
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# 기여 가이드
|
|
2
|
+
|
|
3
|
+
AAT 프로젝트에 기여해 주셔서 감사합니다. 이 문서는 개발 환경 설정부터 PR 제출까지의 과정을 설명합니다.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 개발 환경 설정
|
|
8
|
+
|
|
9
|
+
### 필수 조건
|
|
10
|
+
|
|
11
|
+
- Python 3.11 이상
|
|
12
|
+
- Tesseract OCR (`brew install tesseract` 또는 `apt-get install tesseract-ocr`)
|
|
13
|
+
- Git
|
|
14
|
+
|
|
15
|
+
### 설치
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone <repo-url> && cd AI_Auto_Tester
|
|
19
|
+
make dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`make dev`는 다음을 수행한다:
|
|
23
|
+
|
|
24
|
+
```makefile
|
|
25
|
+
dev:
|
|
26
|
+
pip install -e ".[dev]" # 패키지 + 개발 의존성 설치
|
|
27
|
+
playwright install chromium # Chromium 브라우저 설치
|
|
28
|
+
pre-commit install # pre-commit 훅 설치
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 가상 환경 (권장)
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python -m venv .venv
|
|
35
|
+
source .venv/bin/activate # macOS/Linux
|
|
36
|
+
make dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 코드 스타일
|
|
42
|
+
|
|
43
|
+
### ruff (린터 + 포매터)
|
|
44
|
+
|
|
45
|
+
프로젝트는 ruff를 린터와 포매터로 사용한다. 설정은 `pyproject.toml`에 정의되어 있다.
|
|
46
|
+
|
|
47
|
+
```toml
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
target-version = "py311"
|
|
50
|
+
line-length = 99
|
|
51
|
+
src = ["src"]
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = ["E", "F", "I", "N", "UP", "B", "SIM", "TCH"]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
주요 규칙:
|
|
58
|
+
|
|
59
|
+
| 코드 | 설명 |
|
|
60
|
+
|------|------|
|
|
61
|
+
| `E`, `F` | pyflakes, pycodestyle 기본 규칙 |
|
|
62
|
+
| `I` | import 정렬 (isort) |
|
|
63
|
+
| `N` | 네이밍 컨벤션 |
|
|
64
|
+
| `UP` | Python 3.11+ 문법으로 업그레이드 |
|
|
65
|
+
| `B` | bugbear (잠재적 버그) |
|
|
66
|
+
| `SIM` | 코드 단순화 |
|
|
67
|
+
| `TCH` | TYPE_CHECKING 블록 사용 |
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# 린트 검사
|
|
71
|
+
make lint
|
|
72
|
+
|
|
73
|
+
# 자동 포맷 + 자동 수정
|
|
74
|
+
make format
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### mypy (타입 검사)
|
|
78
|
+
|
|
79
|
+
strict 모드로 동작한다. 모든 함수에 타입 힌트를 작성해야 한다.
|
|
80
|
+
|
|
81
|
+
```toml
|
|
82
|
+
[tool.mypy]
|
|
83
|
+
python_version = "3.11"
|
|
84
|
+
strict = true
|
|
85
|
+
warn_return_any = true
|
|
86
|
+
warn_unused_configs = true
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
make typecheck
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### pre-commit
|
|
94
|
+
|
|
95
|
+
커밋 시 ruff 린트와 포맷이 자동으로 실행된다. `.pre-commit-config.yaml`에 정의되어 있다.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 수동 실행 (전체 파일)
|
|
99
|
+
pre-commit run --all-files
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 테스트
|
|
105
|
+
|
|
106
|
+
### 테스트 실행
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# 전체 테스트
|
|
110
|
+
make test
|
|
111
|
+
|
|
112
|
+
# 커버리지 포함
|
|
113
|
+
make test-cov
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`make test-cov`는 터미널 리포트와 HTML 리포트(`htmlcov/`)를 모두 생성한다.
|
|
117
|
+
|
|
118
|
+
### 테스트 설정
|
|
119
|
+
|
|
120
|
+
```toml
|
|
121
|
+
[tool.pytest.ini_options]
|
|
122
|
+
testpaths = ["tests"]
|
|
123
|
+
asyncio_mode = "auto"
|
|
124
|
+
addopts = "-v --tb=short"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- `asyncio_mode = "auto"` -- async 테스트 함수를 자동으로 감지한다. `@pytest.mark.asyncio` 데코레이터가 필요 없다.
|
|
128
|
+
- `addopts = "-v --tb=short"` -- 상세 출력, 짧은 트레이스백.
|
|
129
|
+
|
|
130
|
+
### 테스트 구조
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
tests/
|
|
134
|
+
├── conftest.py # 공통 fixtures
|
|
135
|
+
├── test_engine/ # engine 모듈 테스트
|
|
136
|
+
├── test_matchers/ # matchers 모듈 테스트
|
|
137
|
+
├── test_adapters/ # adapters 모듈 테스트
|
|
138
|
+
├── test_learning/ # learning 모듈 테스트
|
|
139
|
+
└── integration/ # 통합 테스트
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 테스트 작성 규칙
|
|
143
|
+
|
|
144
|
+
- 파일명: `test_<모듈명>.py`
|
|
145
|
+
- 함수명: `test_<동작>_<조건>_<기대결과>` (예: `test_match_with_low_confidence_returns_none`)
|
|
146
|
+
- fixture 활용: 공통 setup은 `conftest.py`에 정의한다.
|
|
147
|
+
- 외부 의존성(API, 브라우저)은 mock으로 대체한다.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## PR 프로세스
|
|
152
|
+
|
|
153
|
+
### 1. 브랜치 생성
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
git checkout -b feat/<기능명> # 기능 추가
|
|
157
|
+
git checkout -b fix/<버그명> # 버그 수정
|
|
158
|
+
git checkout -b refactor/<대상> # 리팩토링
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 2. 개발 및 검증
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# 코드 작성 후
|
|
165
|
+
make format # 포맷 + 린트 자동 수정
|
|
166
|
+
make lint # 린트 검사
|
|
167
|
+
make typecheck # 타입 검사
|
|
168
|
+
make test # 테스트
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
네 가지 검사를 모두 통과해야 PR을 제출할 수 있다.
|
|
172
|
+
|
|
173
|
+
### 3. 커밋
|
|
174
|
+
|
|
175
|
+
커밋 메시지 형식:
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
<type>(<scope>): <subject>
|
|
179
|
+
|
|
180
|
+
<body>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| type | 설명 |
|
|
184
|
+
|------|------|
|
|
185
|
+
| `feat` | 새 기능 |
|
|
186
|
+
| `fix` | 버그 수정 |
|
|
187
|
+
| `refactor` | 리팩토링 (기능 변경 없음) |
|
|
188
|
+
| `test` | 테스트 추가/수정 |
|
|
189
|
+
| `docs` | 문서 변경 |
|
|
190
|
+
| `chore` | 빌드, CI, 의존성 등 |
|
|
191
|
+
|
|
192
|
+
예시:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
feat(matchers): add FeatureMatcher with ORB descriptor
|
|
196
|
+
|
|
197
|
+
ORB 기반 특징점 매칭을 구현한다. 스케일/회전 변환에 강건한 매칭이 가능해진다.
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 4. PR 제출
|
|
201
|
+
|
|
202
|
+
- PR 제목은 커밋 메시지와 동일한 형식을 따른다.
|
|
203
|
+
- 변경 내용, 테스트 방법, 관련 이슈를 본문에 기술한다.
|
|
204
|
+
- 가능하면 스크린샷이나 로그를 첨부한다.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 아키텍처 개요
|
|
209
|
+
|
|
210
|
+
AAT는 플러그인 기반 아키텍처를 따른다. 각 모듈은 ABC(추상 기본 클래스)를 상속받아 구현하며, Registry에 등록하여 사용한다.
|
|
211
|
+
|
|
212
|
+
### 플러그인 구조
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
BaseEngine (ABC) --> ENGINE_REGISTRY
|
|
216
|
+
├── WebEngine (Playwright)
|
|
217
|
+
└── (향후) DesktopEngine
|
|
218
|
+
|
|
219
|
+
BaseMatcher (ABC) --> MATCHER_REGISTRY
|
|
220
|
+
├── TemplateMatcher (cv2.matchTemplate)
|
|
221
|
+
├── OCRMatcher (pytesseract)
|
|
222
|
+
├── FeatureMatcher (ORB/SIFT)
|
|
223
|
+
└── HybridMatcher (체인 오케스트레이터)
|
|
224
|
+
|
|
225
|
+
AIAdapter (ABC) --> ADAPTER_REGISTRY
|
|
226
|
+
└── ClaudeAdapter (anthropic SDK)
|
|
227
|
+
|
|
228
|
+
BaseParser (ABC) --> PARSER_REGISTRY
|
|
229
|
+
└── MarkdownParser
|
|
230
|
+
|
|
231
|
+
BaseReporter (ABC) --> REPORTER_REGISTRY
|
|
232
|
+
└── MarkdownReporter (Jinja2)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 새 플러그인 추가 방법
|
|
236
|
+
|
|
237
|
+
1. 해당 모듈의 ABC를 상속받는 클래스를 작성한다.
|
|
238
|
+
2. 모듈의 `__init__.py`에 정의된 Registry에 등록한다.
|
|
239
|
+
3. 테스트를 작성한다.
|
|
240
|
+
|
|
241
|
+
예시 -- 새 Matcher 추가:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# src/aat/matchers/my_matcher.py
|
|
245
|
+
from aat.matchers.base import BaseMatcher, MatchResult
|
|
246
|
+
|
|
247
|
+
class MyMatcher(BaseMatcher):
|
|
248
|
+
name = "my_matcher"
|
|
249
|
+
|
|
250
|
+
async def match(self, screenshot: bytes, target: MatchTarget) -> MatchResult | None:
|
|
251
|
+
# 구현
|
|
252
|
+
...
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
# src/aat/matchers/__init__.py
|
|
257
|
+
from aat.matchers.my_matcher import MyMatcher
|
|
258
|
+
|
|
259
|
+
MATCHER_REGISTRY["my_matcher"] = MyMatcher
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 핵심 흐름
|
|
263
|
+
|
|
264
|
+
1. **CLI** -- Typer가 사용자 명령을 파싱한다.
|
|
265
|
+
2. **ScenarioLoader** -- YAML 파일을 Pydantic 모델(`Scenario`)로 변환한다.
|
|
266
|
+
3. **StepExecutor** -- 시나리오의 각 스텝을 순서대로 실행한다.
|
|
267
|
+
4. **Engine** -- 브라우저를 제어한다 (navigate, click, type 등).
|
|
268
|
+
5. **Matcher** -- 스크린샷에서 대상 UI 요소의 좌표를 찾는다.
|
|
269
|
+
6. **Comparator** -- 기대 결과와 실제 결과를 비교하여 Pass/Fail을 판정한다.
|
|
270
|
+
7. **DevQA Loop** -- 실패 시 AI Adapter를 호출하여 수정안을 받고 재실행한다.
|
|
271
|
+
8. **Reporter** -- 실행 결과를 Markdown 리포트로 생성한다.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Make 명령어 요약
|
|
276
|
+
|
|
277
|
+
| 명령어 | 설명 |
|
|
278
|
+
|--------|------|
|
|
279
|
+
| `make install` | 런타임 의존성만 설치 |
|
|
280
|
+
| `make dev` | 개발 환경 전체 설정 |
|
|
281
|
+
| `make lint` | ruff 린트 검사 |
|
|
282
|
+
| `make format` | ruff 포맷 + 자동 수정 |
|
|
283
|
+
| `make typecheck` | mypy strict 타입 검사 |
|
|
284
|
+
| `make test` | pytest 전체 실행 |
|
|
285
|
+
| `make test-cov` | pytest + 커버리지 리포트 |
|
|
286
|
+
| `make clean` | 캐시, 빌드 산출물 정리 |
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Contributing to AWT
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This guide covers everything you need to get started.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Development Setup
|
|
8
|
+
|
|
9
|
+
### Prerequisites
|
|
10
|
+
|
|
11
|
+
- Python 3.11+
|
|
12
|
+
- [Tesseract OCR](https://github.com/tesseract-ocr/tesseract) (`brew install tesseract` / `apt install tesseract-ocr`)
|
|
13
|
+
- Git
|
|
14
|
+
|
|
15
|
+
### Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/ksgisang/AI-Watch-Tester.git
|
|
19
|
+
cd AI-Watch-Tester
|
|
20
|
+
python -m venv .venv && source .venv/bin/activate
|
|
21
|
+
make dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`make dev` will:
|
|
25
|
+
|
|
26
|
+
1. Install the package in editable mode with dev dependencies
|
|
27
|
+
2. Install Playwright Chromium browser
|
|
28
|
+
3. Set up pre-commit hooks
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Code Style
|
|
33
|
+
|
|
34
|
+
### ruff (Linter + Formatter)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
make lint # Check for issues
|
|
38
|
+
make format # Auto-format + auto-fix
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Key rules enforced: pyflakes, pycodestyle, import sorting, naming conventions, Python 3.11+ syntax, bugbear, and code simplification.
|
|
42
|
+
|
|
43
|
+
Configuration is in `pyproject.toml`:
|
|
44
|
+
|
|
45
|
+
```toml
|
|
46
|
+
[tool.ruff]
|
|
47
|
+
target-version = "py311"
|
|
48
|
+
line-length = 99
|
|
49
|
+
|
|
50
|
+
[tool.ruff.lint]
|
|
51
|
+
select = ["E", "F", "I", "N", "UP", "B", "SIM", "TCH"]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### mypy (Type Checking)
|
|
55
|
+
|
|
56
|
+
Runs in **strict mode**. All functions must have type annotations.
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
make typecheck
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### pre-commit
|
|
63
|
+
|
|
64
|
+
Ruff lint and format run automatically on every commit via `.pre-commit-config.yaml`.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# Run manually on all files
|
|
68
|
+
pre-commit run --all-files
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Running Tests
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Regular tests (free, no AI calls)
|
|
77
|
+
pytest tests/
|
|
78
|
+
pytest cloud/tests/
|
|
79
|
+
|
|
80
|
+
# E2E tests (AI API calls, costs money)
|
|
81
|
+
pytest cloud/tests/ -m e2e
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> **Warning**
|
|
85
|
+
> E2E tests call the OpenAI API and may incur costs (~$1-2 per run).
|
|
86
|
+
> Regular tests do not require an API key and are always free to run.
|
|
87
|
+
> Please run regular tests before submitting a PR.
|
|
88
|
+
> E2E tests are run automatically in CI after PR review.
|
|
89
|
+
|
|
90
|
+
### Test Writing Rules
|
|
91
|
+
|
|
92
|
+
- File name: `test_<module>.py`
|
|
93
|
+
- Function name: `test_<action>_<condition>_<expected>`
|
|
94
|
+
- Use fixtures from `conftest.py` for common setup
|
|
95
|
+
- Mock external dependencies (APIs, browsers)
|
|
96
|
+
- `asyncio_mode = "auto"` — no `@pytest.mark.asyncio` decorator needed
|
|
97
|
+
|
|
98
|
+
### Test Structure
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
tests/
|
|
102
|
+
├── conftest.py # Shared fixtures
|
|
103
|
+
├── test_engine/ # Engine module tests
|
|
104
|
+
├── test_matchers/ # Matchers module tests
|
|
105
|
+
├── test_adapters/ # Adapters module tests
|
|
106
|
+
├── test_learning/ # Learning module tests
|
|
107
|
+
└── integration/ # Integration tests
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Pull Request Process
|
|
113
|
+
|
|
114
|
+
### 1. Create a Branch
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
git checkout -b feat/<feature> # New feature
|
|
118
|
+
git checkout -b fix/<bug> # Bug fix
|
|
119
|
+
git checkout -b refactor/<target> # Refactoring
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 2. Verify Before Submitting
|
|
123
|
+
|
|
124
|
+
All four checks must pass:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
make format # Format + auto-fix
|
|
128
|
+
make lint # Lint check
|
|
129
|
+
make typecheck # Type check
|
|
130
|
+
make test # Tests
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 3. Commit Message Format
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
<type>(<scope>): <subject>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
| Type | Description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| `feat` | New feature |
|
|
142
|
+
| `fix` | Bug fix |
|
|
143
|
+
| `refactor` | Refactoring (no behavior change) |
|
|
144
|
+
| `test` | Add/modify tests |
|
|
145
|
+
| `docs` | Documentation changes |
|
|
146
|
+
| `chore` | Build, CI, dependencies |
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
feat(matchers): add FeatureMatcher with ORB descriptor
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### 4. Submit PR
|
|
155
|
+
|
|
156
|
+
- Keep the title short and descriptive
|
|
157
|
+
- Describe what changed and why in the body
|
|
158
|
+
- Attach screenshots or logs when relevant
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Architecture Overview
|
|
163
|
+
|
|
164
|
+
AWT uses a plugin-based architecture. Each module extends an ABC and is registered in a dictionary-based registry.
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
BaseEngine (ABC) → ENGINE_REGISTRY
|
|
168
|
+
├── WebEngine (Playwright)
|
|
169
|
+
└── DesktopEngine (PyAutoGUI + Playwright)
|
|
170
|
+
|
|
171
|
+
BaseMatcher (ABC) → MATCHER_REGISTRY
|
|
172
|
+
├── TemplateMatcher (cv2.matchTemplate)
|
|
173
|
+
├── OCRMatcher (pytesseract)
|
|
174
|
+
├── FeatureMatcher (ORB/SIFT)
|
|
175
|
+
└── HybridMatcher (chain orchestrator)
|
|
176
|
+
|
|
177
|
+
AIAdapter (ABC) → ADAPTER_REGISTRY
|
|
178
|
+
├── ClaudeAdapter (anthropic SDK)
|
|
179
|
+
├── OpenAIAdapter (openai SDK)
|
|
180
|
+
└── OllamaAdapter (httpx)
|
|
181
|
+
|
|
182
|
+
BaseParser (ABC) → PARSER_REGISTRY
|
|
183
|
+
└── MarkdownParser
|
|
184
|
+
|
|
185
|
+
BaseReporter (ABC) → REPORTER_REGISTRY
|
|
186
|
+
└── MarkdownReporter (Jinja2)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Adding a New Plugin
|
|
190
|
+
|
|
191
|
+
1. Create a class extending the module's ABC
|
|
192
|
+
2. Register it in the module's `__init__.py` registry
|
|
193
|
+
3. Write tests
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# src/aat/matchers/my_matcher.py
|
|
197
|
+
from aat.matchers.base import BaseMatcher, MatchResult
|
|
198
|
+
|
|
199
|
+
class MyMatcher(BaseMatcher):
|
|
200
|
+
name = "my_matcher"
|
|
201
|
+
|
|
202
|
+
async def match(self, screenshot: bytes, target: MatchTarget) -> MatchResult | None:
|
|
203
|
+
...
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
# src/aat/matchers/__init__.py
|
|
208
|
+
from aat.matchers.my_matcher import MyMatcher
|
|
209
|
+
|
|
210
|
+
MATCHER_REGISTRY["my_matcher"] = MyMatcher
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Make Commands
|
|
216
|
+
|
|
217
|
+
| Command | Description |
|
|
218
|
+
|---------|-------------|
|
|
219
|
+
| `make dev` | Full development environment setup |
|
|
220
|
+
| `make lint` | ruff lint check |
|
|
221
|
+
| `make format` | ruff format + auto-fix |
|
|
222
|
+
| `make typecheck` | mypy strict type check |
|
|
223
|
+
| `make test` | Run all pytest tests |
|
|
224
|
+
| `make test-cov` | pytest + coverage report |
|
|
225
|
+
| `make clean` | Clean caches and build artifacts |
|
aat_devqa-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 AWT Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|