Преглед изворни кода

Fix docu links, expand documentation & prevent double destroy

George S. Baugh пре 4 година
родитељ
комит
ed6e2e4046
1 измењених фајлова са 58 додато и 10 уклоњено
  1. 58 10
      lib/Playwright.pm

+ 58 - 10
lib/Playwright.pm

@@ -3,6 +3,7 @@ package Playwright;
 use strict;
 use warnings;
 
+#ABSTRACT: Perl client for Playwright
 use 5.006;
 use v5.28.0;    # Before 5.006, v5.10.0 would not be understood.
 
@@ -24,10 +25,6 @@ use Carp qw{confess};
 use Playwright::Base();
 use Playwright::Util();
 
-#ABSTRACT: Perl client for Playwright
-use 5.006;
-use v5.28.0;    # Before 5.006, v5.10.0 would not be understood.
-
 no warnings 'experimental';
 use feature qw{signatures};
 
@@ -50,10 +47,40 @@ Checks and automatically installs a copy of the node dependencies in the local f
 
 Currently understands commands you can send to all the playwright classes defined in api.json (installed wherever your OS puts shared files for CPAN distributions).
 
-See L<https://playwright.dev/#version=master&path=docs%2Fapi.md&q=>
+See L<https://playwright.dev/versions> and drill down into your relevant version (run `npm list playwright` ) 
 for what the classes do, and their usage.
 
-There are two major exceptions in how things work versus the documentation.
+All the classes mentioned there will correspond to a subclass of the Playwright namespace.  For example:
+
+    # ISA Playwright
+    my $playwright = Playwright->new();
+    # ISA Playwright::BrowserContext
+    my $ctx = $playwright->newContext(...);
+    # ISA Playwright::Page
+    my $page = $ctx->newPage(...);
+    # ISA Playwright::ElementHandle
+    my $element = $ctx->select('body');
+
+See example.pl for a more thoroughly fleshed-out display on how to use this module.
+
+=head3 Why this documentation does not list all available subclasses and their methods
+
+The documentation and names for the subclasses of Playwright follow the spec strictly:
+
+Playwright::BrowserContext => L<https://playwright.dev/docs/api/class-browsercontext>
+Playwright::Page           => L<https://playwright.dev/docs/api/class-page>
+Playwright::ElementHandle  => L<https://playwright.dev/docs/api/class-elementhandle>
+
+...And so on.  100% of the spec is accessible regardless of the Playwright version installed
+due to these classes & their methods being built dynamically at run time based on the specification
+which is shipped with Playwright itself.
+
+You can check what methods are installed for each subclass by doing the following:
+
+    use Data::Dumper;
+    print Dumper($instance->{spec});
+
+There are two major exceptions in how things work versus the upstream Playwright documentation, detailed below in the C<Selectors> section.
 
 =head2 Selectors
 
@@ -87,11 +114,25 @@ To maximize the usefulness of these, I have wrapped the string passed with the f
 
 As such you can effectively treat the script string as a function body.
 The same restriction on only being able to pass one arg remains from the upstream:
-L<https://playwright.dev/#version=master&path=docs%2Fapi.md&q=pageevaluatepagefunction-arg>
+L<https://playwright.dev/docs/api/class-page#pageevalselector-pagefunction-arg>
 
 You will have to refer to the arguments array as described here:
 L<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments>
 
+=head3 example of evaluate()
+
+    # Read the console
+    $page->on('console',"return [...arguments]");
+
+    my $promise = $page->waitForEvent('console');
+    #TODO This request can race, the server framework I use to host the playwright spec is *not* FIFO (YET)
+    sleep 1;
+    $page->evaluate("console.log('hug')");
+    my $console_log = $handle->await( $promise );
+
+    print "Logged to console: '".$console_log->text()."'\n";
+
+
 =head2 Asynchronous operations
 
 The waitFor* methods defined on various classes will return an instance of L<AsyncData>, a part of the L<Async> module.
@@ -108,6 +149,8 @@ You will then need to wait on the result of the backgrounded action with the awa
 If you install this module from CPAN, you will likely encounter a croak() telling you to install node module dependencies.
 Follow the instructions and things should be just fine.
 
+If you aren't, please file a bug!
+
 =head1 CONSTRUCTOR
 
 =head2 new(HASH) = (Playwright)
@@ -316,7 +359,7 @@ sub _check_and_build_spec ($self) {
 =head2 launch(HASH) = Playwright::Browser
 
 The Argument hash here is essentially those you'd see from browserType.launch().  See:
-L<https://playwright.dev/#version=v1.5.1&path=docs%2Fapi.md&q=browsertypelaunchoptions>
+L<https://playwright.dev/docs/api/class-browsertype#browsertypelaunchoptions>
 
 There is an additional "special" argument, that of 'type', which is used to specify what type of browser to use, e.g. 'firefox'.
 
@@ -370,11 +413,16 @@ Automatically called when the Playwright object goes out of scope.
 =cut
 
 sub quit ($self) {
+    # Prevent double destroy after quit()
+    return if $self->{killed};
 
-#Prevent destructor from firing in child processes so we can do things like async()
+    # Prevent destructor from firing in child processes so we can do things like async()
+    # This should also prevent the waitpid below from deadlocking due to two processes waiting on the same pid.
     return unless $$ == $self->{parent};
 
+    $self->{killed} = 1;
     Playwright::Util::request( 'GET', 'shutdown', $self->{port}, $self->{ua} );
+
     return waitpid( $self->{pid}, 0 );
 }
 
@@ -398,4 +446,4 @@ sub _start_server ( $port, $debug ) {
     exec( $node_bin, $server_bin, "-p", $port, $debug );
 }
 
-1;
+1;