generate_perl_modules.pl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 @modules;
  60. foreach my $class ( keys(%$spec), 'Mouse', 'Keyboard' ) {
  61. next if $class eq 'Playwright';
  62. my $pkg = "Playwright::$class";
  63. my $subs = '';
  64. push(@modules,$pkg);
  65. my @seen;
  66. my $members = Playwright::Util::arr2hash($spec->{$class}{members},'name');
  67. foreach my $method ( ( keys( %$members ), 'on', 'evaluate', 'evaluateHandle' ) ) {
  68. next if grep { $_ eq $method } @banned;
  69. my $renamed = $method;
  70. $method = $bogus_methods{$method} if exists $bogus_methods{$method};
  71. $renamed = $methods_to_rename{$method} if exists $methods_to_rename{$method};
  72. next if grep { $method eq $_ } @seen;
  73. if (exists $mapper{$method}) {
  74. $subs .= $mapper{$method};
  75. } else {
  76. $subs .= "
  77. =head2 $renamed\(\@args)
  78. Execute the $class\:\:$renamed playwright routine.
  79. See L<https://playwright.dev/api/class-$class#$class-$method> for more information.
  80. =cut
  81. sub $renamed {
  82. my \$self = shift;
  83. return \$self->_api_request(
  84. args => [\@_],
  85. command => '$method',
  86. object => \$self->{guid},
  87. type => \$self->{type}
  88. );
  89. }\n\n";
  90. }
  91. push(@seen,$method);
  92. }
  93. my $local_source = $module_source;
  94. $local_source =~ s/\%REPLACEME\%/$pkg/gm;
  95. $local_source =~ s/\%CLASSNAME\%/$class/gm;
  96. $local_source =~ s/\%SUBROUTINES\%/$subs/gm;
  97. open(my $fh, '>', "$FindBin::Bin/lib/Playwright/$class.pm");
  98. print $fh $local_source;
  99. close $fh;
  100. }
  101. # Now overwrite the list of modules in Playwright.pm
  102. open(my $fh, '>', "$FindBin::Bin/lib/Playwright/ModuleList.pm");
  103. print $fh "#ABSTRACT: Playwright sub classes.
  104. #PODNAME: Playwright::ModuleList
  105. # You should not use this directly; use Playwright instead.
  106. package Playwright::ModuleList;
  107. use strict;
  108. use warnings;
  109. ";
  110. foreach my $mod (@modules) {
  111. print $fh "use $mod;\n";
  112. }
  113. print $fh "\n1;\n";
  114. close($fh);
  115. 1;
  116. __DATA__
  117. # ABSTRACT: Automatically generated class for %REPLACEME%
  118. # PODNAME: %REPLACEME%
  119. # These classes used to be generated at runtime, but are now generated when the module is built.
  120. # Don't send patches against these modules, they will be ignored.
  121. # See generate_perl_modules.pl in the repository for generating this.
  122. use strict;
  123. use warnings;
  124. package %REPLACEME%;
  125. use parent 'Playwright::Base';
  126. =head1 CONSTRUCTOR
  127. =head2 new(%options)
  128. You shouldn't have to call this directly.
  129. Instead it should be returned to you as the result of calls on Playwright objects, or objects it returns.
  130. =cut
  131. sub new {
  132. my ($self,%options) = @_;
  133. $options{type} = '%CLASSNAME%';
  134. return $self->SUPER::new(%options);
  135. }
  136. =head1 METHODS
  137. =cut
  138. sub spec {
  139. return $Playwright::spec->{'%CLASSNAME%'}{members};
  140. }
  141. %SUBROUTINES%
  142. 1;