diff --git a/docs/screenshot_testing.md b/docs/screenshot_testing.md new file mode 100644 index 0000000000..d892948913 --- /dev/null +++ b/docs/screenshot_testing.md @@ -0,0 +1,72 @@ +# Screenshot testing + + + +* [Overview](#overview) +* [Setup](#setup) +* [Recording](#recording) +* [Verifying](#verifying) +* [Contributing](#contributing) +* [Example](#example) + + + +## Overview + +- Screenshot tests are tests which record the content of a rendered screen and verify subsequent runs to check if the screen renders differently. +- Element uses [Paparazzi](https://github.com/cashapp/paparazzi) to render, record and verify android layouts. +- The screenshot verification occurs on every pull request as part of the `tests.yml` workflow. + +## Setup + +- Install Git LFS through your package manager of choice (`brew install git-lfs` | `yay -S git-lfs`). +- Install the Git LFS hooks into the project. + +```bash +# with element-android as the current working directory +git lfs install --local +``` + +- If installed correctly, `git push` and `git pull` will now include LFS content. + +## Recording + +- `./gradlew recordScreenshots` +- Paparazzi will generate images in `${module}/src/test/snapshots`, which will need to be committed to the repository using Git LFS. + +## Verifying + +- `./gradlew verifyScreenshots` +- In the case of failure, Paparazzi will generate images in `${module}/out/failure`. The images will show the expected and actual screenshots along with a delta of the two images. + +## Contributing + +- When creating a test, the file (and class) name names must include `ScreenshotTest`, eg `ItemScreenshotTest`. +- After creating the new test, record and commit the newly rendered screens. +- `./tools/validate_lfs` can be ran to ensure everything is working correctly with Git LFS, the CI also runs this check. + +### Example + +```kotlin +class PaparazziExampleScreenshotTest { + + @get:Rule + val paparazzi = Paparazzi( + deviceConfig = PIXEL_3, + theme = "Theme.Vector.Light", + ) + + @Test + fun `example paparazzi test`() { + // Inflate the layout + val view = paparazzi.inflate(R.layout.item_radio) + + // Bind data to the view + view.findViewById(R.id.actionTitle).text = paparazzi.resources.getString(R.string.room_settings_all_messages) + view.findViewById(R.id.radioIcon).setImageResource(R.drawable.ic_radio_on) + + // Record the bound view + paparazzi.snapshot(view) + } +} +```