Firefox-Profile.t 5.9 KB

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