diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..8aaa782f5 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,113 @@ +# # Tests should be moved here in the future. +# version: 2.1 + +# references: +# machine_config: &machine_config +# machine: +# image: default + +# defaults: &defaults +# resource_class: large +# working_directory: ~/react-native-sdk +# docker: +# - image: cimg/node:20.10 + +# orbs: +# node: circleci/node@6.3.0 +# android: circleci/android@3.0.0 +# rn: react-native-community/react-native@8.0.0 +# ruby: circleci/ruby@2.2.1 + +# jobs: +# install: +# <<: *defaults +# steps: +# - checkout +# workflows: +# build: +# jobs: +# - install + +version: 2.1 + +orbs: + node: circleci/node@6.3.0 + +references: + machine_config: &machine_config + machine: + image: default + + defaults: &defaults + resource_class: large + working_directory: ~/react-native-sdk + docker: + - image: cimg/node:20.10 + +executors: + detox-executor: + macos: + xcode: "14.3.1" # Use the appropriate Xcode version for your project + working_directory: ~/react-native-sdk + +jobs: + detox: + <<: *defaults + executor: detox-executor + steps: + - checkout + + - run: + name: Install Node.js + command: | + node -v + npm -v + + - run: + name: Install Yarn + command: | + npm install -g yarn + yarn -v + + - run: + name: Install Detox CLI + command: | + npm install -g detox-cli + + - run: + name: Install Project Dependencies + command: | + yarn install + + - run: + name: Install Example Dependencies + command: | + cd example + yarn install + cd .. + + - run: + name: Install iOS Dependencies + command: | + cd example/ios + pod install + cd ../.. + + - run: + name: Build the App for Detox + command: | + cd example + detox build --configuration ios.sim.release + cd .. + + - run: + name: Run Detox Tests + command: | + cd example + detox test --configuration ios.sim.release + cd .. + +workflows: + detox-tests: + jobs: + - detox \ No newline at end of file diff --git a/.codeclimate.yml b/.codeclimate.yml index cbbbbab9b..5a24eff1e 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -2,7 +2,6 @@ version: "2" exclude_patterns: - ".*/" - "docs/" - - "integration-testing/" - "**/node_modules/" - "scripts/" - "**/__mocks__/" diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 55ff1dfe4..fb98c79ad 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -23,5 +23,5 @@ runs: - name: Install dependencies if: steps.yarn-cache.outputs.cache-hit != 'true' - run: yarn install --immutable --frozen-lockfile + run: yarn install --immutable shell: bash diff --git a/.github/workflows/corrected-e2d.yml b/.github/workflows/corrected-e2d.yml new file mode 100644 index 000000000..de24db5d9 --- /dev/null +++ b/.github/workflows/corrected-e2d.yml @@ -0,0 +1,257 @@ +# name: E2E Tests +# on: [pull_request] + +# jobs: +# find-test-files: +# name: Find Detox test files +# runs-on: macos-latest +# outputs: +# test-files: ${{ steps.set-test-files.outputs.test-files }} +# steps: +# - name: Checkout Code +# uses: actions/checkout@v4 + +# - name: Find test files +# id: set-test-files +# run: | +# TEST_FILES=$(find example/e2e -name '*.test.js' | sed 's|example/e2e/||g' | jq -R -s -c 'split("\n")[:-1]') +# echo "test-files=$TEST_FILES" >> $GITHUB_OUTPUT + +# build-ios: +# name: iOS - Build app for Detox tests +# runs-on: macos-latest + +# steps: +# - name: Checkout Code +# uses: actions/checkout@v4 +# with: +# fetch-depth: 1 + +# - name: Setup +# uses: ./.github/actions/setup +# with: +# setup-config: ios + +# - name: Setup Ruby (bundle) +# uses: ruby/setup-ruby@v1 +# with: +# ruby-version: 2.6.10 +# bundler-cache: true + +# - name: Install ios-deploy, detox, react-native-cli +# run: npm install -g ios-deploy detox-cli react-native-cli + +# - name: Install Applesimutils +# run: | +# brew tap wix/brew +# brew install applesimutils + +# - name: Example App Yarn install +# run: | +# cd example +# yarn install --frozen-lockfile +# cd .. + +# - uses: actions/cache@v4 +# id: cache +# with: +# path: | +# example/ios/Pods +# ~/Library/Caches/CocoaPods +# ~/.cocoapods +# key: ${{ runner.os }}-pods-${{ hashFiles('example/ios/Podfile.lock') }} +# restore-keys: | +# ${{ runner.os }}-pods- + +# - name: Pod install +# run: | +# cd example/ios +# pod install +# cd ../.. + +# - name: Build Detox +# run: yarn example detox:ios:build + +# - name: Upload iOS app +# uses: actions/upload-artifact@v4 +# with: +# name: ios-app-artifact +# path: example/ios/build/Build/Products/Debug-iphonesimulator/ReactNativeSdkExample.app +# retention-days: 1 + +# build-android: +# name: Android - Build app for Detox tests +# runs-on: ubuntu-latest + +# steps: +# - name: Checkout Code +# uses: actions/checkout@v4 +# with: +# fetch-depth: 1 + +# - name: Free Disk Space (Ubuntu) +# uses: jlumbroso/free-disk-space@main +# with: +# tool-cache: true +# android: false + +# - name: Setup +# uses: ./.github/actions/setup +# with: +# setup-config: android + +# - name: Setup Java +# uses: actions/setup-java@v4 +# with: +# distribution: zulu +# java-version: 17 + +# - name: Setup Gradle +# uses: gradle/actions/setup-gradle@v3 +# with: +# gradle-version: wrapper +# cache-read-only: false + +# - name: Example App Yarn install +# run: | +# cd example +# yarn install +# cd .. + +# - name: Build Detox +# run: yarn example detox:android:build + +# - name: Upload Android app +# uses: actions/upload-artifact@v4 +# with: +# name: android-app-artifact +# path: example/android/app/build/outputs/apk +# retention-days: 1 + +# run-ios-detox-tests: +# needs: [build-ios, find-test-files] +# name: iOS - Run Detox tests +# runs-on: macos-latest + +# strategy: +# fail-fast: false +# matrix: +# test-file: ${{ fromJson(needs.find-test-files.outputs.test-files) }} + +# steps: +# - name: Checkout Code +# uses: actions/checkout@v4 +# with: +# fetch-depth: 1 + +# - name: Download iOS app +# uses: actions/download-artifact@v4 +# with: +# name: ios-app-artifact +# path: example/ios/build/Build/Products/Debug-iphonesimulator/ReactNativeSdkExample.app + +# - name: Setup +# uses: ./.github/actions/setup +# with: +# setup-config: ios + +# - name: Install ios-deploy, detox, react-native-cli +# run: npm install -g ios-deploy detox-cli react-native-cli + +# - name: Install Applesimutils +# run: | +# brew tap wix/brew +# brew install applesimutils + +# - name: Rebuild Detox +# run: | +# cd example +# yarn detox rebuild-framework-cache +# cd .. + +# - name: Start Metro Server +# env: +# ITBL_API_KEY: ${{secrets.ITERABLE_API_KEY}} +# ITBL_ID: ${{secrets.ITBL_ID}} +# run: cd example && yarn detox:start & + +# - name: Run Detox tests +# env: +# ITBL_API_KEY: ${{secrets.ITERABLE_API_KEY}} +# ITBL_ID: ${{secrets.ITBL_ID}} +# run: yarn detox:ios:test:ci -- ${{ matrix.test-file }} + +# - name: Upload Test Artifact - GitHub Action +# if: failure() +# uses: actions/upload-artifact@v4 +# with: +# name: detox-ios-artifacts-${{ matrix.test-file }} +# path: example/artifacts +# retention-days: 1 + +# run-android-detox-tests: +# needs: [build-android, find-test-files] +# name: Android - Run Detox tests +# runs-on: ubuntu-latest + +# strategy: +# fail-fast: false +# matrix: +# test-file: ${{ fromJson(needs.find-test-files.outputs.test-files) }} + +# steps: +# - name: Free Disk Space (Ubuntu) +# uses: jlumbroso/free-disk-space@main +# with: +# tool-cache: true +# android: false + +# - name: Checkout Code +# uses: actions/checkout@v4 +# with: +# fetch-depth: 1 + +# - name: Download Android app +# uses: actions/download-artifact@v4 +# with: +# name: android-app-artifact +# path: example/android/app/build/outputs/apk + +# - name: Setup +# uses: ./.github/actions/setup +# with: +# setup-config: android + +# - name: Start Metro Server +# env: +# ITBL_API_KEY: ${{secrets.ITERABLE_API_KEY}} +# ITBL_ID: ${{secrets.ITBL_ID}} +# run: yarn detox:start & + +# - name: Enable KVM +# run: | +# echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules +# sudo udevadm control --reload-rules +# sudo udevadm trigger --name-match=kvm + +# - name: Run Detox tests +# uses: reactivecircus/android-emulator-runner@v2 +# env: +# ITBL_API_KEY: ${{secrets.ITERABLE_API_KEY}} +# ITBL_ID: ${{secrets.ITBL_ID}} +# with: +# api-level: 31 +# arch: x86_64 +# avd-name: Pixel_3a_API_34 +# force-avd-creation: false +# emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-metrics +# disable-animations: false +# script: yarn detox:android:test:ci -- ${{ matrix.test-file }} + +# - name: Upload Test Artifact - GitHub Action +# if: failure() +# uses: actions/upload-artifact@v4 +# with: +# name: detox-android-artifacts-${{ matrix.test-file }} +# path: example/artifacts +# retention-days: 1 diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml new file mode 100644 index 000000000..53fad39fd --- /dev/null +++ b/.github/workflows/e2e-android.yml @@ -0,0 +1,108 @@ +name: E2E - Android +on: push + +jobs: + e2e-android: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@main + with: + # tool-cache: true + android: false + + - name: Setup + uses: ./.github/actions/setup + + - name: Install detox, detox-cli, react-native-cli + run: npm install -g detox detox-cli react-native-cli + + - name: Setup Java + uses: actions/setup-java@v3 + with: + # cache: gradle + distribution: zulu + java-version: 17 + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + with: + gradle-version: wrapper + # cache-read-only: false + + - name: Example App Yarn install + run: | + cd example + yarn install --immutable + cd .. + + # - name: Cache Detox build + # id: cache-detox-build + # uses: actions/cache@v3 + # with: + # path: example/android/app/build + # key: ${{ runner.os }}-detox-build + # restore-keys: | + # ${{ runner.os }}-detox-build + + - name: Detox build + env: + ITBL_API_KEY: ${{ secrets.ITERABLE_API_KEY }} + ITBL_ID: ${{ secrets.ITBL_ID }} + CI: true + run: | + cd example + yarn detox build --configuration android.emu.release + cd .. + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Unregister runners + continue-on-error: true + run: echo "[]" > ~/.local/share/Detox/device.registry.state.lock + + - name: Get device name + if: success() || failure() + id: device + run: node -e "console.log('AVD_NAME=' + require('./example/.detoxrc').devices.emulator.device.avdName)" >> $GITHUB_OUTPUT + + - name: Detox test + uses: reactivecircus/android-emulator-runner@v2 + env: + ITBL_API_KEY: ${{ secrets.ITERABLE_API_KEY }} + ITBL_ID: ${{ secrets.ITBL_ID }} + CI: true + with: + api-level: 31 + arch: x86_64 + avd-name: ${{ steps.device.outputs.AVD_NAME }} + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -no-metrics + disable-animations: true + script: | + yarn detox test --configuration android.emu.release \ + --headless \ + --record-logs all \ + --record-videos all \ + --take-screenshots all \ + --capture-view-hierarchy enabled \ + --maxWorkers=1 \ + --detectOpenHandles \ + --debug-synchronization 500 \ + -l trace \ + --cleanup + + - name: Upload artifacts + if: failure() + uses: actions/upload-artifact@v3 + with: + name: detox-artifacts + path: example/artifacts \ No newline at end of file diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml deleted file mode 100644 index c7da5448b..000000000 --- a/.github/workflows/integration-test.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Integration Tests - -on: - push: - branches: - - "master" - pull_request: - branches: - - "**" - -jobs: - build: - runs-on: macos-latest - - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0 - with: - xcode-version: 15 - - - name: Install dependencies - run: cd integration-testing/ && yarn install - - - name: pod install - run: cd integration-testing/ios/ && pod install - - - name: Build and Test - shell: bash - env: - ITERABLE_API_KEY: ${{secrets.ITERABLE_API_KEY}} - SEND_IN_APP_CAMPAIGN_ID: ${{secrets.SEND_IN_APP_CAMPAIGN_ID}} - SKIP_IN_APP_CAMPAIGN_ID: ${{secrets.SKIP_IN_APP_CAMPAIGN_ID}} - OPEN_DEEP_LINK_CAMPAIGN_ID: ${{secrets.OPEN_DEEP_LINK_CAMPAIGN_ID}} - OPEN_SAFARI_CAMPAIGN_ID: ${{secrets.OPEN_SAFARI_CAMPAIGN_ID}} - CUSTOM_ACTION_CAMPAIGN_ID: ${{secrets.CUSTOM_ACTION_CAMPAIGN_ID}} - run: | - ./integration-testing/ios/scripts/run_test.sh diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 0eb7af4c4..253275fa3 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -14,6 +14,12 @@ jobs: runs-on: ubuntu-latest steps: + - name: Cancel runs from previous PRs + uses: fkirc/skip-duplicate-actions@master + with: + cancel_others: 'true' + concurrent_skipping: 'outdated_runs' + - uses: actions/checkout@v3 - name: Setup @@ -34,6 +40,12 @@ jobs: runs-on: ubuntu-latest steps: + - name: Cancel runs from previous PRs + uses: fkirc/skip-duplicate-actions@master + with: + cancel_others: 'true' + concurrent_skipping: 'outdated_runs' + - uses: actions/checkout@v3 - name: Setup diff --git a/.gitignore b/.gitignore index 698fbee59..b64166505 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,5 @@ android/generated .env .xcode.env.local coverage/ +.watchman-* +artifacts/ diff --git a/.npmignore b/.npmignore index 8bc21b6c5..5d88bcb63 100644 --- a/.npmignore +++ b/.npmignore @@ -1,5 +1,3 @@ -SampleApp -integration-testing jest.config.js node_modules package-lock.json diff --git a/example/.detoxrc.js b/example/.detoxrc.js new file mode 100644 index 000000000..fc43917bd --- /dev/null +++ b/example/.detoxrc.js @@ -0,0 +1,137 @@ +/** @type {Detox.DetoxConfig} */ +module.exports = { + behavior: { + init: { + reinstallApp: true, + exposeGlobals: true, + }, + launchApp: 'auto', + cleanup: { + shutdownDevice: true, + }, + }, + logger: { + level: process.env.CI ? 'debug' : undefined, + }, + skipLegacyWorkersInjection: true, + testRunner: { + detached: true, + forwardEnv: true, + args: { + $0: 'jest', + config: 'e2e/jest.config.js', + maxWorkers: 1, + }, + jest: { + setupTimeout: 1200000, + }, + }, + artifacts: { + plugins: { + log: process.env.CI ? 'failing' : undefined, + screenshot: process.env.CI ? 'failing' : undefined, + video: process.env.CI ? 'failing' : undefined, + timeline: process.env.CI ? 'all' : undefined, + instruments: process.env.CI ? 'all' : undefined, + uiHierarchy: 'enabled', + }, + }, + apps: { + 'ios.debug': { + type: 'ios.app', + binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/ReactNativeSdkExample.app', + build: + 'xcodebuild -workspace ios/ReactNativeSdkExample.xcworkspace -scheme ReactNativeSdkExample -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', + }, + 'ios.release': { + type: 'ios.app', + binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/ReactNativeSdkExample.app', + build: + 'xcodebuild -workspace ios/ReactNativeSdkExample.xcworkspace -scheme ReactNativeSdkExample -configuration Release -sdk iphonesimulator -derivedDataPath ios/build', + }, + 'android.debug': { + type: 'android.apk', + binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk', + build: 'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', + reversePorts: [8081], + }, + 'android.release': { + type: 'android.apk', + binaryPath: 'android/app/build/outputs/apk/release/app-release.apk', + build: + 'cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -', + }, + }, + devices: { + simulator: { + type: 'ios.simulator', + headless: Boolean(process.env.CI), + device: { + type: 'iPhone SE (3rd generation)', + }, + }, + attached: { + type: 'android.attached', + device: { + adbName: '.*', + }, + }, + emulator: { + type: 'android.emulator', + headless: Boolean(process.env.CI), + gpuMode: process.env.CI ? 'off' : undefined, + device: { + avdName: 'Pixel_3a_API_34', + }, + }, + 'emulator.ci': { + type: 'android.emulator', + device: { + avdName: 'Pixel_3a_API_34', + }, + bootArgs: '-no-boot-anim -noaudio -camera-back none', + headless: true, + gpuMode: 'swiftshader_indirect', + readonly: true, + forceAdbInstall: true, + }, + }, + configurations: { + 'ios.sim.debug': { + device: 'simulator', + app: 'ios.debug', + }, + 'ios.sim.release': { + device: 'simulator', + app: 'ios.release', + }, + 'ios.manual': { + type: 'ios.manual', + behavior: { + launchApp: 'manual', + }, + artifacts: false, + session: { + autoStart: true, + server: 'ws://localhost:8099', + sessionId: 'com.iterable.reactnativesdk.example', + }, + }, + 'android.att.debug': { + device: 'attached', + app: 'android.debug', + }, + 'android.att.release': { + device: 'attached', + app: 'android.release', + }, + 'android.emu.debug': { + device: 'emulator', + app: 'android.debug', + }, + 'android.emu.release': { + device: 'emulator.ci', + app: 'android.release', + }, + }, +}; diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 373c949fd..7711f4e8b 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -84,6 +84,9 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" + testBuildType System.getProperty('testBuildType', 'debug') + // testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + testInstrumentationRunner 'com.iterable.reactnativesdk.example.DetoxTestAppJUnitRunner' } signingConfigs { debug { @@ -103,11 +106,18 @@ android { signingConfig signingConfigs.debug minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" + } + } + sourceSets { + androidTest { + java.srcDirs += 'src/androidTest/java' } } } dependencies { + implementation 'androidx.appcompat:appcompat:1.1.0' // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") @@ -116,6 +126,10 @@ dependencies { } else { implementation jscFlavor } + + // androidTestImplementation('com.wix:detox:+') + androidTestImplementation 'com.wix:detox:+' + androidTestImplementation 'com.linkedin.testbutler:test-butler-library:2.2.1' } apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle") diff --git a/integration-testing/android/app/src/androidTest/java/com/example/DetoxTest.java b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTest.java similarity index 52% rename from integration-testing/android/app/src/androidTest/java/com/example/DetoxTest.java rename to example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTest.java index e5046fe27..1a354a546 100644 --- a/integration-testing/android/app/src/androidTest/java/com/example/DetoxTest.java +++ b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTest.java @@ -1,7 +1,7 @@ -// Replace this with your app's package -package com.example; +package iterable.reactnativesdk.example; import com.wix.detox.Detox; +import com.wix.detox.config.DetoxConfig; import org.junit.Rule; import org.junit.Test; @@ -14,18 +14,16 @@ @RunWith(AndroidJUnit4.class) @LargeTest public class DetoxTest { - - @Rule - // Replace 'MainActivity' with the value of android:name entry in - // in AndroidManifest.xml + @Rule // (2) public ActivityTestRule mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); @Test public void runDetoxTests() { - Detox.DetoxIdlePolicyConfig idlePolicyConfig = new Detox.DetoxIdlePolicyConfig(); - idlePolicyConfig.masterTimeoutSec = 60; - idlePolicyConfig.idleResourceTimeoutSec = 30; + DetoxConfig detoxConfig = new DetoxConfig(); + detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; + detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; + detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60); - Detox.runTests(mActivityRule, idlePolicyConfig); + Detox.runTests(mActivityRule, detoxConfig); } -} +} \ No newline at end of file diff --git a/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTestAppJUnitRunner.java b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTestAppJUnitRunner.java new file mode 100644 index 000000000..49fdbd770 --- /dev/null +++ b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/DetoxTestAppJUnitRunner.java @@ -0,0 +1,21 @@ +package iterable.reactnativesdk.example; + +import android.os.Bundle; + +import com.linkedin.android.testbutler.TestButler; + +import androidx.test.runner.AndroidJUnitRunner; + +public class DetoxTestAppJUnitRunner extends AndroidJUnitRunner { + @Override + public void onStart() { + TestButler.setup(getTargetContext()); + super.onStart(); + } + + @Override + public void finish(int resultCode, Bundle results) { + TestButler.teardown(getTargetContext()); + super.finish(resultCode, results); + } +} \ No newline at end of file diff --git a/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/TestButlerProbe.java b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/TestButlerProbe.java new file mode 100644 index 000000000..7cd91a7af --- /dev/null +++ b/example/android/app/src/androidTest/java/com/iterable.reactnativesdk.example/TestButlerProbe.java @@ -0,0 +1,49 @@ +package iterable.reactnativesdk.example; + +import android.content.pm.PackageManager; +import android.util.Log; +import android.view.Surface; + +import com.linkedin.android.testbutler.TestButler; + +import androidx.test.platform.app.InstrumentationRegistry; + +class TestButlerProbe { + + private static final String LOG_TAG = TestButlerProbe.class.getSimpleName(); + private static final String TEST_BUTLER_PACKAGE_NAME = "com.linkedin.android.testbutler"; + + private TestButlerProbe() { + } + + static void assertReadyIfInstalled() { + Log.i(LOG_TAG, "Test butler service verification started..."); + + if (!isTestButlerServiceInstalled()) { + Log.w(LOG_TAG, "Test butler not installed on device - skipping verification"); + return; + } + + assertTestButlerServiceReady(); + Log.i(LOG_TAG, "Test butler service is up and running!"); + } + + static private boolean isTestButlerServiceInstalled() { + try { + PackageManager pm = InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager(); + pm.getPackageInfo(TEST_BUTLER_PACKAGE_NAME, 0); + return true; + } catch (PackageManager.NameNotFoundException e) { + return false; + } + } + + static private void assertTestButlerServiceReady() { + try { + // This has no effect if test-butler is running. However, if it is not, then unlike TestButler.setup(), it would hard-fail. + TestButler.setRotation(Surface.ROTATION_0); + } catch (Exception e) { + throw new RuntimeException("Test butler service is NOT ready!", e); + } + } +} \ No newline at end of file diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index e1892528b..095bdca45 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -9,7 +9,8 @@ android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme" - android:supportsRtl="true"> + android:supportsRtl="true" + android:networkSecurityConfig="@xml/network_security_config"> 10.0.2.2 10.0.3.2 + localhost - + \ No newline at end of file diff --git a/example/android/build.gradle b/example/android/build.gradle index df1ce4db3..8ffdf2327 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -16,6 +16,17 @@ buildscript { classpath("com.facebook.react:react-native-gradle-plugin") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") } + } + + allprojects { + repositories { + google() + mavenCentral() + maven { + url("$rootDir/../node_modules/detox/Detox-android") + } + // maven { url 'https://www.jitpack.io' } + } } apply plugin: "com.facebook.react.rootproject" diff --git a/example/cache/test-butler-app.apk b/example/cache/test-butler-app.apk new file mode 100644 index 000000000..105e06ed0 Binary files /dev/null and b/example/cache/test-butler-app.apk differ diff --git a/example/e2e/globalSetup.js b/example/e2e/globalSetup.js new file mode 100644 index 000000000..642d3717c --- /dev/null +++ b/example/e2e/globalSetup.js @@ -0,0 +1,29 @@ +import { execSync } from 'child_process'; + +import { pathExists, ensureDir } from 'fs-extra'; + +import { resolveConfig } from 'detox/internals'; +import { globalSetup } from 'detox/runners/jest'; + +export default async function customGlobalSetup() { + const config = await resolveConfig(); + if (config.device.type === 'android.emulator') { + await downloadTestButlerAPK(); + } + + await globalSetup(); +} + +async function downloadTestButlerAPK() { + const version = '2.2.1'; + const artifactUrl = `https://repo1.maven.org/maven2/com/linkedin/testbutler/test-butler-app/${version}/test-butler-app-${version}.apk`; + const filePath = `cache/test-butler-app.apk`; + + await ensureDir('cache'); + if (!(await pathExists(filePath))) { + console.log(`\nDownloading Test-Butler APK v${version}...`); + execSync(`curl -f -o ${filePath} ${artifactUrl}`); + } +} + +module.exports = customGlobalSetup; diff --git a/example/e2e/jest.config.js b/example/e2e/jest.config.js new file mode 100644 index 000000000..a90190bbb --- /dev/null +++ b/example/e2e/jest.config.js @@ -0,0 +1,14 @@ +/** @type {import('@jest/types').Config.InitialOptions} */ +module.exports = { + rootDir: '..', + testMatch: ['/e2e/**/*.test.js'], + testTimeout: 1200000, + maxWorkers: 1, + // globalSetup: 'detox/runners/jest/globalSetup', + globalSetup: './e2e/globalSetup.js', + globalTeardown: 'detox/runners/jest/globalTeardown', + reporters: ['detox/runners/jest/reporter'], + testEnvironment: 'detox/runners/jest/testEnvironment', + setupFilesAfterEnv: ['./e2e/setup.js'], + verbose: true, +}; diff --git a/example/e2e/setup.js b/example/e2e/setup.js new file mode 100644 index 000000000..948909137 --- /dev/null +++ b/example/e2e/setup.js @@ -0,0 +1,17 @@ +import { device } from 'detox'; + +// eslint-disable-next-line no-undef +beforeAll(async () => { + await device.launchApp({ + /** + * Uncomment the following lines to enable verbose logging of + * synchronization issues. + * See: https://wix.github.io/Detox/docs/next/troubleshooting/synchronization + */ + // launchArgs: { + // DTXEnableVerboseSyncSystem: 'YES', + // DTXEnableVerboseSyncResources: 'YES', + // }, + newInstance: true, + }); +}); diff --git a/example/e2e/starter.test.js b/example/e2e/starter.test.js new file mode 100644 index 000000000..2a24bad0e --- /dev/null +++ b/example/e2e/starter.test.js @@ -0,0 +1,36 @@ +import { device, element, by, expect, waitFor } from 'detox'; +import { ITBL_API_KEY, ITBL_ID } from '@env'; + +describe('Example', () => { + beforeAll(async () => { + // await detox.init(); + // await device.terminateApp(); + await device.launchApp({ + /** + * Uncomment the following lines to enable verbose logging of + * synchronization issues. + * See: https://wix.github.io/Detox/docs/next/troubleshooting/synchronization + */ + // launchArgs: { + // DTXEnableVerboseSyncSystem: 'YES', + // DTXEnableVerboseSyncResources: 'YES', + // }, + newInstance: true, + }); + }); + + beforeEach(async () => {}); + + afterAll(async () => { + await device.terminateApp(); + await detox.cleanup(); + }); + + it('should be able to login', async () => { + await expect(element(by.text('Login'))).toBeVisible(); + await element(by.id('api-key')).replaceText(ITBL_API_KEY); + await element(by.id('user-id')).replaceText(ITBL_ID); + await element(by.text('Login')).tap(); + await waitFor(element(by.id('inbox-header'))).toBeVisible(); + }); +}); diff --git a/example/ios/.xcode.env.local b/example/ios/.xcode.env.local deleted file mode 100644 index bd626cd01..000000000 --- a/example/ios/.xcode.env.local +++ /dev/null @@ -1 +0,0 @@ -export NODE_BINARY=/Users/Loren.Posen/.nvm/versions/node/v20.10.0/bin/node diff --git a/example/ios/ReactNativeSdkExample/Info.plist b/example/ios/ReactNativeSdkExample/Info.plist index b8daa7289..ed054385d 100644 --- a/example/ios/ReactNativeSdkExample/Info.plist +++ b/example/ios/ReactNativeSdkExample/Info.plist @@ -24,11 +24,11 @@ $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS - NSAppTransportSecurity LSApplicationQueriesSchemes javascript + NSAppTransportSecurity NSAllowsArbitraryLoads @@ -37,7 +37,7 @@ NSLocationWhenInUseUsageDescription - + Your precise location is used to calculate turn-by-turn directions, show your location on the map, and help improve the map. UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities @@ -67,12 +67,6 @@ FontAwesome6_Solid.ttf Foundation.ttf Ionicons.ttf - MaterialIcons.ttf - MaterialCommunityIcons.ttf - SimpleLineIcons.ttf - Octicons.ttf - Zocial.ttf - Fontisto.ttf diff --git a/example/package.json b/example/package.json index ea1d440a9..56d545aaa 100644 --- a/example/package.json +++ b/example/package.json @@ -7,7 +7,19 @@ "ios": "react-native run-ios", "start": "react-native start", "build:android": "react-native build-android --extra-params \"--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a\"", - "build:ios": "react-native build-ios --scheme ReactNativeSdkExample --mode Debug --extra-params \"-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO\"" + "build:ios": "react-native build-ios --scheme ReactNativeSdkExample --mode Debug --extra-params \"-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO CODE_SIGNING_REQUIRED=NO\"", + "detox": "detox", + "detox:start": "E2E_TESTS='true' react-native start", + "detox:android:debug": "detox --configuration android.emu.debug", + "detox:android:debug:build": "yarn detox:android:debug build", + "detox:android:release": "detox --configuration android.emu.release", + "detox:android:release:build": "yarn detox:android:release build", + "detox:android:build": "detox build --configuration android.emu.debug", + "detox:android:build:ci": "detox build --configuration android.emu.debug", + "detox:ios:build": "detox build --configuration ios.sim.debug", + "detox:ios:build:ci": "detox build --configuration ios.sim.debug", + "detox:android:test:ci": "detox test --configuration android.emu.debug --headless --record-logs all --record-videos failing --take-screenshots failing --cleanup --maxWorkers=2 --debug-synchronization 500 -l trace", + "detox:ios:test:ci": "detox test --configuration ios.sim.debug --headless --record-logs all --record-videos failing --take-screenshots failing --cleanup --maxWorkers=2 --debug-synchronization 500 -l trace" }, "dependencies": { "@react-navigation/bottom-tabs": "^6.6.1", @@ -30,7 +42,11 @@ "@react-native/babel-preset": "0.75.3", "@react-native/metro-config": "0.75.3", "@react-native/typescript-config": "0.75.3", + "@types/detox": "^18.1.0", "@types/react-syntax-highlighter": "^15.5.13", + "detox": "^20.27.3", + "detox-cli": "^20.0.0", + "jest": "^29", "react-native-builder-bob": "^0.30.2", "react-native-dotenv": "^3.4.11" }, diff --git a/example/src/components/Apis/detailScreens/GetHtmlContentForMessage.tsx b/example/src/components/Apis/detailScreens/GetHtmlContentForMessage.tsx index c0e76bbf4..3383840f4 100644 --- a/example/src/components/Apis/detailScreens/GetHtmlContentForMessage.tsx +++ b/example/src/components/Apis/detailScreens/GetHtmlContentForMessage.tsx @@ -38,7 +38,7 @@ export const GetHtmlContentForMessage = () => { return ( <> Code: - + { diff --git a/example/src/components/Apis/detailScreens/InAppConsume.tsx b/example/src/components/Apis/detailScreens/InAppConsume.tsx index 7d39909f7..24b1018f4 100644 --- a/example/src/components/Apis/detailScreens/InAppConsume.tsx +++ b/example/src/components/Apis/detailScreens/InAppConsume.tsx @@ -30,7 +30,7 @@ export const InAppConsume = () => { return ( <> Code: - + { diff --git a/example/src/components/Apis/detailScreens/RemoveInAppMessages.tsx b/example/src/components/Apis/detailScreens/RemoveInAppMessages.tsx index e49f30797..dc867deb0 100644 --- a/example/src/components/Apis/detailScreens/RemoveInAppMessages.tsx +++ b/example/src/components/Apis/detailScreens/RemoveInAppMessages.tsx @@ -30,7 +30,7 @@ export const RemoveInAppMessages = () => { return ( <> Code: - + { diff --git a/example/src/components/Apis/detailScreens/SetReadInAppMessages.tsx b/example/src/components/Apis/detailScreens/SetReadInAppMessages.tsx index c4433c091..58510b96b 100644 --- a/example/src/components/Apis/detailScreens/SetReadInAppMessages.tsx +++ b/example/src/components/Apis/detailScreens/SetReadInAppMessages.tsx @@ -31,7 +31,7 @@ Iterable.inAppManager.getMessages().then((messages) => { Read? Code: - + { diff --git a/example/src/components/Apis/detailScreens/ShowInAppMessages.tsx b/example/src/components/Apis/detailScreens/ShowInAppMessages.tsx index 4ba8265d1..3a2bcd264 100644 --- a/example/src/components/Apis/detailScreens/ShowInAppMessages.tsx +++ b/example/src/components/Apis/detailScreens/ShowInAppMessages.tsx @@ -42,7 +42,7 @@ Iterable.inAppManager.getMessages().then((messages) => { onValueChange={setConsume} /> Code: - + { diff --git a/example/src/components/Apis/detailScreens/TrackInAppClick.tsx b/example/src/components/Apis/detailScreens/TrackInAppClick.tsx index 6a6391453..9e642ce23 100644 --- a/example/src/components/Apis/detailScreens/TrackInAppClick.tsx +++ b/example/src/components/Apis/detailScreens/TrackInAppClick.tsx @@ -29,7 +29,7 @@ export const TrackInAppClick = () => { return ( <> Code: - + { diff --git a/example/src/components/Apis/detailScreens/TrackInAppClose.tsx b/example/src/components/Apis/detailScreens/TrackInAppClose.tsx index af4c61bcc..469b45fff 100644 --- a/example/src/components/Apis/detailScreens/TrackInAppClose.tsx +++ b/example/src/components/Apis/detailScreens/TrackInAppClose.tsx @@ -31,7 +31,7 @@ export const TrackInAppClose = () => { return ( <> Code: - + { diff --git a/example/src/components/Apis/detailScreens/TrackPurchase.tsx b/example/src/components/Apis/detailScreens/TrackPurchase.tsx index a085ae4a5..84fc1181b 100644 --- a/example/src/components/Apis/detailScreens/TrackPurchase.tsx +++ b/example/src/components/Apis/detailScreens/TrackPurchase.tsx @@ -52,7 +52,7 @@ Iterable.trackPurchase( Data Fields Code: - + { diff --git a/example/src/components/CodeBlock.tsx b/example/src/components/CodeBlock.tsx index e3aea6a86..c263fa5b4 100644 --- a/example/src/components/CodeBlock.tsx +++ b/example/src/components/CodeBlock.tsx @@ -1,29 +1,41 @@ +import { useMemo } from 'react'; import { StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native'; // @ts-ignore import SyntaxHighlighter from 'react-native-syntax-highlighter'; // @ts-ignore import { atomOneDark } from 'react-syntax-highlighter/styles/hljs'; -const styles = StyleSheet.create({ - codeContainer: { - height: 200, - marginBottom: 10, - }, -}); - export interface CodeBlockProps { codeString: string; style?: StyleProp; + blockHeight?: number; } -export const CodeBlock = ({ codeString, style = {} }: CodeBlockProps) => ( - - - {codeString} - - -); +export const CodeBlock = ({ + codeString, + style = {}, + blockHeight: height = 200, +}: CodeBlockProps) => { + const styles = useMemo( + () => + StyleSheet.create({ + codeContainer: { + height, + marginBottom: 10, + }, + }), + [height] + ); + + return ( + + + {codeString} + + + ); +}; diff --git a/example/src/components/CustomizedInbox.tsx b/example/src/components/CustomizedInbox.tsx index 8d804f3cb..84770bc87 100644 --- a/example/src/components/CustomizedInbox.tsx +++ b/example/src/components/CustomizedInbox.tsx @@ -2,10 +2,11 @@ import { IterableInbox, type IterableInboxProps, } from '@iterable/react-native-sdk'; +import { View } from 'react-native'; import useIterableApp from '../hooks/useIterableApp'; const iterableInboxCustomization = { - navTitle: 'Iterable', + navTitle: 'Iterable Inbox', noMessagesTitle: 'No messages today', noMessagesBody: 'Come back later', @@ -76,11 +77,13 @@ const iterableInboxCustomization = { export const CustomizedInbox = (props: IterableInboxProps) => { const { returnToInboxTrigger } = useIterableApp(); return ( - + + + ); }; diff --git a/example/src/components/Login/Login.tsx b/example/src/components/Login/Login.tsx index 4d8046d0b..f2b823ef8 100644 --- a/example/src/components/Login/Login.tsx +++ b/example/src/components/Login/Login.tsx @@ -33,6 +33,7 @@ export const Login = ({ navigation }: RootStackScreenProps) => { API key ) => { /> Email address or User Id detox - -# React Native Demo Project - -## Requirements - -* Make sure you have Xcode installed (tested with Xcode 8.1-8.2). -* make sure you have node installed (`brew install node`, node 8.3.0 and up is required for native async-await support, otherwise you'll have to babel the tests). -* Make sure you have react-native dependencies installed: - * react-native-cli is installed (`npm install -g react-native-cli`) - * watchman is installed (`brew install watchman`) - -### Step 1: Npm install - -* Make sure you're in folder `examples/demo-react-native`. -* Run `npm install`. - -## To test Release build of your app -### Step 2: Build -* Build the demo project - - ```sh - detox build --configuration ios.sim.release - ``` - -### Step 3: Test -* Run tests on the demo project - - ```sh - detox test --configuration ios.sim.release - ``` - This action will open a new simulator and run the tests on it. - -## To test Debug build of your app -### Step 2: Build -* Build the demo project - - ```sh - detox build --configuration ios.sim.debug - ``` - -### Step 3: Test - - * start react-native packager - - ```sh - npm run start - ``` - * Run tests on the demo project - - ```sh - detox test --configuration ios.sim.debug - ``` - This action will open a new simulator and run the tests on it. diff --git a/integration-testing/android/app/BUCK b/integration-testing/android/app/BUCK deleted file mode 100644 index d73aebd81..000000000 --- a/integration-testing/android/app/BUCK +++ /dev/null @@ -1,66 +0,0 @@ -import re - -# To learn about Buck see [Docs](https://buckbuild.com/). -# To run your application with Buck: -# - install Buck -# - `npm start` - to start the packager -# - `cd android` -# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US` -# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck -# - `buck install -r android/app` - compile, install and run application -# - -lib_deps = [] -for jarfile in glob(['libs/*.jar']): - name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) - lib_deps.append(':' + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) - -for aarfile in glob(['libs/*.aar']): - name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) - lib_deps.append(':' + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) - -android_library( - name = 'all-libs', - exported_deps = lib_deps -) - -android_library( - name = 'app-code', - srcs = glob([ - 'src/main/java/**/*.java', - ]), - deps = [ - ':all-libs', - ':build_config', - ':res', - ], -) - -android_build_config( - name = 'build_config', - package = 'com.example', -) - -android_resource( - name = 'res', - res = 'src/main/res', - package = 'com.example', -) - -android_binary( - name = 'app', - package_type = 'debug', - manifest = 'src/main/AndroidManifest.xml', - keystore = '//android/keystores:debug', - deps = [ - ':app-code', - ], -) diff --git a/integration-testing/android/app/build.gradle b/integration-testing/android/app/build.gradle deleted file mode 100644 index 496268551..000000000 --- a/integration-testing/android/app/build.gradle +++ /dev/null @@ -1,110 +0,0 @@ -import groovy.json.JsonSlurper -import com.android.build.OutputFile - -apply plugin: 'com.android.application' - -//project.ext.react = [:] -project.ext.react = [ - enableHermes: false -] -apply from: '../../node_modules/react-native/react.gradle' - -Boolean isRN60OrHigher = getRNVersion() >= 60 -Boolean isRN61OrHigher = getRNVersion() >= 61 - -android { - compileSdkVersion 29 - buildToolsVersion '29.0.0' - - defaultConfig { - applicationId 'com.detox.rn.example' - minSdkVersion 18 - targetSdkVersion 29 - versionCode 1 - versionName '1.0' - ndk { - abiFilters 'armeabi-v7a', 'x86', 'x86_64' - } - - testBuildType System.getProperty('testBuildType', 'debug') - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' - } - splits { - abi { - reset() - enable false - universalApk false // If true, also generate a universal APK - include 'armeabi-v7a', 'x86', 'x86_64' - } - } - signingConfigs { - release { - storeFile file("keystore.jks") - storePassword "12345678" - keyAlias "key0" - keyPassword "12345678" - } - } - buildTypes { - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" - - signingConfig signingConfigs.release - } - } - - packagingOptions { - exclude 'META-INF/DEPENDENCIES' - exclude 'META-INF/NOTICE' - exclude 'META-INF/LICENSE' - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE.txt' - } -} - -dependencies { - if (isRN60OrHigher) { - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' - } else { - implementation 'com.android.support:appcompat-v7:28.0.0' - } - - // noinspection GradleDynamicVersion - implementation 'com.facebook.react:react-native:+' - - androidTestImplementation('com.wix:detox:+') -} - -if (isRN60OrHigher) { - // refs: https://react-native-community.github.io/upgrade-helper/?from=0.59.9&to=0.60.6 - // https://react-native-community.github.io/upgrade-helper/?from=0.60.6&to=0.61.4 - dependencies { - def enableHermes = project.ext.react.get('enableHermes', false) - if (enableHermes) { - def hermesModuleName = isRN61OrHigher ? 'hermes-engine' : 'hermesvm' - def hermesPath = "../../node_modules/$hermesModuleName/android/" - debugImplementation files(hermesPath + 'hermes-debug.aar') - releaseImplementation files(hermesPath + 'hermes-release.aar') - } else { - implementation 'org.webkit:android-jsc:+' - } - } -} - -// Run this once to be able to run the application with BUCK -// puts all compile dependencies into folder libs for BUCK to use -task copyDownloadableDepsToLibs(type: Copy) { - from configurations.compile - into 'libs' -} - -static def getRNVersion() { - def jsonSlurper = new JsonSlurper() - Map packageJSON = jsonSlurper.parse(new File('../node_modules/react-native/package.json')) - String rnVersion = packageJSON.get('version') - Integer rnVersionMajor = rnVersion.split('\\.')[1].toInteger() - return rnVersionMajor -} diff --git a/integration-testing/android/app/keystore.jks b/integration-testing/android/app/keystore.jks deleted file mode 100644 index 6be906061..000000000 Binary files a/integration-testing/android/app/keystore.jks and /dev/null differ diff --git a/integration-testing/android/app/proguard-rules.pro b/integration-testing/android/app/proguard-rules.pro deleted file mode 100644 index 55fd3fdac..000000000 --- a/integration-testing/android/app/proguard-rules.pro +++ /dev/null @@ -1,27 +0,0 @@ -# -# Most needed rules come from React Native's proguard-rules.pro (either .aar or source) -- hence -# the lean configuration file. -### - --dontobfuscate - --dontnote android.net.** --dontnote org.apache.** - -# An addition to RN's 'keep' and 'dontwarn' configs -- need to also 'dontnote' some stuff. - --dontnote com.facebook.** --dontnote sun.misc.Unsafe --dontnote okhttp3.** --dontnote okio.** - -# Do not strip any method/class that is annotated with @DoNotStrip --keep @com.facebook.jni.annotations.DoNotStrip class * --keep class * { - @com.facebook.proguard.annotations.DoNotStrip *; - @com.facebook.common.internal.DoNotStrip *; - @com.facebook.jni.annotations.DoNotStrip *; -} --keepclassmembers class * { - @com.facebook.jni.annotations.DoNotStrip *; -} diff --git a/integration-testing/android/app/src/main/AndroidManifest.xml b/integration-testing/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index aa2e7d4f0..000000000 --- a/integration-testing/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/integration-testing/android/app/src/main/java/com/example/MainActivity.java b/integration-testing/android/app/src/main/java/com/example/MainActivity.java deleted file mode 100644 index e84b72551..000000000 --- a/integration-testing/android/app/src/main/java/com/example/MainActivity.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example; - -import com.facebook.react.ReactActivity; - -public class MainActivity extends ReactActivity { - - /** - * Returns the name of the main component registered from JavaScript. - * This is used to schedule rendering of the component. - */ - @Override - protected String getMainComponentName() { - return "example"; - } -} diff --git a/integration-testing/android/app/src/main/java/com/example/MainApplication.java b/integration-testing/android/app/src/main/java/com/example/MainApplication.java deleted file mode 100644 index b404a437f..000000000 --- a/integration-testing/android/app/src/main/java/com/example/MainApplication.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.example; - -import android.app.Application; - -import com.facebook.react.ReactApplication; -import com.facebook.react.ReactNativeHost; -import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; -import com.facebook.soloader.SoLoader; - -import java.util.Arrays; -import java.util.List; - -public class MainApplication extends Application implements ReactApplication { - private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } - - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage() - ); - } - }; - - @Override - public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } - - @Override - public void onCreate() { - super.onCreate(); - SoLoader.init(this, /* native exopackage */ false); - } - -} diff --git a/integration-testing/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/integration-testing/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bccc..000000000 Binary files a/integration-testing/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/integration-testing/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/integration-testing/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cbd..000000000 Binary files a/integration-testing/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/integration-testing/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/integration-testing/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e7..000000000 Binary files a/integration-testing/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/integration-testing/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/integration-testing/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cdd..000000000 Binary files a/integration-testing/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/integration-testing/android/app/src/main/res/values/strings.xml b/integration-testing/android/app/src/main/res/values/strings.xml deleted file mode 100644 index d75426c8a..000000000 --- a/integration-testing/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - example - diff --git a/integration-testing/android/app/src/main/res/values/styles.xml b/integration-testing/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 319eb0ca1..000000000 --- a/integration-testing/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/integration-testing/android/build.gradle b/integration-testing/android/build.gradle deleted file mode 100644 index f847c7e7a..000000000 --- a/integration-testing/android/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -buildscript { - ext { - kotlinVersion = '1.3.41' - buildToolsVersion = '29.0.0' - compileSdkVersion = 29 - targetSdkVersion = 29 - minSdkVersion = 18 - } - - repositories { - jcenter() - google() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' - classpath 'de.undercouch:gradle-download-task:3.4.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" - } -} - -allprojects { - repositories { - mavenLocal() - jcenter() - google() - maven { - url "$rootDir/../node_modules/react-native/android" - } - maven { - url "$rootDir/../node_modules/detox/Detox-android" - } - maven { - // Android JSC is installed from npm - url("$rootDir/../node_modules/jsc-android/dist") - } - } -} diff --git a/integration-testing/android/gradle.properties b/integration-testing/android/gradle.properties deleted file mode 100644 index d86695a57..000000000 --- a/integration-testing/android/gradle.properties +++ /dev/null @@ -1,21 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - -# Not ready for this yet -android.enableR8=false diff --git a/integration-testing/android/gradle/wrapper/gradle-wrapper.jar b/integration-testing/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index b5166dad4..000000000 Binary files a/integration-testing/android/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/integration-testing/android/gradle/wrapper/gradle-wrapper.properties b/integration-testing/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 4aa53223a..000000000 --- a/integration-testing/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Sun Apr 05 21:47:34 IDT 2020 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip diff --git a/integration-testing/android/gradlew b/integration-testing/android/gradlew deleted file mode 100755 index 91a7e269e..000000000 --- a/integration-testing/android/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/integration-testing/android/gradlew.bat b/integration-testing/android/gradlew.bat deleted file mode 100644 index 8a0b282aa..000000000 --- a/integration-testing/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/integration-testing/android/keystores/BUCK b/integration-testing/android/keystores/BUCK deleted file mode 100644 index 15da20e6b..000000000 --- a/integration-testing/android/keystores/BUCK +++ /dev/null @@ -1,8 +0,0 @@ -keystore( - name = 'debug', - store = 'debug.keystore', - properties = 'debug.keystore.properties', - visibility = [ - 'PUBLIC', - ], -) diff --git a/integration-testing/android/keystores/debug.keystore.properties b/integration-testing/android/keystores/debug.keystore.properties deleted file mode 100644 index 121bfb49f..000000000 --- a/integration-testing/android/keystores/debug.keystore.properties +++ /dev/null @@ -1,4 +0,0 @@ -key.store=debug.keystore -key.alias=androiddebugkey -key.store.password=android -key.alias.password=android diff --git a/integration-testing/android/settings.gradle b/integration-testing/android/settings.gradle deleted file mode 100644 index 7ec9296e8..000000000 --- a/integration-testing/android/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'DetoxRNExample' - -include ':app' diff --git a/integration-testing/app.json b/integration-testing/app.json deleted file mode 100644 index 486d55b07..000000000 --- a/integration-testing/app.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "example", - "displayName": "example" -} \ No newline at end of file diff --git a/integration-testing/babel.config.js b/integration-testing/babel.config.js deleted file mode 100644 index f842b77fc..000000000 --- a/integration-testing/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: ['module:metro-react-native-babel-preset'], -}; diff --git a/integration-testing/detox.config.js b/integration-testing/detox.config.js deleted file mode 100644 index 0b47dade8..000000000 --- a/integration-testing/detox.config.js +++ /dev/null @@ -1,55 +0,0 @@ -module.exports = { - "test-runner": "mocha", - "runner-config": "e2e/.mocharc.json", - "behavior": { - "init": { - "exposeGlobals": process.env.DETOX_EXPOSE_GLOBALS === '0' ? false : true, - }, - }, - "configurations": { - "ios.sim.release": { - "binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app", - "build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/example.xcworkspace -UseNewBuildSystem=NO -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "device": { - "type": "iPhone 11" - } - }, - "ios.sim.debug": { - "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", - "build": "export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/example.xcworkspace -UseNewBuildSystem=NO -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "device": { - "type": "iPhone 11" - } - }, - "ios.none": { - "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", - "build": "xcodebuild -workspace ios/example.xcworkspace -UseNewBuildSystem=NO -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.none", - "device": { - "type": "iPhone 11" - }, - "session": { - "server": "ws://localhost:8099", - "sessionId": "com.wix.demo.react.native" - } - }, - "android.emu.debug": { - "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", - "build": "cd android ; ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -", - "type": "android.emulator", - "device": { - "avdName": "Pixel_API_28" - } - }, - "android.emu.release": { - "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", - "build": "cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -", - "type": "android.emulator", - "device": { - "avdName": "Pixel_API_28" - } - } - } -}; diff --git a/integration-testing/e2e/.mocharc.json b/integration-testing/e2e/.mocharc.json deleted file mode 100644 index 39fe622c3..000000000 --- a/integration-testing/e2e/.mocharc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "recursive": true, - "timeout": 300000, - "bail": true, - "file": "e2e/init.js" -} diff --git a/integration-testing/e2e/example.spec.js b/integration-testing/e2e/example.spec.js deleted file mode 100644 index 05471aae3..000000000 --- a/integration-testing/e2e/example.spec.js +++ /dev/null @@ -1,23 +0,0 @@ -describe('Iterable', () => { - beforeEach(async () => { - // await device.reloadReactNative(); - }); - - it('should have Login button', async () => { - // await expect(element(by.id('Logout'))).toBeVisible(); - await expect(element(by.id('loginBtn'))).toBeVisible(); - }); - - it('Login User', async () => { - await expect(element(by.id('loginText'))).toBeVisible(); - await element(by.id('loginText')).typeText('user@example.com'); - await element(by.id('loginBtn')).multiTap(2); - await waitFor(element(by.id('logoutBtn'))).toBeVisible(); - }); - - it('Send in-app', async () => { - await element(by.id('sendInAppBtn')).tap(); - await waitFor(element(by.text('Later'))).toExist().withTimeout(10000); - //await element(by.text('Later')).tap(); - }); -}); \ No newline at end of file diff --git a/integration-testing/e2e/init.js b/integration-testing/e2e/init.js deleted file mode 100644 index 766e3b462..000000000 --- a/integration-testing/e2e/init.js +++ /dev/null @@ -1,18 +0,0 @@ -const detox = require('detox'); -const adapter = require('detox/runners/mocha/adapter'); - -before(async () => { - await detox.init(); -}); - -beforeEach(async function () { - await adapter.beforeEach(this); -}); - -afterEach(async function () { - await adapter.afterEach(this); -}); - -after(async () => { - await detox.cleanup(); -}); diff --git a/integration-testing/e2eExplicitRequire/example.spec.js b/integration-testing/e2eExplicitRequire/example.spec.js deleted file mode 100644 index c33f5a319..000000000 --- a/integration-testing/e2eExplicitRequire/example.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -const {device, expect, element, by, waitFor} = require('detox'); - -describe('Example (explicit)', () => { - beforeEach(async () => { - await device.reloadReactNative(); - }); - - it('should have welcome screen', async () => { - await expect(element(by.id('welcome'))).toBeVisible(); - }); - - it('should show hello screen after tap', async () => { - await element(by.id('hello_button')).tap(); - await expect(element(by.text('Hello!!!'))).toBeVisible(); - }); - - it('should show world screen after tap', async () => { - await element(by.id('world_button')).tap(); - await expect(element(by.text('World!!!'))).toBeVisible(); - }); - - it('waitFor should be exported', async () => { - await waitFor(element(by.id('welcome'))).toExist().withTimeout(2000); - await expect(element(by.id('welcome'))).toExist(); - }); -}); diff --git a/integration-testing/img/black-coffee.png b/integration-testing/img/black-coffee.png deleted file mode 100644 index 3f13bca50..000000000 Binary files a/integration-testing/img/black-coffee.png and /dev/null differ diff --git a/integration-testing/img/cappuccino.png b/integration-testing/img/cappuccino.png deleted file mode 100644 index a5f364b5c..000000000 Binary files a/integration-testing/img/cappuccino.png and /dev/null differ diff --git a/integration-testing/img/iterable-logo.png b/integration-testing/img/iterable-logo.png deleted file mode 100644 index 6e61709b3..000000000 Binary files a/integration-testing/img/iterable-logo.png and /dev/null differ diff --git a/integration-testing/img/mocha.png b/integration-testing/img/mocha.png deleted file mode 100644 index 4b97f3085..000000000 Binary files a/integration-testing/img/mocha.png and /dev/null differ diff --git a/integration-testing/index.js b/integration-testing/index.js deleted file mode 100644 index e367b6062..000000000 --- a/integration-testing/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { AppRegistry } from 'react-native'; -import App from './ts/App.tsx'; -import { name as appName } from './app.json'; - -AppRegistry.registerComponent(appName, () => App); diff --git a/integration-testing/ios/Podfile b/integration-testing/ios/Podfile deleted file mode 100644 index a9bcaf2f4..000000000 --- a/integration-testing/ios/Podfile +++ /dev/null @@ -1,17 +0,0 @@ -require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' -require_relative '../node_modules/react-native/scripts/react_native_pods' - -platform :ios, '12.0' - -target 'example' do - config = use_native_modules! - use_react_native!(:path => config["reactNativePath"]) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_TESTABILITY'] = 'YES' - end - end -end diff --git a/integration-testing/ios/eeUITests/Info.plist b/integration-testing/ios/eeUITests/Info.plist deleted file mode 100644 index 64d65ca49..000000000 --- a/integration-testing/ios/eeUITests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/integration-testing/ios/eeUITests/UITestsHelper.swift b/integration-testing/ios/eeUITests/UITestsHelper.swift deleted file mode 100644 index 030cd1139..000000000 --- a/integration-testing/ios/eeUITests/UITestsHelper.swift +++ /dev/null @@ -1,131 +0,0 @@ -// -// Created by Tapash Majumder on 2020-06-18. -// Copyright © 2019 Iterable. All rights reserved. -// -// This class should have generic helper methods for UI testing. -// It should not contain Iterable specific helper methods. - -import Foundation -import XCTest - -struct UITestsHelper { - static func gotoTab(_ tabName: String, inApp app: XCUIApplication) { - app.tabBars.buttons[tabName].tap() - } - - static func deleteSwipe(_ cell: XCUIElement) { - let startPoint = cell.coordinate(withNormalizedOffset: CGVector(dx: 1.0, dy: 0.0)) - let endPoint = cell.coordinate(withNormalizedOffset: .zero) - startPoint.press(forDuration: 0, thenDragTo: endPoint) - } - - static func pullToRefresh(_ cell: XCUIElement) { - let firstCell = cell - let start = firstCell.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 0)) - let finish = firstCell.coordinate(withNormalizedOffset: CGVector(dx: 0, dy: 25)) - start.press(forDuration: 0, thenDragTo: finish) - } - - static func tableCell(withText text: String, inApp app: XCUIApplication) -> XCUIElement { - return app.tables.cells.staticTexts[text] - } - - static func lastElement(query: XCUIElementQuery) -> XCUIElement { - let count = query.count - return query.element(boundBy: count - 1) - } - - static func lastCell(inApp app: XCUIApplication) -> XCUIElement { - return lastElement(query: app.tables.cells) - } - - static func link(withText text: String, inApp app: XCUIApplication) -> XCUIElement { - return app.links[text].firstMatch - } - - static func label(withText text: String, inApp app: XCUIApplication) -> XCUIElement { - return app.staticTexts[text] - } - - static func button(withText text: String, inApp app: XCUIApplication) -> XCUIElement { - return app.buttons[text] - } - - static func navButton(withText text: String, inApp app: XCUIApplication) -> XCUIElement { - return app.navigationBars.buttons[text] - } -} - -extension XCUIApplication { - func gotoTab(_ tabName: String) { - UITestsHelper.gotoTab(tabName, inApp: self) - } - - func tableCell(withText text: String) -> XCUIElement { - return UITestsHelper.tableCell(withText: text, inApp: self) - } - - func lastCell() -> XCUIElement { - return UITestsHelper.lastCell(inApp: self) - } - - func label(withText text: String) -> XCUIElement { - return UITestsHelper.label(withText: text, inApp: self) - } - - func link(withText text: String) -> XCUIElement { - return UITestsHelper.link(withText: text, inApp: self) - } - - func button(withText text: String) -> XCUIElement { - return UITestsHelper.button(withText: text, inApp: self) - } - - func navButton(withText text: String) -> XCUIElement { - return UITestsHelper.navButton(withText: text, inApp: self) - } -} - -extension XCUIElement { - func deleteSwipe() { - UITestsHelper.deleteSwipe(self) - } - - func pullToRefresh() { - UITestsHelper.pullToRefresh(self) - } - - @discardableResult func waitToAppear(fail: Bool = true) -> XCUIElement { - let exists = waitForExistence(timeout: uiElementWaitTimeout) - - if fail, !exists { - XCTFail("expected element: \(self)") - } - - return self - } -} - -let uiElementWaitTimeout = 120.0 - -protocol IterableUITestsProtocol: AnyObject { - var app: XCUIApplication! { get } -} - -extension IterableUITestsProtocol where Self: XCTestCase { - func waitForElementToAppear(_ element: XCUIElement, fail: Bool = true) { - let exists = element.waitForExistence(timeout: uiElementWaitTimeout) - - if fail, !exists { - XCTFail("expected element: \(element)") - } - } -} - -struct UITestsGlobal { - static let application: XCUIApplication = { - let app = XCUIApplication() - app.launch() - return app - }() -} diff --git a/integration-testing/ios/eeUITests/eeUITests.swift b/integration-testing/ios/eeUITests/eeUITests.swift deleted file mode 100644 index 190aae040..000000000 --- a/integration-testing/ios/eeUITests/eeUITests.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// Created by Tapash Majumder on 6/18/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -import XCTest - -class eeUITests: XCTestCase { - lazy var app: XCUIApplication! = UITestsGlobal.application - - override func setUp() { - app.button(withText: "resetBtn").waitToAppear().tap() - } - - override func tearDown() { - app.button(withText: "resetBtn").waitToAppear().tap() - } - - // this must be called first - func test_aa_clearAllInAppMessages() throws { - app.button(withText: "clearAllInApps").waitToAppear().tap() - app.label(withText: "Cleared all in-apps").waitToAppear() - } - - // this must be called second - func test_aa_Login() throws { - if app.button(withText: "Logout").exists { - app.button(withText: "Logout").tap() - } - app.button(withText: "Login").waitToAppear() - app.textFields["loginText"].tap() - app.textFields["loginText"].typeText("user@example.com") - app.button(withText: "Login").waitToAppear().doubleTap() - app.button(withText: "Logout").waitToAppear() - } - - func testSendInApp() throws { - app.button(withText: "Send In-App").tap() - app.link(withText: "Later").waitToAppear().tap() - } - - func testSkipInApp() throws { - app.button(withText: "Skip In-App").tap() - app.label(withText: "Skipping in-app").waitToAppear() - } - - func testCustomAction() throws { - app.button(withText: "customActionBtn").tap() - app.link(withText: "Custom Action").waitToAppear().tap() - app.label(withText: "Custom Action: 'ActionJackson'").waitToAppear() - } - - func testUrlDelegateOpenDeeplink() throws { - app.button(withText: "openDeepLinkBtn").tap() - app.link(withText: "Buy Now!").waitToAppear().tap() - app.label(withText: "Opening coffee page: 'cappuccino'").waitToAppear() - } - - func testUrlDelegateOpenSafari() throws { - app.button(withText: "openSafariBtn").tap() - app.link(withText: "Open Safari").waitToAppear().tap() - - // Give some time to open - sleep(1) - - // Assert that safari is active - let safariApp = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari") - XCTAssertEqual(safariApp.state, .runningForeground, "Safari is not active") - - // launch this app again for other tests - app.launch() - } -} diff --git a/integration-testing/ios/example.xcodeproj/project.pbxproj b/integration-testing/ios/example.xcodeproj/project.pbxproj deleted file mode 100644 index 5f7ad032a..000000000 --- a/integration-testing/ios/example.xcodeproj/project.pbxproj +++ /dev/null @@ -1,594 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 4220A76D9E01418EA8F8E9BD /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B032AA4480FF30BB594C1A6C /* libPods-example.a */; }; - AC1272892499FCC10006A3C5 /* RNE2E.m in Sources */ = {isa = PBXBuildFile; fileRef = AC1272882499FCC10006A3C5 /* RNE2E.m */; }; - AC12728B2499FCEC0006A3C5 /* ReactE2E.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC12728A2499FCEC0006A3C5 /* ReactE2E.swift */; }; - AC12728D249A567D0006A3C5 /* IterableAPISupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC12728C249A567D0006A3C5 /* IterableAPISupport.swift */; }; - AC27B4652495224E0079F714 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC27B4642495224E0079F714 /* AppDelegate.swift */; }; - AC27B4692495224E0079F714 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC27B4682495224E0079F714 /* ViewController.swift */; }; - AC27B46C2495224E0079F714 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AC27B46A2495224E0079F714 /* Main.storyboard */; }; - AC27B46E249522510079F714 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AC27B46D249522510079F714 /* Assets.xcassets */; }; - AC27B471249522510079F714 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AC27B46F249522510079F714 /* LaunchScreen.storyboard */; }; - AC424ABA249B6266006BE3DC /* eeUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC424AB9249B6266006BE3DC /* eeUITests.swift */; }; - AC424AC2249B6765006BE3DC /* UITestsHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC424AC1249B6765006BE3DC /* UITestsHelper.swift */; }; - ACF93CD824A33A6F004B0745 /* main.jsBundle in Resources */ = {isa = PBXBuildFile; fileRef = ACF93CD724A33A6F004B0745 /* main.jsBundle */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - AC424ABC249B6266006BE3DC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AC27B4592495224E0079F714 /* Project object */; - proxyType = 1; - remoteGlobalIDString = AC27B4602495224E0079F714; - remoteInfo = example; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 3C757389F2C6D30D9AAFFFFB /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; }; - AC1272882499FCC10006A3C5 /* RNE2E.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNE2E.m; sourceTree = ""; }; - AC12728A2499FCEC0006A3C5 /* ReactE2E.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactE2E.swift; sourceTree = ""; }; - AC12728C249A567D0006A3C5 /* IterableAPISupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IterableAPISupport.swift; sourceTree = ""; }; - AC27B4612495224E0079F714 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; - AC27B4642495224E0079F714 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - AC27B4682495224E0079F714 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - AC27B46B2495224E0079F714 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - AC27B46D249522510079F714 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - AC27B470249522510079F714 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - AC27B472249522510079F714 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AC27B478249526180079F714 /* example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "example-Bridging-Header.h"; sourceTree = ""; }; - AC424AB7249B6266006BE3DC /* eeUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = eeUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - AC424AB9249B6266006BE3DC /* eeUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = eeUITests.swift; sourceTree = ""; }; - AC424ABB249B6266006BE3DC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AC424AC1249B6765006BE3DC /* UITestsHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsHelper.swift; sourceTree = ""; }; - ACBA3CD72495F1AB000B555A /* example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = example.entitlements; sourceTree = ""; }; - ACF93CD724A33A6F004B0745 /* main.jsBundle */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.jsBundle; sourceTree = ""; }; - B032AA4480FF30BB594C1A6C /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - D08D72478808E896D10238F8 /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - AC27B45E2495224E0079F714 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4220A76D9E01418EA8F8E9BD /* libPods-example.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC424AB4249B6266006BE3DC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 4AC3CCD3A8ED474D998351AF /* Frameworks */ = { - isa = PBXGroup; - children = ( - B032AA4480FF30BB594C1A6C /* libPods-example.a */, - ); - name = Frameworks; - sourceTree = ""; - }; - 66776D6547833594FC34624D /* Pods */ = { - isa = PBXGroup; - children = ( - 3C757389F2C6D30D9AAFFFFB /* Pods-example.debug.xcconfig */, - D08D72478808E896D10238F8 /* Pods-example.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - AC27B4582495224E0079F714 = { - isa = PBXGroup; - children = ( - AC27B4632495224E0079F714 /* example */, - AC424AB8249B6266006BE3DC /* eeUITests */, - AC27B4622495224E0079F714 /* Products */, - 66776D6547833594FC34624D /* Pods */, - 4AC3CCD3A8ED474D998351AF /* Frameworks */, - ); - sourceTree = ""; - }; - AC27B4622495224E0079F714 /* Products */ = { - isa = PBXGroup; - children = ( - AC27B4612495224E0079F714 /* example.app */, - AC424AB7249B6266006BE3DC /* eeUITests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - AC27B4632495224E0079F714 /* example */ = { - isa = PBXGroup; - children = ( - ACBA3CD72495F1AB000B555A /* example.entitlements */, - AC27B4642495224E0079F714 /* AppDelegate.swift */, - AC27B4682495224E0079F714 /* ViewController.swift */, - AC27B46A2495224E0079F714 /* Main.storyboard */, - AC27B46D249522510079F714 /* Assets.xcassets */, - AC27B46F249522510079F714 /* LaunchScreen.storyboard */, - AC27B472249522510079F714 /* Info.plist */, - AC27B478249526180079F714 /* example-Bridging-Header.h */, - AC1272882499FCC10006A3C5 /* RNE2E.m */, - AC12728A2499FCEC0006A3C5 /* ReactE2E.swift */, - AC12728C249A567D0006A3C5 /* IterableAPISupport.swift */, - ACF93CD724A33A6F004B0745 /* main.jsBundle */, - ); - path = example; - sourceTree = ""; - }; - AC424AB8249B6266006BE3DC /* eeUITests */ = { - isa = PBXGroup; - children = ( - AC424AB9249B6266006BE3DC /* eeUITests.swift */, - AC424ABB249B6266006BE3DC /* Info.plist */, - AC424AC1249B6765006BE3DC /* UITestsHelper.swift */, - ); - path = eeUITests; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - AC27B4602495224E0079F714 /* example */ = { - isa = PBXNativeTarget; - buildConfigurationList = AC27B475249522510079F714 /* Build configuration list for PBXNativeTarget "example" */; - buildPhases = ( - C07AA68C9973F3BAB4F3C542 /* [CP] Check Pods Manifest.lock */, - AC27B45D2495224E0079F714 /* Sources */, - AC27B45E2495224E0079F714 /* Frameworks */, - AC27B45F2495224E0079F714 /* Resources */, - AC27B479249527230079F714 /* Bundle React Native Code and Images */, - 3A97238B2E20DEAB976AC2D5 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = example; - productName = example; - productReference = AC27B4612495224E0079F714 /* example.app */; - productType = "com.apple.product-type.application"; - }; - AC424AB6249B6266006BE3DC /* eeUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = AC424AC0249B6266006BE3DC /* Build configuration list for PBXNativeTarget "eeUITests" */; - buildPhases = ( - AC424AB3249B6266006BE3DC /* Sources */, - AC424AB4249B6266006BE3DC /* Frameworks */, - AC424AB5249B6266006BE3DC /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - AC424ABD249B6266006BE3DC /* PBXTargetDependency */, - ); - name = eeUITests; - productName = eeUITests; - productReference = AC424AB7249B6266006BE3DC /* eeUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - AC27B4592495224E0079F714 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1150; - LastUpgradeCheck = 1150; - ORGANIZATIONNAME = Iterable; - TargetAttributes = { - AC27B4602495224E0079F714 = { - CreatedOnToolsVersion = 11.5; - }; - AC424AB6249B6266006BE3DC = { - CreatedOnToolsVersion = 11.5; - TestTargetID = AC27B4602495224E0079F714; - }; - }; - }; - buildConfigurationList = AC27B45C2495224E0079F714 /* Build configuration list for PBXProject "example" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = AC27B4582495224E0079F714; - productRefGroup = AC27B4622495224E0079F714 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - AC27B4602495224E0079F714 /* example */, - AC424AB6249B6266006BE3DC /* eeUITests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - AC27B45F2495224E0079F714 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AC27B471249522510079F714 /* LaunchScreen.storyboard in Resources */, - ACF93CD824A33A6F004B0745 /* main.jsBundle in Resources */, - AC27B46E249522510079F714 /* Assets.xcassets in Resources */, - AC27B46C2495224E0079F714 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC424AB5249B6266006BE3DC /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3A97238B2E20DEAB976AC2D5 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-example/Pods-example-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - AC27B479249527230079F714 /* Bundle React Native Code and Images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Bundle React Native Code and Images"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\nexport FORCE_BUNDLING=true\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; - }; - C07AA68C9973F3BAB4F3C542 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - AC27B45D2495224E0079F714 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AC12728B2499FCEC0006A3C5 /* ReactE2E.swift in Sources */, - AC1272892499FCC10006A3C5 /* RNE2E.m in Sources */, - AC12728D249A567D0006A3C5 /* IterableAPISupport.swift in Sources */, - AC27B4692495224E0079F714 /* ViewController.swift in Sources */, - AC27B4652495224E0079F714 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC424AB3249B6266006BE3DC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - AC424ABA249B6266006BE3DC /* eeUITests.swift in Sources */, - AC424AC2249B6765006BE3DC /* UITestsHelper.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - AC424ABD249B6266006BE3DC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = AC27B4602495224E0079F714 /* example */; - targetProxy = AC424ABC249B6266006BE3DC /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - AC27B46A2495224E0079F714 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - AC27B46B2495224E0079F714 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - AC27B46F249522510079F714 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - AC27B470249522510079F714 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - AC27B473249522510079F714 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.5; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG NETWORK_DEBUG"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - AC27B474249522510079F714 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.5; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - AC27B476249522510079F714 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 3C757389F2C6D30D9AAFFFFB /* Pods-example.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = example/example.entitlements; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = BP98Z28R86; - INFOPLIST_FILE = example/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.iterable.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_OBJC_BRIDGING_HEADER = "example/example-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - AC27B477249522510079F714 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D08D72478808E896D10238F8 /* Pods-example.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_ENTITLEMENTS = example/example.entitlements; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = BP98Z28R86; - INFOPLIST_FILE = example/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.iterable.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_OBJC_BRIDGING_HEADER = "example/example-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - AC424ABE249B6266006BE3DC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = BP98Z28R86; - INFOPLIST_FILE = eeUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.iterable.eeUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = example; - }; - name = Debug; - }; - AC424ABF249B6266006BE3DC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = BP98Z28R86; - ENABLE_TESTABILITY = YES; - INFOPLIST_FILE = eeUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.iterable.eeUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_TARGET_NAME = example; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - AC27B45C2495224E0079F714 /* Build configuration list for PBXProject "example" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AC27B473249522510079F714 /* Debug */, - AC27B474249522510079F714 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AC27B475249522510079F714 /* Build configuration list for PBXNativeTarget "example" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AC27B476249522510079F714 /* Debug */, - AC27B477249522510079F714 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AC424AC0249B6266006BE3DC /* Build configuration list for PBXNativeTarget "eeUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AC424ABE249B6266006BE3DC /* Debug */, - AC424ABF249B6266006BE3DC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = AC27B4592495224E0079F714 /* Project object */; -} diff --git a/integration-testing/ios/example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/integration-testing/ios/example.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index e35a4f1df..000000000 --- a/integration-testing/ios/example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/integration-testing/ios/example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/integration-testing/ios/example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/integration-testing/ios/example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/integration-testing/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme b/integration-testing/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme deleted file mode 100644 index bca303075..000000000 --- a/integration-testing/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/integration-testing/ios/example.xcworkspace/contents.xcworkspacedata b/integration-testing/ios/example.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 7f5c3aab5..000000000 --- a/integration-testing/ios/example.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/integration-testing/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/integration-testing/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/integration-testing/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/integration-testing/ios/example/AppDelegate.swift b/integration-testing/ios/example/AppDelegate.swift deleted file mode 100644 index eafae54a5..000000000 --- a/integration-testing/ios/example/AppDelegate.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// Created by Tapash Majumder on 6/13/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -import UIKit - -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - - var window: UIWindow? - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - let bridge = RCTBridge(delegate: self, launchOptions: launchOptions)! - let rootView = RCTRootView(bridge: bridge, moduleName: "example", initialProperties: nil) - rootView.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1) - self.window = UIWindow(frame: UIScreen.main.bounds) - let rootViewController = UIViewController() - rootViewController.view = rootView - self.window?.rootViewController = rootViewController - self.window?.makeKeyAndVisible() - - return true - } -} - -extension AppDelegate: RCTBridgeDelegate { - func sourceURL(for bridge: RCTBridge!) -> URL! { - #if DEBUG - // We can't load from "index.js" from metro packager because it fails in Github Action. - // Se we load the same way for debug and release with main.jsBundle. - return Bundle.main.url(forResource: "main", withExtension: "jsBundle") - #else - return Bundle.main.url(forResource: "main", withExtension: "jsBundle") - #endif - } -} diff --git a/integration-testing/ios/example/Assets.xcassets/AppIcon.appiconset/Contents.json b/integration-testing/ios/example/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9221b9bb1..000000000 --- a/integration-testing/ios/example/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/integration-testing/ios/example/Assets.xcassets/Contents.json b/integration-testing/ios/example/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596a..000000000 --- a/integration-testing/ios/example/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/integration-testing/ios/example/Base.lproj/LaunchScreen.storyboard b/integration-testing/ios/example/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index 865e9329f..000000000 --- a/integration-testing/ios/example/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/integration-testing/ios/example/Base.lproj/Main.storyboard b/integration-testing/ios/example/Base.lproj/Main.storyboard deleted file mode 100644 index 25a763858..000000000 --- a/integration-testing/ios/example/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/integration-testing/ios/example/Info.plist b/integration-testing/ios/example/Info.plist deleted file mode 100644 index 2295b7653..000000000 --- a/integration-testing/ios/example/Info.plist +++ /dev/null @@ -1,70 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - $(PRODUCT_NAME) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsArbitraryLoadsInWebContent - - NSAllowsLocalNetworking - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - - NSLocationWhenInUseUsageDescription - - UIAppFonts - - Ionicons.ttf - - UIBackgroundModes - - fetch - remote-notification - - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/integration-testing/ios/example/IterableAPISupport.swift b/integration-testing/ios/example/IterableAPISupport.swift deleted file mode 100644 index 6f070d670..000000000 --- a/integration-testing/ios/example/IterableAPISupport.swift +++ /dev/null @@ -1,156 +0,0 @@ -// -// Created by Tapash Majumder on 6/17/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -import Foundation - -@testable import IterableSDK - -struct IterableAPISupport { - enum Const { - static let apiEndpoint = "https://api.iterable.com/api/" - enum Path { - static let sendInApp = "inApp/target" - static let getInApps = "inApp/getMessages" - static let consumeInApp = "events/inAppConsume" - } - - enum Key { - static let campaignId = "campaignId" - static let recipientEmail = "recipientEmail" - } - } - - static func clearAllInAppMessages(apiKey: String, - email: String) { - // Issue consume requests - getInAppMessages(apiKey: apiKey, email: email).flatMap { - chainCallConsume(apiKey: apiKey, email: email, messages: $0) - }.wait() - - // Now check that messages are gone - getInAppMessages(apiKey: apiKey, email: email).flatMap { - checkMessagesDone(apiKey: apiKey, email: email, messages: $0, attemptsRemaining: 5) - } - .onError(block: { error in - fatalError("\(error.localizedDescription)") - }) - .wait() - } - - - static func sendInApp(apiKey: String, to email: String, withCampaignId campaignId: Int) -> Pending { - let body: [String: Any] = [ - Const.Key.recipientEmail: email, - Const.Key.campaignId: campaignId - ] - - guard let request = IterableRequestUtil.createPostRequest(forApiEndPoint: Const.apiEndpoint, - path: Const.Path.sendInApp, - headers: createIterableHeaders(apiKey: apiKey), - body: body) else { - return SendRequestError.createErroredFuture(reason: "Could not create in-app consume request") - } - - return RequestSender.sendRequest(request, usingSession: urlSession) - } - - private static let urlSession: URLSession = { - return URLSession(configuration: URLSessionConfiguration.default) - } () - - private static let maxMessages = 100 - - private static func getInAppMessages(apiKey: String, - email: String) -> Pending<[IterableInAppMessage], SendRequestError> { - var args: [String: String] = [ - JsonKey.email: email, - JsonKey.InApp.count: maxMessages.description, - JsonKey.platform: JsonValue.iOS, - JsonKey.InApp.sdkVersion: IterableAPI.sdkVersion, - ] - - if let packageName = Bundle.main.appPackageName { - args[JsonKey.InApp.packageName] = packageName - } - - guard let request = IterableRequestUtil.createGetRequest(forApiEndPoint: Const.apiEndpoint, - path: Const.Path.getInApps, - headers: createIterableHeaders(apiKey: apiKey), - args: args) else { - return SendRequestError.createErroredFuture(reason: "could not create get in-app request") - } - - return RequestSender.sendRequest(request, usingSession: urlSession).map { inAppMessages(fromPayload: $0) } - } - - private static func createIterableHeaders(apiKey: String) -> [String: String] { - let headers = [JsonKey.contentType: JsonValue.applicationJson, - JsonKey.Header.sdkPlatform: JsonValue.iOS, - JsonKey.Header.sdkVersion: IterableAPI.sdkVersion, - JsonKey.Header.apiKey: apiKey] - - return headers - } - - - private static func inAppMessages(fromPayload payload: [AnyHashable: Any]) -> [IterableInAppMessage] { - InAppMessageParser.parse(payload: payload).compactMap(parseResultToOptionalMessage) - } - - private static func parseResultToOptionalMessage(result: Result) -> IterableInAppMessage? { - switch result { - case .failure: - return nil - case let .success(message): - return message - } - } - - private static func checkMessagesDone(apiKey: String, email: String, messages: [IterableInAppMessage], attemptsRemaining: Int) -> Pending<[IterableInAppMessage], SendRequestError> { - ITBInfo("attemptsRemaining: \(attemptsRemaining), waiting or 1 s...") - guard messages.count > 0 else { - return Fulfill<[IterableInAppMessage], SendRequestError>(value: []) - } - guard attemptsRemaining > 0 else { - return SendRequestError.createErroredFuture(reason: "Number of attempts exceeded") - } - - Thread.sleep(forTimeInterval: 1.0) - return getInAppMessages(apiKey: apiKey, email: email).flatMap { messages in - return checkMessagesDone(apiKey: apiKey, email: email, messages: messages, attemptsRemaining: attemptsRemaining - 1) - } - } - - // Call consume one after the other - private static func chainCallConsume(apiKey: String, email: String, messages: [IterableInAppMessage]) -> Pending { - guard messages.count > 0 else { - return Fulfill(value: [:]) - } - - let result = Fulfill(value: [:]) - - return messages.reduce(result) { (partialResult, message) -> Pending in - partialResult.flatMap { _ in - consumeInAppMessage(apiKey: apiKey, email: email, messageId: message.messageId) - } - } - } - - private static func consumeInAppMessage(apiKey: String, email: String, messageId: String) -> Pending { - var body = [AnyHashable: Any]() - - body.setValue(for: JsonKey.messageId, value: messageId) - body.setValue(for: JsonKey.email, value: email) - - guard let request = IterableRequestUtil.createPostRequest(forApiEndPoint: Const.apiEndpoint, - path: Const.Path.consumeInApp, - headers: createIterableHeaders(apiKey: apiKey), - body: body) else { - return SendRequestError.createErroredFuture(reason: "Could not create in-app consume request") - } - - return RequestSender.sendRequest(request, usingSession: urlSession) - } -} diff --git a/integration-testing/ios/example/RNE2E.m b/integration-testing/ios/example/RNE2E.m deleted file mode 100644 index 3a30070a4..000000000 --- a/integration-testing/ios/example/RNE2E.m +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by Tapash Majumder on 6/17/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -#import - -#import - -@interface RCT_EXTERN_REMAP_MODULE(RNE2E, ReactE2E, NSObject) - -RCT_EXTERN_METHOD(setApiKey: (nonnull NSString *) apiKey) - -RCT_EXTERN_METHOD(sendCommand: (nonnull NSString *) command - params: (nonnull NSDictionary *) params) - -RCT_EXTERN_METHOD(clearAllInAppMessages: (RCTPromiseResolveBlock) resolve - rejecter: (RCTPromiseRejectBlock) reject) -@end diff --git a/integration-testing/ios/example/ReactE2E.swift b/integration-testing/ios/example/ReactE2E.swift deleted file mode 100644 index 41577d5ec..000000000 --- a/integration-testing/ios/example/ReactE2E.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// Created by Tapash Majumder on 6/17/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -import Foundation - -@testable import IterableSDK - -@objc(ReactE2E) -class ReactE2E: RCTEventEmitter { - @objc(setApiKey:) - func setApiKey(apiKey: String) { - ITBInfo("setApiKey") - self.apiKey = apiKey - } - - @objc(sendCommand:params:) - func sendCommand(command: String, params: [AnyHashable: Any]) { - ITBInfo("sendCommand: \(command)") - execute(command: Command.parse(str: command), params: params) - } - - @objc(clearAllInAppMessages:rejecter:) - func clearAllInAppMessages(resolver: RCTPromiseResolveBlock, rejecter: RCTPromiseRejectBlock) { - ITBInfo() - - IterableAPISupport.clearAllInAppMessages(apiKey: apiKey, email: email) - resolver(true) - } - - override var methodQueue: DispatchQueue! { - _methodQueue - } - - @objc override static func requiresMainQueueSetup() -> Bool { - false - } - - enum EventName: String, CaseIterable { - case handleUrlCalled - case handleCustomActionCalled - case handleInAppCalled - } - - override func supportedEvents() -> [String]! { - var result = [String]() - EventName.allCases.forEach { - result.append($0.rawValue) - } - return result - } - - override func startObserving() { - ITBInfo() - shouldEmit = true - } - - override func stopObserving() { - ITBInfo() - shouldEmit = false - } - - enum Command: String { - case initialize - case sendInApp = "send-in-app" - case unknown - - static func parse(str: String) -> Command { - return Command(rawValue: str.lowercased()) ?? .unknown - } - } - - // MARK: Private - private var apiKey: String! - private var email = "user@example.com" - private var shouldEmit = false - private let _methodQueue = DispatchQueue(label: String(describing: ReactE2E.self)) - - private func execute(command: Command, params: [AnyHashable: Any]) { - switch command { - case .initialize: - break - case .sendInApp: - let campaignId = params["campaignId"] as! Int - _ = IterableAPISupport.sendInApp(apiKey: apiKey, to: email, withCampaignId: campaignId) - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - _ = IterableAPI.implementation?.inAppManager.scheduleSync() - } - break - default: - ITBError("unknown command") - } - } -} diff --git a/integration-testing/ios/example/ViewController.swift b/integration-testing/ios/example/ViewController.swift deleted file mode 100644 index c6b66f7bb..000000000 --- a/integration-testing/ios/example/ViewController.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// Created by Tapash Majumder on 6/13/20. -// Copyright © 2020 Iterable. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/integration-testing/ios/example/example-Bridging-Header.h b/integration-testing/ios/example/example-Bridging-Header.h deleted file mode 100644 index 27cc556e1..000000000 --- a/integration-testing/ios/example/example-Bridging-Header.h +++ /dev/null @@ -1,4 +0,0 @@ -#import -#import -#import -#import diff --git a/integration-testing/ios/example/example.entitlements b/integration-testing/ios/example/example.entitlements deleted file mode 100644 index 0c67376eb..000000000 --- a/integration-testing/ios/example/example.entitlements +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/integration-testing/ios/example/main.jsBundle b/integration-testing/ios/example/main.jsBundle deleted file mode 100644 index 75cbd5b1e..000000000 --- a/integration-testing/ios/example/main.jsBundle +++ /dev/null @@ -1,5 +0,0 @@ -{\rtf1\ansi\ansicpg1252\cocoartf949 -{\fonttbl} -{\colortbl;\red255\green255\blue255;} -\margl1440\margr1440\vieww9000\viewh8400\viewkind0 -} \ No newline at end of file diff --git a/integration-testing/ios/scripts/run_test.sh b/integration-testing/ios/scripts/run_test.sh deleted file mode 100755 index b46dbd535..000000000 --- a/integration-testing/ios/scripts/run_test.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -eo pipefail - -echo export const iterableAPIKey = \"$ITERABLE_API_KEY\" > ./integration-testing/ts/Config.ts -echo export const sendInAppCampaignId = $SEND_IN_APP_CAMPAIGN_ID >> ./integration-testing/ts/Config.ts -echo export const skipInAppCampaignId = $SKIP_IN_APP_CAMPAIGN_ID >> ./integration-testing/ts/Config.ts -echo export const openDeepLinkCampaignId = $OPEN_DEEP_LINK_CAMPAIGN_ID >> ./integration-testing/ts/Config.ts -echo export const openSafariCampaignId = $OPEN_SAFARI_CAMPAIGN_ID >> ./integration-testing/ts/Config.ts -echo export const customActionCampaignId = $CUSTOM_ACTION_CAMPAIGN_ID >> ./integration-testing/ts/Config.ts - -cd ./integration-testing/ios/ -rm -rf build/ - -xcodebuild -workspace example.xcworkspace \ - -scheme example \ - -sdk iphonesimulator \ - -destination 'platform=iOS Simulator,OS=latest,name=iPhone 13' \ - -derivedDataPath ios/build \ - clean test | xcpretty \ No newline at end of file diff --git a/integration-testing/metro.config.js b/integration-testing/metro.config.js deleted file mode 100644 index 13a964217..000000000 --- a/integration-testing/metro.config.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Metro configuration for React Native - * https://github.com/facebook/react-native - * - * @format - */ - -module.exports = { - transformer: { - getTransformOptions: async () => ({ - transform: { - experimentalImportSupport: false, - inlineRequires: false, - }, - }), - }, -}; diff --git a/integration-testing/package.json b/integration-testing/package.json deleted file mode 100644 index 5b3798711..000000000 --- a/integration-testing/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "example", - "version": "16.7.2", - "private": true, - "scripts": { - "start": "react-native start", - "postinstall": "node scripts/postinstall.js", - "e2e:ios": "yarn build:ios-release && yarn test:ios-release", - "e2e:android-debug": "npm run build:android-debug && npm run test:android-debug", - "e2e:android-release": "npm run build:android-release && npm run test:android-release" - }, - "dependencies": { - "@iterable/react-native-sdk": "^1.3.20", - "@react-native-community/masked-view": "^0.1.10", - "@react-navigation/bottom-tabs": "^5.4.5", - "@react-navigation/native": "^5.4.0", - "@react-navigation/stack": "^5.3.7", - "@types/react": "^18.0.12", - "react": "^17.0.2", - "react-native": "^0.64", - "react-native-elements": "^1.2.7", - "react-native-gesture-handler": "^1.6.1", - "react-native-ionicons": "^5.0.0-rc", - "react-native-reanimated": "^1.8.0", - "react-native-safe-area-context": "^0.7.3", - "react-native-screens": "^2.7.0", - "react-native-vector-icons": "^6.6.0", - "react-navigation": "^4.3.9", - "react-navigation-tabs": "^2.8.13" - }, - "devDependencies": { - "@babel/core": "^7.9.6", - "@babel/runtime": "^7.9.6", - "@react-native-community/eslint-config": "^0.0.7", - "@types/react-native": "^0.67.8", - "@types/react-native-vector-icons": "^6.4.5", - "eslint": "^6.8.0", - "metro-react-native-babel-preset": "^0.59.0", - "mocha": "^6.1.3", - "react-test-renderer": "16.9.0" - } -} diff --git a/integration-testing/scripts/clean.sh b/integration-testing/scripts/clean.sh deleted file mode 100755 index 162235f91..000000000 --- a/integration-testing/scripts/clean.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -set -euxo -export IT_DIR=$(cd `dirname "$0"`/.. && pwd) -cd $IT_DIR - -rm -rf node_modules/ -# You should not have to delete yarn.lock. If you do, uncomment the following line. -rm -rf yarn.lock -yarn install -cd ios/ -rm -rf Podfile.lock -rm -rf Pods/ -rm -rf *.xcworkspace/ -rm -rf ~/Library/Caches/CocoaPods -rm -rf build/ -pod install - - - diff --git a/integration-testing/scripts/postinstall.js b/integration-testing/scripts/postinstall.js deleted file mode 100644 index 9843f34c5..000000000 --- a/integration-testing/scripts/postinstall.js +++ /dev/null @@ -1,29 +0,0 @@ -const rnVersion = function() { - const rnPackageJson = require('react-native/package.json'); - return rnPackageJson.version; -}(); - -function patchHermesLocationForRN60Android() { - const semver = require('semver'); - const fs = require('fs-extra'); - const path = require('path'); - - if (semver.minor(rnVersion) === 60) { - console.log('Detox post-install: Detected RN .60...'); - - const HERMES_PATH_ROOT = path.join('node_modules', 'hermesvm'); - const HERMES_PATH_RN = path.join('node_modules', 'react-native', 'node_modules', 'hermesvm'); - - const hermesIsInRoot = fs.existsSync(HERMES_PATH_ROOT); - const hermesIsInRN = fs.existsSync(HERMES_PATH_RN); - - if (hermesIsInRoot && !hermesIsInRN) { - console.log('Detox post-install: Applying hermes-vm patch for RN .60...'); - fs.ensureDirSync(path.join(HERMES_PATH_RN, 'android')); - fs.copySync(path.join(HERMES_PATH_ROOT, 'android'), path.join(HERMES_PATH_RN, 'android')); - } else { - console.log('Detox post-install: hermes-vm patch not needed:', hermesIsInRoot, hermesIsInRN); - } - } -} -patchHermesLocationForRN60Android(); diff --git a/integration-testing/ts/App.tsx b/integration-testing/ts/App.tsx deleted file mode 100644 index 83f1c9fc6..000000000 --- a/integration-testing/ts/App.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import { NativeModules } from 'react-native' -import React from 'react'; -import { - SafeAreaView, - StyleSheet, - ScrollView, - View, - Button, - Text, -} from 'react-native'; - -import { - Iterable, - IterableConfig, - IterableAction, - IterableActionContext, - IterableInAppShowResponse, - IterableInAppLocation, - IterableInAppDeleteSource, -} from '@iterable/react-native-sdk'; - -import IterableInAppMessage from '@iterable/react-native-sdk/js/IterableInAppMessage'; - -import { Login } from './Login' - -// Consts -import { iterableAPIKey, sendInAppCampaignId, skipInAppCampaignId, openDeepLinkCampaignId, openSafariCampaignId, customActionCampaignId } from './Config' - -const RNE2E = NativeModules.RNE2E - -interface State { - statusText?: string -} -export default class App extends React.Component { - constructor(props) { - super(props) - this.state = { statusText: "" } - this.initializeIterable() - } - - render() { - return ( - - - - - - -