一键导入
integration-testing
Use when writing or running integration tests that call the Gemini API, yt-dlp, or browser tests with geckodriver and fantoccini.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when writing or running integration tests that call the Gemini API, yt-dlp, or browser tests with geckodriver and fantoccini.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when selecting a Gemini model, checking rate limits or quotas, configuring the gemini-rust crate, or debugging model name mismatches.
Create new Kiro skills (Agent Skills). Use when asked to create a skill, write a SKILL.md, add a new workflow to .kiro/skills/, or package agent instructions as a reusable skill.
Use when creating a release, bumping the version, tagging a commit, or working with the GitHub Actions release workflow for rs-summarizer.
Use when editing or creating Askama HTML templates, adding template variables, fixing compile-time template errors, or working with HTMX attributes in templates.
Use when working with tokio::spawn background tasks, the summarization pipeline, task state transitions, or the mark_error/mark_summary_done pattern.
Use when building, running, linting with clippy, formatting with rustfmt, or running cargo commands for the rs-summarizer project.
| name | integration-testing |
| description | Use when writing or running integration tests that call the Gemini API, yt-dlp, or browser tests with geckodriver and fantoccini. |
Integration tests exercise real external services (YouTube via yt-dlp, Gemini API). They are marked #[ignore] so they don't run by default, and gracefully skip on rate limits.
# Transcript tests (requires network + Firefox cookies)
cargo test --test integration_transcript -- --ignored
# Full pipeline tests (requires network + GEMINI_API_KEY)
GEMINI_API_KEY=$(cat ~/api_key.txt) cargo test --test integration_pipeline -- --ignored
# With output visible
GEMINI_API_KEY=$(cat ~/api_key.txt) cargo test --test integration_pipeline -- --ignored --nocapture
# All tests including integration
GEMINI_API_KEY=$(cat ~/api_key.txt) cargo test -- --include-ignored
Integration tests use gemma-3-27b-it (14,400 RPD) to avoid hitting rate limits during development. Gemini models have much lower quotas (20-500 RPD).
Tests that hit external APIs gracefully skip on rate limits instead of failing:
match result {
Ok(data) => { /* assertions */ }
Err(e) => {
let err_str = e.to_string();
if err_str.contains("429") || err_str.contains("bot") || err_str.contains("authentication") {
println!("SKIPPED: Rate-limited: {}", err_str);
return;
}
panic!("Unexpected failure: {}", e);
}
}
Tests that need a database use sqlite::memory: to avoid file system side effects:
let db_pool = db::init_db("sqlite::memory:").await.expect("Failed to init test DB");
tests/integration_transcript.rstest_list_subtitles_real_video — yt-dlp can list substest_download_auto_subtitles — VTT file is createdtest_full_transcript_pipeline — List → download → verify contenttests/integration_pipeline.rstest_transcript_download — TranscriptService end-to-endtest_summary_generation — Gemini generates summary from texttest_embedding_computation — Embedding API returns correct dimensionstest_cosine_similarity_integration — Math verificationtest_full_pipeline_end_to_end — Transcript → summary → YouTube format → embeddingsrc/lib.rs re-exports all modules so integration tests can import them:
// In tests:
use rs_summarizer::db;
use rs_summarizer::services::embedding::EmbeddingService;
use rs_summarizer::services::summary::SummaryService;
Browser integration tests drive a real headless Firefox browser against the application server using fantoccini (WebDriver) + geckodriver. They verify end-to-end user-facing behavior including HTMX interactions, form submissions, pagination, and accessibility.
~/bin/geckodriver)GEMINI_API_KEY for search tests only# All browser integration tests
cargo test --test integration_browser -- --ignored
# A specific browser test
cargo test --test integration_browser test_browse_pagination_page_0 -- --ignored
# With output for debugging
cargo test --test integration_browser -- --ignored --nocapture
Each browser test:
| Helper | Purpose |
|---|---|
test_app_state() | Creates default AppState with in-memory DB |
start_test_server() | Starts server with default state on random port |
start_test_server_with_state(state) | Starts server with pre-configured AppState |
start_test_server_controllable(state) | Returns shutdown handle for graceful restart testing |
seed_summaries(db, count) | Inserts count summaries with markdown content |
seed_summary_with_timestamps(db, url) | Inserts a summary with timestamped content |
test_app_state_with_low_limit() | Creates AppState with rpd_limit=1 for rate limit testing |
| Port Range | Tests |
|---|---|
| 4444–4451 | Original tests (index, browse, form, navigation, assets, search, e2e) |
| 4452–4468 | Extended tests (HTMX behavior, pagination, search, concurrency, accessibility) |
For testing generation partials (POST endpoints), tests use JavaScript fetch:
let script = format!(
r#"
const response = await fetch('/generations/{}', {{ method: 'POST' }});
const html = await response.text();
document.getElementById('result').innerHTML = html;
return html;
"#,
id
);
let result: serde_json::Value = client
.execute(&format!("return (async () => {{ {} }})()", script), vec![])
.await.unwrap();
tests/integration_transcript.rs — yt-dlp download teststests/integration_pipeline.rs — Full pipeline teststests/integration_browser.rs — Browser integration tests (fantoccini + geckodriver)src/lib.rs — Module re-exports for test access