-
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from sergio-sastre/release/1.1.0-beta
release 1.1.0-beta
- Loading branch information
Showing
12 changed files
with
256 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,16 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
package="sergio.sastre.uitesting.utils"> | ||
|
||
<uses-permission | ||
android:name="android.permission.CHANGE_CONFIGURATION" | ||
tools:ignore="ProtectedPermissions" /> | ||
|
||
<application> | ||
<activity android:name=".activityscenario.ActivityScenarioConfigurator$PortraitSnapshotConfiguredActivity" /> | ||
<activity android:name=".activityscenario.ActivityScenarioConfigurator$LandscapeSnapshotConfiguredActivity" | ||
android:screenOrientation="landscape"/> | ||
</application> | ||
|
||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
utils/src/main/java/sergio/sastre/uitesting/utils/common/DisplaySize.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package sergio.sastre.uitesting.utils.common | ||
|
||
enum class DisplaySize(val value: String) { | ||
SMALL(0.85f.toString()), | ||
NORMAL(1f.toString()), | ||
LARGE(1.1f.toString()), | ||
LARGER(1.2f.toString()), | ||
LARGEST(1.3f.toString()); | ||
|
||
companion object { | ||
@JvmStatic | ||
fun from(scale: Float): DisplaySize { | ||
for (displaySize in values()) { | ||
if (displaySize.value == scale.toString()) { | ||
return displaySize | ||
} | ||
} | ||
throw IllegalArgumentException("Unknown display scale: $scale") | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ing/utils/testrules/fontsize/Condition.kt → ...re/uitesting/utils/testrules/Condition.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
.../src/main/java/sergio/sastre/uitesting/utils/testrules/displaysize/DisplayScaleSetting.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package sergio.sastre.uitesting.utils.testrules.displaysize | ||
|
||
import android.content.res.Resources | ||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation | ||
import sergio.sastre.uitesting.utils.common.DisplaySize | ||
|
||
class DisplayScaleSetting internal constructor(private val resources: Resources) { | ||
|
||
fun getDensityDpi(): Int { | ||
return resources.configuration.densityDpi | ||
} | ||
|
||
fun resetDisplaySizeScale(originalDensity: Int) { | ||
try { | ||
getInstrumentation().uiAutomation.executeShellCommand("wm density reset") | ||
} catch (e: Exception) { | ||
throw RuntimeException("Unable to reset densityDpi to $originalDensity") | ||
} | ||
} | ||
|
||
fun setDisplaySizeScale(scale: DisplaySize) { | ||
try { | ||
val targetDensityDpi = resources.configuration.densityDpi * (scale.value).toFloat() | ||
getInstrumentation().uiAutomation | ||
.executeShellCommand("wm density " + targetDensityDpi.toInt()) | ||
} catch (e: Exception) { | ||
throw RuntimeException("Unable to set display size with scale ${scale.name} = ${scale.value}") | ||
} | ||
} | ||
} |
116 changes: 116 additions & 0 deletions
116
.../src/main/java/sergio/sastre/uitesting/utils/testrules/displaysize/DisplaySizeTestRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package sergio.sastre.uitesting.utils.testrules.displaysize | ||
|
||
import android.os.SystemClock | ||
import androidx.annotation.IntRange | ||
|
||
import org.junit.rules.TestRule | ||
import org.junit.rules.TestWatcher | ||
import org.junit.runner.Description | ||
import org.junit.runners.model.Statement | ||
|
||
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation | ||
import sergio.sastre.uitesting.utils.common.DisplaySize | ||
import sergio.sastre.uitesting.utils.testrules.Condition | ||
import sergio.sastre.uitesting.utils.testrules.displaysize.DisplaySizeTestRule.DisplaySizeStatement.Companion.MAX_RETRIES_TO_WAIT_FOR_SETTING | ||
import sergio.sastre.uitesting.utils.testrules.displaysize.DisplaySizeTestRule.DisplaySizeStatement.Companion.SLEEP_TO_WAIT_FOR_SETTING_MILLIS | ||
|
||
/** | ||
* A TestRule to change Display size of the device/emulator via adb | ||
*/ | ||
class DisplaySizeTestRule( | ||
private val displaySize: DisplaySize, | ||
) : TestWatcher(), TestRule { | ||
|
||
companion object { | ||
fun smallDisplaySizeTestRule(): DisplaySizeTestRule = DisplaySizeTestRule(DisplaySize.SMALL) | ||
|
||
fun normalDisplaySizeTestRule(): DisplaySizeTestRule = | ||
DisplaySizeTestRule(DisplaySize.NORMAL) | ||
|
||
fun largeDisplaySizeTestRule(): DisplaySizeTestRule = DisplaySizeTestRule(DisplaySize.LARGE) | ||
|
||
fun largerDisplaySizeTestRule(): DisplaySizeTestRule = | ||
DisplaySizeTestRule(DisplaySize.LARGER) | ||
|
||
fun largestDisplaySizeTestRule(): DisplaySizeTestRule = | ||
DisplaySizeTestRule(DisplaySize.LARGEST) | ||
} | ||
|
||
private var timeOutInMillis = MAX_RETRIES_TO_WAIT_FOR_SETTING * SLEEP_TO_WAIT_FOR_SETTING_MILLIS | ||
|
||
private val displayScaleSetting: DisplayScaleSetting = | ||
DisplayScaleSetting(getInstrumentation().targetContext.resources) | ||
|
||
private var previousScale: Int = 0 | ||
|
||
/** | ||
* Since the Display Size setting is changed via adb, it might take longer than expected to | ||
* take effect, and could be device dependent. One can use this method to adjust the default | ||
* time out which is [MAX_RETRIES_TO_WAIT_FOR_SETTING] * [SLEEP_TO_WAIT_FOR_SETTING_MILLIS] | ||
*/ | ||
fun withTimeOut(@IntRange(from = 0) inMillis: Int): DisplaySizeTestRule = apply { | ||
this.timeOutInMillis = inMillis | ||
} | ||
|
||
override fun starting(description: Description?) { | ||
previousScale = getInstrumentation().targetContext.resources.configuration.densityDpi | ||
} | ||
|
||
override fun finished(description: Description?) { | ||
displayScaleSetting.resetDisplaySizeScale(previousScale) | ||
} | ||
|
||
override fun apply(base: Statement, description: Description): Statement { | ||
return DisplaySizeStatement(base, displayScaleSetting, displaySize, timeOutInMillis) | ||
} | ||
|
||
private class DisplaySizeStatement( | ||
private val baseStatement: Statement, | ||
private val scaleSetting: DisplayScaleSetting, | ||
private val scale: DisplaySize, | ||
private val timeOutInMillis: Int, | ||
) : Statement() { | ||
|
||
@Throws(Throwable::class) | ||
override fun evaluate() { | ||
val initialDisplay = scaleSetting.getDensityDpi() | ||
val expectedDisplay = (initialDisplay * scale.value.toFloat()).toInt() | ||
scaleSetting.setDisplaySizeScale(scale) | ||
sleepUntil(scaleMatches(expectedDisplay)) | ||
|
||
baseStatement.evaluate() | ||
|
||
scaleSetting.resetDisplaySizeScale(initialDisplay) | ||
sleepUntil(scaleMatches(initialDisplay)) | ||
} | ||
|
||
private fun scaleMatches(densityDpi: Int): Condition { | ||
return object : Condition { | ||
override fun holds(): Boolean { | ||
return scaleSetting.getDensityDpi() == densityDpi | ||
} | ||
} | ||
} | ||
|
||
private fun sleepUntil(condition: Condition) { | ||
var retries = 0 | ||
while (!condition.holds()) { | ||
val retriesCount = timeOutInMillis / SLEEP_TO_WAIT_FOR_SETTING_MILLIS | ||
SystemClock.sleep(SLEEP_TO_WAIT_FOR_SETTING_MILLIS.toLong()) | ||
if (retries == retriesCount) { | ||
throw timeoutError(retries) | ||
} | ||
retries++ | ||
} | ||
} | ||
|
||
private fun timeoutError(retries: Int): AssertionError { | ||
return AssertionError("Spent too long waiting trying to set display scale.$retries retries") | ||
} | ||
|
||
companion object { | ||
const val SLEEP_TO_WAIT_FOR_SETTING_MILLIS = 100 | ||
const val MAX_RETRIES_TO_WAIT_FOR_SETTING = 100 | ||
} | ||
} | ||
} |
Oops, something went wrong.