Guides
QA: Poll Trigger Executor & GitHub PR Template
Testing guidelines for the poll trigger sweep infrastructure and the new github-pr-opened poll template.
This document covers testing guidelines for the poll trigger executor, which enables poll-type runner triggers to detect new events from MCP providers and fire runner pipelines.
Prerequisites
- Apply migration
035_poll_trigger_cursor.sql(runsupabase db resetor apply manually) - Verify
poll_cursorJSONB column exists onrunner_triggers - Verify partial index
idx_runner_triggers_poll_sweepexists - A GitHub MCP server must be connected with valid OAuth credentials
- Set
CRON_SECRETenv var for testing the cron endpoint
1. Migration
Test: poll_cursor column exists
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'runner_triggers' AND column_name = 'poll_cursor';
- Returns one row with
data_type = 'jsonb'
Test: Partial index exists
SELECT indexname FROM pg_indexes
WHERE tablename = 'runner_triggers' AND indexname = 'idx_runner_triggers_poll_sweep';
- Returns one row
Test: Existing triggers unaffected
- Existing cron/webhook/manual triggers still work after migration
-
poll_cursorisnullfor all existing rows
2. Poll Template: github-pr-opened
Test: Template appears in template list
- Call
getTemplatesForProvider('github')or inspectPOLL_TEMPLATES - Verify
github-pr-openedexists with:-
label: "PR opened or updated" -
providerKey: "github" -
params.repo: required, placeholder "owner/repo" -
defaultIntervalMinutes: 5
-
Test: Template appears in trigger form UI
- Open a Runner's trigger configuration
- Select "Integration" trigger kind
- Select "GitHub" provider
- Verify "PR opened or updated" appears in the template dropdown
- Verify a "Repository" field appears with placeholder "owner/repo"
3. Poll Sweep — Cron Endpoint
Test: Cron endpoint includes poll sweep results
curl -H "Authorization: Bearer $CRON_SECRET" \
http://localhost:3000/api/cron/runners
- Response includes
pollsobject with{ checked, fired, runIds } - When no poll triggers exist:
polls.checked === 0,polls.fired === 0
Test: Poll triggers are skipped when not due
- Create a runner with a poll trigger (intervalMinutes: 5)
- Fire the cron endpoint
- Immediately fire the cron endpoint again
- Second invocation should show
polls.checked === 0(interval not elapsed)
Test: Disabled poll triggers are skipped
- Create a poll trigger with
enabled: false - Fire the cron endpoint
- Trigger is not checked (doesn't appear in errors or fired)
Test: Inactive runners are skipped
- Create a runner with
status: 'draft'and an enabled poll trigger - Fire the cron endpoint
- Trigger is not checked
4. Poll Sweep — GitHub PR Detection
Test: First run sets baseline without firing
- Create a runner + poll trigger with template
github-pr-opened, repoowner/repo - Ensure the repo has at least one open PR
- Fire the cron endpoint
-
polls.fired === 0(first run is baseline only) -
poll_cursorin the database is now set withlast_updated_atandseen_ids
Test: New PR detected on second run
- After baseline is set (step above), open a new PR in the repo
- Wait for intervalMinutes to elapse (or set interval to 1 minute)
- Fire the cron endpoint
-
polls.fired === 1 - A new
runner_runsrow exists withinput.event === 'pr_opened' -
input.pull_requestcontains the PR object -
input.repositorycontains{ owner, name, full_name }
Test: Updated PR detected
- After baseline is set, push a new commit to an existing open PR
- Fire the cron endpoint
-
polls.fired === 1 -
input.event === 'pr_updated'
Test: No duplicate fires
- Fire the cron endpoint after a PR was already detected
- Without any new PR activity
-
polls.fired === 0 -
poll_cursor.last_updated_atis unchanged
Test: Invalid repo param
- Create a poll trigger with
params.reposet toinvalid(no slash) - Fire the cron endpoint
- Error logged:
INVALID_REPO_PARAM - No runs created
Test: Cursor caps seen_ids at 200
- (Simulated) Set
poll_cursor.seen_idsto an array of 250 IDs - Fire the cron endpoint
- After update,
seen_idslength is <= 200
5. Poll Sweep — Other GitHub Templates
Test: github-new-issue detects new issues
- Create a poll trigger with template
github-new-issue - Fire cron endpoint to set baseline
- Create a new issue in the repo
- Fire cron endpoint again
-
input.event === 'issue_opened' - PRs appearing in the issues endpoint are filtered out
Test: github-new-commit detects new commits
- Create a poll trigger with template
github-new-commit, branchmain - Fire cron endpoint to set baseline
- Push a commit to
main - Fire cron endpoint again
-
input.event === 'new_commit' -
input.branch === 'main'
6. MCP Connection Handling
Test: OAuth token refresh
- Configure a GitHub MCP server with an expired OAuth token (but valid refresh token)
- Fire the cron endpoint with a poll trigger pointing to that server
- Token is refreshed automatically
-
mcp_credentials.encrypted_oauthis updated with new token - Poll succeeds
Test: OAuth token revoked
- Configure a GitHub MCP server with a revoked refresh token
- Fire the cron endpoint
- Error logged:
OAUTH_REFRESH_FAILED - No runs created
- Other triggers continue processing (one failure doesn't block the sweep)
Test: MCP server unreachable
- Configure an MCP server with an invalid URL
- Fire the cron endpoint
- Error logged with connection failure details
- Sweep continues processing remaining triggers
Test: MCP tool call timeout
- Simulate a slow MCP server (> 15s response time)
- AbortController fires, error logged
- Sweep continues processing remaining triggers
7. Pipeline Execution
Test: Fired runs execute pipelines
- Create a runner with a poll trigger and at least one agent step
- Trigger a new PR event
- Fire the cron endpoint
-
runner_runsrow created withstatus: 'pending' - Pipeline executes (status progresses to
runningthencompletedorfailed) -
runner_run_stepsrows created for each step
Test: Multiple new events create multiple runs
- Open 3 new PRs between cron ticks
- Fire the cron endpoint
- 3 separate
runner_runsrows created - All 3 pipelines execute
Test: input_defaults merged with event data
- Set
input_defaultson the trigger:{ "review_style": "thorough" } - Trigger a PR event
- Run input contains both
review_styleandevent/pull_requestfields
8. Regression: Existing Trigger Types
Test: Cron triggers still fire
- Cron triggers continue to work as before
- Response JSON still includes
runnersobject
Test: Webhook triggers still fire
-
POST /api/runners/webhooks/{token}still works - Pipeline executes normally
Test: Scheduled tasks still sweep
- Response JSON still includes
tasksobject - Scheduled task sweep runs in parallel with poll sweep