Back to SEO Content Production Workflow

Test and QA Plan

How the build is validated before go-live: three sequential test phases, edge cases, and production verification.

4 pagesPDF · Quality
FS-DOC-06Quality

Test and QA Plan

SEO Content Production Workflow

[YourCompany.com] · Marketing Department · Prepared by FullSpec · [Today's Date]

This document defines every test case the FullSpec team will execute before the SEO Content Production Workflow goes live. It covers all three agents: the Brief Generation Agent, the SEO Audit Agent, and the CMS Publishing Agent. Testing runs in three sequential phases. No phase begins until the previous phase has fully passed. The process owner joins Phase 3 to confirm real-world behaviour and record final approval.

01Testing approach

All testing follows three phases in strict sequence. Each phase must reach a full pass before the next phase begins. Phase 1 tests individual agent logic in isolation using sandbox credentials only. Phase 2 tests how agents hand off to one another and validates behaviour under edge-case conditions. Phase 3 runs a complete end-to-end article journey in the production environment with the process owner present to record sign-off.

1
Phase 1: Unit Testing
Each agent tested in isolation against sandbox credentials
Scope
Individual agent logic: trigger detection, API calls, output formatting, and Notion/Slack writes for each of the three agents independently
Environment
Sandbox only. Ahrefs sandbox API key, Surfer SEO test account, WordPress staging site, Notion test database, Slack test workspace
Credential rule
No production API keys, no production Notion database, and no live WordPress site may be used in Phase 1 under any circumstance
Pass condition
All cases T01 through T18 return the expected output with no unhandled errors and no writes to production systems
Who runs it
FullSpec team only. Process owner is not required for Phase 1
2
Phase 2: Integration and Edge Case Testing
Agent handoffs and failure-mode validation in sandbox
Scope
End-to-end agent handoffs across Notion status changes, inter-agent data passing, and all defined edge cases including duplicates, missing fields, and tool unavailability
Environment
Sandbox only. Same credential set as Phase 1. WordPress staging environment must be online and reachable throughout
Credential rule
Sandbox credentials only. Phase 2 may not be promoted to production credentials until all Phase 1 cases pass and are recorded
Pass condition
All cases T19 through T27 pass and all edge-case cases E01 through E08 either resolve gracefully or route correctly to the defined error handler
Who runs it
FullSpec team only. Process owner is not required for Phase 2
3
Phase 3: End-to-End Production Test
Full pipeline run on live credentials with process owner present
Scope
A real article traced from Notion 'Approved' status through brief generation, SEO audit, editorial approval, and WordPress publish, with URL written back to Notion
Environment
Production credentials for all tools. A designated test article slug is used and the post is set to 'Private' or 'Draft' in WordPress before voiding after the run
Credential rule
Production API keys are used for the first time in Phase 3. Keys must be stored in the automation platform's secrets vault, not in plain text or environment variable files
Pass condition
All cases T28 through T32 pass including process owner review case T32, which constitutes the formal go-live approval. Recorded in the FullSpec confirmation log
Who runs it
FullSpec team executes cases T28 through T31. Process owner (Content Manager) joins for T32 and records approval
Test and QA PlanPage 1 of 4
FS-DOC-06Quality

02Phase 1 — unit test cases

Sandbox credentials only for all Phase 1 cases. The Ahrefs sandbox key, Surfer SEO test account, WordPress staging URL, Notion test database ID, and Slack test workspace token must be loaded before any case is run. Verify that no production environment variable is active in the automation platform before proceeding.

Brief Generation Agent — tests T01 to T06

ID
Scenario
Input
Expected Output
Pass Criteria
T01
Happy path: valid topic approved in Notion
Notion row status set to 'Approved'; target keyword 'content marketing strategy'; all required Notion fields populated
Ahrefs API called with correct keyword; Google Docs brief created from template; Notion row status updated to 'Brief Ready'; brief URL written to Notion record
Brief doc exists in Google Docs folder; Notion status is 'Brief Ready'; brief contains target keyword, secondary keywords, recommended headings, intent summary, word count, and at least 3 competitor URLs
T02
Ahrefs API returns zero results for keyword
Notion row status set to 'Approved'; target keyword is an obscure low-volume term with no Ahrefs data
Agent logs a warning; Notion status set to 'Brief Error'; Slack alert sent to content manager channel with error reason
No blank brief is created in Google Docs; Notion status is 'Brief Error'; Slack message received in test workspace within 60 seconds
T03
Notion row is missing the target keyword field
Notion row status set to 'Approved' but the 'Target Keyword' field is empty
Agent detects missing required field before calling Ahrefs; Notion status set to 'Brief Error'; error logged
Ahrefs API is not called; Notion status is 'Brief Error'; error log entry contains field name 'Target Keyword' and row ID
T04
Ahrefs API rate limit hit mid-run
Valid Notion row; Ahrefs sandbox key configured to return a 429 response on the second call
Agent retries after the configured back-off interval (60 seconds); on second attempt succeeds and completes brief normally
Retry attempt logged; brief created successfully on second attempt; total run time under 3 minutes
T05
Google Docs template not found
Valid Notion row and Ahrefs response; Google Docs template file ID in config is incorrect or file deleted
Agent returns an error before writing any content; Notion status set to 'Brief Error'; Slack alert sent
No orphaned Google Docs file created; error message references 'template not found'; Notion status is 'Brief Error'
T06
Duplicate trigger: same Notion row triggers twice within 30 seconds
Notion row status toggled to 'Approved' twice in rapid succession due to a double-click or webhook retry
Idempotency check prevents a second brief from being created; second run exits cleanly with a 'duplicate detected' log entry
Exactly one Google Docs brief exists for the article; Notion row shows one 'Brief Ready' status update; no duplicate Slack notification

SEO Audit Agent — tests T07 to T12

ID
Scenario
Input
Expected Output
Pass Criteria
T07
Happy path: draft marked ready, Surfer SEO score returned
Notion row status set to 'Draft Ready'; Google Docs draft URL present in Notion record; Surfer SEO sandbox returns score 74 with 3 flagged sections
Surfer SEO API called with draft content; score 74 logged to Notion row; Slack scorecard sent to content manager with flagged sections listed
Notion row contains Surfer score field value 74; Slack message received in test workspace; message body lists all 3 flagged section headings
T08
Surfer SEO API returns a score above the passing threshold
Draft content with Surfer score 88 returned by sandbox API; threshold configured at 70
Score logged to Notion; Slack notification sent confirming the draft passes the threshold with no flags
Notion score field is 88; Slack message contains 'No sections flagged below threshold'; no revision prompt included
T09
Surfer SEO API is unavailable (503 response)
Valid Notion row and Google Docs draft; Surfer SEO sandbox returns 503
Agent retries twice with 90-second back-off; after both retries fail, Notion status set to 'Audit Error'; Slack alert sent to content manager
Two retry attempts logged with timestamps; Notion status is 'Audit Error'; Slack alert received; Google Docs draft not modified
T10
Google Docs draft URL in Notion is a broken link
Notion row status set to 'Draft Ready'; Google Docs URL field contains an invalid or deleted file ID
Agent returns a file-not-found error; Notion status set to 'Audit Error'; Slack alert sent with the broken URL
Surfer SEO API not called; error log contains the invalid URL; Notion status is 'Audit Error'
T11
Draft content is below the minimum word count for Surfer SEO submission
Google Docs draft contains fewer than 300 words (Surfer SEO minimum); Notion row status set to 'Draft Ready'
Agent detects word count below threshold before calling Surfer SEO API; Slack message sent to writer channel indicating draft is too short
Surfer SEO API not called; Slack message references the article title and minimum word count; Notion status remains 'Draft Ready'
T12
Slack workspace token is invalid or expired
Valid Surfer SEO score returned; Slack API call fails with 401 invalid_auth
Score still logged to Notion row; error logged for Slack delivery failure; fallback log entry created in the automation platform run history
Notion score field updated correctly; Slack message not delivered (expected); error log entry references 'Slack auth failure'; no unhandled exception

CMS Publishing Agent — tests T13 to T18

ID
Scenario
Input
Expected Output
Pass Criteria
T13
Happy path: content manager marks 'Approved for Publish'
Notion row status set to 'Approved for Publish'; all metadata fields populated (meta title, meta description, slug, categories, tags, featured image URL, publish date); Google Docs draft accessible
WordPress REST API called; post created in staging with all metadata mapped correctly; Notion row updated to 'Published' with the WordPress post URL
WordPress staging post exists with correct slug, meta title, meta description, categories, tags, and featured image; Notion row status is 'Published'; canonical URL in Notion matches WordPress permalink
T14
Notion metadata field 'slug' is missing
Notion row status set to 'Approved for Publish'; slug field is blank
Agent detects missing required field; Notion status set to 'Publish Error'; Slack alert sent to content manager listing the missing field
WordPress REST API not called; Notion status is 'Publish Error'; Slack alert received referencing 'slug' field
T15
WordPress REST API authentication fails (401)
Valid Notion row; WordPress Application Password is incorrect or revoked in staging config
Agent returns auth error; Notion status set to 'Publish Error'; Slack alert sent; no draft post created in WordPress
No WordPress post created; error log contains HTTP 401 response detail; Notion status is 'Publish Error'; Slack alert received
T16
Featured image URL is unreachable
Notion row has a featured image URL that returns 404
Agent proceeds with post creation but omits the featured image; Notion status set to 'Published (No Image)'; Slack alert sent to content manager
WordPress post created without featured image; Notion status contains 'No Image' flag; Slack message received referencing the broken image URL
T17
Publish date in Notion is in the past
Notion publish date field contains a date 3 days prior to the test run date
Agent sets WordPress post status to 'publish' immediately rather than scheduling; Notion row updated with the actual publish timestamp
WordPress post is live (not scheduled); Notion row updated with today's timestamp; no error state set
T18
Google Docs draft content is empty
Notion row status set to 'Approved for Publish'; linked Google Docs file exists but contains no body text
Agent detects empty content before calling WordPress REST API; Notion status set to 'Publish Error'; Slack alert sent
WordPress REST API not called; error log references 'empty document body'; Notion status is 'Publish Error'
Test and QA PlanPage 2 of 4
FS-DOC-06Quality

03Phase 2 — integration and edge case tests

Phase 2 validates the handoffs between agents and tests how the full pipeline responds to real-world failure conditions. All cases in this phase still use sandbox credentials. Integration tests continue the T sequence from T19. Edge case tests use the separate E sequence starting at E01.

Integration tests: agent handoffs — T19 to T27

ID
Scenario
Input
Expected Output
Pass Criteria
T19
Brief Generation Agent completes and triggers Slack writer notification
Notion row moves to 'Brief Ready' after T01 happy path
Slack DM sent to assigned writer channel containing brief URL, target word count, due date, and a receipt confirmation prompt
Slack message received in test writer channel within 90 seconds of Notion status update; all four data fields present in message body
T20
SEO Audit Agent fires correctly on 'Draft Ready' status change
Notion row status manually set to 'Draft Ready' in the test database after a simulated brief cycle
SEO Audit Agent triggers within 30 seconds; Surfer SEO API called with draft content from the correct Google Docs URL stored in the Notion row
Agent trigger timestamp logged within 30 seconds of status change; Surfer SEO sandbox API call recorded with the correct document content
T21
Surfer SEO scorecard Slack message links to the correct Google Docs draft
SEO Audit Agent completes with score 68 and 2 flagged sections
Slack message to content manager channel contains a clickable link to the Google Docs draft plus the score and flagged section names
Link in Slack message resolves to the correct Google Docs file; score shown is 68; both flagged section names appear in the message
T22
CMS Publishing Agent fires only after 'Approved for Publish' status, not on earlier statuses
Notion row cycles through 'Draft Ready', 'In Review', and 'Approved' without reaching 'Approved for Publish'
CMS Publishing Agent does not fire on any status other than 'Approved for Publish'
WordPress staging receives zero API calls during the status cycle; CMS agent run log shows no execution records for the test row
T23
Notion URL write-back after WordPress publish
CMS Publishing Agent successfully creates a staging post; WordPress returns a permalink
Notion row 'Canonical URL' field updated with the WordPress permalink; status updated to 'Published'
Notion row 'Canonical URL' is not empty; value matches the WordPress staging permalink exactly; status field is 'Published'
T24
Brief Generation Agent and SEO Audit Agent run concurrently for two different articles
Two Notion rows set to 'Approved' within 5 seconds of each other, each with a different keyword
Each agent run creates a separate Google Docs brief and logs a separate Surfer SEO score in the correct Notion row
Two distinct Google Docs brief files created; each Notion row's Surfer score field contains only that row's own score; no data cross-contamination between rows
T25
Full three-agent pipeline completes in sandbox from 'Approved' to 'Published' status
Single Notion row progressed manually through all required status changes in the correct sequence
All three agents fire in order; all Notion fields updated at each stage; Slack notifications delivered at brief-ready and scorecard stages; staging WordPress post created
Notion row passes through 'Brief Ready', 'Draft Ready', and 'Published' in order; all agent run logs show success; no manual intervention required between agent steps
T26
SEO Audit Agent does not re-run when Notion row is already in 'Brief Ready' status
Notion row status is 'Brief Ready'; status toggled back to 'Brief Ready' after an accidental edit
SEO Audit Agent does not trigger on 'Brief Ready' status; only triggers on 'Draft Ready'
No Surfer SEO API call recorded for the re-set event; SEO agent run log shows no new execution for that row
T27
CMS Publishing Agent rejects a second 'Approved for Publish' trigger on an already-published row
Notion row with status 'Published' is manually reset to 'Approved for Publish' to simulate an accidental re-trigger
Agent detects that a WordPress post already exists for this slug; exits without creating a duplicate post; logs a warning
No second WordPress post created; warning log entry references 'duplicate slug detected'; Notion status remains 'Published'

Edge case tests — E01 to E08

ID
Scenario
Input
Expected Output
Pass Criteria
E01
Duplicate Notion row created for the same keyword
Two Notion rows with identical target keyword 'content marketing strategy' both set to 'Approved'
Both rows trigger Brief Generation Agent independently; each creates a separate Google Docs brief; a warning is logged noting duplicate keywords
Two brief documents created; warning log entry references both row IDs and the duplicate keyword; no brief content is shared between documents
E02
Notion row missing the assigned writer field when brief completes
Notion row reaches 'Brief Ready' status but the 'Assigned Writer' field is blank
Slack notification cannot be directed to a named writer; message sent to the general content team channel instead with a flag that writer assignment is missing
Slack message received in general content channel; message body includes 'Writer not assigned' warning; Notion row status remains 'Brief Ready'
E03
Ahrefs API quota exhausted mid-month
Ahrefs sandbox configured to return a 403 quota-exceeded response
Agent halts; Notion status set to 'Brief Error'; Slack alert sent to content manager and SEO lead channels; no partial brief created
No Google Docs brief created; Slack alert received by both channels; error log references 'Ahrefs quota exceeded'; Notion status is 'Brief Error'
E04
Surfer SEO returns a malformed JSON response
Surfer SEO sandbox configured to return an incomplete JSON payload missing the 'score' key
Agent catches the parse error; Notion status set to 'Audit Error'; Slack alert sent; raw response body captured in the error log
Error log contains the raw malformed response; Notion status is 'Audit Error'; Slack alert received; no partial score written to Notion
E05
WordPress staging site is unreachable during CMS publish attempt
WordPress staging URL returns a connection timeout after 30 seconds
Agent retries twice with 2-minute back-off; after both retries fail, Notion status set to 'Publish Error'; Slack alert sent to content manager
Two retry attempts logged with timestamps; total wait time approximately 4 minutes before error state; Notion status is 'Publish Error'; Slack alert received
E06
Notion API webhook delivery fails and is retried by Notion
Notion sends the status-change webhook; the automation platform's webhook endpoint returns 500; Notion retries after 5 minutes
On the retry, the automation platform processes the webhook normally; idempotency check confirms no prior run for this row and event type; agent runs once
Exactly one agent execution recorded for the event; no duplicate outputs; retry gap of approximately 5 minutes visible in the run log
E07
Content manager does not mark 'Approved for Publish' within 14 days of draft ready
Notion row remains in 'In Review' status for 14 calendar days with no status change
A scheduled check fires after 14 days and sends a Slack reminder to the content manager channel referencing the stalled article title
Slack reminder received on day 14; message references the correct article title and the date the draft was submitted; no agent fires; no status change made
E08
Google Docs brief file is moved to a different folder by a team member between brief creation and SEO audit
Brief Generation Agent saves brief to the designated Google Docs folder; a team member moves it to a personal folder before the draft is submitted
SEO Audit Agent attempts to read the file using the stored file ID; Google Docs API returns 200 (file IDs are folder-independent in Google Drive); agent proceeds normally
SEO Audit Agent reads file content successfully using the stored file ID regardless of folder location; Surfer SEO API called normally; no error state set
Test and QA PlanPage 3 of 4
FS-DOC-06Quality

04Phase 3 — end-to-end production test

Important before running Phase 3: Use a designated internal test article only. Set the WordPress post status to 'Private' or 'Draft' before the agent fires, and confirm this setting in the WordPress REST API payload before execution. After all Phase 3 cases pass, delete the test WordPress post, remove the test Notion row, and confirm with the FullSpec team that no test data remains in any production system. Do not use a real article slug or keyword that conflicts with a live or planned post. Phase 3 must not begin until every Phase 1 and Phase 2 case is recorded as passed in the FullSpec QA log.

Phase 3 uses production API credentials for all tools: the live Ahrefs account, the live Surfer SEO account, the live WordPress site, the live Notion workspace, and the live Slack workspace. The FullSpec team loads production credentials from the secrets vault immediately before running Phase 3 cases and rotates the test-specific Application Password in WordPress after the run completes.

ID
Scenario
Input
Expected Output
Pass Criteria
T28
Full production run: topic approved through to brief delivered
Internal test Notion row with keyword 'internal-test-qa-[date]' set to 'Approved' in the live content calendar; all metadata fields populated with test values
Brief Generation Agent fires on live Ahrefs account; Google Docs brief created in production Docs folder; Notion row updated to 'Brief Ready'; Slack DM sent to content manager
Brief doc in production Google Docs folder; Notion row status is 'Brief Ready'; brief contains target keyword, secondary keywords, headings, intent, word count, and competitor URLs; Slack message delivered to live workspace within 2 minutes
T29
SEO audit runs on production Surfer SEO account
Test Notion row status set to 'Draft Ready'; Google Docs file contains a 600-word test article body
SEO Audit Agent calls the live Surfer SEO API; score returned and logged to Notion row; Slack scorecard delivered to content manager in the live workspace
Live Surfer SEO account shows one API call consumed; Notion row 'Surfer Score' field populated; Slack message received in live workspace; message body matches the score returned by the API
T30
CMS Publishing Agent creates a private post in production WordPress
Test Notion row status set to 'Approved for Publish'; WordPress REST API payload configured with post status 'private'; all metadata fields populated with test values using the slug 'internal-qa-test-do-not-index'
WordPress REST API creates a private post with all mapped metadata; Notion row updated to 'Published' with the private post permalink; post is not publicly accessible
WordPress admin panel shows one private post with slug 'internal-qa-test-do-not-index'; all metadata fields correct; Notion row 'Canonical URL' matches the WordPress permalink; post visibility confirmed as 'Private'
T31
Error log verification across all production agents
Review the automation platform run log for the Phase 3 test article across all three agent executions
All three agent runs show 'Success' status; no unhandled exceptions; all retry or warning entries (if any) are explained and documented; run durations are within acceptable bounds (Brief Agent under 3 min, SEO Agent under 2 min, CMS Agent under 2 min)
Run log exported and reviewed by FullSpec team; all three runs marked 'Success'; any warnings are explained in the FullSpec QA log; no silent failures or incomplete writes detected
T32
Process owner review and go-live approval
Process owner (Content Manager) reviews the Phase 3 test article journey: brief quality in Google Docs, Surfer SEO scorecard in Slack, private WordPress post metadata, and Notion row field values at each stage
Process owner confirms that brief output meets editorial standards, Slack notifications are clear and actionable, WordPress metadata mapping is correct, and Notion status updates are accurate throughout the pipeline
Process owner records approval in the FullSpec confirmation log by confirming all four review points above. This approval constitutes the formal go-live sign-off for the SEO Content Production Workflow automation. Contact FullSpec at support@gofullspec.com to record the approval and schedule the production switch-on.
After T32 is recorded, the FullSpec team will void the test record: delete the private WordPress post, archive or delete the test Notion row, remove the test Google Docs brief, and confirm in writing to [YourCompany.com] that no test data remains in any production tool. The production pipeline is then ready for live articles.
Test and QA PlanPage 4 of 4

More documents for this process

Every document generated for SEO Content Production Workflow.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Developer Handover Pack
Technical · Developer
View
Integration and API Spec
Technical · Developer
View