generate_perl_modules.pl 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #!/usr/bin/perl
  2. # The point of this is to build skeleton classes which are then fleshed out at runtime
  3. # so that people can wrap a mop around it
  4. use strict;
  5. use warnings;
  6. use FindBin;
  7. use File::Slurper;
  8. use JSON;
  9. use lib "$FindBin::Bin/lib";
  10. use Playwright::Util;
  11. my $module_source = '';
  12. while (<DATA>) {
  13. $module_source .= $_;
  14. }
  15. # Next, grab the API JSON and iterate to build classes.
  16. our $raw = File::Slurper::read_binary("$FindBin::Bin/api.json");
  17. our $spec = JSON::decode_json($raw);
  18. $spec = Playwright::Util::arr2hash($spec,'name');
  19. our %mapper = (
  20. mouse => "
  21. =head2 mouse()
  22. Returns a Playwright::Mouse object.
  23. =cut
  24. sub mouse {
  25. my ( \$self ) = \@_;
  26. return Playwright::Mouse->new(
  27. handle => \$self,
  28. parent => \$self,
  29. id => \$self->{guid},
  30. );
  31. }\n\n",
  32. keyboard => "
  33. =head2 keyboard()
  34. Returns a Playwright::Keyboard object.
  35. =cut
  36. sub keyboard {
  37. my ( \$self ) = \@_;
  38. return Playwright::Keyboard->new(
  39. handle => \$self,
  40. parent => \$self,
  41. id => \$self->{guid},
  42. );
  43. }\n\n",
  44. );
  45. our %methods_to_rename = (
  46. '$' => 'select',
  47. '$$' => 'selectMulti',
  48. '$eval' => 'eval',
  49. '$$eval' => 'evalMulti',
  50. );
  51. our %bogus_methods = (
  52. 'querySelector' => '$',
  53. 'querySelectorAll' => '$$',
  54. 'evalOnSelector' => '$eval',
  55. 'evalOnSelectorAll' => '$$eval',
  56. );
  57. # Playwright methods we can't actually have work here
  58. our @banned = ('_api_request');
  59. my $ncallback = sub {
  60. $_[0] =~ s/#.*$//;
  61. return shift;
  62. };
  63. my @modules;
  64. foreach my $class ( keys(%$spec), 'Mouse', 'Keyboard' ) {
  65. next if $class eq 'Playwright';
  66. my $pkg = "Playwright::$class";
  67. my $subs = '';
  68. push(@modules,$pkg);
  69. my @seen;
  70. my $members = Playwright::Util::arr2hash($spec->{$class}{members},'name', $ncallback);
  71. foreach my $method ( ( keys( %$members ), 'on', 'evaluate', 'evaluateHandle' ) ) {
  72. next if grep { $_ eq $method } @banned;
  73. my $renamed = $method;
  74. $method = $bogus_methods{$method} if exists $bogus_methods{$method};
  75. $renamed = $methods_to_rename{$method} if exists $methods_to_rename{$method};
  76. next if grep { $method eq $_ } @seen;
  77. if (exists $mapper{$method}) {
  78. $subs .= $mapper{$method};
  79. } else {
  80. $subs .= "
  81. =head2 $renamed\(\@args)
  82. Execute the $class\:\:$renamed playwright routine.
  83. See L<https://playwright.dev/docs/api/class-$class#$class-$method> for more information.
  84. =cut
  85. sub $renamed {
  86. my \$self = shift;
  87. return \$self->_api_request(
  88. args => [\@_],
  89. command => '$method',
  90. object => \$self->{guid},
  91. type => \$self->{type}
  92. );
  93. }\n\n";
  94. }
  95. push(@seen,$method);
  96. }
  97. my $local_source = $module_source;
  98. $local_source =~ s/\%REPLACEME\%/$pkg/gm;
  99. $local_source =~ s/\%CLASSNAME\%/$class/gm;
  100. $local_source =~ s/\%SUBROUTINES\%/$subs/gm;
  101. open(my $fh, '>', "$FindBin::Bin/lib/Playwright/$class.pm");
  102. print $fh $local_source;
  103. close $fh;
  104. }
  105. # Now overwrite the list of modules in Playwright.pm
  106. open(my $fh, '>', "$FindBin::Bin/lib/Playwright/ModuleList.pm");
  107. print $fh "#ABSTRACT: Playwright sub classes.
  108. #PODNAME: Playwright::ModuleList
  109. # You should not use this directly; use Playwright instead.
  110. package Playwright::ModuleList;
  111. use strict;
  112. use warnings;
  113. ";
  114. foreach my $mod (@modules) {
  115. print $fh "use $mod;\n";
  116. }
  117. print $fh "\n1;\n";
  118. close($fh);
  119. 1;
  120. __DATA__
  121. # ABSTRACT: Automatically generated class for %REPLACEME%
  122. # PODNAME: %REPLACEME%
  123. # These classes used to be generated at runtime, but are now generated when the module is built.
  124. # Don't send patches against these modules, they will be ignored.
  125. # See generate_perl_modules.pl in the repository for generating this.
  126. use strict;
  127. use warnings;
  128. package %REPLACEME%;
  129. use parent 'Playwright::Base';
  130. =head1 CONSTRUCTOR
  131. =head2 new(%options)
  132. You shouldn't have to call this directly.
  133. Instead it should be returned to you as the result of calls on Playwright objects, or objects it returns.
  134. =cut
  135. sub new {
  136. my ($self,%options) = @_;
  137. $options{type} = '%CLASSNAME%';
  138. return $self->SUPER::new(%options);
  139. }
  140. =head1 METHODS
  141. =cut
  142. sub spec {
  143. return $Playwright::spec->{'%CLASSNAME%'}{members};
  144. }
  145. %SUBROUTINES%
  146. 1;