Project

General

Profile

action #120022

Updated by JERiveraMoya over 1 year ago

#### Motivation 
 Once Yam squad is starting progressively to rewrite some YaST modules test cases with libyui-rest-api and apply a good design to them, like in this PR: https://github.com/os-autoinst/os-autoinst-distri-opensuse/pull/15496 
 we still need to improve how each step is visualized, we can see that the screenshot we provide is not in sync with the action: 
 https://openqa.opensuse.org/tests/2857887#step/yast2_firewall_stop_service/5 
 Wrapping the method, for example like this `wait_screen_change(sub { $testapi::distri->get_firewall()->start_firewall() } );` 
 See Draft PR: https://github.com/os-autoinst/os-autoinst-distri-opensuse/pull/15844/files#diff-8fc5ca29998de81bd0c818e44236ad9c51cc838bafc7429a1f30d83e43acbc3dR23 
 we can achieve: https://openqa.opensuse.org/tests/2857895#step/yast2_firewall_stop_service/8 

 The goal is to find a solution, perhaps decorator pattern in Perl or some sort of wrapping which is flexible and decoupled from the other layers. 
 Therefore in the example above we still run `$testapi::distri->get_firewall()->start_firewall()` but behind the scene the other actions will take place. But those actions should be assigned from outside, so Controller layer can have some variable to store and execute it, but doesn't know anything about testapi.pm. 

 #### Acceptance criteria 
 **AC1**: Research about potential solution to wrap functions in Perl 
 **AC2**: Define a wrapper/decorator for some methods of the Controller 
 **AC3**: **AC2**: Being able to have other Controller methods not decorated 

 #### Additional information 
 We could use this snippet as starting point: 
 ``` 
 #!/usr/bin/perl 
 use strict; 
 use warnings; 

 use experimental 'signatures'; 
 use Sub::Util 'subname'; 
 use feature qw(say); 

 # This utility function accepts a func ref and a code ref and wraps them 
 sub wrap ($func, $code) { 
     no strict; 
     no warnings 'redefine'; 
     *{ subname($func) } = $code->($func); 
 } 

 # This will be the wrapper. Like a Python decorator, it's accepts the wrapped 
 # function as the first argument, and returns a new function 
 sub debug($func) { 
     my $func_name = subname($func); 
     return sub (@args) { 
         say {*STDERR} "DEBUG: Calling $func_name(@args)"; 
         $func->(@args); 
     } 
 } 

 # You can wrap the function anywhere, but doing it before the function 
 # definition it easier to notice, and is also similar to Python decorators. 
 wrap(\&double, \&debug); 
 sub double($n) { 
     return $n * 2; 
 ``` 
 where 'debug' might be our step_decorator method where we can apply those additional functions, 
 the calls to wrap can be done at the level of Test Layer, without the need to change anything in Controller or Page. 
 Notice that we can get function reference from inner objects, so we can break this example in different clases.

Back