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
17 changes: 17 additions & 0 deletions IntegrationTests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Temporary artifacts directory
temp_artifacts/

# Xcode
*.xcworkspace
!*.xcworkspace/contents.xcworkspacedata
!*.xcworkspace/xcshareddata/
IntegrationTests.xcodeproj/
Derived/

# Build artifacts
build/
*.app

# Tuist
.tuist/

25 changes: 25 additions & 0 deletions IntegrationTests/Project.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import ProjectDescription

let project = Project(
name: "IntegrationTests",
packages: [
.local(path: "../")
],
targets: [
.target(
name: "IntegrationTests",
destinations: .iOS,
product: .app,
bundleId: "com.mparticle.IntegrationTests",
deploymentTargets: .iOS("14.0"),
sources: ["Sources/**"],
dependencies: [
.package(product: "mParticle-Apple-SDK", type: .runtime)
]
)
],
additionalFiles: [
.glob(pattern: "wiremock-recordings/**/*.json"),
.glob(pattern: "*.sh")
]
)
110 changes: 110 additions & 0 deletions IntegrationTests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Integration Tests

Tools for recording mParticle Apple SDK API requests using WireMock for later use in integration testing.

## Prerequisites
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add the installation of any tools just to CONTRIBUTING.md
Also there's mention of docker commands below so I'm assuming this should be a prerequisite too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, will update in then PR


Before getting started, install Tuist:

```bash
brew install tuist
```

Then generate the Xcode project:

```bash
cd IntegrationTests
tuist generate
```

This will create the `IntegrationTests.xcodeproj` and `IntegrationTests.xcworkspace` files and automatically open them in Xcode.

If you need to edit the Tuist project configuration (`Project.swift`):

```bash
tuist edit
```

This will open a temporary Xcode project for editing Tuist manifest files.

If you encounter any issues with project generation, you can clean the Tuist cache first:

```bash
tuist clean
tuist generate
```

## Overview

This project provides tools for recording mParticle SDK API requests by:
- Generating a test iOS app using Tuist
- Linking directly to local SDK source code
- Running the app in iOS Simulator
- Recording all API traffic with WireMock for later use in testing

The project uses Tuist with `.local(path: "../")` package reference, which allows Xcode to resolve the local SDK package and use source files directly, automatically picking up your latest code changes.

## Available Scripts

### `run_wiremock_recorder.sh` - Record API Requests for Testing

Records all mParticle SDK API requests using WireMock for later use in integration testing.

```bash
./run_wiremock_recorder.sh
```

**What it does:**
1. Generates Tuist project with local SDK sources
2. Builds the integration test application
3. Finds and resets iOS Simulators
4. Automatically selects available iPhone simulator (iPhone 17/16/15 priority)
5. Starts simulator
6. Installs test application
7. Starts WireMock in recording mode
8. Launches test application
9. Records all API traffic to mapping files
10. Waits for application completion
11. Stops WireMock and shows results

**Recorded Files:**
- `wiremock-recordings/mappings/*.json` - API request/response mappings
- `wiremock-recordings/__files/*` - Response body files

## Troubleshooting

### Port Already in Use / No Recordings Created

If you see "port already allocated" errors or if no API requests were recorded, it's likely that the ports (8080 and 443) where WireMock should be running are already occupied by another container or application.

Check what's running on the ports:

```bash
# Check running Docker containers
docker ps

# Check what's using port 443
lsof -i :443

# Check what's using port 8080
lsof -i :8080
```

Stop any conflicting Docker containers:

```bash
docker stop <container-name>
docker rm <container-name>
```

If another application is using the ports, terminate it before running the script.

## Development Workflow

1. Make changes to SDK source code
2. Run `./run_wiremock_recorder.sh`
3. Script automatically uses your latest changes, runs the app, and records API traffic
4. Review recorded mappings in `wiremock-recordings/`
5. Commit mappings to document expected API behavior

**Note:** No need to rebuild the SDK separately - the project links directly to source files and automatically picks up your changes!
43 changes: 43 additions & 0 deletions IntegrationTests/Sources/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// main.swift
// IntegrationTests
//
// Created by Denis Chilik on 11/4/25.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should be either removed or changed to Rokt. Ideally this should be in the project config

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, but let discuss with after the daily first. To keep it consistent.

//

import Foundation
import mParticle_Apple_SDK


var options = MParticleOptions(
key: "", // Put your key
secret: "" // Put your secret
)

var identityRequest = MPIdentityApiRequest.withEmptyUser()
identityRequest.email = "[email protected]";
identityRequest.customerId = "123456";
options.identifyRequest = identityRequest;

options.onIdentifyComplete = { apiResult, error in
if let apiResult {
apiResult.user.setUserAttribute("example attribute key", value: "example attribute value")
}
}
options.logLevel = .verbose

var networkOptions = MPNetworkOptions()
networkOptions.configHost = "127.0.0.1"; // config2.mparticle.com
networkOptions.eventsHost = "127.0.0.1"; // nativesdks.mparticle.com
networkOptions.identityHost = "127.0.0.1"; // identity.mparticle.com
networkOptions.pinningDisabled = true;

options.networkOptions = networkOptions;
let mparticle = MParticle.sharedInstance()
mparticle.start(with: options)

sleep(1)

mparticle.logEvent("Simple Event Name", eventType: .other, eventInfo: ["SimpleKey": "SimpleValue"])

sleep(7)
3 changes: 3 additions & 0 deletions IntegrationTests/Tuist.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ProjectDescription

let tuist = Tuist(project: .tuist())
Loading