Skip to content

Commit

Permalink
chore: configure automatic screenshots
Browse files Browse the repository at this point in the history
  • Loading branch information
AsCress committed Jul 9, 2024
1 parent c6b95f2 commit 1fd8d5f
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 3 deletions.
58 changes: 58 additions & 0 deletions .github/actions/screenshot-android/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: "Android Screenshots Workflow"

inputs:
ANDROID_EMULATOR_API:
description: 'Emulator API to be used when running tests'
required: false
default: 34
ANDROID_EMULATOR_ARCH:
description: 'Emulator architecture to be used when running tests'
required: false
default: x86_64

runs:
using: "composite"
steps:
- name: Enable KVM group perms
shell: bash
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Cache AVD
uses: actions/cache@v4
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ inputs.ANDROID_EMULATOR_API }}-${{ inputs.ANDROID_EMULATOR_ARCH }}

- name: Create AVD and Cache Snapshot
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ inputs.ANDROID_EMULATOR_API }}
arch: ${{ inputs.ANDROID_EMULATOR_ARCH }}
profile: pixel_6
avd-name: pixel_6
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: false
script: echo "Generated AVD snapshot for caching."

- name: Create Android Screenshots
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ inputs.ANDROID_EMULATOR_API }}
arch: ${{ inputs.ANDROID_EMULATOR_ARCH }}
profile: pixel_6
avd-name: pixel_6
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: |
bundle exec fastlane screengrab
if [[ $? -ne 0 ]]; then
exit 1
fi
13 changes: 10 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,27 @@ jobs:
read -r version_code < versionCode.txt
echo "VERSION_CODE=$version_code" >> $GITHUB_OUTPUT
- name: Add Changelogs to fastlane branch
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git clone --branch=fastlane --depth=1 https://${{ github.repository_owner }}:${{ github.token }}@github.com/${{ github.repository }} fastlane
- name: Android Screenshot Workflow
uses: ./.github/actions/screenshot-android
with:
ANDROID_EMULATOR_API: ${{ env.ANDROID_EMULATOR_API }}
ANDROID_EMULATOR_ARCH: ${{ env.ANDROID_EMULATOR_ARCH }}

- name: Add Changelogs to fastlane branch
run: |
cd fastlane
echo "${{ github.event.release.body }}" > metadata/android/en-US/changelogs/${{ steps.download-assets.outputs.VERSION_CODE }}.txt
# Force push to fastlane branch
git checkout --orphan temporary
git add --all .
git commit -am "[Auto] Add changelogs for versionCode: ${{ steps.download-assets.outputs.VERSION_CODE }} ($(date +%Y-%m-%d.%H:%M:%S))"
git commit -am "[Auto] Update metadata for versionCode: ${{ steps.download-assets.outputs.VERSION_CODE }} ($(date +%Y-%m-%d.%H:%M:%S))"
git branch -D fastlane
git branch -m fastlane
git push --force origin fastlane
Expand Down
6 changes: 6 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ android {
versionCode = System.getenv("VERSION_CODE")?.toInt() ?: 1
versionName = System.getenv("VERSION_NAME") ?: "1.0.0"
resConfigs("en","ru","ar","si","pl")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

signingConfigs {
Expand Down Expand Up @@ -97,6 +98,11 @@ dependencies {

// OKHTTP
implementation("com.squareup.okhttp3:okhttp:4.12.0")
androidTestImplementation("tools.fastlane:screengrab:2.1.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
androidTestImplementation("androidx.test.espresso:espresso-contrib:3.6.1")
androidTestImplementation("androidx.test:rules:1.6.1")

// ButterKnife
val butterKnifeVersion = "10.2.3"
Expand Down
183 changes: 183 additions & 0 deletions app/src/androidTest/java/io/pslab/activity/ScreenshotsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package io.pslab.activity;


import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.*;
import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
import static androidx.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

import androidx.test.espresso.Espresso;
import androidx.test.ext.junit.rules.ActivityScenarioRule;

import tools.fastlane.screengrab.FalconScreenshotStrategy;
import tools.fastlane.screengrab.Screengrab;
import tools.fastlane.screengrab.locale.LocaleTestRule;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.GrantPermissionRule;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import io.pslab.R;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class ScreenshotsTest {

@ClassRule
public static final LocaleTestRule localeTestRule = new LocaleTestRule();

@Rule
public ActivityScenarioRule<MainActivity> mActivityScenarioRule =
new ActivityScenarioRule<>(MainActivity.class);

@Rule
public GrantPermissionRule mGrantPermissionRule =
GrantPermissionRule.grant(
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.RECORD_AUDIO",
"android.permission.WRITE_EXTERNAL_STORAGE");

@Test
public void testTakeScreenshot() {
mActivityScenarioRule.getScenario().onActivity(activity -> Screengrab.setDefaultScreenshotStrategy(new FalconScreenshotStrategy(activity)));

Screengrab.screenshot("dashboard");

onView(
allOf(withContentDescription("open_drawer"),
childAtPosition(
allOf(withId(R.id.toolbar),
childAtPosition(
withClassName(is("com.google.android.material.appbar.AppBarLayout")),
0)),
1),
isDisplayed())).perform(click());

Screengrab.screenshot("drawer");

Espresso.pressBack();

onView(
allOf(withId(R.id.applications_recycler_view),
childAtPosition(
withClassName(is("android.widget.RelativeLayout")),
0))).perform(actionOnItemAtPosition(7, click()));

Screengrab.screenshot("instrument_accelerometer_view");

Espresso.pressBack();

onView(
allOf(withId(R.id.applications_recycler_view),
childAtPosition(
withClassName(is("android.widget.RelativeLayout")),
0))).perform(actionOnItemAtPosition(8, click()));

Screengrab.screenshot("instrument_barometer_view");

Espresso.pressBack();

onView(
allOf(withId(R.id.applications_recycler_view),
childAtPosition(
withClassName(is("android.widget.RelativeLayout")),
0))).perform(actionOnItemAtPosition(1, click()));

Screengrab.screenshot("instrument_multimeter_view");

Espresso.pressBack();

onView(
allOf(withId(R.id.applications_recycler_view),
childAtPosition(
withClassName(is("android.widget.RelativeLayout")),
0))).perform(actionOnItemAtPosition(2, click()));

Screengrab.screenshot("logic_analyzer_view");

Espresso.pressBack();

onView(
allOf(withContentDescription("More options"),
childAtPosition(
childAtPosition(
withId(R.id.toolbar),
2),
1),
isDisplayed())).perform(click());

onView(
allOf(withId(me.zhanghai.android.materialprogressbar.R.id.title), withText("Pin Layout Front"),
childAtPosition(
childAtPosition(
withId(R.id.content),
0),
0),
isDisplayed())).perform(click());

Screengrab.screenshot("layout_pin_front");

onView(
allOf(withContentDescription("open_drawer"),
childAtPosition(
allOf(withId(R.id.toolbar),
childAtPosition(
withClassName(is("com.google.android.material.appbar.AppBarLayout")),
0)),
1),
isDisplayed())).perform(click());

onView(
allOf(withId(R.id.nav_instruments),
childAtPosition(
allOf(withId(com.google.android.material.R.id.design_navigation_view),
childAtPosition(
withId(R.id.nav_view),
0)),
1),
isDisplayed())).perform(click());

onView(
allOf(withId(R.id.applications_recycler_view),
childAtPosition(
withClassName(is("android.widget.RelativeLayout")),
0))).perform(actionOnItemAtPosition(0, click()));

Screengrab.screenshot("oscilloscope_channel_view");

Espresso.pressBack();
}

private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {

return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}

@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"
tools:ignore="HighSamplingRate" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
<uses-permission android:name="android.permission.DUMP"/>

<uses-feature
android:name="android.hardware.sensor.light"
Expand Down

0 comments on commit 1fd8d5f

Please sign in to comment.