George S. Baugh 4 vuotta sitten
vanhempi
sitoutus
5ec21d9ab2
4 muutettua tiedostoa jossa 67 lisäystä ja 5 poistoa
  1. 1 0
      conf/Changes
  2. 8 4
      example.pl
  3. 41 0
      lib/Playwright.pm
  4. 17 1
      playwright_server

+ 1 - 0
conf/Changes

@@ -2,6 +2,7 @@ Revision history for Playwright
 
 0.014 2021-09-09 TEODESIAN
     - Add cleanup option to Playwright::new, and bin/reap_playwright_servers to assist in cleanup when doing manual investigations.
+    - Fix issue with reference to eval() rather than evaluate()
 
 0.013 2021-08-31 TEODESIAN
     - Statically generate playwright subclasses so that callers can easily wrap them with MOPs.

+ 8 - 4
example.pl

@@ -11,13 +11,11 @@ my $handle = Playwright->new( debug => 1 );
 
 # Open a new chrome instance
 my $browser = $handle->launch( headless => 1, type => 'firefox' );
+my $process = $handle->server( browser => $browser, command => 'process' );
+print "Browser PID: ".$process->{pid}."\n";
 
 # Open a tab therein
 my $page = $browser->newPage({ videosPath => 'video', acceptDownloads => 1 });
-my $bideo = $page->video;
-
-my $vidpath = $bideo->path;
-print "Video Path: $vidpath\n";
 
 # Browser contexts don't exist until you open at least one page.
 # You'll need this to grab and set cookies.
@@ -124,3 +122,9 @@ my $parent = $page->select('body');
 my $child = $parent->select('#drphil');
 print ref($child)."\n";
 
+# Save a video now that we are done
+my $bideo = $page->video;
+
+# IT IS IMPORTANT TO CLOSE THE PAGE FIRST OR THIS WILL HANG!
+$page->close();
+my $vidpath = $bideo->saveAs('video/example.webm');

+ 41 - 0
lib/Playwright.pm

@@ -200,6 +200,19 @@ Be aware that this will prevent debug => 1 from printing extra messages from pla
 
 A convenience script has been provided to clean up these orphaned instances, `reap_playwright_servers` which will kill all extant `playwright_server` processes.
 
+=head2 Taking videos
+
+We spawn browsers via BrowserType.launchServer() and then connect to them over websocket.
+This means you can't just set paths up front and have videos recorded, the Video.path() method will throw.
+Instead you will need to call the Video.saveAs() method after closing a page to record video:
+
+    # Do stuff
+    ...
+    # Save video
+    my $video = $page->video;
+    $page->close();
+    $video->saveAs('video/example.webm');
+
 =head1 INSTALLATION NOTE
 
 If you install this module from CPAN, you will likely encounter a croak() telling you to install node module dependencies.
@@ -344,6 +357,7 @@ sub launch ( $self, %args ) {
         type => delete $args{type},
         args => [ \%args ]
     );
+
     return $Playwright::mapper{ $msg->{_type} }->( $self, $msg )
       if ( ref $msg eq 'HASH' )
       && $msg->{_type}
@@ -351,6 +365,33 @@ sub launch ( $self, %args ) {
     return $msg;
 }
 
+=head2 server (HASH) = MIXED
+
+Call Playwright::BrowserServer methods on the server which launched your browser object.
+
+Parameters:
+
+    browser : The Browser object you wish to call a server method upon.
+    command : The BrowserServer method you wish to call
+
+The most common use for this is to get the PID of the underlying browser process:
+
+    my $browser = $playwright->launch( browser => chrome );
+    my $process = $playwright->server( browser => $browser, command => 'process' );
+    print "Browser process PID: $process->{pid}\n";
+
+BrowserServer methods (at the time of writing) take no arguments, so they are not processed.
+
+=cut
+
+sub server ( $self, %args ) {
+    return Playwright::Util::request(
+        'POST', 'server', $self->{port}, $self->{ua},
+        object  => $args{browser}{guid},
+        command => $args{command},
+    );
+}
+
 =head2 await (HASH) = Object
 
 Waits for an asynchronous operation returned by the waitFor* methods to complete and returns the value.

+ 17 - 1
playwright_server

@@ -119,7 +119,10 @@ app.post('/session', async (req, res) => {
     var result;
     if ( type && browsers[type] ) {
         try {
-            var browser = await browsers[type].launch(...args);
+            var browserServer = await browsers[type].launchServer(...args);
+            var wsEndpoint = browserServer.wsEndpoint();
+            var browser = await browsers[type].connect({ wsEndpoint });
+            browser.server = browserServer;
             objects[browser._guid] = browser;
             result = { error : false, message : browser };
         } catch (e) {
@@ -131,6 +134,19 @@ app.post('/session', async (req, res) => {
     res.json(result);
 });
 
+app.post('/server', async (req, res) => {
+    var payload = req.body;
+    var object  = payload.object;
+    var command = payload.command;
+    var result = { error : true, message : "Please pass a valid browser object ID. got:", object };
+    console.log(object,command);
+    if (objects[object]) {
+        var msg = objects[object].server[command](...args);
+        result = { error : false, message : msg };
+    }
+    res.json(result);
+});
+
 app.post('/command', async (req, res) => {
 
     var payload = req.body;