From 0ab60ea381f3aeea5426e4a6aed5db7453216045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Sat, 31 Aug 2019 13:01:49 +0200 Subject: [PATCH] Factor out click functionality from assert_and_click There are two cases where the fixed combination of assert_screen with the click functionality is problematic: 1. Multiple needles, where only some need/support clicking. This is typically solved with a combination of assert_screen + match_has_tag + assert_and_click. This is wasteful, as it checks twice for the same needle. 2. Repeated assert_and_click due to lost events. As it is impossible to know if an event was lost or just handled late, the repeated assert_and_click may encounter the just changed screen contents. Splitting the click allows to do it conditionally, i.e. for (1.), just replacing the assert_and_click by click_lastmatch, and for (2.), by using something like: ``` assert_and_click(needle); while(1) { assert_screen([needle, after]); last if match_has_tag(after); click_lastmatch; } ``` For a sequence of clicks, the "after" can specify the coordinates for the next click. --- OpenQA/Isotovideo/Interface.pm | 2 +- testapi.pm | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/OpenQA/Isotovideo/Interface.pm b/OpenQA/Isotovideo/Interface.pm index 2bed4988..8ec5e37c 100644 --- a/OpenQA/Isotovideo/Interface.pm +++ b/OpenQA/Isotovideo/Interface.pm @@ -22,7 +22,7 @@ use warnings; # -> increment on every change of such APIs # -> never move that variable to another place (when refactoring) # because it may be accessed by the tests itself -our $version = 16; +our $version = 17; # major version of the (web socket) API relevant to the developer mode # -> increment when making non-backward compatible changes to that API diff --git a/testapi.pm b/testapi.pm index b6b60e98..a7c0da5b 100755 --- a/testapi.pm +++ b/testapi.pm @@ -47,7 +47,7 @@ our @EXPORT = qw($realname $username $password $serialdev %cmd %vars assert_screen check_screen assert_and_dclick save_screenshot assert_and_click mouse_hide mouse_set mouse_click - mouse_dclick mouse_tclick match_has_tag + mouse_dclick mouse_tclick match_has_tag click_lastmatch assert_script_run script_run assert_script_sudo script_sudo script_output validate_script_output @@ -482,14 +482,39 @@ Throws C exception if C<$timeout> timeout is hit. Default timeout sub assert_and_click { my ($mustmatch, %args) = @_; - $args{timeout} //= $bmwqemu::default_timeout; + $args{timeout} //= $bmwqemu::default_timeout; + + $last_matched_needle = assert_screen($mustmatch, $args{timeout}); + bmwqemu::log_call(mustmatch => $mustmatch, %args); + + my %click_args = map { $_ => $args{$_} } qw(button dclick mousehide); + return click_lastmatch(%click_args); +} + +=head2 click_lastmatch + + click_lastmatch([, button => $button] [, clicktime => $clicktime ] [, dclick => 1 ] [, mousehide => 1 ]); + +Click C<$button> at the "click_point" position as defined in the needle JSON file +of the last matched needle, or - if the JSON has not explicit "click_point" - +in the middle of the last match area. If C<$dclick> is set, do double click +instead. Supported values for C<$button> are C<'left'> and C<'right'>, C<'left'> +is the default. If C<$mousehide> is true then always move mouse to the 'hidden' +position after clicking to prevent to disturb the area where user wants to +assert/click in second step, otherwise move the mouse back to its previous +position. + +=cut + +sub click_lastmatch { + my %args = @_; $args{button} //= 'left'; $args{dclick} //= 0; $args{mousehide} //= 0; - $last_matched_needle = assert_screen($mustmatch, $args{timeout}); + return unless $last_matched_needle; + my $old_mouse_coords = query_isotovideo('backend_get_last_mouse_set'); - bmwqemu::log_call(mustmatch => $mustmatch, %args); # determine click coordinates from the last area which has those explicitly specified my $relevant_area; -- 2.23.0