Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
1be050d
check for message
grablack Jun 27, 2024
1e1f3bf
update local.xml
grablack Jun 28, 2024
dbd7520
add more tests
grablack Jul 1, 2024
a85f84a
basic activity
grablack Jul 19, 2024
23a0a3b
repeatable functions
grablack Jul 24, 2024
06d359f
updates
grablack Jul 25, 2024
b269fbf
check modal condition
grablack Jul 25, 2024
604526a
rename functions
grablack Jul 26, 2024
e2e647f
seperate files
grablack Jul 31, 2024
637a8de
github action espresso
grablack Aug 7, 2024
cfa3416
use reponse to execute test
grablack Aug 7, 2024
8ee7a0b
fix error
grablack Aug 7, 2024
ae002f4
error logging
grablack Aug 7, 2024
07f5f4d
echo urls
grablack Aug 8, 2024
11a38fa
make test apk
grablack Aug 8, 2024
0df6be1
1 build step
grablack Aug 8, 2024
f7ebeec
try splitting
grablack Aug 8, 2024
b28138f
provide path
grablack Aug 9, 2024
f8ee839
update device
grablack Aug 9, 2024
c511f70
use demo tests
grablack Aug 12, 2024
200f2d8
change apk
grablack Aug 12, 2024
762878e
make build a single line
grablack Aug 12, 2024
a309fca
use debug
grablack Aug 12, 2024
7ccb2e8
fix path
grablack Aug 12, 2024
950b627
changes to timing
grablack Aug 12, 2024
e4c7e1f
try longer wait
grablack Aug 12, 2024
1e72734
fun to wait
grablack Aug 13, 2024
88ed428
restore showwebview before merge
grablack Aug 13, 2024
9f1dc00
Merge branch 'develop' into feature-testing-tool
grablack Aug 13, 2024
29b2937
use other new wait
grablack Aug 13, 2024
f6de342
seperate functions
grablack Aug 13, 2024
7e6f3be
set environment
grablack Aug 27, 2024
dbad550
moved
grablack Aug 27, 2024
eff4d19
comments for modal clicks
grablack Aug 28, 2024
12687ea
test jetpack modal
grablack Aug 28, 2024
e4e06e6
wait longer
grablack Aug 28, 2024
627683e
exclude new tests
grablack Sep 3, 2024
b5444da
change exclude
grablack Sep 3, 2024
f90e46a
update exclude
grablack Sep 5, 2024
5f5e36d
add exclude to gradle
grablack Sep 5, 2024
d615737
move
grablack Sep 5, 2024
25cb1f5
remove gradle change
grablack Sep 5, 2024
30f9e35
path to all
grablack Sep 5, 2024
ddfa874
remove espresso test
grablack Sep 6, 2024
8dd405f
comment out failing tests
grablack Sep 6, 2024
90b5373
add back testImplementation
grablack Sep 9, 2024
c1cd27e
exclude
grablack Sep 13, 2024
34b357a
Merge branch 'develop' into feature-testing-tool
grablack Jul 7, 2025
6fead6a
fix: update cache action to v3 for improved performance
grablack Jul 7, 2025
31dbd9a
fix: correct Sonatype Nexus username and password secrets in release …
grablack Jul 7, 2025
3d9068c
feat: add Sonatype snapshot repository configuration for publishing
grablack Jul 7, 2025
0b03dc6
fix: add conditional logic for snapshot and release publishing in act…
grablack Jul 7, 2025
330e52c
fix: exclude duplicate sources in androidSourcesJar task
grablack Jul 7, 2025
4e346de
fix: update Sonatype snapshot repository URL for consistency
grablack Jul 7, 2025
4282199
fix: update snapshot publishing logic and apply nexus plugin conditio…
grablack Jul 7, 2025
e3cb551
fix: streamline publishing process by removing nexus plugin and using…
grablack Jul 7, 2025
92e227f
fix: update repository configuration to use Sonatype OSS for publishing
grablack Jul 8, 2025
c7933b3
fix: enhance publishing logic to handle snapshots and releases separa…
grablack Jul 8, 2025
189e992
fix: update publishing logic to handle snapshots and releases separately
grablack Jul 8, 2025
9fc79bc
fix: update authentication method to use token-based approach for Son…
grablack Jul 8, 2025
9d63156
fix: update authentication method to use username/password for Sonaty…
grablack Jul 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/actions/publish_all_modules/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,18 @@ runs:
using: "composite"
steps:
- run: |
./gradlew --stacktrace clean publishToSonatype closeAndReleaseSonatypeStagingRepository
if [[ $USE_SNAPSHOT == "true" ]]; then
# For snapshots, only publish to the sonatypeSnapshots repository
./gradlew --stacktrace clean publishAllPublicationsToSonatypeSnapshotsRepository
else
# For releases, publish to the sonatypeReleases repository
./gradlew --stacktrace clean publishAllPublicationsToSonatypeReleasesRepository
fi
shell: bash
env:
SONATYPE_NEXUS_USERNAME: ${{ inputs.sonatype_user }}
SONATYPE_NEXUS_PASSWORD: ${{ inputs.sonatype_password }}
SIGNING_KEY_ID: ${{ inputs.signing_key_id }}
SIGNING_KEY_PASSWORD: ${{ inputs.signing_key_password }}
SIGNING_KEY_FILE: ${{ inputs.signing_key_file }}
USE_SNAPSHOT: ${{ env.USE_SNAPSHOT }}
92 changes: 92 additions & 0 deletions .github/workflows/espresso-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Espresso Test

on:
push:
branches:
- feature-testing-tool
pull_request:
branches:
- feature-testing-tool

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'

- name: Cache Gradle packages
uses: actions/cache@v3
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Add Client ID
env:
CLIENT_ID: ${{ secrets.CLIENT_ID }}
run: ./gradlew updateLocalsXmlFile

- name: Build APKs
run: |
./gradlew :demo:assembleDebug :demo:assembleAndroidTest

- name: Upload App to BrowserStack
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
run: |
APP_APK_PATH=./demo/build/outputs/apk/debug/demo-debug.apk
TEST_APK_PATH=./demo/build/outputs/apk/androidTest/debug/demo-debug-androidTest.apk

echo "App APK path: $APP_APK_PATH"
echo "Test APK path: $TEST_APK_PATH"

if [[ -z "$APP_APK_PATH" || -z "$TEST_APK_PATH" ]]; then
echo "Error: APK file not found."
exit 1
fi

# Upload app APK and capture response
APP_UPLOAD_RESPONSE=$(curl -s -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/espresso/v2/app" \
-F "file=@$APP_APK_PATH")

echo "App upload response: $APP_UPLOAD_RESPONSE"

APP_URL=$(echo $APP_UPLOAD_RESPONSE | jq -r '.app_url')

if [[ -z "$APP_URL" ]]; then
echo "Error: App URL not found in response."
exit 1
fi

# Upload test suite APK and capture response
TEST_SUITE_UPLOAD_RESPONSE=$(curl -s -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/espresso/v2/test-suite" \
-F "file=@$TEST_APK_PATH")

echo "Test suite upload response: $TEST_SUITE_UPLOAD_RESPONSE"

TEST_SUITE_URL=$(echo $TEST_SUITE_UPLOAD_RESPONSE | jq -r '.test_suite_url')

if [[ -z "$TEST_SUITE_URL" ]]; then
echo "Error: Test suite URL not found in response."
exit 1
fi

# Use the app_url and test_suite_url in another cURL request
FINAL_RESPONSE=$(curl -s -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/espresso/v2/build" \
-d "{\"app\": \"$APP_URL\", \"testSuite\": \"$TEST_SUITE_URL\", \"devices\": [\"Samsung Galaxy S23-13.0\"], \"project\": \"Paypal_Messages_Android\"}" \
-H "Content-Type: application/json")

echo "Final response: $FINAL_RESPONSE"
4 changes: 2 additions & 2 deletions .github/workflows/release-snapshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ jobs:
- name: Publish to Maven
uses: ./.github/actions/publish_all_modules
with:
sonatype_user: ${{ secrets.SONATYPE_SDKS_NEXUS_USERNAME }}
sonatype_password: ${{ secrets.SONATYPE_SDKS_NEXUS_PASSWORD }}
sonatype_user: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
sonatype_password: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
signing_key_id: ${{ secrets.SIGNING_KEY_ID }}
signing_key_password: ${{ secrets.SIGNING_KEY_PASSWORD }}
signing_key_file: ${{ env.SIGNING_KEY_FILE_PATH }}
68 changes: 51 additions & 17 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.jmailen.gradle.kotlinter.tasks.FormatTask

buildscript {
ext.modules = [
"sdkVersionName" : "1.0.4",
"sdkVersionName" : "1.0.4-SNAPSHOT",
"androidMinSdkVersion": 23,
"androidTargetVersion": 34
]
Expand All @@ -15,7 +15,6 @@ plugins {
id 'com.android.library' version '8.0.2' apply false
id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
id 'org.jmailen.kotlinter' version '3.16.0'
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
id 'signing'
}

Expand All @@ -35,20 +34,8 @@ tasks.register('ktFormat', FormatTask) {

version modules.sdkVersionName

nexusPublishing {
repositories {
sonatype {
username = System.getenv('SONATYPE_NEXUS_USERNAME') ?: ''
password = System.getenv('SONATYPE_NEXUS_PASSWORD') ?: ''
repositoryDescription = 'Paypal Messages'
packageGroup = 'com.paypal'
}
}
transitionCheckOptions {
// give nexus sonatype more time to close the staging repository
delayBetween.set(Duration.ofSeconds(20))
}
}
// Completely disable nexus-publish-plugin for all builds
// We'll handle publishing differently for snapshots vs releases

subprojects {
group = "com.paypal.messages"
Expand All @@ -61,9 +48,56 @@ tasks.register('changeReleaseVersion') {
def topLevelGradleFileText = topLevelGradleFile.getText('UTF-8')
def useSnapshot = System.getenv('USE_SNAPSHOT')
def snapshotParam = useSnapshot == "true" || useSnapshot == true ? "-SNAPSHOT" : ""

def updatedScript =
topLevelGradleFileText.replaceFirst(/("sdkVersionName"\s*: )".*",/, '$1"' + versionParam + snapshotParam + '",')
topLevelGradleFile.write(updatedScript, 'UTF-8')
}
}



task updateLocalsXmlFile(type: ReplaceStringTask) {
replacementString = System.getenv('CLIENT_ID') ?: "REPLACE_WITH_CLIENT_ID_IN_LOCALS_XML"
}

class ReplaceStringTask extends DefaultTask {
@Input
String replacementString

@TaskAction
void updateLocalsXml() {
def filePath = "demo/src/main/res/values/locals.xml"
def file = project.file(filePath) // Use project's file method

// Read the current contents of locals.xml
def currentContent = file.text

// Perform replacement
def modifiedContent = currentContent.replaceAll("REPLACE_WITH_CLIENT_ID_IN_LOCALS_XML", replacementString)

// Write the modified content back to locals.xml
file.text = modifiedContent
}
}

// Add a specific task for publishing snapshots
task publishSnapshotToMavenCentral {
group = 'publishing'
description = 'Publishes all modules as SNAPSHOT versions to Maven Central'

doFirst {
println "Preparing to publish snapshot version: ${version}"

// Set the USE_SNAPSHOT environment variable if not already set
if (System.getenv('USE_SNAPSHOT') == null) {
println "Setting USE_SNAPSHOT=true for this build"
ant.setProperty(name: "env.USE_SNAPSHOT", value: "true")
}
}

// Make this task depend on the publish task of each subproject
gradle.projectsEvaluated {
dependsOn subprojects.collect { it.tasks.matching { task -> task.name == 'publish' } }
}
}
14 changes: 13 additions & 1 deletion demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ android {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
sourceSets {
androidTest {
java {
// Exclude tests in specific directories
exclude '**/src/androidTest/**'
}
}
}

}

dependencies {
Expand All @@ -74,9 +83,12 @@ dependencies {
implementation project(':library')
implementation 'com.google.android.material:material:1.10.0'

testImplementation 'junit:junit:4.13.2'
implementation 'junit:junit:4.13.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.4.0'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation platform('androidx.compose:compose-bom:2023.09.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.5.1'
debugImplementation 'androidx.compose.ui:ui-tooling:1.5.1'
Expand Down
58 changes: 58 additions & 0 deletions demo/src/androidTest/java/com/paypal/messagesdemo/InlineXmlTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.paypal.messagesdemo

import android.view.Gravity
import androidx.core.content.ContextCompat
import androidx.test.espresso.Espresso
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
import com.paypal.messages.R
import com.paypal.messages.config.message.style.PayPalMessageColor
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4ClassRunner::class)
public class InlineXmlTest {
var expectedColor: Int? = null

@get:Rule
val activityScenarioRule = ActivityScenarioRule(BasicXmlActivity::class.java)

@Test
fun testGenericMessage() {
waitForApp(500)

// Check if SecondActivity is displayed by verifying a TextView in SecondActivity
checkMessage("%paypal_logo% Buy now, pay later. Learn more")
onView(withId(R.id.content)).check(matches(GravityMatcher.withGravity(Gravity.LEFT)))

// Get the actual color value from the resource ID
activityScenarioRule.scenario.onActivity { activity ->
expectedColor = ContextCompat.getColor(activity, PayPalMessageColor.BLACK.colorResId)
}

// Use the custom matcher to check the text color of the TextView
onView(withId(R.id.content))
.check(matches(ColorMatcher.withTextColor(expectedColor!!)))
}

@Test
fun testGenericModalCloseWithBackButton() {
waitForApp(500)
checkMessage("%paypal_logo% Buy now, pay later. Learn more")

clickMessage()
waitForApp(1000)
modalContent("Get more info")

Espresso.pressBack()
waitForApp(500)
checkMessage("%paypal_logo% Buy now, pay later. Learn more")
clickMessage()
waitForApp(1000)
modalContent("Get more info")
}
}
55 changes: 55 additions & 0 deletions demo/src/androidTest/java/com/paypal/messagesdemo/JetPackTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.paypal.messagesdemo

// @RunWith(AndroidJUnit4ClassRunner::class)
// public class JetPackTest {

Choose a reason for hiding this comment

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

Hi @grablack, I noticed that all of the code in JetPackTest.kt is currently commented out.

Is this intentional? If it's meant for future work, it might be cleaner to:

  • Push an empty test class with a @Test method marked @Ignore and a TODO note explaining what will be added in the next PR, or
  • Remove this file for now and add it back once it's ready.

This keeps the repo clean and avoids confusion for others pulling the branch 🙂

Let me know if I can help clarify!

// var expectedColor: Int? = null
//
// @Rule
// @JvmField
// val activityScenarioRule = ActivityScenarioRule<JetpackActivity>(
// Intent(ApplicationProvider.getApplicationContext(), JetpackActivity::class.java).apply {
// putExtra("TEST_ENV", "LIVE")
// },
// )
//
// fun submit() {
// onView(withId(Demo.id.submit)).perform(scrollTo())
// onView(withId(Demo.id.submit)).perform(click())
// waitForApp(500)
// }
//
// @Test
// fun testGenericMessage() {
// // Perform a delay
// waitForApp(1000)
//
// // Check if SecondActivity is displayed by verifying a TextView in SecondActivity
// checkMessage("%paypal_logo% Buy now, pay later. Learn more")
// onView(withId(R.id.content)).check(matches(GravityMatcher.withGravity(Gravity.LEFT)))
//
// // Get the actual color value from the resource ID
// activityScenarioRule.scenario.onActivity { activity ->
// expectedColor = ContextCompat.getColor(activity, PayPalMessageColor.BLACK.colorResId)
// }
//
// // Use the custom matcher to check the text color of the TextView
// onView(withId(R.id.content))
// .check(matches(ColorMatcher.withTextColor(expectedColor!!)))
// }
//
// @Test
// fun testGenericMessageAndModal() {
// waitForApp(2000)
//
// // Check if SecondActivity is displayed by verifying a TextView in SecondActivity
// checkMessage("%paypal_logo% Buy now, pay later. Learn more")
// clickMessage()
//
// onView(withId(R.id.ModalWebView)).check(
// matches(ViewMatchers.isDisplayed()),
// )
//
// modalContent("Pay Later options")
// waitForApp(2000)
// }
// }
Loading
Loading