Manual Test Runbook — A1: HubSpot lead enrichment
Owner: Sagar | Time: ~30 min | Requires: HubSpot sandbox portal + Clearbit/Apollo test token
Purpose
Verify that the A1 Custom Code Action enriches contact properties when triggered by a HubSpot workflow on contact create.
Prerequisites
- HubSpot developer/sandbox account with sufficient permissions.
- Clearbit API token (free tier or test account).
- Or: Apollo API token.
- Node 20+ locally to run the test suite.
Custom properties in HubSpot
The action writes to these contact properties. Create them if they don't exist:
| Property Name | Label | Type | Notes |
|---|---|---|---|
jobtitle |
Job Title | Single-line text | Standard HubSpot property |
hs_linkedin_url |
LinkedIn URL | Single-line text | Standard |
company |
Company | Single-line text | Standard |
industry |
Industry | Single-line text | Standard |
numberofemployees |
Number of Employees | Single-line text | Standard |
annualrevenue |
Annual Revenue | Single-line text | Standard |
country |
Country | Single-line text | Standard |
snowops_enrichment_source |
Enrichment Source | Single-line text | Custom (create via Private App settings) |
snowops_enrichment_timestamp |
Enrichment Timestamp | DateTime | Custom |
snowops_tech_stack |
Tech Stack | Multi-line text | Custom |
Steps
1. Create a HubSpot Private App
In the HubSpot sandbox portal:
- Settings → Integrations → Private Apps.
- Create a new app named
snowops-enrichment-test. - Grant scopes:
-
crm.objects.contacts.read -
crm.objects.contacts.write - Copy the Private App token → save locally as
HUBSPOT_TOKEN_TEST.
2. Create a Clearbit test token
- Register for a free Clearbit account (or use a test token if already set up).
- Copy the API token → save locally as
CLEARBIT_TOKEN_TEST.
3. Run the unit test suite locally
- All 19 tests pass (including action.test.ts, enricher.test.ts, offer-email.test.ts).
4. Build the action
-
dist/directory created with compiled.jsfiles.
5. Create the Custom Code Action in HubSpot
In HubSpot, navigate to Automation → Custom Code:
- Create a new Custom Code Action named
Lead Enrichment (A1). - Language: Node.js 20.
- Input fields:
-
email(type: string, required) -
contactId(type: number, required) - Output fields:
-
enriched(type: boolean) -
source(type: string, nullable) -
failure_reason(type: string, nullable) - Secrets (configure in Private App settings):
-
HUBSPOT_PRIVATE_APP_TOKEN→ paste the token from step 1. -
ENRICHMENT_API_TOKEN→ paste the Clearbit token from step 2. -
ENRICHMENT_PROVIDER→ set toclearbit(orapolloif using Apollo).
Copy the compiled code from dist/lead-enrichment/action.js into the action editor. The entry point is the main export.
6. Create a test contact in HubSpot
- Create a new contact:
Alice Liddellwith emailalice@acme.com(or any real person's email the enrichment provider has data for). - Manually note the contact ID (visible in URL or contact details).
7. Test the action manually (optional — if HubSpot UI supports it)
In the Custom Code Action UI:
- Click "Test Action".
- Provide input:
email:alice@acme.comcontactId: (the ID from step 6)- Click "Run".
- Output should show:
enriched: truesource: "clearbit"failure_reason: null- Wait 5 seconds.
- Refresh the contact in HubSpot.
- Verify enriched properties are now populated (job title, company, etc.).
8. Create a test workflow
In HubSpot Workflows:
- Trigger: Contact created.
- Action: Run the
Lead Enrichment (A1)custom code. - Input mapping:
email← Contact Email property.contactId← Contact ID (built-in).- Enroll a test contact by creating a new contact via the portal.
- Workflow runs the action automatically.
- Check that enriched properties were written to the contact.
9. Test non-matching email
- Create a contact with an email the enrichment provider doesn't recognize (e.g.,
nobody@fake-local-domain.test). - Run the workflow.
- Verify output:
enriched: falsesource: nullfailure_reason: "provider_no_match"- Check that
snowops_enrichment_sourcewas set to"none"so the workflow doesn't re-fire.
10. Test invalid email
- Create a contact with an invalid email (e.g.,
not-an-email). - Verify output:
enriched: falsefailure_reason: "invalid_email"
Pass criteria
- Unit test suite passes (19 tests).
- Custom Code Action is creatable in HubSpot.
- Action returns expected output shape (enriched, source, failure_reason).
- Enriched contact properties are populated in HubSpot for valid matches.
- Non-matches and invalid emails are handled gracefully.
- Idempotent: re-running the action overwrites with provider response without error.
Failure modes & escalation
| Symptom | Action |
|---|---|
| Test suite fails | Check TypeScript syntax; run npm run lint. |
| HubSpot auth fails in the action | Verify Private App token secret is set and has correct scopes. |
| Enrichment provider returns 401 | Check API token is correct and not rate-limited. |
| Properties not written to contact | Check property names match exactly; HubSpot property IDs are case-sensitive. |
| Workflow never runs | Trigger may not be enrolling contacts; manually create a test contact. |
Sign-off
- Tester: ___ | Date: _ | Result: PASS / FAIL / N/A
- Notes: