File Coverage

blib/lib/Weasel/FindExpanders.pm
Criterion Covered Total %
statement 14 30 46.6
branch 1 8 12.5
condition 0 2 0.0
subroutine 5 6 83.3
pod 2 2 100.0
total 22 48 45.8


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3              
4             Weasel::FindExpanders - Mapping find patterns to xpath locators
5              
6             =head1 VERSION
7              
8             version 0.32
9              
10             =head1 SYNOPSIS
11              
12             use Weasel::FindExpanders qw( register_find_expander );
13              
14             register_find_expander(
15             'button',
16             'HTML',
17             sub {
18             my %args = @_;
19             $args{text} =~ s/'/''/g; # quote the quotes (XPath 2.0)
20             return ".//button[text()='$args{text}']";
21             });
22              
23             $session->find($session->page, "*button|{text=>\"whatever\"}");
24              
25             =cut
26              
27             =head1 DESCRIPTION
28              
29             The concept of I<find expanders> is used to define XPath templates for use
30             with the C<find> and C<find_all> methods. Multiple patterns may be registered
31             with the same pattern name ("mnemonic"); eg, there could be a two patterns
32             associated with the C<button> mnemonic, one for the C<< <button> >> tag and
33             one for the C<< <input type="submit"> >> tag. Or there could even be more
34             patterns registered, eg., to match Vue, React or Web Component elements.
35             All patterns registered on a single mnemonic (template name) will be compiled
36             into a single XPath expression which will match any of the patterns.
37              
38             Weasel comes with a standard set of patterns in the L<Weasel::FindExpanders::HTML>
39             package.
40              
41             =cut
42              
43             =head1 DEPENDENCIES
44              
45              
46              
47             =cut
48              
49             package Weasel::FindExpanders 0.32;
50              
51 2     2   28 use strict;
  2         5  
  2         87  
52 2     2   13 use warnings;
  2         4  
  2         136  
53              
54 2     2   14 use base 'Exporter';
  2         5  
  2         320  
55 2     2   15 use Carp;
  2         4  
  2         1045  
56              
57             our @EXPORT_OK = qw| register_find_expander expand_finder_pattern |;
58              
59             =head1 SUBROUTINES/METHODS
60              
61             =over
62              
63             =item register_find_expander($pattern_name, $group_name, &expander_function)
64              
65             Registers C<&expander_function> as an expander for C<$pattern_name> in
66             C<$group_name>.
67              
68             C<Weasel::Session> selects the expanders to be applied using its C<groups>
69             attribute.
70              
71             =cut
72              
73              
74             # Stores handlers as arrays per group
75             my %find_expanders;
76              
77             sub register_find_expander {
78 0     0 1 0 my ($pattern_name, $group, $expander_function) = @_;
79              
80 0         0 return push @{$find_expanders{$group}{$pattern_name}}, $expander_function;
  0         0  
81             }
82              
83             =item expand_finder_pattern($pattern, $args, $groups)
84              
85             Returns a string of concatenated (using xpath '|' operator) expansions.
86              
87             When C<$groups> is undef, all groups will be searched for C<pattern_name>.
88              
89             If the pattern doesn't match '*<pattern_name>|{<arguments>}', the pattern
90             is returned as the only list/arrayref element.
91              
92             =cut
93              
94             sub expand_finder_pattern {
95 2     2 1 4 my ($pattern, $args, $groups) = @_;
96              
97             ##no critic(ProhibitCaptureWithoutTest)
98 2 50       7 return $pattern
99             if ! ($pattern =~ m/^\*([^\|]+)/x);
100 0           my $name = $1;
101             ##critic(ProhibitCaptureWithoutTest)
102              
103 0 0         croak "No expansions registered (while expanding '$pattern')"
104             if scalar(keys %find_expanders) == 0;
105              
106 0   0       $groups //= [ keys %find_expanders ]; # undef --> unrestricted
107             # Using eval below to transform a hash-in-string to a hash efficiently
108              
109 0           my @matches;
110              
111 0           for my $group (@{$groups}) {
  0            
112 0 0         next if ! exists $find_expanders{$group}{$name};
113              
114             push @matches,
115 0           reverse map { $_->(%{$args}) } @{$find_expanders{$group}{$name}};
  0            
  0            
  0            
116             }
117              
118 0 0         croak "No expansions matching '$pattern'"
119             if ! @matches;
120              
121 0           return join "\n|", @matches;
122             }
123              
124             =back
125              
126             =cut
127              
128             =head1 AUTHOR
129              
130             Erik Huelsmann
131              
132             =head1 CONTRIBUTORS
133              
134             Erik Huelsmann
135             Yves Lavoie
136              
137             =head1 MAINTAINERS
138              
139             Erik Huelsmann
140              
141             =head1 BUGS AND LIMITATIONS
142              
143             Bugs can be filed in the GitHub issue tracker for the Weasel project:
144             https://github.com/perl-weasel/weasel/issues
145              
146             =head1 SOURCE
147              
148             The source code repository for Weasel is at
149             https://github.com/perl-weasel/weasel
150              
151             =head1 SUPPORT
152              
153             Community support is available through
154             L<perl-weasel@googlegroups.com|mailto:perl-weasel@googlegroups.com>.
155              
156             =head1 LICENSE AND COPYRIGHT
157              
158             (C) 2016-2023 Erik Huelsmann
159              
160             Licensed under the same terms as Perl.
161              
162             =cut
163              
164              
165             1;