├── README.pod
├── t
├── 00_compile.t
├── driver
│ ├── mechanize
│ │ ├── browser.t
│ │ ├── scripting.t
│ │ ├── headers.t
│ │ ├── pages.t
│ │ └── navigation.t
│ └── selenium_server
│ │ ├── browser.t
│ │ ├── headers.t
│ │ ├── scripting.t
│ │ ├── navigation.t
│ │ └── pages.t
├── session
│ ├── external_server.t
│ ├── create_server.t
│ ├── mechanize
│ │ ├── attach_file.t
│ │ ├── click_link.t
│ │ ├── choose.t
│ │ ├── click_button.t
│ │ ├── fill_in.t
│ │ ├── check.t
│ │ └── select.t
│ └── selenium_server
│ │ ├── attach_file.t
│ │ ├── click_link.t
│ │ ├── choose.t
│ │ ├── click_button.t
│ │ ├── fill_in.t
│ │ ├── check.t
│ │ └── select.t
├── dsl.t
└── node
│ ├── mechanize
│ ├── accessor.t
│ ├── state.t
│ └── finder.t
│ └── selenium_server
│ ├── accessor.t
│ ├── state.t
│ └── finder.t
├── xt
├── perlcriticrc
├── 01_pod.t
├── 02_podcoverage.t
├── 04_perlcritic.t
└── 03_podspell.t
├── .shipit
├── lib
├── Brownie
│ ├── Helpers.pm
│ ├── Node
│ │ ├── SeleniumServer.pm
│ │ └── Mechanize.pm
│ ├── DSL.pm
│ ├── Driver
│ │ ├── Mechanize.pm
│ │ └── SeleniumServer.pm
│ ├── Driver.pm
│ ├── Node.pm
│ ├── XPath.pm
│ └── Session.pm
└── Brownie.pm
├── .gitignore
├── MANIFEST.SKIP
├── eg
└── google.pl
├── Makefile.PL
└── Changes
/README.pod:
--------------------------------------------------------------------------------
1 | lib/Brownie.pm
--------------------------------------------------------------------------------
/t/00_compile.t:
--------------------------------------------------------------------------------
1 | use Test::UseAllModules;
2 | BEGIN { all_uses_ok(); }
3 |
--------------------------------------------------------------------------------
/xt/perlcriticrc:
--------------------------------------------------------------------------------
1 | [TestingAndDebugging::ProhibitNoStrict]
2 | allow=refs
3 |
--------------------------------------------------------------------------------
/.shipit:
--------------------------------------------------------------------------------
1 | steps = FindVersion, ChangeVersion, CheckChangeLog, Manifest, DistTest, Commit, Tag, MakeDist, UploadCPAN, DistClean
2 | git.tagpattern = %v
3 | git.push_to = origin
4 |
--------------------------------------------------------------------------------
/lib/Brownie/Helpers.pm:
--------------------------------------------------------------------------------
1 | package Brownie::Helpers;
2 |
3 | use warnings;
4 | use utf8;
5 | use Carp ();
6 |
7 | sub not_implemented { Carp::croak('Not implemented') }
8 |
9 | 1;
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Build
2 | _build
3 | Makefile
4 | Makefile.old
5 | MANIFEST
6 | MANIFEST.bak
7 | META.*
8 | MYMETA.*
9 | blib
10 | cover_db
11 | cover_db_view
12 | inc
13 | nytprof
14 | nytprof.out
15 | pm_to_blib
16 | tmon.out
17 |
--------------------------------------------------------------------------------
/xt/01_pod.t:
--------------------------------------------------------------------------------
1 | use Test::More;
2 | eval "use Test::Pod 1.00";
3 | plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
4 | plan skip_all => "set TEST_POD or TEST_ALL to enable this test"
5 | unless $ENV{TEST_POD} or $ENV{TEST_ALL};
6 | all_pod_files_ok();
7 |
--------------------------------------------------------------------------------
/xt/02_podcoverage.t:
--------------------------------------------------------------------------------
1 | use Test::More;
2 | eval "use Test::Pod::Coverage 1.04";
3 | plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@;
4 | plan skip_all => "set TEST_POD or TEST_ALL to enable this test"
5 | unless $ENV{TEST_POD} or $ENV{TEST_ALL};
6 | all_pod_coverage_ok();
7 |
--------------------------------------------------------------------------------
/t/driver/mechanize/browser.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Driver::Mechanize;
5 |
6 | my $driver = Brownie::Driver::Mechanize->new;
7 |
8 | subtest 'Browser' => sub {
9 | ok $driver->browser;
10 | isa_ok $driver->browser => 'WWW::Mechanize';
11 | };
12 |
13 | done_testing;
14 |
--------------------------------------------------------------------------------
/t/driver/selenium_server/browser.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Driver::SeleniumServer;
5 |
6 | my $driver = Brownie::Driver::SeleniumServer->new;
7 |
8 | subtest 'Browser' => sub {
9 | ok $driver->browser;
10 | isa_ok $driver->browser => 'Selenium::Remote::Driver';
11 | };
12 |
13 | done_testing;
14 |
--------------------------------------------------------------------------------
/MANIFEST.SKIP:
--------------------------------------------------------------------------------
1 | \bRCS\b
2 | \bCVS\b
3 | ,v$
4 | \.svn/
5 | \.git/
6 | ~$
7 | ^#
8 | ^MANIFEST\.
9 | ^Makefile$
10 | ^Build$
11 | \.old$
12 | ^blib/
13 | ^pm_to_blib
14 | ^_build
15 | ^MakeMaker-\d
16 | \.gz$
17 | ^cover_db
18 | ^nytprof
19 | ^tmon\.out
20 | ^tools/
21 | ^author/
22 | ^MYMETA\.
23 | \.cvsignore
24 | \.gitignore
25 | \.shipit
26 | \._
27 | \.DS_Store
28 |
--------------------------------------------------------------------------------
/xt/04_perlcritic.t:
--------------------------------------------------------------------------------
1 | use Test::More;
2 | eval {
3 | require Test::Perl::Critic;
4 | Test::Perl::Critic->import(-profile => 'xt/perlcriticrc');
5 | };
6 | plan skip_all => "Test::Perl::Critic is not installed." if $@;
7 | plan skip_all => "set TEST_CRITIC or TEST_ALL to enable this test"
8 | unless $ENV{TEST_CRITIC} or $ENV{TEST_ALL};
9 | all_critic_ok('lib');
10 |
--------------------------------------------------------------------------------
/eg/google.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 |
3 | use strict;
4 | use warnings;
5 | use FindBin;
6 | use lib "$FindBin::Bin/../lib";
7 | use Test::More;
8 | use Brownie::Session;
9 |
10 | my $bs = Brownie::Session->new(driver => 'Mechanize', app_host => 'http://www.google.com');
11 | $bs->visit('/webhp');
12 |
13 | like $bs->title => qr/Google/;
14 |
15 | $bs->fill_in('q' => "Brownie\n"); # enable auto-search
16 | sleep 3;
17 |
18 | like $bs->title => qr/Brownie/i;
19 |
20 | done_testing;
21 |
--------------------------------------------------------------------------------
/t/driver/selenium_server/headers.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Exception;
5 | use Brownie::Driver::SeleniumServer;
6 |
7 | my $driver = Brownie::Driver::SeleniumServer->new;
8 |
9 | subtest 'Headers' => sub {
10 | subtest 'status_code' => sub {
11 | dies_ok { $driver->status_code } 'not supported status_code()';
12 | };
13 |
14 | subtest 'response_headers' => sub {
15 | dies_ok { $driver->response_headers } 'not supported response_headers()';
16 | };
17 | };
18 |
19 | done_testing;
20 |
--------------------------------------------------------------------------------
/t/driver/mechanize/scripting.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Exception;
5 | use Brownie::Driver::Mechanize;
6 |
7 | my $driver = Brownie::Driver::Mechanize->new;
8 |
9 | subtest 'Scripting' => sub {
10 | subtest 'execute_script' => sub {
11 | dies_ok { $driver->execute_script("document.title='execute_script'") } 'not supported execute_script()';
12 | };
13 |
14 | subtest 'evaluate_script' => sub {
15 | dies_ok { $driver->evaluate_script('1 + 2') } 'not supported evaluate_script()';
16 | };
17 | };
18 |
19 | done_testing;
20 |
--------------------------------------------------------------------------------
/t/session/external_server.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use Test::Fake::HTTPD;
6 |
7 | subtest 'use external app' => sub {
8 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
9 | $httpd->run(sub {
10 | return [ 200, [ 'Content-Type' => 'text/html' ], [ 'OK' ] ];
11 | });
12 |
13 | my $bs = Brownie::Session->new(app_host => $httpd->endpoint);
14 | ok $bs->app_host;
15 | is $bs->app_host => $httpd->endpoint;
16 |
17 | $bs->visit('/');
18 | is $bs->current_url => $bs->app_host . '/';
19 | is $bs->status_code => 200;
20 | is $bs->body => 'OK';
21 | };
22 |
23 | done_testing;
24 |
--------------------------------------------------------------------------------
/t/driver/mechanize/headers.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Brownie::Driver::Mechanize;
6 |
7 | my $driver = Brownie::Driver::Mechanize->new;
8 |
9 | my $body = '
ok';
10 |
11 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
12 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
13 |
14 | subtest 'Headers' => sub {
15 | $driver->visit($httpd->endpoint);
16 |
17 | subtest 'status_code' => sub {
18 | is $driver->status_code => '200';
19 | };
20 |
21 | subtest 'response_headers' => sub {
22 | my $headers = $driver->response_headers;
23 | isa_ok $headers => 'HTTP::Headers';
24 |
25 | my $ct = $headers->header('Content-Type');
26 | like $ct => qr!text/html!i;
27 | like $ct => qr/charset=utf-8/i;
28 | };
29 | };
30 |
31 | done_testing;
32 |
--------------------------------------------------------------------------------
/xt/03_podspell.t:
--------------------------------------------------------------------------------
1 | use Test::More;
2 | use Config ();
3 | use File::Spec ();
4 | eval "use Test::Spelling";
5 | plan skip_all => "Test::Spelling is not installed." if $@;
6 | plan skip_all => "set TEST_POD or TEST_ALL to enable this test"
7 | unless $ENV{TEST_POD} or $ENV{TEST_ALL};
8 |
9 | my $spell;
10 | for my $path (split /$Config::Config{path_sep}/ => $ENV{PATH}) {
11 | -x File::Spec->catfile($path => 'spell') and $spell = 'spell', last;
12 | -x File::Spec->catfile($path => 'ispell') and $spell = 'ispell -l', last;
13 | -x File::Spec->catfile($path => 'aspell') and $spell = 'aspell list', last;
14 | }
15 | plan skip_all => "spell/ispell/aspell are not installed." unless $spell;
16 |
17 | add_stopwords(map { split /[\s\:\-]/ } );
18 | set_spell_cmd($spell) if $spell;
19 | local $ENV{LANG} = 'C';
20 | all_pod_files_spelling_ok('lib');
21 | __DATA__
22 | NAKAGAWA Masaki
23 | masaki@cpan.org
24 | Brownie
25 |
--------------------------------------------------------------------------------
/t/driver/selenium_server/scripting.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Exception;
5 | use Test::Fake::HTTPD;
6 | use Brownie::Driver::SeleniumServer;
7 |
8 | my $driver = Brownie::Driver::SeleniumServer->new;
9 |
10 | my $body = <<__HTTPD__;
11 | ok
12 | __HTTPD__
13 |
14 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
15 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ] });
16 |
17 | subtest 'Scripting' => sub {
18 | $driver->visit($httpd->endpoint);
19 |
20 | subtest 'execute_script' => sub {
21 | lives_ok { $driver->execute_script("document.title='execute_script'") };
22 | is $driver->title => 'execute_script';
23 | };
24 |
25 | subtest 'evaluate_script' => sub {
26 | my $got;
27 | lives_ok { $got = $driver->evaluate_script('1 + 2') };
28 | is $got => 3;
29 | };
30 | };
31 |
32 | done_testing;
33 |
--------------------------------------------------------------------------------
/Makefile.PL:
--------------------------------------------------------------------------------
1 | use inc::Module::Install;
2 |
3 | name 'Brownie';
4 | license 'perl';
5 | all_from 'lib/Brownie.pm';
6 |
7 | requires 'parent';
8 | requires 'Class::Load';
9 | requires 'Sub::Install';
10 | requires 'Scalar::Util' => 1.14;
11 | requires 'URI';
12 | requires 'HTML::Selector::XPath';
13 | requires 'Plack::Runner';
14 | requires 'Test::TCP';
15 | # Mechanize
16 | requires 'WWW::Mechanize';
17 | requires 'HTML::TreeBuilder::XPath';
18 | # SeleniumServer
19 | requires 'Selenium::Remote::Driver';
20 | requires 'Selenium::Server';
21 | requires 'File::Slurp';
22 | requires 'MIME::Base64';
23 |
24 | tests 't/*.t t/*/*.t t/*/mechanize/*.t';
25 | test_requires 'Test::More' => 0.98;
26 | test_requires 'Test::UseAllModules';
27 | test_requires 'Test::Fake::HTTPD' => 0.03;
28 | test_requires 'Test::Mock::Guard';
29 | test_requires 'Test::Exception';
30 | test_requires 'File::Temp';
31 | test_requires 'URI::QueryParam';
32 |
33 | recursive_author_tests 'xt';
34 | auto_set_repository;
35 |
36 | WriteAll;
37 |
--------------------------------------------------------------------------------
/t/driver/mechanize/pages.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::Mechanize;
7 |
8 | my $driver = Brownie::Driver::Mechanize->new;
9 |
10 | my $body = <<__HTTPD__;
11 |
12 | test title
13 | Hello Brownie
14 |
15 | __HTTPD__
16 |
17 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
18 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ] });
19 |
20 | subtest 'Pages' => sub {
21 | $driver->visit($httpd->endpoint);
22 |
23 | subtest 'title' => sub {
24 | is $driver->title => 'test title';
25 | };
26 |
27 | subtest 'source' => sub {
28 | my $data = $driver->source;
29 | like $data => qr!!s;
30 | like $data => qr!!s;
31 | like $data => qr!Hello Brownie!;
32 | };
33 |
34 | subtest 'screenshot' => sub {
35 | dies_ok { $driver->screenshot };
36 | };
37 | };
38 |
39 |
40 | done_testing;
41 |
--------------------------------------------------------------------------------
/t/session/create_server.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use File::Temp;
6 |
7 | subtest 'spawn PSGI from app sub' => sub {
8 | my $app = sub { [ 201, [ 'Content-Type' => 'text/html' ], [ 'Created' ] ] };
9 |
10 | my $bs = Brownie::Session->new(app => $app);
11 | ok $bs->app_host;
12 | like $bs->app_host => qr/localhost/;
13 |
14 | $bs->visit('/');
15 | is $bs->current_url => $bs->app_host . '/';
16 | is $bs->status_code => 201;
17 | is $bs->body => 'Created';
18 | };
19 |
20 | subtest 'spawn PSGI from file' => sub {
21 | my $fh = File::Temp->new(UNLINK => 1);
22 | print $fh "sub { [ 202, [ 'Content-Type' => 'text/html' ], [ 'Accepted' ] ] };";
23 | close $fh;
24 |
25 | my $bs = Brownie::Session->new(app => $fh->filename);
26 | ok $bs->app_host;
27 | like $bs->app_host => qr/localhost/;
28 |
29 | $bs->visit('/');
30 | is $bs->current_url => $bs->app_host . '/';
31 | is $bs->status_code => 202;
32 | is $bs->body => 'Accepted';
33 | };
34 |
35 | done_testing;
36 |
--------------------------------------------------------------------------------
/Changes:
--------------------------------------------------------------------------------
1 | Revision history for Perl extension Brownie
2 |
3 | 0.09
4 | - use Selenium::Server, instead of Align::SeleniumRC (ikasam_a)
5 | - experimental Brownie::DSL (Cside)
6 | - can use external selenium server permanently (Cside)
7 |
8 | 0.08
9 | - support Selenium RemoteWebDriver (selenium-server) driver
10 | - fixed syntax error on Session.pm
11 |
12 | 0.07
13 | - added missing dependency
14 |
15 | 0.06
16 | - remove Selenium (Remote / Selenium-Server) driver
17 | - support Mechanize driver
18 | - support local app w/ Plack::Runner
19 |
20 | 0.05
21 | - does not call clear() if file attachment field
22 | - support input[not(@type)] as text field
23 |
24 | 0.04
25 | - added status_code() and response_headers() to driver I/F
26 | - tests based on shared examples
27 |
28 | 0.03
29 | - refresh current_node every time
30 |
31 | 0.02
32 | - add eg/google.pl
33 | - joining XPath
34 | - use selenium driver native find_element()
35 |
36 | 0.01
37 | - original version
38 | - implements selenium driver
39 |
--------------------------------------------------------------------------------
/t/driver/mechanize/navigation.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::Mechanize;
7 |
8 | my $driver = Brownie::Driver::Mechanize->new;
9 |
10 | my $body = <<__HTTPD__;
11 | ok
12 | __HTTPD__
13 |
14 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
15 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ] });
16 |
17 | my $base_url = $httpd->endpoint;
18 | my $other_url = $base_url->clone;
19 | $other_url->path('/foo/bar');
20 |
21 | subtest 'Navigation' => sub {
22 | subtest 'visit' => sub {
23 | lives_ok { $driver->visit($base_url) };
24 | };
25 |
26 | subtest 'current_url' => sub {
27 | for my $url ($base_url, $other_url) {
28 | $driver->visit($url);
29 | is $driver->current_url => $url;
30 | }
31 | };
32 |
33 | subtest 'current_path' => sub {
34 | for my $url ($base_url, $other_url) {
35 | $driver->visit($url);
36 | is $driver->current_path => $url->path;
37 | }
38 | };
39 | };
40 |
41 | done_testing;
42 |
--------------------------------------------------------------------------------
/t/driver/selenium_server/navigation.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::SeleniumServer;
7 |
8 | my $driver = Brownie::Driver::SeleniumServer->new;
9 |
10 | my $body = <<__HTTPD__;
11 | ok
12 | __HTTPD__
13 |
14 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
15 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ] });
16 |
17 | my $base_url = $httpd->endpoint;
18 |
19 | subtest 'Navigation' => sub {
20 | my @path = qw(
21 | /foo/bar
22 | /baz/quux
23 | );
24 |
25 | subtest 'visit' => sub {
26 | lives_ok { $driver->visit($base_url) };
27 | };
28 |
29 | subtest 'current_url' => sub {
30 | for my $path (@path) {
31 | my $url = $base_url . $path;
32 | $driver->visit($url);
33 | is $driver->current_url => $url;
34 | }
35 | };
36 |
37 | subtest 'current_path' => sub {
38 | for my $path (@path) {
39 | my $url = $base_url . $path;
40 | $driver->visit($url);
41 | is $driver->current_path => $path;
42 | }
43 | };
44 | };
45 |
46 | done_testing;
47 |
--------------------------------------------------------------------------------
/t/driver/selenium_server/pages.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use File::Temp;
7 | use Brownie::Driver::SeleniumServer;
8 |
9 | my $driver = Brownie::Driver::SeleniumServer->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 | test title
14 | Hello Brownie
15 |
16 | __HTTPD__
17 |
18 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
19 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ] });
20 |
21 | subtest 'Pages' => sub {
22 | $driver->visit($httpd->endpoint);
23 |
24 | subtest 'title' => sub {
25 | is $driver->title => 'test title';
26 | };
27 |
28 | subtest 'source' => sub {
29 | my $data = $driver->source;
30 | like $data => qr! qr!!s;
32 | like $data => qr!Hello Brownie!;
33 | };
34 |
35 | subtest 'screenshot' => sub {
36 | my $path = File::Temp->new(UNLINK => 1, suffix => '.png')->filename;
37 | ok ! -e $path;
38 |
39 | $driver->screenshot($path);
40 | ok -e $path && -s _ && -B _;
41 |
42 | unlink $path;
43 | };
44 | };
45 |
46 |
47 | done_testing;
48 |
--------------------------------------------------------------------------------
/t/dsl.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Mock::Guard;
5 | use Brownie::DSL;
6 |
7 | sub reset_test {
8 | Brownie->reset_sessions;
9 | $Brownie::Driver = 'Mechanize';
10 | $Brownie::AppHost = undef;
11 | }
12 |
13 | my $guard = mock_guard('Brownie::Driver::SeleniumServer', +{
14 | new => sub { bless +{}, shift },
15 | });
16 |
17 | subtest 'DSL methods' => sub {
18 | for my $method (@Brownie::DSL::DslMethods) {
19 | can_ok __PACKAGE__, $method;
20 | }
21 | };
22 |
23 | subtest 'page is a Brownie::Session object' => sub {
24 | isa_ok page, 'Brownie::Session';
25 | reset_test;
26 | };
27 |
28 | subtest 'driver' => sub {
29 | isa_ok page->driver, 'Brownie::Driver::Mechanize';
30 | reset_test;
31 |
32 | Brownie->driver('SeleniumServer');
33 | isa_ok page->driver, 'Brownie::Driver::SeleniumServer';
34 | reset_test;
35 | };
36 |
37 | subtest 'app host' => sub {
38 | ok ! page->app_host;
39 | reset_test;
40 |
41 | Brownie->app_host('http://example.com');
42 | is page->app_host, 'http://example.com';
43 | reset_test;
44 | };
45 |
46 | subtest 'app' => sub {
47 | ok ! page->server;
48 | reset_test;
49 |
50 | Brownie->app(sub { [ 200, [ 'Content-Type' => 'text/html' ], [ 'App' ] ] });
51 | ok page->server;
52 | reset_test;
53 | };
54 |
55 | done_testing;
56 |
--------------------------------------------------------------------------------
/t/session/mechanize/attach_file.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use File::Spec;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
26 |
27 |
28 | __HTTPD__
29 |
30 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
31 | };
32 |
33 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
34 |
35 | subtest 'attach_file' => sub {
36 | my $file_path = File::Spec->rel2abs($0);
37 |
38 | for (
39 | ['file1', 'file1'],
40 | ['File1 Label', 'file1'],
41 | ['File2 Label', 'file2'],
42 | ) {
43 | my ($locator, $id) = @$_;
44 | $bs->visit('/');
45 |
46 | ok $bs->attach_file($locator, $file_path);
47 | # XXX: should check whether file is uploaded
48 | }
49 | };
50 |
51 | done_testing;
52 |
--------------------------------------------------------------------------------
/t/session/selenium_server/attach_file.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use File::Spec;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
26 |
27 |
28 | __HTTPD__
29 |
30 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
31 | };
32 |
33 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
34 |
35 | subtest 'attach_file' => sub {
36 | my $file_path = File::Spec->rel2abs($0);
37 |
38 | for (
39 | ['file1', 'file1'],
40 | ['File1 Label', 'file1'],
41 | ['File2 Label', 'file2'],
42 | ) {
43 | my ($locator, $id) = @$_;
44 | $bs->visit('/');
45 |
46 | ok $bs->attach_file($locator, $file_path);
47 | # XXX: should check whether file is uploaded
48 | }
49 | };
50 |
51 | done_testing;
52 |
--------------------------------------------------------------------------------
/t/node/mechanize/accessor.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::Mechanize;
7 | use Brownie::Node::Mechanize;
8 |
9 | my $driver = Brownie::Driver::Mechanize->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 | test title
14 |
15 | Heading 1
16 |
19 |
20 |
21 | __HTTPD__
22 |
23 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
24 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
25 |
26 | my $base_url = $httpd->endpoint;
27 |
28 | subtest 'Accessor' => sub {
29 | $driver->visit($base_url);
30 | my $doc = $driver->find('/html');
31 |
32 | subtest 'text element' => sub {
33 | my $elem = $doc->find('h1');
34 |
35 | is $elem->tag_name => 'h1';
36 | is $elem->text => 'Heading 1';
37 | is $elem->id => 'title';
38 | is $elem->attr('title') => 'heading';
39 | };
40 |
41 | subtest 'control element' => sub {
42 | my $elem = $doc->find('#text');
43 |
44 | is $elem->tag_name => 'input';
45 | is $elem->id => 'text';
46 | is $elem->type => 'text';
47 | is $elem->name => 'text';
48 | is $elem->value => 'text value';
49 | };
50 | };
51 |
52 | done_testing;
53 |
--------------------------------------------------------------------------------
/t/node/selenium_server/accessor.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::SeleniumServer;
7 | use Brownie::Node::SeleniumServer;
8 |
9 | my $driver = Brownie::Driver::SeleniumServer->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 | test title
14 |
15 | Heading 1
16 |
19 |
20 |
21 | __HTTPD__
22 |
23 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
24 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
25 |
26 | my $base_url = $httpd->endpoint;
27 |
28 | subtest 'Accessor' => sub {
29 | $driver->visit($base_url);
30 | my $doc = $driver->find('/html');
31 |
32 | subtest 'text element' => sub {
33 | my $elem = $doc->find('h1');
34 |
35 | is $elem->tag_name => 'h1';
36 | is $elem->text => 'Heading 1';
37 | is $elem->id => 'title';
38 | is $elem->attr('title') => 'heading';
39 | };
40 |
41 | subtest 'control element' => sub {
42 | my $elem = $doc->find('#text');
43 |
44 | is $elem->tag_name => 'input';
45 | is $elem->id => 'text';
46 | is $elem->type => 'text';
47 | is $elem->name => 'text';
48 | is $elem->value => 'text value';
49 | };
50 | };
51 |
52 | done_testing;
53 |
--------------------------------------------------------------------------------
/t/session/mechanize/click_link.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
15 | Link
16 | Link
17 | Text of Link
18 | Link
19 |
20 |
21 |
22 |
23 | __HTTPD__
24 |
25 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
26 | };
27 |
28 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
29 |
30 | my @endpoints = (
31 | ['link_id', '/id'],
32 | ['Text of Link', '/text'],
33 | ['Title of Link', '/title'],
34 | ['Alt of Image', '/img/alt'],
35 | );
36 |
37 | subtest 'click_link' => sub {
38 | for (@endpoints) {
39 | my ($locator, $path) = @$_;
40 | $bs->visit('/');
41 |
42 | is $bs->current_path => '/';
43 | ok $bs->click_link($locator);
44 | is $bs->current_path => $path;
45 | }
46 | };
47 |
48 | subtest 'click_link_or_button' => sub {
49 | for (@endpoints) {
50 | my ($locator, $path) = @$_;
51 | $bs->visit('/');
52 |
53 | is $bs->current_path => '/';
54 | ok $bs->click_link_or_button($locator);
55 | is $bs->current_path => $path;
56 | }
57 | };
58 |
59 | done_testing;
60 |
--------------------------------------------------------------------------------
/t/session/selenium_server/click_link.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
15 | Link
16 | Link
17 | Text of Link
18 | Link
19 |
20 |
21 |
22 |
23 | __HTTPD__
24 |
25 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
26 | };
27 |
28 | my $bs = Brownie::Session->new(driver => 'SeleniumServer', app => $app);
29 |
30 | my @endpoints = (
31 | ['link_id', '/id'],
32 | ['Text of Link', '/text'],
33 | ['Title of Link', '/title'],
34 | ['Alt of Image', '/img/alt'],
35 | );
36 |
37 | subtest 'click_link' => sub {
38 | for (@endpoints) {
39 | my ($locator, $path) = @$_;
40 | $bs->visit('/');
41 |
42 | is $bs->current_path => '/';
43 | ok $bs->click_link($locator);
44 | is $bs->current_path => $path;
45 | }
46 | };
47 |
48 | subtest 'click_link_or_button' => sub {
49 | for (@endpoints) {
50 | my ($locator, $path) = @$_;
51 | $bs->visit('/');
52 |
53 | is $bs->current_path => '/';
54 | ok $bs->click_link_or_button($locator);
55 | is $bs->current_path => $path;
56 | }
57 | };
58 |
59 | done_testing;
60 |
--------------------------------------------------------------------------------
/t/node/mechanize/state.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::Mechanize;
7 | use Brownie::Node::Mechanize;
8 |
9 | my $driver = Brownie::Driver::Mechanize->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 |
14 | test title
15 |
16 |
17 |
18 | Heading 1
19 |
28 |
29 |
30 | __HTTPD__
31 |
32 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
33 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
34 |
35 | my $base_url = $httpd->endpoint;
36 |
37 | subtest 'State' => sub {
38 | $driver->visit($base_url);
39 | my $doc = $driver->find('/html');
40 |
41 | subtest 'visibility' => sub {
42 | ok $doc->find('h1')->is_displayed;
43 |
44 | ok $doc->find('head')->is_not_displayed;
45 | ok $doc->find('script')->is_not_displayed;
46 | ok $doc->find('#hidden')->is_not_displayed;
47 | };
48 |
49 | subtest 'selection' => sub {
50 | ok $doc->find('#check1')->is_checked;
51 | ok $doc->find('#radio1')->is_checked;
52 |
53 | ok $doc->find('#check2')->is_not_checked;
54 | ok $doc->find('#radio2')->is_not_checked;
55 | };
56 | };
57 |
58 | done_testing;
59 |
--------------------------------------------------------------------------------
/t/node/selenium_server/state.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::SeleniumServer;
7 | use Brownie::Node::SeleniumServer;
8 |
9 | my $driver = Brownie::Driver::SeleniumServer->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 |
14 | test title
15 |
16 |
17 |
18 | Heading 1
19 |
28 |
29 |
30 | __HTTPD__
31 |
32 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
33 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
34 |
35 | my $base_url = $httpd->endpoint;
36 |
37 | subtest 'State' => sub {
38 | $driver->visit($base_url);
39 | my $doc = $driver->find('/html');
40 |
41 | subtest 'visibility' => sub {
42 | ok $doc->find('h1')->is_displayed;
43 |
44 | ok $doc->find('head')->is_not_displayed;
45 | ok $doc->find('script')->is_not_displayed;
46 | ok $doc->find('#hidden')->is_not_displayed;
47 | };
48 |
49 | subtest 'selection' => sub {
50 | ok $doc->find('#check1')->is_checked;
51 | ok $doc->find('#radio1')->is_checked;
52 |
53 | ok $doc->find('#check2')->is_not_checked;
54 | ok $doc->find('#radio2')->is_not_checked;
55 | };
56 | };
57 |
58 | done_testing;
59 |
--------------------------------------------------------------------------------
/t/session/mechanize/choose.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use URI::QueryParam;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
35 |
36 |
37 | __HTTPD__
38 |
39 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
40 | };
41 |
42 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
43 |
44 | subtest 'choose' => sub {
45 | for (
46 | [ 'Radio1 Value' => [ 'radio1', 'Radio1 Label', 'Radio1 Value' ] ],
47 | [ 'Radio2 Value' => [ 'radio2', 'Radio2 Label', 'Radio2 Value' ] ],
48 | [ 'Radio3 Value' => [ 'radio3', 'Radio3 Label', 'Radio3 Value' ] ],
49 | ) {
50 | my ($value, $locators) = @$_;
51 |
52 | for my $locator (@$locators) {
53 | $bs->visit('/');
54 |
55 | ok $bs->choose($locator);
56 | $bs->click_button('submit');
57 | is $bs->current_url->query_param('radio') => $value;
58 | }
59 | }
60 | };
61 |
62 | done_testing;
63 |
--------------------------------------------------------------------------------
/t/session/selenium_server/choose.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use URI::QueryParam;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
35 |
36 |
37 | __HTTPD__
38 |
39 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
40 | };
41 |
42 | my $bs = Brownie::Session->new(driver => 'SeleniumServer', app => $app);
43 |
44 | subtest 'choose' => sub {
45 | for (
46 | [ 'Radio1 Value' => [ 'radio1', 'Radio1 Label', 'Radio1 Value' ] ],
47 | [ 'Radio2 Value' => [ 'radio2', 'Radio2 Label', 'Radio2 Value' ] ],
48 | [ 'Radio3 Value' => [ 'radio3', 'Radio3 Label', 'Radio3 Value' ] ],
49 | ) {
50 | my ($value, $locators) = @$_;
51 |
52 | for my $locator (@$locators) {
53 | $bs->visit('/');
54 |
55 | ok $bs->choose($locator);
56 | $bs->click_button('submit');
57 | is $bs->current_url->query_param('radio') => $value;
58 | }
59 | }
60 | };
61 |
62 | done_testing;
63 |
--------------------------------------------------------------------------------
/t/session/mechanize/click_button.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
21 |
22 |
23 | __HTTPD__
24 |
25 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
26 | };
27 |
28 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
29 |
30 | my @buttons = (
31 | 'input_submit',
32 | 'Input Submit Title',
33 | 'Input Submit Value',
34 | 'button_submit',
35 | 'Button Submit Title',
36 | 'Button Submit Value',
37 | 'Button Submit',
38 | );
39 |
40 | subtest 'click_button' => sub {
41 | for my $locator (@buttons) {
42 | $bs->visit('/');
43 |
44 | is $bs->current_path => '/';
45 | ok $bs->click_button($locator);
46 | is $bs->current_path => '/form';
47 | }
48 | };
49 |
50 | subtest 'click_button' => sub {
51 | for my $locator (@buttons) {
52 | $bs->visit('/');
53 |
54 | is $bs->current_path => '/';
55 | ok $bs->click_link_or_button($locator);
56 | is $bs->current_path => '/form';
57 | }
58 | };
59 |
60 | done_testing;
61 |
--------------------------------------------------------------------------------
/t/session/selenium_server/click_button.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
21 |
22 |
23 | __HTTPD__
24 |
25 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
26 | };
27 |
28 | my $bs = Brownie::Session->new(driver => 'SeleniumServer', app => $app);
29 |
30 | my @buttons = (
31 | 'input_submit',
32 | 'Input Submit Title',
33 | 'Input Submit Value',
34 | 'button_submit',
35 | 'Button Submit Title',
36 | 'Button Submit Value',
37 | 'Button Submit',
38 | );
39 |
40 | subtest 'click_button' => sub {
41 | for my $locator (@buttons) {
42 | $bs->visit('/');
43 |
44 | is $bs->current_path => '/';
45 | ok $bs->click_button($locator);
46 | is $bs->current_path => '/form';
47 | }
48 | };
49 |
50 | subtest 'click_button' => sub {
51 | for my $locator (@buttons) {
52 | $bs->visit('/');
53 |
54 | is $bs->current_path => '/';
55 | ok $bs->click_link_or_button($locator);
56 | is $bs->current_path => '/form';
57 | }
58 | };
59 |
60 | done_testing;
61 |
--------------------------------------------------------------------------------
/t/session/mechanize/fill_in.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
38 |
39 |
40 | __HTTPD__
41 |
42 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
43 | };
44 |
45 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
46 |
47 | subtest 'fill_in' => sub {
48 | for my $locator (
49 | 'text1', 'Text1 Label', 'Text1 Title',
50 | 'text2', 'Text2 Label',
51 | 'password1', 'Password1 Label',
52 | 'textarea1', 'Textarea1 Label',
53 | 'textarea2', 'Textarea2 Label',
54 | 'hidden1',
55 | ) {
56 | $bs->visit('/');
57 | my $value = time . $$;
58 |
59 | unlike $bs->current_url => qr/$value/;
60 |
61 | ok $bs->fill_in($locator, $value);
62 | $bs->click_button('submit');
63 |
64 | like $bs->current_url => qr/$value/;
65 | }
66 | };
67 |
68 | done_testing;
69 |
--------------------------------------------------------------------------------
/t/session/selenium_server/fill_in.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 |
6 | my $app = sub {
7 | my $body = <<__HTTPD__;
8 |
9 |
10 |
11 | test
12 |
13 |
14 |
38 |
39 |
40 | __HTTPD__
41 |
42 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
43 | };
44 |
45 | my $bs = Brownie::Session->new(driver => 'SeleniumServer', app => $app);
46 |
47 | subtest 'fill_in' => sub {
48 | for my $locator (
49 | 'text1', 'Text1 Label', 'Text1 Title',
50 | 'text2', 'Text2 Label',
51 | 'password1', 'Password1 Label',
52 | 'textarea1', 'Textarea1 Label',
53 | 'textarea2', 'Textarea2 Label',
54 | # XXX: selenium can not interact hidden element. 'hidden1',
55 | ) {
56 | $bs->visit('/');
57 | my $value = time . $$;
58 |
59 | unlike $bs->current_url => qr/$value/;
60 |
61 | ok $bs->fill_in($locator, $value);
62 | $bs->click_button('submit');
63 |
64 | like $bs->current_url => qr/$value/;
65 | }
66 | };
67 |
68 | done_testing;
69 |
--------------------------------------------------------------------------------
/t/session/mechanize/check.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use URI::QueryParam;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
40 |
41 |
42 | __HTTPD__
43 |
44 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
45 | };
46 |
47 | my $bs = Brownie::Session->new(driver => 'Mechanize', app => $app);
48 |
49 | subtest 'check' => sub {
50 | for (
51 | [ checkbox1 => [ 'checkbox1', 'Checkbox1 Label', 'Checkbox1 Value' ] ],
52 | [ checkbox2 => [ 'checkbox2', 'Checkbox2 Label', 'Checkbox2 Value' ] ],
53 | ) {
54 | my ($id, $locators) = @$_;
55 |
56 | for my $locator (@$locators) {
57 | $bs->visit('/');
58 |
59 | ok $bs->check($locator);
60 | $bs->click_button('submit');
61 | ok $bs->current_url->query_param($id);
62 | }
63 | }
64 | };
65 |
66 | subtest 'uncheck' => sub {
67 | for (
68 | [ checkbox3 => [ 'checkbox3', 'Checkbox3 Label', 'Checkbox3 Value' ] ],
69 | [ checkbox4 => [ 'checkbox4', 'Checkbox4 Label', 'Checkbox4 Value' ] ],
70 | ) {
71 | my ($id, $locators) = @$_;
72 |
73 | for my $locator (@$locators) {
74 | $bs->visit('/');
75 |
76 | ok $bs->uncheck($locator);
77 | $bs->click_button('submit');
78 | ok not $bs->current_url->query_param($id);
79 | }
80 | }
81 | };
82 |
83 | done_testing;
84 |
--------------------------------------------------------------------------------
/t/session/selenium_server/check.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Brownie::Session;
5 | use URI::QueryParam;
6 |
7 | my $app = sub {
8 | my $body = <<__HTTPD__;
9 |
10 |
11 |
12 | test
13 |
14 |
15 |
40 |
41 |
42 | __HTTPD__
43 |
44 | [ 200, [ 'Content-Type' => 'text/html;charset=utf-8' ], [$body] ];
45 | };
46 |
47 | my $bs = Brownie::Session->new(driver => 'SeleniumServer', app => $app);
48 |
49 | subtest 'check' => sub {
50 | for (
51 | [ checkbox1 => [ 'checkbox1', 'Checkbox1 Label', 'Checkbox1 Value' ] ],
52 | [ checkbox2 => [ 'checkbox2', 'Checkbox2 Label', 'Checkbox2 Value' ] ],
53 | ) {
54 | my ($id, $locators) = @$_;
55 |
56 | for my $locator (@$locators) {
57 | $bs->visit('/');
58 |
59 | ok $bs->check($locator);
60 | $bs->click_button('submit');
61 | ok $bs->current_url->query_param($id);
62 | }
63 | }
64 | };
65 |
66 | subtest 'uncheck' => sub {
67 | for (
68 | [ checkbox3 => [ 'checkbox3', 'Checkbox3 Label', 'Checkbox3 Value' ] ],
69 | [ checkbox4 => [ 'checkbox4', 'Checkbox4 Label', 'Checkbox4 Value' ] ],
70 | ) {
71 | my ($id, $locators) = @$_;
72 |
73 | for my $locator (@$locators) {
74 | $bs->visit('/');
75 |
76 | ok $bs->uncheck($locator);
77 | $bs->click_button('submit');
78 | ok not $bs->current_url->query_param($id);
79 | }
80 | }
81 | };
82 |
83 | done_testing;
84 |
--------------------------------------------------------------------------------
/t/node/mechanize/finder.t:
--------------------------------------------------------------------------------
1 | use strict;
2 | use warnings;
3 | use Test::More;
4 | use Test::Fake::HTTPD;
5 | use Test::Exception;
6 | use Brownie::Driver::Mechanize;
7 | use Brownie::Node::Mechanize;
8 |
9 | my $driver = Brownie::Driver::Mechanize->new;
10 |
11 | my $body = <<__HTTPD__;
12 |
13 | test title
14 |
15 |
16 | - li 1
17 | - li 2
18 | - li 3
19 | - li 4
20 | - li 5
21 |
22 |
23 | outer paragraph
24 |
25 |
inner paragraph
26 |
27 |
28 |
29 | __HTTPD__
30 |
31 | my $httpd = Test::Fake::HTTPD->new(timeout => 30);
32 | $httpd->run(sub { [ 200, [ 'Content-Type' => 'text/html; charset=utf-8' ], [ $body ] ] });
33 |
34 | my $base_url = $httpd->endpoint;
35 |
36 | subtest 'Finder' => sub {
37 | $driver->visit($base_url);
38 | my $doc = $driver->find('/html');
39 |
40 | subtest 'using XPath' => sub {
41 | subtest 'all' => sub {
42 | is scalar($doc->all('//li')) => 5;
43 | is scalar($doc->all('//li[@class="even"]')) => 2;
44 |
45 | subtest 'empty when not exist locator' => sub {
46 | lives_ok {
47 | my @elems = $doc->all('//span[@class="noexist"]');
48 | is scalar(@elems) => 0;
49 | };
50 | };
51 | };
52 |
53 | subtest 'find' => sub {
54 | is $doc->find('//li')->text => 'li 1';
55 | is $doc->find('//li[@class="even"]')->text => 'li 2';
56 |
57 | subtest 'child element' => sub {
58 | my $base = $doc->find('//div[@id="parent"]');
59 | my $child = $base->find('//p');
60 | is $child->text => 'inner paragraph';
61 | };
62 | };
63 | };
64 |
65 | subtest 'using CSS Selector' => sub {
66 | subtest 'all' => sub {
67 | is scalar($doc->all('li')) => 5;
68 | is scalar($doc->all('li.even')) => 2;
69 |
70 | subtest 'empty when not exist locator' => sub {
71 | lives_ok {
72 | my @elems = $doc->all('span.noexist');
73 | is scalar(@elems) => 0;
74 | };
75 | };
76 | };
77 |
78 | subtest 'find' => sub {
79 | is $doc->find('li')->text => 'li 1';
80 | is $doc->find('li.even')->text => 'li 2';
81 |
82 | subtest 'child element' => sub {
83 | my $base = $doc->find('#parent');
84 | my $child = $base->find('p');
85 | is $child->text => 'inner paragraph';
86 | };
87 | };
88 | };
89 | };
90 |
91 | done_testing;
92 |
--------------------------------------------------------------------------------
/lib/Brownie/Node/SeleniumServer.pm:
--------------------------------------------------------------------------------
1 | package Brownie::Node::SeleniumServer;
2 |
3 | use strict;
4 | use warnings;
5 | use parent 'Brownie::Node';
6 |
7 | sub attr {
8 | my ($self, $name) = @_;
9 | return $self->native->get_attribute($name);
10 | }
11 |
12 | sub value {
13 | my $self = shift;
14 | return $self->native->get_value;
15 | }
16 |
17 | sub text {
18 | my $self = shift;
19 | return $self->native->get_text;
20 | }
21 |
22 | sub tag_name {
23 | my $self = shift;
24 | return lc $self->native->get_tag_name;
25 | }
26 |
27 | sub is_displayed {
28 | my $self = shift;
29 | return $self->native->is_displayed;
30 | }
31 |
32 | sub is_selected {
33 | my $self = shift;
34 | return $self->native->is_selected;
35 | }
36 |
37 | sub is_checked {
38 | my $self = shift;
39 | return $self->native->is_selected;
40 | }
41 |
42 | sub set {
43 | my ($self, $value) = @_;
44 |
45 | if ($self->tag_name eq 'input' and $self->type =~ /(?:checkbox|radio)/) {
46 | $self->select;
47 | }
48 | elsif ($self->tag_name eq 'input' or $self->tag_name eq 'textarea') {
49 | $self->native->clear if $self->type ne 'file';
50 | $self->native->send_keys($value);
51 | }
52 | }
53 |
54 | sub select {
55 | my $self = shift;
56 | $self->click unless $self->is_selected;
57 | }
58 |
59 | sub unselect {
60 | my $self = shift;
61 | # TODO: check if multiple select options
62 | $self->click if $self->is_selected;
63 | }
64 |
65 | sub click {
66 | my $self = shift;
67 | $self->native->click;
68 | }
69 |
70 | 1;
71 |
72 | =head1 NAME
73 |
74 | Brownie::Node::SeleniumServer
75 |
76 | =head1 METHODS
77 |
78 | =over 4
79 |
80 | =item * C
81 |
82 | =item * C
83 |
84 | =item * C
85 |
86 | =item * C
87 |
88 | =item * C
89 |
90 | =item * C
91 |
92 | =item * C
93 |
94 | =item * C
95 |
96 | =item * C
97 |
98 | =item * C
99 |
100 | =item * C
101 |
102 | =item * C
103 |
104 | =item * C
105 |
106 | =item * C
107 |
108 | =item * C
109 |
110 | =item * C
111 |
112 | =item * C
113 |
114 | =item * C