Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roborazzi demo tests #303

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
303b648
POC roborazzi screenshot tests
jeprubio Aug 28, 2023
260a6ed
POC roborazzi set screenshot folder
jeprubio Sep 1, 2023
849960c
POC roborazzi using getScreenshotName() to get the screenshot file name
jeprubio Sep 4, 2023
595750e
POC roborazzi add compare_screenshots.yml
jeprubio Sep 4, 2023
53865e1
POC roborazzi updating failure report
jeprubio Sep 8, 2023
f97a966
Merge branch 'main' into poc/roborazzi
jeprubio Sep 8, 2023
9745034
POC roborazzi buttons test
jeprubio Sep 8, 2023
c050235
POC roborazzi update screenshots baseline
jeprubio Sep 8, 2023
4155351
POC roborazzi execute update_screenshot_baseline.yml on push
jeprubio Sep 8, 2023
db7ff60
Updated screenshots baseline
jeprubio Sep 8, 2023
8db018d
POC roborazzi update record screenshots baseline
jeprubio Sep 8, 2023
9734388
POC roborazzi runs on ubuntu-latest
jeprubio Sep 8, 2023
a84e7c4
Updated screenshots baseline
jeprubio Sep 8, 2023
0e92faa
POC roborazzi remove on push
jeprubio Sep 8, 2023
e1520b2
Merge remote-tracking branch 'origin/poc/roborazzi' into poc/roborazzi
jeprubio Sep 8, 2023
c0e890c
POC roborazzi upload to azure
jeprubio Sep 8, 2023
07ecb8f
POC roborazzi upload to azure if failure
jeprubio Sep 8, 2023
3e586c1
POC roborazzi updated upload to azure
jeprubio Sep 8, 2023
693f71c
POC roborazzi updated upload to azure
jeprubio Sep 8, 2023
434bb80
POC roborazzi force screenshots error
jeprubio Sep 8, 2023
99f2239
POC roborazzi add pngs of other directories
jeprubio Sep 8, 2023
f5114d3
POC roborazzi add pngs of other directories
jeprubio Sep 8, 2023
027f5bb
POC roborazzi revert brand names
jeprubio Sep 8, 2023
a13ee3a
POC roborazzi update baseline
jeprubio Sep 8, 2023
64ead38
POC roborazzi update baseline
jeprubio Sep 8, 2023
adffa31
POC roborazzi update baseline
jeprubio Sep 8, 2023
f04c8d3
POC roborazzi using Enclosed to run parametrized and not parametrized…
jeprubio Sep 11, 2023
026d865
POC roborazzi update screenshots
jeprubio Sep 11, 2023
3ad5a71
POC roborazzi update screenshots
jeprubio Sep 11, 2023
d6ed913
POC roborazzi update globs
jeprubio Sep 15, 2023
9573d41
POC roborazzi also upload artifact
jeprubio Sep 15, 2023
bc19b0c
POC roborazzi update job name
jeprubio Sep 15, 2023
b42a4af
POC roborazzi fix uppercase
jeprubio Sep 15, 2023
bc2df7b
POC roborazzi upload names
jeprubio Sep 15, 2023
5b73d35
POC roborazzi use pixel 5
jeprubio Sep 15, 2023
a363339
POC roborazzi update baseline on push
jeprubio Sep 15, 2023
84a264f
Updated screenshots baseline
jeprubio Sep 15, 2023
e1ab44c
POC roborazzi update device
jeprubio Sep 15, 2023
61bc591
POC roborazzi force error
jeprubio Sep 15, 2023
11ee4d8
POC roborazzi update device
jeprubio Sep 15, 2023
7e730f0
POC roborazzi force error
jeprubio Sep 15, 2023
07e60ae
POC roborazzi pixel 5 + 33% image size
jeprubio Sep 15, 2023
4d3342c
POC roborazzi add error on PasswordInput
jeprubio Sep 15, 2023
4d385b4
POC roborazzi change report image dimensions
jeprubio Sep 15, 2023
79b3ca2
POC roborazzi add image click
jeprubio Sep 15, 2023
349fcbc
POC roborazzi update compare_screenshots.yml AZURE_ACCOUNT_NAME
jeprubio Sep 18, 2023
e39ae82
POC roborazzi update setting GraphicsMode from build.gradle file
jeprubio Sep 18, 2023
aa0414e
Correct screenshots
pmartinbTEF Sep 22, 2023
aa97cc1
Modified UI element
pmartinbTEF Sep 22, 2023
d4132f2
Updated baseline
pmartinbTEF Sep 22, 2023
a7cfdfa
Updated baseline PART 2
pmartinbTEF Sep 22, 2023
f22d663
Updated screenshots baseline
pmartinbTEF Sep 22, 2023
6e287a3
Undo temp GH changes
pmartinbTEF Sep 22, 2023
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
114 changes: 114 additions & 0 deletions .github/workflows/compare_screenshots.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Compare Screenshots

on:
workflow_dispatch:
pull_request:

jobs:
CompareScreenshots:

runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v3

- name: Verify Screenshots (roborazzi)
run: 'bash ./gradlew verifyRoborazziDebug'

- id: generate-html
name: Generate Html Report
if: failure()
env:
BRANCH_NAME: companion_${{ github.event.workflow_run.head_branch }}
shell: bash
run: |
mkdir reports
touch reports/report.html
cp */screenshots/*_compare.png reports/
files=$(find . -type f -name "*_compare.png" | grep "reports/")
{
echo '<!doctype html>'
echo '<html>'
echo '<head>'
echo '<title>Screenshots failure report</title>'
echo '<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" rel="stylesheet">'
echo '<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">'
echo '<meta charset="UTF-8">'
echo '</head>'
echo '<style>'
echo 'body {'
echo 'display: flex;'
echo 'min-height: 100vh;'
echo 'flex-direction: column;'
echo '}'
echo 'main {'
echo 'flex: 1 0 auto;'
echo '}'
echo '</style>'
echo '<body>'
echo '<nav>'
echo '<div class="nav-wrapper indigo darken-3">'
echo '<a href="#" class="brand-logo left">Screenshots failure report</a>'
echo '<ul id="nav-mobile" class="right hide-on-med-and-down">'
echo '<li><a href="https://github.com/takahirom/roborazzi">Roborazzi</a></li>'
echo '</ul>'
echo '</div>'
echo '</nav>'
echo '<main class="container">'
echo '<div class="section">'
echo '<table class="highlight responsive-table">'
echo '<tr><th>File name</th><th>Comparison</th></tr>'
} >> reports/report.html

for file in $files; do
# Get the file name and insert newlines every 100 characters
fileName=$(basename "$file" | sed -r 's/(.{100})/\1<br>/g')
echo "<tr><td>$(basename "$file")</td>" >> reports/report.html
echo "<td><a href=\"$(basename "$file")\"><img src=\"$(basename "$file")\" width=\"100%\" height=\"100%\" /></a></td></tr>" >> reports/report.html
done
{
echo '</table>'
echo '</div>'
echo '</main>'
echo '<footer class="page-footer indigo darken-3">'
echo '<div></div>'
echo '</footer>'
echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>'
echo '</body></html>'
} >> reports/report.html

echo "Report: "
cat reports/report.html

- name: Generate screenshots tests reports tar.gz
if: failure()
run: |
tar cvzf mistica-screenshots-tests-report.tar.gz reports || echo "No screenshots tests reports found"
shell: bash

- name: Checkout Telefonica/github-actions repo
if: failure()
uses: actions/checkout@v3
with:
repository: Telefonica/github-actions
token: "${{ secrets.NOVUM_PRIVATE_REPOS }}"
path: .github/shared-actions

- name: Upload reports to azure
if: failure()
uses: ./.github/shared-actions/azure/upload-to-storage
with:
azure-account-name: ${{secrets.AZURE_ACCOUNT_NAME}}
azure-account-key: ${{secrets.AZURE_ACCOUNT_KEY}}
globs: |
mistica-screenshots-tests-report.tar.gz
generate-summary: true

- name: Upload reports to github
uses: actions/upload-artifact@v3
if: failure()
with:
name: failure-report
path: 'reports/*'
retention-days: 14
24 changes: 24 additions & 0 deletions .github/workflows/update_screenshot_baseline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: "Update screenshot baseline"
on:
workflow_dispatch:

jobs:
screenshots_baseline:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2

- name: Run Roborazzi Record
run: 'bash ./gradlew clean recordRoborazziDebug'

- name: Check Git status
run: 'git status'
shell: bash

- name: Commit and push screenshots baseline
id: commitAndPushScreenshotsBaseline
uses: EndBug/add-and-commit@v7
with:
message: 'Updated screenshots baseline'
add: './**/screenshots/*'
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ buildscript {
plugins {
id 'org.jetbrains.kotlin.android' version '1.5.21' apply false
id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' apply false
id "io.github.takahirom.roborazzi" version "1.4.0" apply false
}

allprojects {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Fri May 19 13:07:06 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
14 changes: 14 additions & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'maven-publish'
id 'io.github.takahirom.roborazzi'
}

android {
Expand Down Expand Up @@ -51,6 +52,15 @@ android {
sarifReport true
checkDependencies true
}

testOptions {
unitTests {
includeAndroidResources = true
all {
systemProperty 'robolectric.graphicsMode', 'NATIVE'
}
}
}
}

task sourceJar(type: Jar) {
Expand Down Expand Up @@ -88,6 +98,10 @@ dependencies {

testImplementation 'junit:junit:4.13.2'
testImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
testImplementation 'androidx.compose.ui:ui-test-manifest:1.0.5'
testImplementation 'org.robolectric:robolectric:4.10.3'
testImplementation 'io.github.takahirom.roborazzi:roborazzi:1.4.0'
testImplementation 'io.github.takahirom.roborazzi:roborazzi-compose:1.4.0'
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"

debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
Expand Down Expand Up @@ -175,7 +176,7 @@ private fun ButtonContent(
it.size.height.toDp()
}
},
text = text,
text = text.toUpperCase(),
color = textColor,
style = size.textStyle,
maxLines = 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package com.telefonica.mistica.compose.button

import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import com.github.takahirom.roborazzi.RobolectricDeviceQualifiers
import com.github.takahirom.roborazzi.captureRoboImage
import com.telefonica.mistica.compose.theme.MisticaTheme
import com.telefonica.mistica.compose.theme.brand.BlauBrand
import com.telefonica.mistica.compose.theme.brand.Brand
import com.telefonica.mistica.compose.theme.brand.MovistarBrand
import com.telefonica.mistica.compose.theme.brand.O2Brand
import com.telefonica.mistica.compose.theme.brand.TelefonicaBrand
import com.telefonica.mistica.compose.theme.brand.VivoBrand
import com.telefonica.mistica.testutils.ScreenshotUtils
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.experimental.runners.Enclosed
import org.junit.runner.RunWith
import org.robolectric.ParameterizedRobolectricTestRunner
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(Enclosed::class)
internal class ButtonKtTest {

@RunWith(ParameterizedRobolectricTestRunner::class)
@Config(qualifiers = RobolectricDeviceQualifiers.Pixel5)
internal class ButtonKtTestParametrized(private val brand: Brand) {
@get:Rule
val composeTestRule = createComposeRule()

@Test
fun `check the button screenshot`() = test {
`when Button`(brand)

`then screenshot is OK`(brand)
}

@Test
fun `check the button is clicked`() = test {
`given Button`()

`when the button is clicked`()

`then the onClickListener has been invoked`()
}

private fun TestScope.`given Button`() {
`when Button`()
}

private fun TestScope.`when Button`(brand: Brand = MovistarBrand) {
composeTestRule.setContent {
MisticaTheme(brand = brand) {
Button(
text = textValue,
onClickListener = onClickListener,
modifier = Modifier.padding(16.dp)
)
}
}
}

private fun TestScope.`when the button is clicked`() {
composeTestRule.onNodeWithText(textValue).performClick()
}

private fun `then screenshot is OK`(brand: Brand) {
composeTestRule.onRoot()
.captureRoboImage(ScreenshotUtils.getScreenshotName(brand))
}

private fun TestScope.`then the onClickListener has been invoked`() {
assertTrue(clicked)
}

private fun test(block: TestScope.() -> Unit) {
TestScope().block()
}

private class TestScope {
val textValue = "TEXTVALUE"
var clicked = false
val onClickListener: () -> Unit = { clicked = true }
}

companion object {
@JvmStatic
@ParameterizedRobolectricTestRunner.Parameters(name = "Input: {0}")
fun brands() = listOf(
arrayOf(MovistarBrand),
arrayOf(VivoBrand),
arrayOf(O2Brand),
arrayOf(BlauBrand),
arrayOf(TelefonicaBrand),
)
}
}

@RunWith(RobolectricTestRunner::class)
internal class ButtonKtTestNotParametrized {
@get:Rule
val composeTestRule = createComposeRule()

@Test
fun `check the button is clicked`() = test {
`given Button`()

`when the button is clicked`()

`then the onClickListener has been invoked`()
}

private fun TestScope.`given Button`() {
`when Button`()
}

private fun TestScope.`when Button`() {
composeTestRule.setContent {
MisticaTheme(brand = MovistarBrand) {
Button(
text = textValue,
onClickListener = onClickListener,
modifier = Modifier.padding(16.dp)
)
}
}
}

private fun TestScope.`when the button is clicked`() {
composeTestRule.onNodeWithText(textValue).performClick()
}

private fun TestScope.`then the onClickListener has been invoked`() {
assertTrue(clicked)
}

private fun test(block: TestScope.() -> Unit) {
TestScope().block()
}

private class TestScope {
val textValue = "TEXTVALUE"
var clicked = false
val onClickListener: () -> Unit = { clicked = true }
}
}
}
Loading