Skip to content

Instantly share code, notes, and snippets.

@jberger
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jberger/493850ba69b13f2c6b42 to your computer and use it in GitHub Desktop.
Save jberger/493850ba69b13f2c6b42 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
package Test::Mojo::Phantom;
use Mojo::Base -strict;
use Test::More ();
use File::Temp ();
use Mojo::Util;
use Mojo::IOLoop;
use Mojo::IOLoop::Stream;
use Mojo::JSON 'j';
use constant DEBUG => $ENV{TEST_MOJO_PHANTOM_DEBUG};
sub phantom_raw {
my $cb = pop;
my ($js, $read) = @_;
my $tmp = File::Temp->new(SUFFIX => '.js');
Mojo::Util::spurt($js => "$tmp");
my $pid = open my $phantom, '-|', 'phantomjs', "$tmp";
die 'Could not spawn' unless defined $pid;
my $stream = Mojo::IOLoop::Stream->new($phantom);
if ($read) { $stream->on(read => $read) }
my $id = Mojo::IOLoop->stream($stream);
$stream->on(close => sub {
waitpid $pid, 0;
undef $tmp;
Mojo::IOLoop->remove($id);
$cb->(undef);
});
}
sub phantom {
my $t = shift;
my $js = pop;
my $url = $t->app->url_for(@_);
unless ($url->is_abs) {
my $base = $t->ua->server->nb_url;
$url = $url->to_abs($base);
}
my $sep = '--__TEST_MOJO_PHANTOM__--';
my $lib = <<' LIB';
function test(args) {
var system = require('system');
system.stdout.writeLine(JSON.stringify(args));
system.stdout.writeLine('%s');
system.stdout.flush();
}
var page = require('webpage').create();
page.open('%s', function(status) {
%s;
phantom.exit();
});
LIB
$js = sprintf $lib, $sep, $url, $js;
warn "Test::Mojo >>>> Phantom: $js" if DEBUG;
my $buffer = '';
my $read = sub {
my ($stream, $bytes) = @_;
warn "Test::Mojo <<<< Phantom: $bytes" if DEBUG;
$buffer .= $bytes;
while ($buffer =~ s/^(.*)\n$sep\n//) {
my ($test, @args) = @{ j $1 };
Test::More->can($test)->(@args);
}
};
Mojo::IOLoop->delay(sub{
phantom_raw($js, $read, shift->begin);
})->wait;
}
package main;
use Mojolicious::Lite;
any '/' => 'main';
use Test::More;
use Test::Mojo;
my $t = Test::Mojo->new;
my $phantom = \&Test::Mojo::Phantom::phantom;
ok 1, 'from mojo';
my $js = <<'JS';
test(['ok', 1, 'ok from phantomjs']);
test(['is', status, 'success', 'status check']);
var text = page.evaluate(function(){
return document.getElementsByTagName('p')[0].innerHTML;
})
test(['is', text, 'Goodbye', 'code evaluation']);
JS
$t->$phantom('main', $js);
done_testing;
__DATA__
@@ main.html.ep
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<p>Hello</p>
%= javascript begin
$(function(){ $('p').text('Goodbye') });
% end
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment