Tuesday, May 14, 2013

Mojo::UserAgent dom parsing is FUN!

I'm about to roll out a new feature at work. I've added new data to the "schema" behind some of our pages and another team has implemented the template changes.

Now, How do I test that feature appears on the page? And by "on the page" I mean embedded attributes into a javascript call on the page.

I used Mojo::UserAgent and it's built in dom handling to make this easy-peasy! Load the page, look for script tags, find the one calling our Magic.Marker function and then use a regex to pull the args. Wrap it all up in Test::Most and throw some data into _DATA_!

ps. Writing his post took considerably longer than writing this test.

#!/usr/bin/perl
use v5.12;

use Mojo::UserAgent;
use List::Util qw(first);
use Test::Most;

my $ua = Mojo::UserAgent->new();
sub x_param_from_url
{
    # load URL and find the first script block that 
    # contains Magic.Marker.  Parse Magic.Marker args 
    # for items like "{ x: value }" and return all the 
    # values found.
    my $url     = shift;
    my @scripts = $ua->get($url)->res->dom->find('script')->each();
    my $script  = first { $_->all_text =~ /Magic\.Marker/ } @scripts;
    return unless $script;
    
    my $text = $script->all_text;
    my @matches = ( $text =~ m/\{ \s* x \s* : \s* (\S+) \s* \}/gimx );
    return @matches;
}

foreach my $data (<DATA>)
{
    chomp $data;
    my ( $url, @expected ) = split( /\s/, $data );
    # redirect to the internal-staging server
    my $url =~ s/www.example.com/internal-staging.example.com/;
    my @output = x_param_from_url($url);
    eq_or_diff( \@output, \@expected, "$url")
}
done_testing

__DATA__
www.example.com/how-to_123  '2' '3'
www.example.com/why-not-1234 '1' '2'
www.example.com/why-not-777 '3'
This produces a lovely TAP output for the site:
% ./verify.pl

not ok 1 - internal-staging.example.com/how-to_123
#   Failed test 'internal-staging.example.com/how-to_123'
#   at ./verify.pl line 35.
# +----+---------+----+----------+
# | Elt|Got      | Elt|Expected  |
# +----+---------+----+----------+
# |   0|'\'2\''  |   0|'\'2\''   |
# |    |         *   1|'\'3\''   *
# +----+---------+----+----------+
ok 2 - internal-staging.example.com/how-to_123
ok 3 - internal-staging.example.com/why-not-777

No comments: