Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/workflows/bcit-integration-test-embedded-messages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: BCIT Embedded Messages Integration Test
permissions:
contents: read

on:
pull_request:
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:
inputs:
ref:
description: 'Branch or commit to test (leave empty for current branch)'
required: false
type: string

jobs:
embedded-messages-test:
name: BCIT Embedded Messages Integration Test
runs-on: macos-latest
timeout-minutes: 30
env:
XCODE_VERSION: '16.4'
if: >
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'pull_request' && (
contains(github.event.pull_request.labels.*.name, 'bcit') ||
contains(github.event.pull_request.labels.*.name, 'BCIT') ||
contains(github.event.pull_request.labels.*.name, 'bcit-embedded') ||
contains(github.event.pull_request.labels.*.name, 'BCIT-EMBEDDED') ||
contains(github.event.pull_request.labels.*.name, 'bcit-embedded-messages') ||
contains(github.event.pull_request.labels.*.name, 'BCIT-EMBEDDED-MESSAGES') ||
contains(github.event.pull_request.labels.*.name, 'Bcit') ||
contains(github.event.pull_request.labels.*.name, 'Bcit-Embedded') ||
startsWith(github.event.pull_request.head.ref, 'release/')
)
)

steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.ref || github.ref }}

- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Validate Xcode Version
run: |
echo "🔍 Validating Xcode version and environment..."
echo "DEVELOPER_DIR: $DEVELOPER_DIR"

# Check xcodebuild version
echo "🔍 Checking xcodebuild version..."
ACTUAL_XCODE_VERSION=$(xcodebuild -version | head -n 1 | awk '{print $2}')
echo "Xcode version: $ACTUAL_XCODE_VERSION"
echo "Expected version: $XCODE_VERSION"

# Check xcodebuild path
XCODEBUILD_PATH=$(which xcodebuild)
echo "xcodebuild path: $XCODEBUILD_PATH"

# Verify we're using the correct Xcode version
if echo "$ACTUAL_XCODE_VERSION" | grep -q "$XCODE_VERSION"; then
echo "✅ Using correct Xcode version: $ACTUAL_XCODE_VERSION"
else
echo "❌ Incorrect Xcode version!"
echo "Current: $ACTUAL_XCODE_VERSION"
echo "Expected: $XCODE_VERSION"
exit 1
fi

- name: Setup Local Environment
working-directory: tests/business-critical-integration
run: |
echo "🚀 Setting up local environment for integration tests..."

# Run setup script with parameters from repository secrets
./scripts/setup-local-environment.sh \
"${{ secrets.BCIT_TEST_PROJECT_ID }}" \
"${{ secrets.BCIT_ITERABLE_SERVER_KEY }}" \
"${{ secrets.BCIT_ITERABLE_API_KEY }}"

- name: Validate Setup
working-directory: tests/business-critical-integration
run: |
echo "🔍 Validating environment setup..."
./scripts/validate-setup.sh

- name: Run Embedded Messages Tests
working-directory: tests/business-critical-integration
run: |
echo "🧪 Running embedded messages integration tests..."
CI=true ./scripts/run-tests.sh embedded

- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: embedded-messages-test-results
path: |
tests/business-critical-integration/reports/
tests/business-critical-integration/screenshots/
tests/business-critical-integration/logs/
retention-days: 7

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ extension AppDelegate {
config.inAppDisplayInterval = 1
config.autoPushRegistration = false // Disable automatic push registration for testing control
config.allowedProtocols = ["tester"] // Allow our custom tester:// deep link scheme
config.enableEmbeddedMessaging = true

let apiKey = loadApiKeyFromConfig()
IterableAPI.initialize(apiKey: apiKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
if let isGhostPush = iterableData["isGhostPush"] as? Bool {
print("👻 [APP] Ghost push flag: \(isGhostPush)")
}

if let notificationType = iterableData["notificationType"] as? String {
print("📝 [APP] Notification type: \(notificationType)")
}
}

// Call completion handler
completionHandler(.newData)
// Pass to Iterable SDK for processing
// This enables automatic embedded message sync when silent push with "UpdateEmbedded" type is received
print("📲 [APP] Passing silent push to Iterable SDK for processing...")
IterableAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
}

// MARK: - Deep link
Expand Down Expand Up @@ -242,6 +248,22 @@ extension AppDelegate: UNUserNotificationCenterDelegate {

if let iterableData = notification.request.content.userInfo["itbl"] as? [String: Any] {
print("🔔 [APP] Iterable-specific data: \(iterableData)")

// Check if this is a silent push for embedded messages
if let notificationType = iterableData["notificationType"] as? String {
print("📝 [APP] Notification type: \(notificationType)")
if notificationType == "UpdateEmbedded" {
print("🎯 [APP] Silent push for embedded messages detected in FOREGROUND")
print("💡 [APP] Passing to SDK for embedded message sync...")

// Pass to SDK even when in foreground
IterableAppIntegration.application(
UIApplication.shared,
didReceiveRemoteNotification: notification.request.content.userInfo,
fetchCompletionHandler: { _ in }
)
}
}
}

print("🔔 Foreground notification received: \(notification.request.content.userInfo)")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// EmbeddedMessageTestHostingController.swift
// IterableSDK-Integration-Tester
//

import UIKit
import SwiftUI

final class EmbeddedMessageTestHostingController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// Create SwiftUI view
let embeddedTestView = EmbeddedMessageTestView()
let hostingController = UIHostingController(rootView: embeddedTestView)

// Add hosting controller as child
addChild(hostingController)
view.addSubview(hostingController.view)

// Setup constraints
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

hostingController.didMove(toParent: self)
}
}

Loading
Loading