1
0

Firefox-Profile.t 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. use strict;
  2. use warnings;
  3. use Selenium::Remote::Driver;
  4. use Test::More;
  5. use MIME::Base64 qw/decode_base64/;
  6. use IO::Uncompress::Unzip qw(unzip $UnzipError);
  7. use File::Temp;
  8. use JSON;
  9. use Selenium::Remote::Mock::RemoteConnection;
  10. use Selenium::Firefox::Profile;
  11. use FindBin;
  12. use lib $FindBin::Bin . '/lib';
  13. use TestHarness;
  14. $Selenium::Remote::Driver::FORCE_WD2 = 1;
  15. my $harness = TestHarness->new(
  16. this_file => $FindBin::Script
  17. );
  18. my %selenium_args = %{ $harness->base_caps };
  19. my $fixture_dir = $FindBin::Bin . '/www/';
  20. CUSTOM_EXTENSION_LOADED: {
  21. my $profile = Selenium::Firefox::Profile->new;
  22. my $domain = $harness->domain;
  23. my $website = $harness->website;
  24. my $mock_encoded_profile = $fixture_dir . 'encoded_profile.b64';
  25. my $encoded;
  26. # Set this to true to re-encode the profile. This should not need
  27. # to happen often.
  28. my $create_new_profile = 0;
  29. if ($create_new_profile) {
  30. $profile->set_preference(
  31. 'browser.startup.homepage' => $website
  32. );
  33. # This extension rewrites any page url to a single <h1>. The
  34. # following javascript is in redisplay.xpi's
  35. # resources/gempesaw/lib/main.js:
  36. # var pageMod = require("sdk/page-mod");
  37. # pageMod.PageMod({
  38. # include: "*",
  39. # contentScript: 'document.body.innerHTML = ' +
  40. # ' "<h1>Page matches ruleset</h1>";'
  41. # });
  42. $profile->add_extension($fixture_dir . 'redisplay.xpi');
  43. $encoded = $profile->_encode;
  44. open (my $fh, ">", $mock_encoded_profile);
  45. print $fh $encoded;
  46. close ($fh);
  47. }
  48. else {
  49. open (my $fh, "<", $mock_encoded_profile);
  50. $encoded = do {local $/ = undef; <$fh>};
  51. close ($fh);
  52. }
  53. my %driver_args = %selenium_args;
  54. $driver_args{extra_capabilities} = { firefox_profile => $encoded };
  55. my $driver = Selenium::Remote::Driver->new(%driver_args);
  56. ok(defined $driver, "made a driver without dying");
  57. # We don't have to `$driver->get` because our extension should do
  58. # it for us. However, the initial automatic homepage load found in
  59. # the preference 'browser.startup.homepage' isn't blocking, so we
  60. # need to wait until the page is loaded (when we can find
  61. # elements)
  62. $driver->set_implicit_wait_timeout(30000);
  63. $driver->find_element("h1", "tag_name");
  64. cmp_ok($driver->get_current_url, '=~', qr/$domain/i,
  65. "profile loaded and preference respected!");
  66. $driver->get($website . '/index.html');
  67. cmp_ok($driver->get_text("body", "tag_name"), "=~", qr/ruleset/,
  68. "custom profile with extension loaded");
  69. }
  70. PREFERENCES: {
  71. my $profile = Selenium::Firefox::Profile->new();
  72. # We're keeping the expected values together as we accumulate them
  73. # so we can validate them all at the end in the pack_and_unpack
  74. # section
  75. my $expected = {};
  76. STRINGS_AND_INTEGERS: {
  77. my $prefs = {
  78. 'string' => "howdy, there",
  79. 'integer' => 12345,
  80. 'string.like.integer' => '"12345"',
  81. };
  82. foreach (keys %$prefs) {
  83. my $q = $_ eq 'string' ? '"' : '';
  84. $expected->{$_} = $q . $prefs->{$_} . $q;
  85. }
  86. $profile->set_preference(%$prefs);
  87. foreach (keys %$prefs) {
  88. cmp_ok($profile->get_preference($_), "eq", $expected->{$_},
  89. "$_ preference is formatted properly");
  90. }
  91. }
  92. BOOLEANS: {
  93. my $prefs = {
  94. 'boolean.true' => 1,
  95. 'boolean.false' => 0,
  96. };
  97. foreach (keys %$prefs) {
  98. $expected->{$_} = $prefs->{$_} ? 'true' : 'false';
  99. }
  100. $profile->set_boolean_preference(%$prefs);
  101. foreach (keys %$prefs) {
  102. cmp_ok($profile->get_preference($_), "eq", $expected->{$_},
  103. "$_ pref is formatted correctly");
  104. }
  105. $profile->set_preference(
  106. 'boolean.true.2' => JSON::true,
  107. 'boolean.false.2' => JSON::false
  108. );
  109. is($profile->get_preference('boolean.true.2'), 'true',
  110. 'format true booleans via set_preference & JSON::true');
  111. is($profile->get_preference('boolean.false.2'), 'false',
  112. 'format false booleans via set_preference & JSON::false');
  113. }
  114. PACK_AND_UNPACK: {
  115. my $encoded = $profile->_encode();
  116. my $fh = File::Temp->new();
  117. print $fh decode_base64($encoded);
  118. close $fh;
  119. my $userjs;
  120. unzip $fh->filename => \$userjs, Name => "user.js"
  121. or die "unzip failed: $UnzipError\n";
  122. foreach (keys %$expected) {
  123. my $value = $expected->{$_};
  124. cmp_ok($userjs, "=~", qr/$value\);/,
  125. "$_ preference is formatted properly after packing and unpacking");
  126. }
  127. }
  128. MUTABLE_WEBDRIVER: {
  129. my $prefs = {
  130. 'browser.startup.homepage' => 'mutable!'
  131. };
  132. my $profile = Selenium::Firefox::Profile->new;
  133. $profile->set_preference(%$prefs);
  134. $profile->add_webdriver('port');
  135. my $homepage_pref = $profile->get_preference('browser.startup.homepage');
  136. is($homepage_pref, '"mutable!"', 'can mutate webdriver.json preferences');
  137. }
  138. }
  139. CROAKING: {
  140. my $profile = Selenium::Firefox::Profile->new;
  141. eval { $profile->add_extension('gibberish'); };
  142. cmp_ok($@, '=~', qr/File not found/i, 'throws on missing file');
  143. eval { $profile->add_extension($FindBin::Bin . '/00-load.t'); };
  144. cmp_ok($@, '=~', qr/xpi format/i, "caught invalid extension filetype");
  145. eval {
  146. $profile->add_extension($fixture_dir . 'invalid-extension.xpi') ;
  147. $profile->_encode;
  148. };
  149. ok($@ =~ /install\.rdf/i, "caught invalid extension structure");
  150. eval {
  151. my %driver_args = %selenium_args;
  152. $driver_args{firefox_profile} = 'clearly invalid';
  153. my $croakingDriver = Selenium::Remote::Driver->new(
  154. %driver_args
  155. );
  156. };
  157. ok ($@ =~ /coercion.*failed/, "caught invalid extension in driver constructor");
  158. }
  159. PROFILE_DIR: {
  160. my $tempdir = File::Temp->newdir;
  161. my $dirname = $tempdir->dirname;
  162. my $profile = Selenium::Firefox::Profile->new( profile_dir => $dirname );
  163. ok( $profile->{profile_dir} eq $dirname, "profile_dir passed to constructor" );
  164. $profile->_layout_on_disk;
  165. ok( -f $dirname . '/user.js', "wrote to profile_dir" );
  166. }
  167. done_testing;