2019-10-03 18:30:55 +02:00
/ * This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/. */
@file : Suppress ( " TooManyFunctions " )
package org.mozilla.fenix.ui.robots
2020-02-06 21:58:47 +01:00
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
2019-10-03 18:30:55 +02:00
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
2020-02-06 21:58:47 +01:00
import android.view.KeyEvent
import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
import android.view.KeyEvent.KEYCODE_DPAD_LEFT
import android.view.KeyEvent.ACTION_DOWN
import android.view.View
import android.widget.SeekBar
import android.widget.TextView
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.assertion.ViewAssertions.doesNotExist
import org.hamcrest.CoreMatchers.allOf
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility
import androidx.test.espresso.matcher.ViewMatchers.Visibility
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
import org.hamcrest.Matcher
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.ui.robots.SettingsSubMenuAccessibilityRobot.Companion.DECIMAL_CONVERSION
import org.mozilla.fenix.ui.robots.SettingsSubMenuAccessibilityRobot.Companion.MIN_VALUE
import org.mozilla.fenix.ui.robots.SettingsSubMenuAccessibilityRobot.Companion.STEP_SIZE
import org.mozilla.fenix.ui.robots.SettingsSubMenuAccessibilityRobot.Companion.TEXT_SIZE
import kotlin.math.roundToInt
2019-10-03 18:30:55 +02:00
/ * *
* Implementation of Robot Pattern for the settings Accessibility sub menu .
* /
class SettingsSubMenuAccessibilityRobot {
2020-02-06 21:58:47 +01:00
companion object {
const val STEP _SIZE = 5
const val MIN _VALUE = 50
const val DECIMAL _CONVERSION = 100f
const val TEXT _SIZE = 16f
}
fun verifyAutomaticFontSizingMenuItems ( ) = assertAutomaticFontSizingMenuItems ( )
fun clickFontSizingSwitch ( ) = toggleFontSizingSwitch ( )
fun verifyNewMenuItems ( ) = assertNewMenuItems ( )
fun verifyNewMenuItemsAreGone ( ) = assertNewMenuItemsAreGone ( )
fun changeTextSizeSlider ( seekBarPercentage : Int ) = adjustTextSizeSlider ( seekBarPercentage )
fun verifyTextSizePercentage ( textSize : Int ) = assertTextSizePercentage ( textSize )
2019-10-03 18:30:55 +02:00
class Transition {
val mDevice = UiDevice . getInstance ( InstrumentationRegistry . getInstrumentation ( ) )
fun goBack ( interact : SettingsRobot . ( ) -> Unit ) : SettingsRobot . Transition {
mDevice . waitForIdle ( )
2020-02-06 21:58:47 +01:00
goBackButton ( ) . perform ( click ( ) )
2019-10-03 18:30:55 +02:00
SettingsRobot ( ) . interact ( )
return SettingsRobot . Transition ( )
}
}
}
2020-02-06 21:58:47 +01:00
val device = UiDevice . getInstance ( InstrumentationRegistry . getInstrumentation ( ) )
private fun assertAutomaticFontSizingMenuItems ( ) {
onView ( withText ( " Automatic Font Sizing " ) )
. check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
2019-10-03 18:30:55 +02:00
val strFont = " Font size will match your Android settings. Disable to manage font size here. "
2020-02-06 21:58:47 +01:00
onView ( withText ( strFont ) )
. check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
}
private fun toggleFontSizingSwitch ( ) {
// Toggle font size to off
onView ( withText ( " Automatic Font Sizing " ) )
. check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
. perform ( click ( ) )
}
private fun assertNewMenuItems ( ) {
assertFontSize ( )
assertSliderBar ( )
}
private fun assertFontSize ( ) {
val view = onView ( withText ( " Font Size " ) )
view . check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
val strFont = " Make text on websites larger or smaller "
onView ( withText ( strFont ) )
. check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
}
private fun assertSliderBar ( ) {
onView ( withId ( org . mozilla . fenix . R . id . sampleText ) )
. check ( matches ( withText ( " This is sample text. It is here to show how text will appear when you increase or decrease the size with this setting. " ) ) )
onView ( withId ( org . mozilla . fenix . R . id . seekbar _value ) )
. check ( matches ( withText ( " 100% " ) ) )
onView ( withId ( org . mozilla . fenix . R . id . seekbar ) )
. check ( matches ( withEffectiveVisibility ( Visibility . VISIBLE ) ) )
}
private fun adjustTextSizeSlider ( seekBarPercentage : Int ) {
onView ( withId ( org . mozilla . fenix . R . id . seekbar ) )
. perform ( SeekBarChangeProgressViewAction ( seekBarPercentage ) )
}
private fun assertTextSizePercentage ( textSize : Int ) {
onView ( withId ( org . mozilla . fenix . R . id . sampleText ) )
. check ( textSizePercentageEquals ( textSize ) )
}
private fun assertNewMenuItemsAreGone ( ) {
onView ( withText ( " Font Size " ) ) . check ( doesNotExist ( ) )
val strFont = " Make text on websites larger or smaller "
onView ( withText ( strFont ) )
. check ( doesNotExist ( ) )
onView ( withId ( org . mozilla . fenix . R . id . sampleText ) )
. check ( doesNotExist ( ) )
onView ( withId ( org . mozilla . fenix . R . id . seekbar _value ) )
. check ( doesNotExist ( ) )
onView ( withId ( org . mozilla . fenix . R . id . seekbar ) )
. check ( doesNotExist ( ) )
2019-10-03 18:30:55 +02:00
}
private fun goBackButton ( ) =
2020-02-06 21:58:47 +01:00
onView ( allOf ( withContentDescription ( " Navigate up " ) ) )
class SeekBarChangeProgressViewAction ( val seekBarPercentage : Int ) : ViewAction {
override fun getConstraints ( ) : Matcher < View > {
return isAssignableFrom ( SeekBar :: class . java )
}
override fun perform ( uiController : UiController ? , view : View ? ) {
val targetStepSize = calculateStepSizeFromPercentage ( seekBarPercentage )
val seekbar = view as SeekBar
var progress = seekbar . progress
if ( targetStepSize > progress ) {
for ( i in progress until targetStepSize ) {
seekbar . onKeyDown ( KEYCODE _DPAD _RIGHT , KeyEvent ( ACTION _DOWN , KEYCODE _DPAD _RIGHT ) )
}
} else if ( progress > targetStepSize ) {
for ( i in progress downTo targetStepSize ) {
seekbar . onKeyDown ( KEYCODE _DPAD _LEFT , KeyEvent ( ACTION _DOWN , KEYCODE _DPAD _LEFT ) )
}
}
}
override fun getDescription ( ) : String {
return " Changes the progress on a SeekBar, based on the percentage value. "
}
}
fun textSizePercentageEquals ( textSizePercentage : Int ) : ViewAssertion {
return ViewAssertion { view , noViewFoundException ->
if ( noViewFoundException != null ) throw noViewFoundException
val textView = view as TextView
val scaledPixels =
textView . textSize / InstrumentationRegistry . getInstrumentation ( ) . context . resources . displayMetrics . scaledDensity
val currentTextSizePercentage = calculateTextPercentageFromTextSize ( scaledPixels )
if ( currentTextSizePercentage != textSizePercentage ) throw AssertionError ( " The textview has a text size percentage of $currentTextSizePercentage , and does not match $textSizePercentage " )
}
}
fun calculateTextPercentageFromTextSize ( textSize : Float ) : Int {
val decimal = textSize / TEXT _SIZE
return ( decimal * DECIMAL _CONVERSION ) . roundToInt ( )
}
fun calculateStepSizeFromPercentage ( textSizePercentage : Int ) : Int {
return ( ( textSizePercentage - MIN _VALUE ) / STEP _SIZE )
}
fun checkTextSizeOnWebsite ( textSizePercentage : Int , components : Components ) : Boolean {
// Checks the Gecko engine settings for the font size
val textSize = calculateStepSizeFromPercentage ( textSizePercentage )
val newTextScale = ( ( textSize * STEP _SIZE ) + MIN _VALUE ) . toFloat ( ) / DECIMAL _CONVERSION
return components . core . engine . settings . fontSizeFactor == newTextScale
}