Skip to content

Commit

Permalink
feat: screenshot tests [WPB-983] (#3538)
Browse files Browse the repository at this point in the history
  • Loading branch information
Garzas authored Oct 22, 2024
1 parent bc37f84 commit e8ad3bf
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
app/src/internalDebug/screenshotTests/** filter=lfs diff=lfs merge=lfs -text
107 changes: 107 additions & 0 deletions .github/workflows/generate-screenshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: "Generate and Verify Screenshot Tests"

on:
workflow_dispatch:

permissions:
contents: write
pull-requests: write

env:
GITHUB_TOKEN: ${{ secrets.ANDROID_BOB_GH_TOKEN }}

jobs:
generate-screenshots:
runs-on: buildjet-8vcpu-ubuntu-2204

if: github.ref == 'refs/heads/develop'

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0

- name: Set up JDK 17
uses: buildjet/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v4

- name: Install Git LFS
run: |
git lfs install
git lfs fetch --all
git lfs checkout
- name: Merge Develop into screenshot-tests
run: |
git checkout screenshot-tests
git merge origin/develop --no-edit
git push origin screenshot-tests
- name: Verify Screenshot Tests
run: ./gradlew validateInternalDebugScreenshotTest
continue-on-error: true # Ensure this task doesn't fail the build

- name: Copy test results to simplified directory
run: |
mkdir -p screenshotTest
cp -r app/build/reports/screenshotTest/preview/debug/internal/* screenshotTest/
- name: Zip Screenshot Test Reports
run: |
zip -r screenshot-test-report.zip screenshotTest/
- name: Upload Screenshot Test Report
id: upload_artifact
uses: actions/upload-artifact@v4
with:
name: screenshot-test-report
path: screenshot-test-report.zip

- name: Clear changes before generating new screenshots
run: |
git reset --hard HEAD
git clean -fd
- name: Update Screenshot Reference Images
run: ./gradlew updateInternalDebugScreenshotTest

- name: Setup GitHub Actions Bot for Git
uses: fregante/setup-git-user@v2

- name: Create New Branch
id: create_branch
run: |
BRANCH_NAME="test/screenshots-update-$(date +%Y%m%d%H%M%S)"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
git checkout -b "$BRANCH_NAME"
git add .
git commit -m "test: update screenshot tests"
git push origin "$BRANCH_NAME"
- name: Create PR
env:
PR_TITLE: "test: Update Screenshot Tests [WPB-983]"
PR_BODY: "Automated PR to update screenshot tests with the latest reference images."
PR_BRANCH: ${{ env.BRANCH_NAME }}
run: |
gh pr create --title "$PR_TITLE" --body "$PR_BODY" --base screenshot-tests --head "$PR_BRANCH" --label "screenshot-test"
PR_NUMBER=$(gh pr view --json number -q .number)
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
- name: Add comment with test report link
run: |
ARTIFACT_ID=${{ steps.upload_artifact.outputs.artifact-id }}
gh issue comment "${{ env.PR_NUMBER }}" --body "Screenshot test results have been generated. [Download the report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/artifacts/$ARTIFACT_ID)"
- name: Cleanup Gradle Cache
run: |
rm -f ~/.gradle/caches/modules-2/modules-2.lock
rm -f ~/.gradle/caches/modules-2/gc.properties
11 changes: 11 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ plugins {
id(ScriptPlugins.testing)
id(libs.plugins.wire.kover.get().pluginId)
id(libs.plugins.wire.versionizer.get().pluginId)
alias(libs.plugins.screenshot)
}

repositories {
Expand Down Expand Up @@ -82,6 +83,13 @@ android {
jniLibs.pickFirsts.add("**/libsodium.so")
}
android.buildFeatures.buildConfig = true
experimentalProperties["android.experimental.enableScreenshotTest"] = true

testOptions {
screenshotTests {
imageDifferenceThreshold = 0.0001f // 0.01%
}
}

sourceSets {
allFlavors.forEach { flavor ->
Expand Down Expand Up @@ -240,6 +248,9 @@ dependencies {
implementation(libs.aboutLibraries.ui)
implementation(libs.compose.qr.code)

// screenshot testing
screenshotTestImplementation(libs.compose.ui.tooling)

// Unit/Android tests dependencies
testImplementation(libs.androidx.test.archCore)
testImplementation(libs.junit4) // Maybe migrate completely to Junit 5?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

@file:Suppress("TooManyFunctions")

package com.wire.android.ui.home.conversations.messages.item
package com.wire.android.kotlin.ui.home.conversations.messages.item

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
Expand All @@ -27,6 +27,9 @@ import com.wire.android.media.audiomessage.AudioMediaPlayingState
import com.wire.android.media.audiomessage.AudioState
import com.wire.android.model.Clickable
import com.wire.android.ui.home.conversations.info.ConversationDetailsData
import com.wire.android.ui.home.conversations.messages.item.MessageClickActions
import com.wire.android.ui.home.conversations.messages.item.RegularMessageItem
import com.wire.android.ui.home.conversations.messages.item.SystemMessageItem
import com.wire.android.ui.home.conversations.mock.mockAssetAudioMessage
import com.wire.android.ui.home.conversations.mock.mockAssetMessage
import com.wire.android.ui.home.conversations.mock.mockFooter
Expand Down Expand Up @@ -136,7 +139,8 @@ fun PreviewDeletedMessage() {
it.copy(
header = it.header.copy(
messageStatus = MessageStatus(
flowStatus = MessageFlowStatus.Delivered, isDeleted = true,
flowStatus = MessageFlowStatus.Delivered,
isDeleted = true,
expirationStatus = ExpirationStatus.NotExpirable
)
)
Expand Down Expand Up @@ -336,15 +340,15 @@ fun PreviewMessageWithSystemMessage() {
SystemMessageItem(
mockMessageWithKnock.copy(
messageContent = UIMessageContent.SystemMessage.MissedCall.YouCalled(
UIText.DynamicString("You")
UIText.DynamicString("ME")
)
)
)
SystemMessageItem(
mockMessageWithKnock.copy(
messageContent = UIMessageContent.SystemMessage.MemberAdded(
UIText.DynamicString("You"),
listOf(UIText.DynamicString("Adam Smith"))
UIText.DynamicString("ME"),
listOf(UIText.DynamicString("John Smith"))
)
)
)
Expand Down Expand Up @@ -407,7 +411,7 @@ fun PreviewAggregatedMessagesWithErrorMessage() {
)
),
conversationDetailsData = ConversationDetailsData.None(null),
showAuthor = false,
showAuthor = true,
audioState = null,
clickActions = MessageClickActions.Content(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
*/
@file:Suppress("TooManyFunctions")

package com.wire.android.ui.home.conversations.messages.item
package com.wire.android.kotlin.ui.home.conversations.messages.item

import androidx.compose.runtime.Composable
import com.wire.android.ui.home.conversations.messages.item.SystemMessageItem
import com.wire.android.ui.home.conversations.mock.mockMessageWithKnock
import com.wire.android.ui.home.conversations.mock.mockUsersUITexts
import com.wire.android.ui.home.conversations.model.UIMessageContent
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ kotlin.code.style=official
# Support KMP Gradle Composite Builds - See https://youtrack.jetbrains.com/issue/KT-52172/
kotlin.mpp.import.enableKgpDependencyResolution=true
org.gradle.logging.level=QUIET
android.experimental.enableScreenshotTest=true
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ compose-compiler = "1.5.13"
compose-constraint = "1.0.1"
compose-navigation = "2.7.7" # adjusted to work with compose-destinations "1.9.54"
compose-destinations = "1.10.2"
screenshot = "0.0.1-alpha07"

# Hilt
hilt = "2.51.1"
Expand Down Expand Up @@ -115,6 +116,7 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
aboutLibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "aboutLibraries" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
screenshot = { id = "com.android.compose.screenshot", version.ref = "screenshot"}

# Home-made convention plugins defined in build-logic
wire-android-application = { id = "com.wire.android.application" }
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pluginManagement {
includeBuild("build-logic")
repositories {
mavenCentral()
google()
}
}

Expand Down

0 comments on commit e8ad3bf

Please sign in to comment.