diff --git a/api/cpp/include/slint-testing.h b/api/cpp/include/slint-testing.h index 3bc3657ed..955f1d48d 100644 --- a/api/cpp/include/slint-testing.h +++ b/api/cpp/include/slint-testing.h @@ -88,6 +88,57 @@ public: return std::nullopt; } + /// Returns the accessible-value-maximum of that element, if any. + std::optional accessible_value_maximum() const + { + if (auto item = private_api::upgrade_item_weak(inner)) { + SharedString result; + if (item->item_tree.vtable()->accessible_string_property( + item->item_tree.borrow(), item->index, + cbindgen_private::AccessibleStringProperty::ValueMaximum, &result)) { + float value = 0.0; + if (cbindgen_private::slint_string_to_float(&result, &value)) { + return value; + } + } + } + return std::nullopt; + } + + /// Returns the accessible-value-minimum of that element, if any. + std::optional accessible_value_minimum() const + { + if (auto item = private_api::upgrade_item_weak(inner)) { + SharedString result; + if (item->item_tree.vtable()->accessible_string_property( + item->item_tree.borrow(), item->index, + cbindgen_private::AccessibleStringProperty::ValueMinimum, &result)) { + float value = 0.0; + if (cbindgen_private::slint_string_to_float(&result, &value)) { + return value; + } + } + } + return std::nullopt; + } + + /// Returns the accessible-value-step of that element, if any. + std::optional accessible_value_step() const + { + if (auto item = private_api::upgrade_item_weak(inner)) { + SharedString result; + if (item->item_tree.vtable()->accessible_string_property( + item->item_tree.borrow(), item->index, + cbindgen_private::AccessibleStringProperty::ValueStep, &result)) { + float value = 0.0; + if (cbindgen_private::slint_string_to_float(&result, &value)) { + return value; + } + } + } + return std::nullopt; + } + /// Returns the accessible-checked of that element, if any. std::optional accessible_checked() const { diff --git a/api/cpp/include/slint_tests_helpers.h b/api/cpp/include/slint_tests_helpers.h index 56c46ad9f..9d838db9a 100644 --- a/api/cpp/include/slint_tests_helpers.h +++ b/api/cpp/include/slint_tests_helpers.h @@ -51,6 +51,9 @@ void assert_eq_impl(const A &a, const B &b, const char *a_str, const char *b_str // Do a cast to the common type to avoid warning about signed vs. unsigned compare using T = std::common_type_t; nok = T(a) != T(b); + } else if constexpr (std::is_floating_point_v && std::is_floating_point_v) { + const double dEpsilon = 0.000001; // or some other small number + nok = fabs(a - b) > dEpsilon * fabs(a); } else { nok = a != b; } diff --git a/internal/backends/testing/search_api.rs b/internal/backends/testing/search_api.rs index f61861e28..9901b0749 100644 --- a/internal/backends/testing/search_api.rs +++ b/internal/backends/testing/search_api.rs @@ -96,6 +96,30 @@ impl ElementHandle { } } + /// Returns the value of the element's `accessible-value-maximum` property, if present. + pub fn accessible_value_maximum(&self) -> Option { + self.0.upgrade().and_then(|item| { + item.accessible_string_property(AccessibleStringProperty::ValueMaximum) + .and_then(|item| item.parse().ok()) + }) + } + + /// Returns the value of the element's `accessible-value-minimum` property, if present. + pub fn accessible_value_minimum(&self) -> Option { + self.0.upgrade().and_then(|item| { + item.accessible_string_property(AccessibleStringProperty::ValueMinimum) + .and_then(|item| item.parse().ok()) + }) + } + + /// Returns the value of the element's `accessible-value-step` property, if present. + pub fn accessible_value_step(&self) -> Option { + self.0.upgrade().and_then(|item| { + item.accessible_string_property(AccessibleStringProperty::ValueStep) + .and_then(|item| item.parse().ok()) + }) + } + /// Returns the value of the `accessible-label` property, if present. pub fn accessible_label(&self) -> Option { self.0 diff --git a/tests/cases/widgets/button.slint b/tests/cases/widgets/button.slint index 7d512a980..97a80a3c1 100644 --- a/tests/cases/widgets/button.slint +++ b/tests/cases/widgets/button.slint @@ -52,6 +52,9 @@ let aaa = result.pop().unwrap(); assert_eq!(aaa.accessible_label().unwrap(), "Aaa"); assert_eq!(aaa.accessible_description().unwrap(), "Checkable Button"); assert_eq!(aaa.accessible_value(), None); +assert_eq!(aaa.accessible_value_maximum(), None); +assert_eq!(aaa.accessible_value_minimum(), None); +assert_eq!(aaa.accessible_value_step(), None); assert_eq!(instance.get_a_focused(), false); assert_eq!(aaa.accessible_checked(), Some(false)); assert_eq!(aaa.accessible_checkable(), Some(true)); @@ -106,6 +109,9 @@ auto aaa = label_search[0]; assert_eq(aaa.accessible_label().value(), "Aaa"); assert_eq(aaa.accessible_description().value(), "Checkable Button"); assert(!aaa.accessible_value()); +assert(!aaa.accessible_value_maximum()); +assert(!aaa.accessible_value_minimum()); +assert(!aaa.accessible_value_step()); assert_eq(aaa.accessible_checked().value(), false); assert_eq(aaa.accessible_checkable().value(), true); aaa.invoke_accessible_default_action(); diff --git a/tests/cases/widgets/spinbox_default_value.slint b/tests/cases/widgets/spinbox_default_value.slint index 309f9bad6..f30afec79 100644 --- a/tests/cases/widgets/spinbox_default_value.slint +++ b/tests/cases/widgets/spinbox_default_value.slint @@ -7,7 +7,10 @@ export component TestCase inherits Window { width: 100px; height: 100px; - spin_min_pos := SpinBox { minimum: 10; } + spin_min_pos := SpinBox { + accessible-label: "spinbox"; + minimum: 10; + } out property pos-val <=> spin-min-pos.value; spin_min_default := SpinBox {} @@ -24,7 +27,6 @@ export component TestCase inherits Window { /* ```rust - let instance = TestCase::new().unwrap(); assert_eq!(instance.get_pos_val(), 10); @@ -32,6 +34,26 @@ assert_eq!(instance.get_default_min(), 0); assert_eq!(instance.get_default_val(), 0); assert_eq!(instance.get_neg_val(), -10); +let mut label_search = slint_testing::ElementHandle::find_by_accessible_label(&instance, "spinbox").collect::>(); +assert_eq!(label_search.len(), 1); +let spinbox = label_search.pop().unwrap(); +assert_eq!(spinbox.accessible_value_maximum(), Some(100f32)); +assert_eq!(spinbox.accessible_value_minimum(), Some(10f32)); +assert_eq!(spinbox.accessible_value_step(), Some(0.9)); + + +``` + +```cpp +auto handle = TestCase::create(); + +auto label_search = slint::testing::ElementHandle::find_by_accessible_label(handle, "spinbox"); +assert(label_search.size() == 1); +auto spinbox = label_search[0]; +assert_eq(spinbox.accessible_value_maximum().value(), 100); +assert_eq(spinbox.accessible_value_minimum().value(), 10); +assert_eq(spinbox.accessible_value_step().value(), 0.9); + ``` */