Skip to content

Commit

Permalink
Add first skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
vbarthel-fr committed Nov 6, 2024
1 parent 42696a3 commit ff46de2
Show file tree
Hide file tree
Showing 15 changed files with 550 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.iml
.gradle
/local.properties
/.idea
/.kotlin
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# E2E Test for setOrientation command on Android

This repo aims at providing the minimum material to have an end-to-end test for the setOrientation
command on Android:

- an android app that observe the `user_rotation` system settings and display a human readable
version of it in a text view:
- 0 -> "PORTRAIT"
- 1 -> "LANDSCAPE_LEFT"
- 2 -> "UPSIDE_DOWN"
- 3 -> "LANDSCAPE_RIGHT"
- a maestro script `test-set-orientation-flow.yaml` that calls the `setOrientation` command for each
supported orientation and that assert that its visible on screen.

I tried to use no extra libraries and good old java to keep the assembled debug APK as small as
possible: ~8Kb on my mac.

Context: https://github.com/mobile-dev-inc/maestro/pull/2121

- Assemble a debug APK: `./gradlew assembleDebug`
- Install it: `adb install ./app/build/outputs/apk/debug/app-debug.apk`
- Run the maestro flow: `./maestro test ./test-set-orientation-flow.yaml`
- Observe test passing:

```
║ > Flow: test-set-orientation-flow
║ ✅ Launch app "com.example.maestro.orientation"
║ ✅ Set orientation LANDSCAPE_LEFT
║ ✅ Assert that "LANDSCAPE_LEFT" is visible
║ ✅ Set orientation LANDSCAPE_RIGHT
║ ✅ Assert that "LANDSCAPE_RIGHT" is visible
║ ✅ Set orientation UPSIDE_DOWN
║ ✅ Assert that "UPSIDE_DOWN" is visible
║ ✅ Set orientation PORTRAIT
║ ✅ Assert that "PORTRAIT" is visible
```

Note: this requires a version of maestro with the `setOrientation` command.
See https://github.com/mobile-dev-inc/maestro/pull/2121
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
26 changes: 26 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
alias(libs.plugins.android.application)
}

android {
namespace = "com.example.maestro.orientation"
compileSdk = 35

defaultConfig {
applicationId = "com.example.maestro.orientation"
minSdk = 26
targetSdk = 35
versionCode = 1
versionName = "1.0"
}

buildTypes {
debug {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
}
23 changes: 23 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="false"
android:label="maestro orientation"
android:supportsRtl="true"
android:theme="@android:style/Theme.Light.NoTitleBar"
tools:ignore="DataExtractionRules,MissingApplicationIcon"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.example.maestro.orientation;

import android.app.Activity;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.TextView;

/**
* Display a human readable value of the current user_orientation system settings.
* 0 -> "PORTRAIT"
* 1 -> "LANDSCAPE_LEFT"
* 2 -> "UPSIDE_DOWN"
* 3 -> "LANDSCAPE_RIGHT"
* A content observer is used because in some cases the same activity
* is "simply" rotated without being even paused and resumed. For example,
* changing the user_orientation from "PORTRAIT" to "UPSIDE_DOWN" keeps the
* same activity (no onDestroy and onCreate) and does not trigger onPaused/onResumed.
*/
public class MainActivity extends Activity {

private TextView textView;
private ContentObserver contentObserver;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

textView = new TextView(this);
textView.setGravity(Gravity.CENTER);
setContentView(
textView,
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
);

Handler handler = new Handler(Looper.getMainLooper());
contentObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
updateOrientationLabel();
}
};

getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.USER_ROTATION),
true,
contentObserver
);

updateOrientationLabel();
}

@Override
protected void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(contentObserver);
}

private void updateOrientationLabel() {
int userOrientation = Settings.System.getInt(
getContentResolver(),
Settings.System.USER_ROTATION,
0
);

String orientationLabel;
switch (userOrientation) {
case 0:
orientationLabel = "PORTRAIT";
break;
case 1:
orientationLabel = "LANDSCAPE_LEFT";
break;
case 2:
orientationLabel = "UPSIDE_DOWN";
break;
case 3:
orientationLabel = "LANDSCAPE_RIGHT";
break;
default:
throw new IllegalStateException(
"Unsupported user orientation. Found: " + userOrientation
);
}

textView.setText(orientationLabel);
}
}

5 changes: 5 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.android) apply false
}
23 changes: 23 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
8 changes: 8 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[versions]
agp = "8.7.2"
kotlin = "2.0.21"

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
6 changes: 6 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Wed Nov 06 18:18:25 CET 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit ff46de2

Please sign in to comment.