added typed action clear_focus

c6c010f5eae937b1db19a40ac338aa88c8be003a
This commit is contained in:
edubinskaya
2024-03-19 18:49:42 +03:00
parent 5d0e153679
commit 00f437eab9
9 changed files with 327 additions and 2 deletions
+5
View File
@@ -907,6 +907,7 @@
"client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/DivVisibilityChangeListener.java",
"client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/ScrollDirection.java",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedArrayMutationHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedArrayMutationHandler.kt",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedClearFocusHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedClearFocusHandler.kt",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedCopyToClipboardHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedCopyToClipboardHandler.kt",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedFocusElementHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedFocusElementHandler.kt",
"client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandler.kt":"divkit/public/client/android/div/src/main/java/com/yandex/div/core/actions/DivActionTypedHandler.kt",
@@ -1375,12 +1376,14 @@
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/SuperLineHeightTextViewTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/SuperLineHeightTextViewTest.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TabsSwipeTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TabsSwipeTest.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypeAutoAccessibilityTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypeAutoAccessibilityTest.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypedFocusActionsTest.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/TypedFocusActionsTest.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/ActivityParamsTestRule.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/ActivityParamsTestRule.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/Rules.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/rule/Rules.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/ClickHandlingTestSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/ClickHandlingTestSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/CoordinateSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/CoordinateSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivCustomSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivCustomSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusTypedActionsSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivFocusTypedActionsSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivGallerySteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivGallerySteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivHistogramsSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivHistogramsSteps.kt",
"client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivInputSteps.kt":"divkit/public/client/android/divkit-demo-app/src/androidTest/java/com/yandex/div/steps/DivInputSteps.kt",
@@ -14744,6 +14747,7 @@
"schema/div-action-array-insert-value.json":"divkit/public/schema/div-action-array-insert-value.json",
"schema/div-action-array-remove-value.json":"divkit/public/schema/div-action-array-remove-value.json",
"schema/div-action-base.json":"divkit/public/schema/div-action-base.json",
"schema/div-action-clear-focus.json":"divkit/public/schema/div-action-clear-focus.json",
"schema/div-action-copy-to-clipboard-content.json":"divkit/public/schema/div-action-copy-to-clipboard-content.json",
"schema/div-action-copy-to-clipboard.json":"divkit/public/schema/div-action-copy-to-clipboard.json",
"schema/div-action-focus-element.json":"divkit/public/schema/div-action-focus-element.json",
@@ -16022,6 +16026,7 @@
"test_data/ui_test_data/custom/div_custom_several_states_changing.json":"divkit/public/test_data/ui_test_data/custom/div_custom_several_states_changing.json",
"test_data/ui_test_data/custom/div_custom_state_changing.json":"divkit/public/test_data/ui_test_data/custom/div_custom_state_changing.json",
"test_data/ui_test_data/focus/actions.json":"divkit/public/test_data/ui_test_data/focus/actions.json",
"test_data/ui_test_data/focus/focus-element-and-clear-actions.json":"divkit/public/test_data/ui_test_data/focus/focus-element-and-clear-actions.json",
"test_data/ui_test_data/focus/snapshot_div_input_selection.json":"divkit/public/test_data/ui_test_data/focus/snapshot_div_input_selection.json",
"test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background.json":"divkit/public/test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background.json",
"test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background_and_border.json":"divkit/public/test_data/ui_test_data/focus/snapshot_with_blurred_and_focused_background_and_border.json",
@@ -0,0 +1,26 @@
package com.yandex.div.core.actions
import android.view.inputmethod.InputMethodManager
import androidx.core.content.ContextCompat
import com.yandex.div.core.view2.Div2View
import com.yandex.div2.DivActionTyped
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
internal class DivActionTypedClearFocusHandler @Inject constructor() : DivActionTypedHandler {
override fun handleAction(action: DivActionTyped, view: Div2View): Boolean = when (action) {
is DivActionTyped.ClearFocus -> {
view.clearFocus()
closeKeyboard(view)
true
}
else -> false
}
private fun closeKeyboard(view: Div2View) {
val imm = ContextCompat.getSystemService(view.getContext(), InputMethodManager::class.java)
imm?.hideSoftInputFromWindow(view.windowToken, InputMethodManager.SHOW_IMPLICIT)
}
}
@@ -1,6 +1,7 @@
package com.yandex.div.core.dagger
import com.yandex.div.core.actions.DivActionTypedArrayMutationHandler
import com.yandex.div.core.actions.DivActionTypedClearFocusHandler
import com.yandex.div.core.actions.DivActionTypedCopyToClipboardHandler
import com.yandex.div.core.actions.DivActionTypedSetVariableHandler
import com.yandex.div.core.actions.DivActionTypedHandler
@@ -8,7 +9,6 @@ import com.yandex.div.core.actions.DivActionTypedFocusElementHandler
import com.yandex.yatagan.Binds
import com.yandex.yatagan.IntoSet
import com.yandex.yatagan.Module
import javax.inject.Singleton
@Module
internal interface DivActionTypedModule {
@@ -36,4 +36,10 @@ internal interface DivActionTypedModule {
fun provideCopyToClipboardActionHandler(
impl: DivActionTypedCopyToClipboardHandler
): DivActionTypedHandler
@Binds
@IntoSet
fun provideClearFocusActionHandler(
impl: DivActionTypedClearFocusHandler
): DivActionTypedHandler
}
@@ -0,0 +1,37 @@
package com.yandex.div
import com.yandex.div.rule.ActivityParamsTestRule
import com.yandex.div.rule.uiTestRule
import com.yandex.div.steps.divFocusTypedActions
import com.yandex.divkit.demo.screenshot.DivScreenshotActivity
import org.junit.Rule
import org.junit.Test
class TypedFocusActionsTest {
@get:Rule
val rule = uiTestRule {
ActivityParamsTestRule(
DivScreenshotActivity::class.java,
DivScreenshotActivity.EXTRA_DIV_ASSET_NAME to "ui_test_data/focus/focus-element-and-clear-actions.json"
)
}
@Test
fun focusViewFocusInput() {
divFocusTypedActions {
triggerFocusInputAction()
assert { checkInputFocused() }
}
}
@Test
fun clearFocusRemovesFocusFromInput() {
divFocusTypedActions {
triggerFocusInputAction()
waitForClearFocusActionTriggered()
assert { checkFocusCleared() }
}
}
}
@@ -0,0 +1,48 @@
package com.yandex.div.steps
import android.view.View
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.isFocused
import androidx.test.espresso.matcher.ViewMatchers.isNotFocused
import androidx.test.espresso.matcher.ViewMatchers.withText
import com.yandex.div.view.ViewActions
import com.yandex.test.util.StepsDsl
import org.hamcrest.Matcher
import ru.tinkoff.allure.step
internal fun divFocusTypedActions(f: DivFocusTypedActionsSteps.() -> Unit) = f(DivFocusTypedActionsSteps())
@StepsDsl
internal class DivFocusTypedActionsSteps {
fun triggerFocusInputAction(): Unit = step("Click on button 'Focus input'") {
clickOnView(focusInputMatcher)
}
fun waitForClearFocusActionTriggered(): Unit = step("Wait for until timer clean focus") {
ViewActions.waitForView(finishedLabelMatcher, waitingTimeout = 2500)
}
fun assert(f: DivFocusTypedActionsAssertions.() -> Unit) = f(DivFocusTypedActionsAssertions())
}
@StepsDsl
internal class DivFocusTypedActionsAssertions {
fun checkInputFocused(): Unit = step("Check input has focus") {
onView(inputMatcher).check(matches(isFocused()))
}
fun checkFocusCleared(): Unit = step("Check input has no focus") {
onView(inputMatcher).check(matches(isNotFocused()))
}
}
private fun clickOnView(matcher: Matcher<View>) = onView(matcher).perform(click())
private val focusInputMatcher = getTextMatcher("Focus input")
private val inputMatcher = getTextMatcher("input view")
private val finishedLabelMatcher = getTextMatcher("finished")
private fun getTextMatcher(text: String) = withText(text)
+15
View File
@@ -0,0 +1,15 @@
{
"type": "object",
"$description": "translations.json#/div_action_clear_focus",
"properties": {
"type": {
"type": "string",
"enum": [
"clear_focus"
]
}
},
"required": [
"type"
]
}
+6
View File
@@ -16,6 +16,12 @@
"web"
]
},
{
"$ref": "div-action-clear-focus.json",
"platforms": [
"android"
]
},
{
"$ref": "div-action-copy-to-clipboard.json"
}
+5 -1
View File
@@ -69,7 +69,11 @@
},
"div_action_copy_to_clipboard": {
"en": "Copies data to the clipboard.",
"ru": "Копирует данные в буфер обмена"
"ru": "Копирует данные в буфер обмена."
},
"div_action_clear_focus": {
"en": "Removes focus from focused item.",
"ru": "Снимает фокус со сфокусированного элемента."
},
"div_action_focus_element": {
"en": "Requests focus for an element. May require a user action on the web.",
@@ -0,0 +1,178 @@
{
"templates": {
"button": {
"type": "text",
"paddings": {
"top": 4,
"bottom": 4,
"left": 8,
"right": 8
},
"margins": {
"right": 8,
"left": 8
},
"text_alignment_horizontal": "center",
"text_alignment_vertical": "center",
"font_size": 12,
"text_color": "#ffff",
"font_weight": "bold",
"height": {
"type": "wrap_content"
},
"width": {
"type": "match_parent"
},
"border": {
"corner_radius": 16
},
"background": [
{
"type": "solid",
"color": "#0000FF"
}
],
"focus": {
"background": [
{
"type": "solid",
"color": "#ff5500"
}
]
}
}
},
"card": {
"log_id": "tests",
"variables": [
{
"name": "input_value_1",
"type": "string",
"value": "input view"
},
{
"name": "timer_label",
"type": "string",
"value": "finished"
}
],
"timers": [
{
"id": "clear_focus",
"duration": 2000,
"end_actions": [
{
"log_id": "clear focus",
"typed": {
"type": "clear_focus"
}
},
{
"url": "div-action://set_variable?name=timer_label&value=finished",
"log_id": "timer finished"
}
]
}
],
"states": [
{
"state_id": 0,
"div": {
"type": "container",
"orientation": "vertical",
"margins": {
"top": 24,
"bottom": 24
},
"items": [
{
"type": "container",
"orientation": "horizontal",
"margins": {
"left": 16,
"top": 16
},
"width": {
"type": "wrap_content"
},
"items": [
{
"type": "text",
"text": "Timer for clear focus: ",
"font_weight": "bold"
},
{
"type": "text",
"text": "@{timer_label}"
}
]
},
{
"id": "input",
"text_variable": "input_value_1",
"type": "input",
"width": {
"type": "match_parent"
},
"height": {
"type": "wrap_content"
},
"paddings": {
"left": 16,
"top": 16,
"right": 16,
"bottom": 16
},
"margins": {
"left": 16,
"top": 16,
"right": 16,
"bottom": 16
},
"border": {
"corner_radius": 8,
"stroke": {
"color": "#0000FF"
}
},
"focus": {
"background": [
{
"type": "solid",
"color": "#ff5500"
}
]
}
},
{
"type": "button",
"text": "Focus input",
"id": "button_1",
"alignment_horizontal": "center",
"width": {
"type": "wrap_content"
},
"actions": [
{
"log_id": "focus_1",
"typed": {
"type": "focus_element",
"element_id": "input"
}
},
{
"log_id": "Start timer",
"url": "div-action://timer?id=clear_focus&action=start"
},
{
"url": "div-action://set_variable?name=timer_label&value=started",
"log_id": "timer started"
}
]
}
]
}
}
]
}
}