Skip to content

Commit

Permalink
Merge pull request #134 from superwall/develop
Browse files Browse the repository at this point in the history
1.2.0
  • Loading branch information
ianrumac authored Jul 12, 2024
2 parents 43ac4be + f26fcc5 commit 5305202
Show file tree
Hide file tree
Showing 171 changed files with 3,940 additions and 2,595 deletions.
11 changes: 11 additions & 0 deletions .github/firebase-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
android-pixel-7:
type: instrumentation
use-orchestrator: true
app: app/build/outputs/apk/debug/app-debug.apk
test: app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
directories-to-pull: /sdcard/Download/
device:
- model: panther
version: 33
locale: 'en'
orientation: portrait
10 changes: 10 additions & 0 deletions .github/workflows/build+test+deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ jobs:
- name: Build gradle project
run: ./gradlew build

- name: Build test project
run: ./gradlew :app:assembleAndroidTest -DtestBuildType=debug

- name: Run tests on Firebase Test Lab
uses: asadmansr/Firebase-Test-Lab-Action@v1.0
with:
arg-spec: '.github/firebase-tests.yml:android-pixel-7'
env:
SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }}

# See what version we're on
# Writes to superwall/build/version.json with the version set
# in the superwall build.gradle
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/build+test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,14 @@ jobs:
# Run Build & Test the Project
- name: Build gradle project
run: ./gradlew build

- name: Build test project
run: ./gradlew :app:assembleAndroidTest -DtestBuildType=debug

- name: Run tests on Firebase Test Lab
uses: asadmansr/Firebase-Test-Lab-Action@v1.0
with:
arg-spec: '.github/firebase-tests.yml:android-pixel-7'
env:
SERVICE_ACCOUNT: ${{ secrets.SERVICE_ACCOUNT }}

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
private_key.pepk
upload-keystore.jks
.env
**/google-services.json
57 changes: 57 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,63 @@

The changelog for `Superwall`. Also see the [releases](https://github.com/superwall/Superwall-Android/releases) on GitHub.

## 1.2.0

### Enhancements
- Adds DSL methods for configuring the SDK. You can now use a configuration block:
```kotlin
fun Application.configureSuperwall(
apiKey: String,
configure: SuperwallBuilder.() -> Unit,
)
```

This allows you to configure the SDK in a more idiomatic way:
```kotlin
configureSuperwall(CONSTANT_API_KEY){
options {
logging {
level = LogLevel.debug
}
paywalls {
shouldPreload = false
}
}
}
```

### Deprecations

This release includes multiple deprecations that will be removed in upcoming versions.
Most are internal and will not affect the public API, those that will are marked as such and a simple migration
path is provided. The notable ones in the public API are as follows:

- Deprecated `DebugViewControllerActivity` in favor of `DebugViewActivity`
- Deprecated `PaywallViewController` in favor of `PaywallView`
- Deprecated belonging methods:
- `viewWillAppear` in favor of `beforeViewCreated`
- `viewDidAppear` in favor of `onViewCreated`
- `viewWillDisappear` in favor of `beforeOnDestroy`
- `viewDidDisappear` in favor of `destroyed`
- `presentAlert` in favor of `showAlert`
- Deprecated `PaywallViewControllerDelegate` in favor of `PaywallViewCallback`
- Deprecated belonging methods:
- `didFinish` in favor of `onFinished`
- Deprecated `PaywallViewControllerEventDelegate` in favor of `PaywallViewEventCallback`
- Users might also note deprecation of `PaywallWebEvent.OpenedUrlInSafari` in favor of `PaywallWebEvent.OpenedUrlInChrome`
- `didFinish` in favor of `onFinished`

- In `Superwall`, the following methods were deprecated:
- `Superwall.paywallViewController` in favor of `Superwall.paywallView`
- `Superwall.eventDidOccur` argument `paywallViewController` in favor of `paywallView`
- `Superwall.dismiss` in favor of `Superwall.presentPaywallView
- `Superwall.presentPaywallViewController` in favor of `Superwall.presentPaywallView`
- Deprecated `Paywallmanager.getPaywallViewController` in favor of `PaywallManager.getPaywallView`
- Deprecated `DebugManager.viewController` in favor of `DebugManager.view`
- Deprecated `DebugViewController` in favor of `DebugView`
- Deprecated `LogScope.debugViewController` in favor of `LogScope.debugView`
- Deprecated `PaywallPresentationRequestStatus.NoPaywallViewController` in favor of `NoPaywallView`

## 1.1.9

### Deprecations
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The preferred installation method is with [Gradle](https://superwall.com/docs/in
android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar"
android:configChanges="orientation|screenSize|keyboardHidden">
</activity>
<activity android:name="com.superwall.sdk.debug.DebugViewControllerActivity" />
<activity android:name="com.superwall.sdk.debug.DebugViewActivity" />
<activity android:name="com.superwall.sdk.debug.localizations.SWLocalizationActivity" />
<activity android:name="com.superwall.sdk.debug.SWConsoleActivity" />
```
Expand Down
16 changes: 15 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
alias(libs.plugins.serialization)
alias(libs.plugins.dropshot)
}

android {
Expand All @@ -17,6 +18,14 @@ android {

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
testInstrumentationRunnerArguments["clearPackageData"] = "true"
testInstrumentationRunnerArguments["no-isolated-storage"] = "1"
}

testOptions {
execution = "ANDROIDX_TEST_ORCHESTRATOR"
animationsDisabled = true
resultsDir
}

buildTypes {
Expand All @@ -35,6 +44,7 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}

buildFeatures {
compose = true
}
Expand Down Expand Up @@ -78,13 +88,17 @@ dependencies {
androidTestImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.test.ext.junit)
androidTestImplementation(libs.espresso.core)
androidTestImplementation(libs.test.core)
androidTestImplementation(libs.test.runner)
androidTestImplementation(libs.test.rules)
androidTestImplementation(platform(libs.compose.bom))
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.leakcanary.android)
androidTestImplementation(libs.uiautomator)
androidTestImplementation(libs.test.runner)
androidTestUtil(libs.orchestrator)

// Debug
debugImplementation(libs.leakcanary.android)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
}
Binary file removed app/screenshots/debug/unknown_test0.png
Binary file not shown.
8 changes: 8 additions & 0 deletions app/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="com.superwall.superapp.uid">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<application android:requestLegacyExternalStorage="true" />
</manifest>
28 changes: 28 additions & 0 deletions app/src/androidTest/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Superwall integration & screenshot tests

This module contains the Superwall integration tests and screenshot tests, using the [Dropshot](https://github.com/dropbox/dropshots) library
for screenshot testing. The tests need to run on an Android device, emulator or a device lab (such as Firebase Test Lab).
Note: currently screenshots are recorded only for Pixel 7, API 33. Devices with different resolutions might fail.

### Running the tests

To run the tests, just run `./gradlew :app:connectedCheck` from the root of the project.
This will run the integration tests on your adb connected device or emulator.

### Viewing tests results

The tests results will be saved under `app/build/reports/androidTests/connected` folder in this directory.
If there are failing tests, the screenshots will be saved under `app/build/outputs/androidTest-results/connected/debug` folder.

### Recording the screenshots

To record the screenshots, run `./gradlew :app:connectedCheck -Pdropshots.record` from the root of the project.
This will record new screenshots on your current device.

### Viewing the recorded screenshots

To recorded screenshots are saved under `screenshots` folder in this directory.




This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
@file:Suppress("ktlint:standard:no-empty-file")

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.dropbox.dropshots.Dropshots
import com.dropbox.dropshots.ThresholdValidator
import com.example.superapp.utils.CustomComparator
import com.example.superapp.utils.awaitUntilShimmerDisappears
import com.example.superapp.utils.awaitUntilWebviewAppears
import com.example.superapp.utils.delayFor
import com.example.superapp.utils.screenshotFlow
import com.example.superapp.utils.waitFor
import com.superwall.sdk.Superwall
import com.superwall.sdk.analytics.superwall.SuperwallEvent
import com.superwall.superapp.test.UITestHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

@RunWith(AndroidJUnit4::class)
class FlowScreenshotTestExecutor {
@get:Rule
val dropshots =
Dropshots(
resultValidator = ThresholdValidator(0.01f),
imageComparator = CustomComparator(),
)

val mainScope = CoroutineScope(Dispatchers.Main)

@Test
fun test_paywall_reappers_with_video() =
with(dropshots) {
screenshotFlow(UITestHandler.test4Info) {
step("first_paywall") {
it.waitFor { it is SuperwallEvent.PaywallWebviewLoadComplete }
awaitUntilShimmerDisappears()
awaitUntilWebviewAppears()
delayFor(500.milliseconds)
}
step("second_paywall") {
awaitUntilWebviewAppears()
delayFor(1.seconds)
}
}
}

@Test
fun test_paywall_presents_regardless_of_subscription() =
with(dropshots) {
screenshotFlow(UITestHandler.test9Info) {
step("") {
it.waitFor { it is SuperwallEvent.PaywallOpen }
awaitUntilShimmerDisappears()
awaitUntilWebviewAppears()
delayFor(500.milliseconds)
// We scroll a bit to display the button
mainScope
.async {
Superwall.instance.paywallView
?.webView
?.scrollBy(0, 300) ?: kotlin.run {
throw IllegalStateException("No viewcontroller found")
}
}.await()
// We delay a bit to ensure the button is visible
delayFor(100.milliseconds)
// We scroll back to the top
mainScope
.async {
Superwall.instance.paywallView
?.webView
?.scrollTo(0, 0) ?: kotlin.run {
throw IllegalStateException("No viewcontroller found")
}
}.await()
// We delay a bit to ensure scroll has finished
delayFor(1.seconds)
}
}
}

@Test
fun test_paywall_reappears_after_dismissing() =
with(dropshots) {
screenshotFlow(UITestHandler.test11Info) {
step {
it.waitFor { it is SuperwallEvent.PaywallWebviewLoadComplete }
awaitUntilShimmerDisappears() || awaitUntilWebviewAppears()
delayFor(1.seconds)
}
step {
it.waitFor { it is SuperwallEvent.PaywallOpen }
awaitUntilWebviewAppears()
delayFor(1.seconds)
}
step {
it.waitFor { it is SuperwallEvent.PaywallOpen }
awaitUntilWebviewAppears()
delayFor(1.seconds)
}
}
}

@Test
fun test_paywall_calls_reset_after_present() =
with(dropshots) {
screenshotFlow(UITestHandler.test34Info) {
step("") {
it.waitFor { it is SuperwallEvent.PaywallWebviewLoadComplete }
awaitUntilShimmerDisappears()
awaitUntilWebviewAppears()
}
step {
it.waitFor { it is SuperwallEvent.Reset }
delayFor(100.milliseconds)
}
}
}

@Test
fun test_paywall_presents_then_dismisses_without_reappearing() =
with(dropshots) {
screenshotFlow(UITestHandler.test14Info) {
step {
it.waitFor { it is SuperwallEvent.PaywallWebviewLoadComplete }
awaitUntilShimmerDisappears()
awaitUntilWebviewAppears()
delayFor(100.milliseconds)
mainScope
.async {
// We scroll a bit to display the button
Superwall.instance.paywallView
?.webView
?.apply {
// Disable the scrollbar for the test
// so its not visible in screenshots
isVerticalScrollBarEnabled = false
scrollTo(0, 300)
}
}.await()
// We delay a bit to ensure the button is visible
delayFor(100.milliseconds)
// We scroll back to the top
mainScope
.async {
Superwall.instance.paywallView
?.webView
?.apply {
scrollTo(0, 0)
}
}.await()
// We delay a bit to ensure scroll has finished
delayFor(500.milliseconds)
}

step {
delayFor(10.seconds)
}
}
}
}
Loading

0 comments on commit 5305202

Please sign in to comment.