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

Merge branch 'main' of github.com:teodesian/playwright-perl into main

George S. Baugh пре 4 година
родитељ
комит
e9a4d56f03
6 измењених фајлова са 53 додато и 6 уклоњено
  1. 7 0
      README.md
  2. 34 3
      bin/playwright_server
  3. 2 0
      example.pl
  4. 3 3
      lib/Playwright.pm
  5. 1 0
      lib/Playwright/Base.pm
  6. 6 0
      lib/Playwright/Util.pm

+ 7 - 0
README.md

@@ -26,6 +26,13 @@ Everything newer than 5.28 is supported.
 Things should work on 5.20 or newer, but...
 Tests might fail due to Temp file weirdness with Test::MockFile.
 
+## Supported OS
+
+Everything seems to work fine on OSX and Linux.
+
+On Windows, you will have to approve a UAC prompt to exempt playwright_server from being firewalled off.
+
+
 ## How2develop
 
 Everything should more or less set itself up automatically, or explode and tell you what to do.

+ 34 - 3
bin/playwright_server

@@ -14,18 +14,50 @@ const path = require('path');
 let sharedir = require.resolve('playwright'); // api.json should be shipped with playwright itself
 var theFile = path.dirname(sharedir) + '/api.json';
 let rawdata = fs.readFileSync(theFile);
+
+// On newer versions of playwright, instead of using hash tables they just lazily output arrays, so we have to convert this
 let spec = JSON.parse(rawdata);
 
-// Establish argument order for callers
+function arr2hash (arr,primary_key) {
+    var inside_out = {};
+    for (var item of arr) {
+        inside_out[item.name] = item;
+    }
+    return inside_out;
+}
+
+var fix_it=false;
+if (spec instanceof Array) {
+    fix_it = true;
+    spec = arr2hash(spec,'name');
+}
+
+// Establish argument order for callers, and correct spec array-ification
 for (var classname of Object.keys(spec)) {
+    if (spec[classname].members instanceof Array) {
+        spec[classname].members = arr2hash(spec[classname].members,'name');
+    }
     for (var method of Object.keys(spec[classname].members)) {
         var order = 0;
+        if (spec[classname].members[method].args instanceof Array) {
+            spec[classname].members[method].args = arr2hash(spec[classname].members[method].args,'name');
+        }
         for (var arg of Object.keys(spec[classname].members[method].args) ) {
             spec[classname].members[method].args[arg].order = order++;
         }
     }
 }
 
+//XXX spec is wrong here unfortunately
+if (fix_it) {
+    for (var className of ['Page','Frame']) {
+        spec[className].members.$$     = spec[className].members.querySelectorAll;
+        spec[className].members.$      = spec[className].members.querySelector;
+        spec[className].members.$$eval = spec[className].members.evalOnSelectorAll;
+        spec[className].members.$eval  = spec[className].members.evalOnSelector;
+    }
+}
+
 const argv = yargs
     .option('debug', {
         alias: 'd',
@@ -112,7 +144,6 @@ app.post('/command', async (req, res) => {
                     ...args
                 ];
             }
-
             const res = await subject[command](...args);
             result = { error : false, message : res };
 
@@ -150,7 +181,7 @@ app.post('/command', async (req, res) => {
             result = { error : true, message : e.message };
         }
     } else {
-        result = { error : true, message : "No such object, or " + command + " is not a globally recognized command for puppeteer" };
+        result = { error : true, message : "No such object, or " + command + " is not a globally recognized command for Playwright" };
     }
 
     res.json(result);

+ 2 - 0
example.pl

@@ -51,6 +51,8 @@ print Dumper($result);
 $page->on('console',"return [...arguments]");
 
 my $promise = $page->waitForEvent('console');
+#XXX this *can* race
+sleep 1;
 $page->evaluate("console.log('hug')");
 my $console_log = $handle->await( $promise );
 

+ 3 - 3
lib/Playwright.pm

@@ -18,7 +18,7 @@ use Net::EmptyPort();
 use JSON::MaybeXS();
 use File::Slurper();
 use File::Which();
-use Capture::Tiny qw{capture_stderr};
+use Capture::Tiny qw{capture capture_stderr};
 use Carp qw{confess};
 
 use Playwright::Base();
@@ -136,7 +136,6 @@ sub _check_node {
     confess("Can't locate Playwright server in '$server_bin'!")
       unless -f $server_bin;
 
-    #TODO make this portable with File::Which etc
     # Check that node and npm are installed
     $node_bin = File::Which::which('node');
     confess("node must exist and be executable") unless -x $node_bin;
@@ -149,7 +148,7 @@ sub _check_node {
     {
         #XXX the node Depsolver is deranged, global modules DO NOT WORK
         my $curdir = pushd(File::Basename::dirname($server_bin));
-        capture_stderr { $dep_raw = qx{$npm_bin list --json} };
+        ($dep_raw) = capture { system($npm_bin, qw{list --json}) };
         confess("Could not list available node modules!") unless $dep_raw;
 
         chomp $dep_raw;
@@ -307,6 +306,7 @@ sub _check_and_build_spec ($self) {
     $spec = Playwright::Util::request(
         'GET', 'spec', $self->{port}, $self->{ua},
     );
+
     confess("Could not retrieve Playwright specification.  Check that your playwright installation is correct and complete.") unless ref $spec eq 'HASH';
     return $spec;
 }

+ 1 - 0
lib/Playwright/Base.pm

@@ -72,6 +72,7 @@ sub _coerce ( $spec, %args ) {
             $args{args}[$i] = $truthy ? JSON::true : JSON::false;
         }
         elsif ( $type->{name} eq 'Object' ) {
+            $type->{properties} = Playwright::Util::arr2hash($type->{properties},'name') if ref $type->{properties} eq 'ARRAY';
             foreach my $prop ( keys( %{ $type->{properties} } ) ) {
                 next unless exists $arg->{$prop};
                 my $truthy = int( !!$arg->{$prop} );

+ 6 - 0
lib/Playwright/Util.pm

@@ -35,4 +35,10 @@ sub request ( $method, $url, $port, $ua, %args ) {
     return $msg;
 }
 
+sub arr2hash ($array,$primary_key) {
+    my $inside_out = {};
+    @$inside_out{map { $_->{$primary_key} } @$array} = @$array;
+    return $inside_out;
+}
+
 1;