example.pl 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. use strict;
  2. use warnings;
  3. use Data::Dumper;
  4. use Playwright;
  5. use Try::Tiny;
  6. my $handle = Playwright->new( debug => 1 );
  7. # Open a new chrome instance
  8. my $browser = $handle->launch( headless => 1, type => 'firefox' );
  9. my $process = $handle->server( browser => $browser, command => 'process' );
  10. print "Browser PID: ".$process->{pid}."\n";
  11. # Open a tab therein
  12. my $page = $browser->newPage({ videosPath => 'video', acceptDownloads => 1 });
  13. # Test the spec method
  14. print Dumper($page->spec(),$page);
  15. # Browser contexts don't exist until you open at least one page.
  16. # You'll need this to grab and set cookies.
  17. my ($context) = @{$browser->contexts()};
  18. # Load a URL in the tab
  19. my $res = $page->goto('http://google.com', { waitUntil => 'networkidle' });
  20. print Dumper($res->status(), $browser->version());
  21. # Put your hand in the jar
  22. my $cookies = $context->cookies();
  23. print Dumper($cookies);
  24. # Grab the main frame, in case this is a frameset
  25. my $frameset = $page->mainFrame();
  26. print Dumper($frameset->childFrames());
  27. # Run some JS
  28. my $fun = "
  29. var input = arguments[0];
  30. return {
  31. width: document.documentElement.clientWidth,
  32. height: document.documentElement.clientHeight,
  33. deviceScaleFactor: window.devicePixelRatio,
  34. arg: input
  35. };";
  36. my $result = $page->evaluate($fun, 'zippy');
  37. print Dumper($result);
  38. # Read the console
  39. $page->on('console',"return [...arguments]");
  40. my $promise = $page->waitForEvent('console');
  41. #XXX this *can* race
  42. sleep 1;
  43. $page->evaluate("console.log('hug')");
  44. my $console_log = $handle->await( $promise );
  45. print "Logged to console: '".$console_log->text()."'\n";
  46. # Use a selector to find which input is visible and type into it
  47. # Ideally you'd use a better selector to solve this problem, but this is just showing off
  48. my $inputs = $page->selectMulti('input');
  49. foreach my $input (@$inputs) {
  50. try {
  51. # Pretty much a brute-force approach here, again use a better pseudo-selector instead like :visible
  52. $input->fill('tickle', { timeout => 250 } );
  53. } catch {
  54. print "Element not visible, skipping...\n";
  55. }
  56. }
  57. # Said better selector
  58. my $actual_input = $page->select('input[name=q]');
  59. $actual_input->fill('whee');
  60. # Ensure we can grab the parent (convenience)
  61. print "Got Parent: ISA ".ref($actual_input->{parent})."\n";
  62. # Take screen of said element
  63. $actual_input->screenshot({ path => 'test.jpg' });
  64. # Fiddle with HIDs
  65. my $mouse = $page->mouse;
  66. $mouse->move( 0, 0 );
  67. my $keyboard = $page->keyboard();
  68. $keyboard->type('F12');
  69. # Start to do some more advanced actions with the page
  70. use FindBin;
  71. use Cwd qw{abs_path};
  72. my $pg = abs_path("$FindBin::Bin/at/test.html");
  73. # Handle dialogs on page start, and dialog after dialog
  74. # NOTE -- the 'load' event won't fire until the dialog is dismissed in some browsers
  75. $promise = $page->waitForEvent('dialog');
  76. $page->goto("file://$pg", { waitUntil => 'networkidle' });
  77. my $dlg = $handle->await($promise);
  78. $promise = $page->waitForEvent('dialog');
  79. $dlg->dismiss();
  80. $dlg = $handle->await($promise);
  81. $dlg->accept();
  82. # Download stuff -- note this requries acceptDownloads = true in the page open
  83. # NOTE -- the 'download' event fires unreliably, as not all browsers properly obey the 'download' property in hrefs.
  84. # Chrome, for example would choke here on an intermediate dialog.
  85. $promise = $page->waitForEvent('download');
  86. $page->select('#d-lo')->click();
  87. my $download = $handle->await( $promise );
  88. print "Download suggested filename\n";
  89. print $download->suggestedFilename()."\n";
  90. $download->saveAs('test2.jpg');
  91. # Fiddle with file inputs
  92. my $choochoo = $page->waitForEvent('filechooser');
  93. $page->select('#drphil')->click();
  94. my $chooseu = $handle->await( $choochoo );
  95. $chooseu->setFiles('test.jpg');
  96. # Make sure we can do child selectors
  97. my $parent = $page->select('body');
  98. my $child = $parent->select('#drphil');
  99. print ref($child)."\n";
  100. # Test out pusht/popt/try_until
  101. # Timeouts are in milliseconds
  102. Playwright::pusht($page,5000);
  103. my $checkpoint = time();
  104. my $element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');
  105. my $elapsed = time() - $checkpoint;
  106. Playwright::popt($page);
  107. print "Waited $elapsed seconds for timeout to drop\n";
  108. $checkpoint = time();
  109. $element = Playwright::try_until($page, 'select', 'bogus-bogus-nothere');
  110. $elapsed = time() - $checkpoint;
  111. print "Waited $elapsed seconds for timeout to drop\n";
  112. # Try out the API testing extensions
  113. print "HEAD http://google.com : \n";
  114. my $fr = $page->request;
  115. my $resp = $fr->fetch("http://google.com", { method => "HEAD" });
  116. print Dumper($resp->headers());
  117. print "200 OK\n" if $resp->status() == 200;
  118. # Save a video now that we are done
  119. my $bideo = $page->video;
  120. # IT IS IMPORTANT TO CLOSE THE PAGE FIRST OR THIS WILL HANG!
  121. $page->close();
  122. my $vidpath = $bideo->saveAs('video/example.webm');