Skip to content

Commit

Permalink
Fix #51: add host option to connect to remote hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
teodesian committed Dec 29, 2022
1 parent 93abe7b commit 1ab18b6
Show file tree
Hide file tree
Showing 13 changed files with 295 additions and 161 deletions.
4 changes: 4 additions & 0 deletions conf/Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Revision history for Playwright

1.291 2022-12-28 TEODESIAN
- Add 'port' mechanism to connect to remote instances of playwright_server
- Add systemd service files for running things in user mode. See service/Readme.md

1.251 2022-08-21 TEODESIAN
- Fix some undef value warnings in odd situations when using the --port option.

Expand Down
2 changes: 1 addition & 1 deletion dist.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = Playwright
version = 1.251
version = 1.291
author = George S. Baugh <[email protected]>
license = MIT
copyright_holder = Troglodyne LLC
Expand Down
310 changes: 164 additions & 146 deletions example.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5,152 +5,170 @@
use Playwright;
use Try::Tiny;

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 });

# Test the spec method
print Dumper($page->spec(),$page);

# Browser contexts don't exist until you open at least one page.
# You'll need this to grab and set cookies.
my ($context) = @{$browser->contexts()};

# Load a URL in the tab
my $res = $page->goto('http://google.com', { waitUntil => 'networkidle' });
print Dumper($res->status(), $browser->version());

# Put your hand in the jar
my $cookies = $context->cookies();
print Dumper($cookies);

# Grab the main frame, in case this is a frameset
my $frameset = $page->mainFrame();
print Dumper($frameset->childFrames());

# Run some JS
my $fun = "
var input = arguments[0];
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
arg: input
};";
my $result = $page->evaluate($fun, 'zippy');
print Dumper($result);

# Read the console
$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 );

print "Logged to console: '".$console_log->text()."'\n";

# Use a selector to find which input is visible and type into it
# Ideally you'd use a better selector to solve this problem, but this is just showing off
my $inputs = $page->selectMulti('input');

foreach my $input (@$inputs) {
try {
# Pretty much a brute-force approach here, again use a better pseudo-selector instead like :visible
$input->fill('tickle', { timeout => 250 } );
} catch {
print "Element not visible, skipping...\n";
{
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 });

# Test the spec method
print Dumper($page->spec(),$page);

# Browser contexts don't exist until you open at least one page.
# You'll need this to grab and set cookies.
my ($context) = @{$browser->contexts()};

# Load a URL in the tab
my $res = $page->goto('http://troglodyne.net', { waitUntil => 'networkidle' });
print Dumper($res->status(), $browser->version());

# Put your hand in the jar
my $cookies = $context->cookies();
print Dumper($cookies);

# Grab the main frame, in case this is a frameset
my $frameset = $page->mainFrame();
print Dumper($frameset->childFrames());

# Run some JS
my $fun = "
var input = arguments[0];
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio,
arg: input
};";
my $result = $page->evaluate($fun, 'zippy');
print Dumper($result);

# Read the console
$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 );

print "Logged to console: '".$console_log->text()."'\n";

# Use a selector to find which input is visible and type into it
# Ideally you'd use a better selector to solve this problem, but this is just showing off
my $inputs = $page->selectMulti('input');

foreach my $input (@$inputs) {
try {
# Pretty much a brute-force approach here, again use a better pseudo-selector instead like :visible
$input->fill('tickle', { timeout => 250 } );
} catch {
print "Element not visible, skipping...\n";
}
}

# Said better selector
my $actual_input = $page->select('input[name=like]');
$actual_input->fill('whee');

# Ensure we can grab the parent (convenience)
print "Got Parent: ISA ".ref($actual_input->{parent})."\n";

# Take screen of said element
$actual_input->screenshot({ path => 'test.jpg' });

# Fiddle with HIDs
my $mouse = $page->mouse;
$mouse->move( 0, 0 );
my $keyboard = $page->keyboard();
$keyboard->type('F12');

# Start to do some more advanced actions with the page
use FindBin;
use Cwd qw{abs_path};
my $pg = abs_path("$FindBin::Bin/at/test.html");

# Handle dialogs on page start, and dialog after dialog
# NOTE -- the 'load' event won't fire until the dialog is dismissed in some browsers
$promise = $page->waitForEvent('dialog');
$page->goto("file://$pg", { waitUntil => 'networkidle' });

my $dlg = $handle->await($promise);
$promise = $page->waitForEvent('dialog');
$dlg->dismiss();
$dlg = $handle->await($promise);
$dlg->accept();

# Download stuff -- note this requries acceptDownloads = true in the page open
# NOTE -- the 'download' event fires unreliably, as not all browsers properly obey the 'download' property in hrefs.
# Chrome, for example would choke here on an intermediate dialog.
$promise = $page->waitForEvent('download');
$page->select('#d-lo')->click();

my $download = $handle->await( $promise );

print "Download suggested filename\n";
print $download->suggestedFilename()."\n";
$download->saveAs('test2.jpg');

# Fiddle with file inputs
my $choochoo = $page->waitForEvent('filechooser');
$page->select('#drphil')->click();
my $chooseu = $handle->await( $choochoo );
$chooseu->setFiles('test.jpg');

# Make sure we can do child selectors
my $parent = $page->select('body');
my $child = $parent->select('#drphil');
print ref($child)."\n";

# Test out pusht/popt/try_until

# Timeouts are in milliseconds
Playwright::pusht($page,5000);
my $checkpoint = time();
my $element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');

my $elapsed = time() - $checkpoint;
Playwright::popt($page);
print "Waited $elapsed seconds for timeout to drop\n";

$checkpoint = time();
$element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');
$elapsed = time() - $checkpoint;
print "Waited $elapsed seconds for timeout to drop\n";

# Try out the API testing extensions
print "HEAD http://troglodyne.net : \n";
my $fr = $page->request;
my $resp = $fr->fetch("http://troglodyne.net", { method => "HEAD" });
print Dumper($resp->headers());
print "200 OK\n" if $resp->status() == 200;

# 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');
}

# Example of using persistent mode / remote hosts
{
my $handle = Playwright->new( debug => 1 );
my $handle2 = Playwright->new( debug => 1, host => 'localhost', port => $handle->{port} );

my $browser = $handle2->launch( headless => 1, type => 'firefox' );
my $process = $handle2->server( browser => $browser, command => 'process' );
print "Browser PID: ".$process->{pid}."\n";

}

# Said better selector
my $actual_input = $page->select('input[name=q]');
$actual_input->fill('whee');

# Ensure we can grab the parent (convenience)
print "Got Parent: ISA ".ref($actual_input->{parent})."\n";

# Take screen of said element
$actual_input->screenshot({ path => 'test.jpg' });

# Fiddle with HIDs
my $mouse = $page->mouse;
$mouse->move( 0, 0 );
my $keyboard = $page->keyboard();
$keyboard->type('F12');

# Start to do some more advanced actions with the page
use FindBin;
use Cwd qw{abs_path};
my $pg = abs_path("$FindBin::Bin/at/test.html");

# Handle dialogs on page start, and dialog after dialog
# NOTE -- the 'load' event won't fire until the dialog is dismissed in some browsers
$promise = $page->waitForEvent('dialog');
$page->goto("file://$pg", { waitUntil => 'networkidle' });

my $dlg = $handle->await($promise);
$promise = $page->waitForEvent('dialog');
$dlg->dismiss();
$dlg = $handle->await($promise);
$dlg->accept();

# Download stuff -- note this requries acceptDownloads = true in the page open
# NOTE -- the 'download' event fires unreliably, as not all browsers properly obey the 'download' property in hrefs.
# Chrome, for example would choke here on an intermediate dialog.
$promise = $page->waitForEvent('download');
$page->select('#d-lo')->click();

my $download = $handle->await( $promise );

print "Download suggested filename\n";
print $download->suggestedFilename()."\n";
$download->saveAs('test2.jpg');

# Fiddle with file inputs
my $choochoo = $page->waitForEvent('filechooser');
$page->select('#drphil')->click();
my $chooseu = $handle->await( $choochoo );
$chooseu->setFiles('test.jpg');

# Make sure we can do child selectors
my $parent = $page->select('body');
my $child = $parent->select('#drphil');
print ref($child)."\n";

# Test out pusht/popt/try_until

# Timeouts are in milliseconds
Playwright::pusht($page,5000);
my $checkpoint = time();
my $element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');

my $elapsed = time() - $checkpoint;
Playwright::popt($page);
print "Waited $elapsed seconds for timeout to drop\n";

$checkpoint = time();
$element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');
$elapsed = time() - $checkpoint;
print "Waited $elapsed seconds for timeout to drop\n";

# Try out the API testing extensions
print "HEAD http://google.com : \n";
my $fr = $page->request;
my $resp = $fr->fetch("http://google.com", { method => "HEAD" });
print Dumper($resp->headers());
print "200 OK\n" if $resp->status() == 200;

# 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');
# Clean up, since we left survivors
require './bin/reap_playwright_servers';
Playwright::ServerReaper::main();
0;
Loading

0 comments on commit 1ab18b6

Please sign in to comment.