Skip to content

Commit efaf943

Browse files
authored
MOB-11527: Business Critical Integration Push Notifications (#918)
1 parent f142c27 commit efaf943

File tree

80 files changed

+15054
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+15054
-1
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
name: BCIT Push Notification Integration Test
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened, labeled]
6+
workflow_dispatch:
7+
inputs:
8+
ref:
9+
description: 'Branch or commit to test (leave empty for current branch)'
10+
required: false
11+
type: string
12+
13+
env:
14+
DEVELOPER_DIR: /Applications/Xcode_16.2.app/Contents/Developer
15+
16+
jobs:
17+
push-notification-test:
18+
name: BCIT Push Notification Integration Test
19+
runs-on: macos-latest
20+
timeout-minutes: 30
21+
if: >
22+
github.event_name == 'workflow_dispatch' ||
23+
(
24+
github.event_name == 'pull_request' && (
25+
contains(github.event.pull_request.labels.*.name, 'bcit') ||
26+
contains(github.event.pull_request.labels.*.name, 'BCIT') ||
27+
contains(github.event.pull_request.labels.*.name, 'bcit-push') ||
28+
contains(github.event.pull_request.labels.*.name, 'BCIT-PUSH') ||
29+
contains(github.event.pull_request.labels.*.name, 'Bcit') ||
30+
contains(github.event.pull_request.labels.*.name, 'Bcit-Push') ||
31+
startsWith(github.event.pull_request.head.ref, 'release/')
32+
)
33+
)
34+
35+
steps:
36+
- name: Checkout Repository
37+
uses: actions/checkout@v4
38+
with:
39+
ref: ${{ github.event.inputs.ref || github.ref }}
40+
41+
- name: Setup Xcode
42+
uses: maxim-lobanov/setup-xcode@v1
43+
with:
44+
xcode-version: '16.2'
45+
46+
- name: Validate Xcode Version
47+
run: |
48+
echo "🔍 Validating Xcode version and environment..."
49+
echo "DEVELOPER_DIR: $DEVELOPER_DIR"
50+
echo "Expected Xcode path: /Applications/Xcode_16.2.app/Contents/Developer"
51+
52+
# Check if DEVELOPER_DIR points to the right Xcode
53+
if [[ "$DEVELOPER_DIR" == "/Applications/Xcode_16.2.app/Contents/Developer" ]]; then
54+
echo "✅ DEVELOPER_DIR is correctly set"
55+
else
56+
echo "❌ DEVELOPER_DIR mismatch!"
57+
echo "Current: $DEVELOPER_DIR"
58+
echo "Expected: /Applications/Xcode_16.2.app/Contents/Developer"
59+
fi
60+
61+
# Check xcodebuild version
62+
echo "🔍 Checking xcodebuild version..."
63+
XCODE_VERSION=$(xcodebuild -version | head -n 1)
64+
echo "Xcode version: $XCODE_VERSION"
65+
66+
# Check xcodebuild path
67+
XCODEBUILD_PATH=$(which xcodebuild)
68+
echo "xcodebuild path: $XCODEBUILD_PATH"
69+
70+
# Verify we're using Xcode 16.2
71+
if echo "$XCODE_VERSION" | grep -q "16.2"; then
72+
echo "✅ Using correct Xcode version: $XCODE_VERSION"
73+
else
74+
echo "❌ Incorrect Xcode version!"
75+
echo "Current: $XCODE_VERSION"
76+
echo "Expected: Xcode 16.2"
77+
exit 1
78+
fi
79+
80+
- name: Setup Local Environment
81+
working-directory: tests/business-critical-integration
82+
run: |
83+
echo "🚀 Setting up local environment for integration tests..."
84+
85+
# Run setup script with parameters from repository secrets
86+
./scripts/setup-local-environment.sh \
87+
"${{ secrets.BCIT_TEST_PROJECT_ID }}" \
88+
"${{ secrets.BCIT_ITERABLE_SERVER_KEY }}" \
89+
"${{ secrets.BCIT_ITERABLE_API_KEY }}"
90+
91+
- name: Validate Setup
92+
working-directory: tests/business-critical-integration
93+
run: |
94+
echo "🔍 Validating environment setup..."
95+
./scripts/validate-setup.sh
96+
97+
- name: Run Push Notification Tests
98+
working-directory: tests/business-critical-integration
99+
run: |
100+
echo "🧪 Running push notification integration tests..."
101+
CI=true ./scripts/run-tests.sh push
102+
103+
- name: Upload Test Results
104+
if: always()
105+
uses: actions/upload-artifact@v4
106+
with:
107+
name: push-notification-test-results
108+
path: |
109+
tests/business-critical-integration/reports/
110+
tests/business-critical-integration/screenshots/
111+
tests/business-critical-integration/logs/
112+
retention-days: 7

.github/workflows/prepare-for-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ jobs:
103103
- [ ] All tests passing
104104
- [ ] Documentation updated (if needed)
105105
106-
branch: "MOB-${{ github.event.inputs.jira_ticket }}-prepare-for-release-${{ steps.update_changelog.outputs.new_version }}"
106+
branch: "release/MOB-${{ github.event.inputs.jira_ticket }}-prepare-for-release-${{ steps.update_changelog.outputs.new_version }}"
107107
commit-message: "[MOB-${{ github.event.inputs.jira_ticket }}]: Prepare for release ${{ steps.update_changelog.outputs.new_version }}"
108108
labels: release
109109
delete-branch: true

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@ xcuserdata
33

44
.claude/
55

6+
tests/business-critical-integration/logs
7+
tests/business-critical-integration/integration-test-app/config
8+
tests/business-critical-integration/reports
9+
tests/business-critical-integration/screenshots
10+
11+
612
.swiftpm/
713

14+
.claude
15+
816
*~
917
Podfile.lock
1018
Pods/
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Business Critical Integration Tests - CI Push Notification Strategy
2+
3+
## Overview
4+
This project implements push notification integration tests that work seamlessly in both local and CI environments.
5+
6+
## CI Push Notification Strategy
7+
8+
### Problem
9+
- CI servers use macOS virtualization which doesn't provide device tokens
10+
- Without device tokens, apps can't register for APNS push notifications
11+
- This breaks push notification integration tests in CI
12+
13+
### Solution Implemented
14+
1. **Environment Detection**: Automatically detects CI environment via environment variables
15+
2. **Mock Device Token**: Generates fake device tokens for CI testing
16+
3. **Simulated Push Notifications**: Uses `xcrun simctl push` to send fake pushes to simulator
17+
4. **Local Testing Unchanged**: Real APNS pushes continue to work locally
18+
19+
## Technical Implementation
20+
21+
### Key Files Modified
22+
- `AppDelegate+IntegrationTest.swift`: CI detection + mock device token generation
23+
- `IntegrationTestBase.swift`: CI environment detection + simulated push capabilities
24+
- `PushNotificationIntegrationTests.swift`: CI-aware push notification testing
25+
- `run-tests.sh`: CI environment variable setup
26+
27+
### CI Environment Detection
28+
- Checks for `CI=1`, `GITHUB_ACTIONS`, `JENKINS_URL`, `BUILDKITE` environment variables
29+
- Automatically enables mock mode when detected
30+
31+
### Mock Device Token Generation
32+
- Generates realistic 32-byte hex string tokens in CI
33+
- Simulates `didRegisterForRemoteNotificationsWithDeviceToken` callback
34+
- Maintains full Iterable SDK registration flow
35+
36+
### Simulated Push Notifications
37+
- Uses `xcrun simctl push` command with temporary `.apns` payload files
38+
- Supports both standard and deep link push notifications
39+
- Validates same notification handling logic as real pushes
40+
- **NEW**: Background push monitor in test runner automatically executes queued push commands
41+
- Test creates persistent payload and command files in `/tmp/push_queue`
42+
- Test runner monitors queue directory and executes `xcrun simctl` commands automatically
43+
44+
## Usage
45+
46+
### Local Testing (Default)
47+
```bash
48+
./scripts/run-tests.sh
49+
```
50+
- Uses real APNS push notifications
51+
- Full end-to-end validation
52+
53+
### CI Testing
54+
```bash
55+
CI=1 ./scripts/run-tests.sh
56+
```
57+
- Uses mock device tokens
58+
- Sends simulated push notifications
59+
- Tests full push notification flow without network dependencies
60+
61+
## Push Notification Payloads
62+
63+
### Standard Push (CI)
64+
```json
65+
{
66+
"aps": {
67+
"alert": {
68+
"title": "Integration Test",
69+
"body": "This is an integration test simple push"
70+
},
71+
"badge": 1,
72+
"sound": "default"
73+
},
74+
"itbl": {
75+
"campaignId": 12345,
76+
"templateId": 67890,
77+
"isGhostPush": false
78+
}
79+
}
80+
```
81+
82+
### Deep Link Push (CI)
83+
```json
84+
{
85+
"aps": {
86+
"alert": {
87+
"title": "Deep Link Test",
88+
"body": "This is a deep link push notification test"
89+
},
90+
"badge": 1,
91+
"sound": "default"
92+
},
93+
"itbl": {
94+
"campaignId": 12346,
95+
"templateId": 67891,
96+
"isGhostPush": false,
97+
"deepLinkURL": "tester://product?itemId=12345&category=shoes"
98+
}
99+
}
100+
```
101+
102+
## Screenshot Management
103+
104+
### Problem
105+
- Screenshots were being saved to iOS simulator's Documents directory instead of project's screenshots folder
106+
- Screenshots from test runs were not accessible for review or CI artifacts
107+
108+
### Solution
109+
- Added `copy_screenshots_from_simulator()` function to run-tests.sh
110+
- Automatically copies screenshots from simulator Documents to project screenshots folder after tests complete
111+
- Clears previous screenshots from project directory before copying new ones
112+
- Cleans up simulator screenshots after successful copy
113+
114+
### Implementation
115+
- Parses screenshot directory path directly from test log files in reports directory
116+
- Uses `find` to locate most recent `.log` file for parsing
117+
- Falls back to searching simulator directories if log parsing fails
118+
- Integrates into test completion flow before cleanup
119+
- Fixed xcresulttool deprecation warning by adding `--legacy` flag
120+
121+
## Test Artifacts Organization
122+
123+
### Directory Structure
124+
- **📁 reports/**: XCTest result bundles (.xcresult) and test reports (.log files for screenshot parsing)
125+
- **📁 logs/**: Complete test execution logs with full output
126+
- **📁 screenshots/**: Test screenshots automatically copied from simulator
127+
- **📁 scripts/**: Test execution and utility scripts
128+
129+
### File Naming Convention
130+
- Timestamp format: `YYYYMMDD-HHMMSS`
131+
- Test class name converted to lowercase
132+
- Examples:
133+
- `pushnotificationintegrationtests-20250829-131349.xcresult`
134+
- `pushnotificationintegrationtests-20250829-131349.log`
135+
136+
## CI Network Validation Strategy
137+
138+
### Mock Device Token Handling
139+
- **CI Environment**: Skips 200 status code validation for `registerDeviceToken` API calls
140+
- **Reason**: Mock device tokens in CI may return unpredictable backend responses
141+
- **Local Environment**: Full validation including 200 status codes continues as normal
142+
- **Detection**: Uses existing `isRunningInCI` environment detection
143+
144+
## Daily Test User Creation
145+
146+
### Enhancement
147+
- **Date-Prefixed Email Generation**: Test user emails now include current date prefix for daily unique users
148+
- **Format**: `[email protected]` (e.g., `[email protected]`)
149+
- **Automatic**: Both interactive and non-interactive modes generate date-prefixed emails
150+
- **Benefits**: Enables fresh test users daily, avoiding conflicts with previous test data
151+
152+
### Implementation
153+
- Modified `setup-local-environment.sh` to add `$(date +"%Y-%m-%d")` prefix to test emails
154+
- Works in both interactive and non-interactive setup modes
155+
- Updates JSON configuration automatically with date-prefixed email
156+
- Maintains backward compatibility with existing test infrastructure
157+
158+
## Benefits
159+
- ✅ Push notification tests run successfully in CI
160+
- ✅ No changes to existing local testing workflow
161+
- ✅ Tests complete push flow including device registration
162+
- ✅ Supports both standard and deep link push notifications
163+
- ✅ Maintains payload format compatibility for future changes
164+
- ✅ Screenshots automatically copied to project directory for review and CI artifacts
165+
- ✅ Complete test artifacts organized in dedicated directories
166+
- ✅ XCTest results saved for detailed analysis and CI integration
167+
- ✅ Smart network validation that adapts to CI vs local environments
168+
-**NEW**: Automated push execution via background monitor eliminates manual intervention
169+
-**NEW**: Enhanced logging provides comprehensive visibility into push simulation process
170+
-**NEW**: Robust file-based communication between iOS test and macOS test runner
171+
-**NEW**: Daily test user creation with date-prefixed emails for fresh testing environment

0 commit comments

Comments
 (0)