Firefox-Profile.t 5.5 KB

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