Inbox Pipeline Ownership Transfer
As a Push Channel developer I want to understand and independently execute the legacy testing pipeline so that I can own the complete test execution process without QA team dependency.
| The inbox test code is intentionally not refactored — inbox will eventually be removed as a product. Refactoring should only happen when the team takes full QA ownership or when a new e2e pipeline is set up. |
Jenkins Pipelines
Two pipelines are in scope — they share code and are treated as a single unit:
| Pipeline | Jenkins URL |
|---|---|
Staging CI |
|
Production Watchdog |
Automatic Triggers
Both pipelines run on a schedule:
-
Staging CI — targets
trunk/ customer213239625(me_push_QAstaging) -
Production Watchdog — targets
suite17_WD/ customer767116266(ME_PerformanceTest_s17)
The entry point is vars/InboxPipeline.groovy in jenkins_sharedlib.
The suite-level job calls InboxPipeline once per test recipient, passing customerId and stagingOrProd.
Pipeline Parameters
| Parameter | Description | Staging | Production |
|---|---|---|---|
|
Test scenario name — determines which stages run |
e.g. |
e.g. |
|
Emarsys account ID |
|
|
|
Environment label |
|
|
|
Branch of me-qa-vienna to check out |
|
|
|
Send Slack alerts on completion |
|
|
How to Trigger a Regression Run
To manually trigger a full regression against staging:
-
Open Inbox_CI_TestSuite_Pipeline in Jenkins.
-
Click Build with Parameters in the left sidebar.
-
Set the parameters:
-
customerId:213239625(staging) or767116266(production watchdog) -
stagingOrProd:trunk(staging) orsuite17_WD(production) -
git_branch_name:master, or a feature branch fromme-qa-viennaif testing a test change -
Leave all other parameters at their defaults.
-
-
Click Build.
To re-run only a single failed stage, trigger the relevant downstream Jenkins job directly with
the appropriate Target_Recipient parameter rather than re-running the full suite.
Each downstream job maps to one InboxPipelineBuilder method — see Jenkins Job Inventory.
|
Repository Overview
jenkins_sharedlib
Pipeline orchestration — defines stages, sequencing, retry logic, and triggers downstream jobs.
jenkins_sharedlib/
├── vars/
│ └── InboxPipeline.groovy # Entry point — stages and flow
│
└── src/org/ems/inbox/
├── InboxPipelineBuilder.groovy # Stage implementations — maps stages to Jenkins jobs
├── InboxSuiteData.groovy # Test data and customer configs per environment
└── InboxSdkData.groovy # SDK-specific test data (not used in CI/WD pipelines)
Shared framework (same for all products):
src/org/ems/common/ ├── PipelineFactory.groovy # Creates pipeline component instances ├── PipelineConfigBuilder.groovy # Fluent API for pipeline configuration ├── TestPipelineManager.groovy # Manages job triggering and data access ├── JenkinsPipelineHelper.groovy # executeWithRetry and utility methods ├── AbstractTestData.groovy # Base class for test data └── AbstractPipelineBuilder.groovy # Base class for pipeline builders
me-qa-vienna
Test execution — Playwright specs that drive the Suite UI.
me-qa-vienna/playwright/
├── tests/inbox/
│ ├── createCampaign.spec.ts # Create and launch campaign
│ ├── cloneCampaign.spec.ts # Clone template and launch campaign
│ ├── recallCampaign.spec.ts # Recall a launched campaign
│ └── checkInboxReport.spec.ts # Validate report statistics
│
├── campaigns/
│ └── InboxCampaign.ts # Page object: inbox campaign wizard
│
├── pages/
│ ├── InboxReportPage.ts # Page object: inbox report page
│ └── OverviewTablePage.ts # Page object: campaigns list table
│
└── testData/
└── InboxTestData.ts # Test data management and Consul read/write
Architecture
┌──────────────────────────────────────────────────────────┐
│ Layer 1: jenkins_sharedlib (Pipeline Orchestration) │
│ InboxPipeline.groovy — stages and retry logic │
│ InboxPipelineBuilder — triggers downstream jobs │
│ InboxSuiteData — customer / env configuration │
└───────────────────────┬──────────────────────────────────┘
│ triggers (parameterized)
┌───────────────────────▼──────────────────────────────────┐
│ Layer 2: Jenkins Jobs (manually configured) │
│ Each job runs a Playwright spec with env parameters │
└───────────────────────┬──────────────────────────────────┘
│ executes
┌───────────────────────▼──────────────────────────────────┐
│ Layer 3: me-qa-vienna (Test Execution) │
│ Playwright specs drive the Suite UI │
│ InboxTestData reads/writes campaign state via Consul │
└───────────────────────┬──────────────────────────────────┘
│ reads/writes
┌───────────────────────▼──────────────────────────────────┐
│ Layer 4: External Systems │
│ Suite UI — inbox campaign management │
│ Consul KV Store — shared state between stages │
│ me-inbox-service API — service under test │
└──────────────────────────────────────────────────────────┘
Stage Sequencing
Stages run sequentially. Stages are skipped (not failed) when the recipient does not apply.
| Stage | Active recipients | Retry config |
|---|---|---|
Create Inbox campaign |
All |
16 retries, 1 min |
Get Information |
All |
16 retries, 1 min |
Event Trigger |
|
None |
Waiting .. |
|
11 min sleep |
Inbox Delivery Checkpoint |
All ( |
22 retries, 2 min |
Browser Inbox Delivery Checkpoint |
|
22 retries, 2 min |
Inbox Add/Remove Tag * Request (×8) |
|
22 retries, 2 min |
Inbox Sending DB Checkpoint |
All except |
22 retries, 2 min |
Inbox Add/Remove Tag * Checkpoint (×8) |
|
22 retries, 2 min |
Inbox Recall |
|
22 retries, 2 min |
Inbox Recall Checkpoint |
|
22 retries, 2 min |
Inbox Report Checkpoint |
All except |
20 retries, 2 min |
executeWithRetry is intentional on delivery and DB checkpoint stages — they poll for an
asynchronous result.
|
Test Recipient Scenarios
| Recipient | Description | CheckType | Environments |
|---|---|---|---|
|
Suite segment — full tag lifecycle + report |
Delivered |
Both |
|
Contact list campaign |
Delivered |
Both |
|
Contact list test message |
Delivered |
Both |
|
Suite segment test message |
Delivered |
Both |
|
Suite segment test via email |
Delivered |
Both |
|
Automation Center — contact list |
Delivered |
Both |
|
Automation Center — single (clone flow) |
Delivered |
Both |
|
Real-Time Interaction |
Delivered |
Both |
|
Schedule then cancel |
NotDelivered |
Both |
|
Mobile segment, no personalization |
Delivered |
Both |
|
Launch then delete (11 min wait) |
NotDelivered |
Both |
|
Device filter + recall flow |
Delivered |
Both |
Test Cases
All inbox Playwright tests live in playwright/tests/inbox/ in me-qa-vienna.
They drive the Suite UI via page objects and share state through Consul.
Create and Launch Campaign (createCampaign.spec.ts)
Jenkins job: 01.Inbox_PW_Create_Campaign_UI
Creates a new inbox campaign from scratch, launches it, and saves the campaign ID to Consul.
-
prepareTestData('Inbox')— loads config from Consul -
Log in to Suite UI
-
Navigate to Inbox Campaigns
-
Create new campaign
-
Complete Message Settings
-
Complete Content Creation
-
(Conditional) Send test message if
isTestMessage === 'true' -
(Conditional) Navigate to Scheduling if not RTI/ACContactList/ACSingle and not a test message
-
(Conditional) Complete Scheduling if
cancelLaunchorlaunchDeleteistrue -
Launch campaign
-
Navigate back to campaign list
-
Verify status (see table below)
-
(Conditional) Cancel launch if
cancelLaunch === 'true' -
Get campaign ID from URL and save to
InboxTestData.params.campaignId -
(Conditional) For RTI/ACContactList/ACSingle — navigate to Automation and update AC program
-
Save campaign details to Consul
-
Log out
| Condition | Expected status |
|---|---|
Normal launch |
|
|
|
RTI / ACContactList / ACSingle |
|
|
|
Clone and Launch Campaign (cloneCampaign.spec.ts)
Jenkins job: Inbox_PW_Clone_Campaign_UI (also used for ACSingle_Inbox in the create flow)
Clones an existing template campaign, edits it, launches it, and updates the Automation Center program.
-
prepareTestData('Inbox')— loads config from Consul -
Log in to Suite UI
-
Navigate to Inbox Campaigns
-
Verify template has status
In design -
Clone the template campaign
-
Open the clone for editing
-
Update Message Settings
-
Navigate to Content Creation and update content
-
Launch campaign
-
Verify status is
Ready to launch -
Get campaign ID and save to Consul
-
Navigate to Automation and update AC program (
AC_INBOX_Templateor event-based template forMobileEventrecipient) -
Save campaign details to Consul (
writeCampaignDetailsToConsul('Clone')) -
Log out
Recall Campaign (recallCampaign.spec.ts)
Jenkins job: 07.Inbox_PW_Recall_Campaign_UI
Recalls a previously launched campaign and verifies it reaches Recalled status.
This test must run after createCampaign or cloneCampaign — it reads the campaign name
from Consul.
|
-
prepareTestData('Inbox')— loads config from Consul -
Read campaign details from Consul
-
Log in to Suite UI
-
Navigate to Inbox Campaigns
-
Open the campaign for editing
-
Recall the campaign
-
Navigate back to campaign list
-
Verify status is
Recalled -
Log out
Check Inbox Report (checkInboxReport.spec.ts)
Jenkins job: Inbox_Report_Check_PW_UI
Validates the campaign report page shows correct delivery statistics.
-
prepareTestData('Inbox')— loads config from Consul -
Read campaign details from Consul
-
(suite0_mobile only) Read report values from Consul
-
Log in to Suite UI
-
Navigate to Inbox Campaigns
-
Navigate to the campaign reporting page
-
Validate stats (
validateCounts()) -
(Conditional) Validate recall text if
recall === 'true' -
(Conditional) Validate undelivered reasons if not suite0_mobile and
undeliveredPercentage !== '0' -
Log out
Metrics validated per scenario: Total_Sent, Total_Open, Delivered_Value, Undelivered_Percentage,
Undelivered_Count_With_Reason (e.g. Personalisation=1,NoDevice=1).
Data Flow & Consul Integration
Consul KV store is the shared state mechanism between pipeline stages.
Each Playwright test reads parameters at startup (prepareTestData) and writes results on completion.
Jenkins Job Inventory
| Jenkins job definitions are manually configured in Jenkins and are not stored in version control. To view or edit a job, navigate to it in Jenkins and click Configure. |
| Job name | Builder method | Purpose |
|---|---|---|
|
|
Create and launch inbox campaign (Playwright) |
|
|
Clone template and launch (Playwright) |
|
|
Read campaign data from API, write to Consul |
|
|
Trigger external events for RTI/ACSingle |
|
|
Check inbox delivery state in API |
|
|
Check browser inbox delivery |
|
|
Add/remove inbox tags via API |
|
|
Validate tag operations in DB |
|
|
Recall campaign via UI (Playwright) |
|
|
Validate report page stats (Playwright) |
|
|
Validate sending data in DB |
Test Failure Analysis
Distinguishing Infrastructure vs. Product Failures
| Symptom | Likely cause | Action |
|---|---|---|
Fails on first attempt, passes on retry |
Transient infrastructure / timing |
Safe to ignore if it recovers |
Consistently fails after all retries |
Product regression or broken test data |
Investigate the downstream job logs |
|
Message not delivered in time, or me-inbox-service issue |
Check service health and logs |
|
Data pipeline delay |
Check if data appears after a longer wait |
Playwright test fails — UI element not found |
UI change in Suite, or stale Consul data |
Check for UI changes; re-run if Consul data expired |
|
Consul config missing, or Suite UI issue |
Verify static Consul config values are present |
Where to Find Logs
-
Jenkins stage log: Click the failed stage in the pipeline view → Console Output of the triggered downstream job.
-
Playwright output: The downstream Playwright job prints test steps and assertion errors to its console. Look for the failed
test.stepname. -
Consul data: After a failed run, check Consul to see what was written (or not) by previous stages — this shows where in the chain the failure occurred.
Common Issues
-
Expired Consul data — If stale data from a previous run is in Consul, the report check may validate wrong counts. Each
jsonFilenameis unique per recipient and environment so this is rare but can happen after manual interventions. -
Campaign name collision — Campaign names include a timestamp. If jobs run too close together they may target the same campaign name. Re-running usually resolves this.
-
Recall checkpoint mistiming — The
Inbox Recall CheckpointverifiesNotDeliveredstate. If the API processes the recall faster than expected the checkpoint may pass immediately; if slower it relies on the 22-retry loop.