[SDK-115] Enable full BCIT on CI#1061
Open
franco-zalamena-iterable wants to merge 9 commits into
Open
Conversation
After the SDK-170 migration of this workflow to ubuntu-latest + KVM (#1048, commit 7d4a80b), every PR opened against master has been failing the In-App Message E2E Tests check at the build stage: Execution failed for task ':integration-tests:mergeDebugAndroidTestResources'. > Cannot access output property 'blameLogOutputFolder' … > Failed to create MD5 hash for file '.../merged_res_blame_folder/.../values-az.json' as it does not exist. with this warning a few lines earlier: Detected multiple Kotlin daemon sessions at kotlin/sessions The 'Pre-download Gradle and Build (Parallel with Emulator)' step backgrounded a separate Gradle invocation that was meant to assemble the APKs while the emulator booted. On macos-15-intel the background process was resource-starved during emulator boot (2 cores / slow HVF) so it usually finished or stalled before the action's Gradle started. On ubuntu-latest + KVM both Gradle processes get real CPU and run in true parallel, racing on the same integration-tests/build/intermediates directory. Affected runs: - feature/sdk-338-mobile-inbox-customization: 5 failures - fix/SDK-412-UUA-Naming-inconsistencies: 1 failure - SDK-170-emulator-network-trace: green (warm cache made the race window negligible — masked the regression during review) Removing the parallel pre-build is sufficient. The action's script already invokes ':integration-tests:connectedDebugAndroidTest' which transitively builds the APKs it needs. Expected wall-clock impact: +30-90s on a cold Gradle cache, traded for 'all PRs can run this check'. Co-authored-by: Cursor <cursoragent@cursor.com>
- Rename .github/workflows/inapp-e2e-tests.yml to integration-tests-bcit.yml; rename job/step/artifact accordingly and update path filters. - Add a global concurrency group so runs serialise across all branches/refs: the suite drives a single shared BCIT user, so two PRs (or a PR overlapping the nightly cron) would race on backend state otherwise. - Switch run-e2e.sh from a single-method class filter to a package filter (com.iterable.integration.tests), so all five integration-test classes run in CI and any new test under that package is picked up automatically. - Add a CI fail-fast gate when any BCIT_* secret is empty, so a misconfigured branch fails clearly instead of running with the gradle default 'test_api_key' and 401-ing later. - Drop the dead test-summary block and stale block-comments left over from the macOS-Intel era. @ignore PushNotificationIntegrationTest#testPushNotificationMVP for now: local-suite run shows the foreground assertion after openNotification() is unreliable on the BCIT emulator (notification taps don't always resume the test app). Tracked in an SDK-115 follow-up. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ger BCIT The `branches:` key under `pull_request:` filters by the PR's *target* branch, not its head — so PRs targeting long-lived integration branches (e.g. the followup #1062 targeting SDK-115-bcit-ci) silently skipped this workflow. Path filters still gate which PRs actually fire it; only PRs that touch integration-tests / iterableapi(-ui) / the workflow / the run-e2e.sh script will trigger. Push trigger keeps `branches: [master]` so we don't double-run on every feature branch's push events alongside its PR run. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The SDK-115 BCIT CI run revealed that /api/embedded-messaging/messages
returns `{"placements": []}` for the CI user (bcituser@iterable.com)
after updateUser({isPremium: true}), so embeddedManager.syncMessages
finds no eligible message and the test asserts on an empty list.
This is a campaign / user-configuration gap in the BCIT Iterable
project, not a code bug. @ignore'd on the base SDK-115 branch so PR
#1061 can land with the workflow consolidation green; a separate
follow-up will re-enable the test once the backend side is configured
to deliver an eligible embedded message to bcituser@iterable.com for
placement 2157 when isPremium=true.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The BCIT iOS suite uses a per-day generated test email
(YYYY-MM-DD-integration-test-user@test.com) so a fresh user is created
daily; campaign audience-eligibility transitions fire reliably without
state accumulating on a long-lived account. Android was using a
hardcoded BCIT_ITERABLE_TEST_USER_EMAIL secret (bcituser@iterable.com)
which had stale state and caused the embedded test to fail with
`placements: []` on CI.
Changes:
- New TestUserEmailGenerator object that produces the dated email in
UTC; takes a Date param so the formatting logic is unit-testable
without time mocks. Avoids java.time so the test app keeps working
on minSdk 21 without core-library desugaring.
- 4 unit tests covering format, zero-padding, epoch boundary and
late-day-UTC stability.
- BaseIntegrationTest gains `isRunningInCI` (instrumentation-arg
routed; env vars don't reach the device-side test JVM through
`am instrument`) and `testUserEmail` (dated email in CI, secret
fallback locally).
- InApp / Deeplink / Embedded tests' ensureUserSignedIn calls use
`testUserEmail` so the SDK email and the request-payload email
match end-to-end.
- Embedded test refactored to mirror iOS shape (false→true isPremium
transition with sync polling); helpers extracted.
Local verification (CI mode, dated user 2026-06-02-...@test.com):
$ ./gradlew :integration-tests:connectedDebugAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.package=com.iterable.integration.tests \
-Pandroid.testInstrumentationRunnerArguments.notClass=com.iterable.integration.tests.PushNotificationIntegrationTest \
-Pandroid.testInstrumentationRunnerArguments.ci=true
Tests 8/7 completed. (1 skipped) (0 failed)
BUILD SUCCESSFUL
testEmbeddedMessageMVP stays @ignore'd — even with the dated user AND
the iOS-shape transition, /api/embedded-messaging/messages returns
`placements: []`. Same dated email works fine for InApp + Deeplink and
for iOS embedded, so the gap is on the BCIT-project configuration side
(no Android-targeting embedded campaign). Re-enable once the backend
side is set up — no further code change should be needed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lets a developer pick which user the SDK signs in as without editing local.properties or rebuilding. Field + Save / Clear buttons on MainActivity persist to SharedPreferences; both manual app flows and instrumented tests honour it (override → CI dated email → BuildConfig). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CI run on PR #1064 surfaced four failures that all share the same root cause: the Pixel Launcher ANRs on Ubuntu+KVM during heavy parallel work and steals focus from the activity-under-test, so findObject().exists() returns false even though the view is in the tree (logcat shows `current package: android` instead of `com.iterable.integration.tests`). Three fixes: 1. BaseIntegrationTest.setUp now pressBack/pressHome to dismiss any lingering system dialog before the test runs. Universal CI-emulator hardening; benefits every test class that extends BaseIntegrationTest. 2. EmbeddedMessageIntegrationTest + DeepLinkIntegrationTest now use findObject().waitForExists(5000) instead of bare .exists(). ActivityScenario reports RESUMED before the view tree is fully rendered; waitForExists handles the race. Same pattern as PushNotificationIntegrationTest already uses. 3. activity_main.xml is now wrapped in a ScrollView so the Test Scenario buttons stay reachable even when the override card grows. Local verification: `Tests 7/7 completed. (0 skipped) (0 failed)` for the full non-push suite with `ci=true`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ster\") Two small infra pieces that every BCIT test needs: - run-e2e.sh now passes `ci=true` as an instrumentation argument so tests can detect CI mode via InstrumentationRegistry.getArguments(). Env vars don't reach the test JVM through `am instrument`, so the arg is the only reliable channel. - BaseIntegrationTest.initializeIterableSDK now adds `tester` to IterableConfig.allowedProtocols. BCIT campaigns use `tester://` deep links; without this the SDK silently drops the URL before invoking the URL handler. Matches iOS's `config.allowedProtocols = ["tester", "https", "http"]`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
sumeruchat
requested changes
Jun 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔹 Jira Ticket(s) if any
✏️ Description
We had two different test sets before for bcit, some functionality was not working, now with this pr we are adding all the bcit test suite.
The new test is called Integration Tests (BCIT), on this PR it runs what was already running on E2E in app tests.
We are then creating different PRs for each test suite and we can see it working independently