Manual test suite: use more precise data when comparing image size.
[tails.git] / features / step_definitions / browser.rb
blob78c11ff156fc70d0ea1a55198848301ff50cfc86
1 # coding: utf-8
2 When /^I start the Unsafe Browser(?: through the GNOME menu)?$/ do
3   step "I start \"Unsafe Browser\" via GNOME Activities Overview"
4 end
6 When /^I successfully start the Unsafe Browser$/ do
7   step "I start the Unsafe Browser"
8   step "I see and accept the Unsafe Browser start verification"
9   step "I see the \"Starting the Unsafe Browser...\" notification after at most 60 seconds"
10   step "the Unsafe Browser has started"
11 end
13 When /^I close the (?:Tor|Unsafe) Browser$/ do
14   @screen.type("q", Sikuli::KeyModifier.CTRL)
15 end
17 def xul_application_info(application)
18   address_bar_image = "BrowserAddressBar.png"
19   unused_tbb_libs = ['libnssdbm3.so', "libmozavcodec.so", "libmozavutil.so"]
20   case application
21   when "Tor Browser"
22     user = LIVE_USER
23     binary = $vm.execute_successfully(
24       'echo ${TBB_INSTALL}/firefox.real', :libs => 'tor-browser'
25     ).stdout.chomp
26     cmd_regex = "#{binary} .* -profile /home/#{user}/\.tor-browser/profile\.default"
27     chroot = ""
28     browser_reload_button_image = "TorBrowserReloadButton.png"
29     browser_stop_button_image = "TorBrowserStopButton.png"
30     new_tab_button_image = "TorBrowserNewTabButton.png"
31   when "Unsafe Browser"
32     user = "clearnet"
33     binary = $vm.execute_successfully(
34       'echo ${TBB_INSTALL}/firefox.real', :libs => 'tor-browser'
35     ).stdout.chomp
36     cmd_regex = "#{binary} .* -profile /home/#{user}/\.unsafe-browser/profile\.default"
37     chroot = "/var/lib/unsafe-browser/chroot"
38     browser_reload_button_image = "UnsafeBrowserReloadButton.png"
39     browser_stop_button_image = "UnsafeBrowserStopButton.png"
40     new_tab_button_image = "UnsafeBrowserNewTabButton.png"
41   when "Tor Launcher"
42     user = "tor-launcher"
43     # We do not enable AppArmor confinement for the Tor Launcher.
44     binary = $vm.execute_successfully(
45       'echo ${TBB_INSTALL}/firefox-unconfined', :libs => 'tor-browser'
46     ).stdout.chomp
47     tor_launcher_install = $vm.execute_successfully(
48       'echo ${TOR_LAUNCHER_INSTALL}', :libs => 'tor-browser'
49     ).stdout.chomp
50     cmd_regex = "#{binary}\s+-app #{tor_launcher_install}/application\.ini.*"
51     chroot = ""
52     new_tab_button_image = nil
53     address_bar_image = nil
54     browser_reload_button_image = nil
55     browser_stop_button_image = nil
56     # The standalone Tor Launcher uses fewer libs than the full
57     # browser.
58     unused_tbb_libs.concat(["libfreebl3.so", "libfreeblpriv3.so", "libnssckbi.so", "libsoftokn3.so"])
59   else
60     raise "Invalid browser or XUL application: #{application}"
61   end
62   return {
63     :user => user,
64     :cmd_regex => cmd_regex,
65     :chroot => chroot,
66     :new_tab_button_image => new_tab_button_image,
67     :address_bar_image => address_bar_image,
68     :browser_reload_button_image => browser_reload_button_image,
69     :browser_stop_button_image => browser_stop_button_image,
70     :unused_tbb_libs => unused_tbb_libs,
71   }
72 end
74 When /^I open a new tab in the (.*)$/ do |browser|
75   info = xul_application_info(browser)
76   @screen.click(info[:new_tab_button_image])
77   @screen.wait(info[:address_bar_image], 10)
78 end
80 When /^I open the address "([^"]*)" in the (.*)$/ do |address, browser|
81   step "I open a new tab in the #{browser}"
82   info = xul_application_info(browser)
83   open_address = Proc.new do
84     @screen.click(info[:address_bar_image])
85     # This static here since we have no reliable visual indicators
86     # that we can watch to know when typing is "safe".
87     sleep 5
88     # The browser sometimes loses keypresses when suggestions are
89     # shown, which we work around by pasting the address from the
90     # clipboard, in one go.
91     $vm.set_clipboard(address)
92     @screen.type('v', Sikuli::KeyModifier.CTRL)
93     @screen.type(Sikuli::Key.ENTER)
94   end
95   recovery_on_failure = Proc.new do
96     @screen.type(Sikuli::Key.ESC)
97     @screen.waitVanish(info[:browser_stop_button_image], 3)
98     open_address.call
99   end
100   if browser == "Tor Browser"
101     retry_method = method(:retry_tor)
102   else
103     retry_method = Proc.new { |p, &b| retry_action(10, recovery_proc: p, &b) }
104   end
105   open_address.call
106   retry_method.call(recovery_on_failure) do
107     @screen.waitVanish(info[:browser_stop_button_image], 120)
108     @screen.wait(info[:browser_reload_button_image], 120)
109   end
112 # This step is limited to the Tor Browser due to #7502 since dogtail
113 # uses the same interface.
114 Then /^"([^"]+)" has loaded in the Tor Browser$/ do |title|
115   if @language == 'German'
116     browser_name = 'Tor-Browser'
117     reload_action = 'Neu laden'
118   else
119     browser_name = 'Tor Browser'
120     reload_action = 'Reload'
121   end
122   expected_title = "#{title} - #{browser_name}"
123   try_for(60) { @torbrowser.child(expected_title, roleName: 'frame') }
124   # The 'Reload' button (graphically shown as a looping arrow)
125   # is only shown when a page has loaded, so once we see the
126   # expected title *and* this button has appeared, then we can be sure
127   # that the page has fully loaded.
128   try_for(60) { @torbrowser.child(reload_action, roleName: 'push button') }
131 Then /^the (.*) has no plugins installed$/ do |browser|
132   step "I open the address \"about:plugins\" in the #{browser}"
133   step "I see \"TorBrowserNoPlugins.png\" after at most 30 seconds"
136 def xul_app_shared_lib_check(pid, chroot, expected_absent_tbb_libs = [])
137   absent_tbb_libs = []
138   unwanted_native_libs = []
139   tbb_libs = $vm.execute_successfully("ls -1 #{chroot}${TBB_INSTALL}/*.so",
140                                       :libs => 'tor-browser').stdout.split
141   firefox_pmap_info = $vm.execute("pmap --show-path #{pid}").stdout
142   for lib in tbb_libs do
143     lib_name = File.basename lib
144     if not /\W#{lib}$/.match firefox_pmap_info
145       absent_tbb_libs << lib_name
146     end
147     native_libs = $vm.execute_successfully(
148                        "find /usr/lib /lib -name \"#{lib_name}\""
149                                            ).stdout.split
150     for native_lib in native_libs do
151       if /\W#{native_lib}$"/.match firefox_pmap_info
152         unwanted_native_libs << lib_name
153       end
154     end
155   end
156   absent_tbb_libs -= expected_absent_tbb_libs
157   assert(absent_tbb_libs.empty? && unwanted_native_libs.empty?,
158          "The loaded shared libraries for the firefox process are not the " +
159          "way we expect them.\n" +
160          "Expected TBB libs that are absent: #{absent_tbb_libs}\n" +
161          "Native libs that we don't want: #{unwanted_native_libs}")
164 Then /^the (.*) uses all expected TBB shared libraries$/ do |application|
165   info = xul_application_info(application)
166   pid = $vm.execute_successfully("pgrep --uid #{info[:user]} --full --exact '#{info[:cmd_regex]}'").stdout.chomp
167   assert(/\A\d+\z/.match(pid), "It seems like #{application} is not running")
168   xul_app_shared_lib_check(pid, info[:chroot], info[:unused_tbb_libs])
171 Then /^the (.*) chroot is torn down$/ do |browser|
172   info = xul_application_info(browser)
173   try_for(30, :msg => "The #{browser} chroot '#{info[:chroot]}' was " \
174                       "not removed") do
175     !$vm.execute("test -d '#{info[:chroot]}'").success?
176   end
179 Then /^the (.*) runs as the expected user$/ do |browser|
180   info = xul_application_info(browser)
181   assert_vmcommand_success($vm.execute(
182     "pgrep --full --exact '#{info[:cmd_regex]}'"),
183     "The #{browser} is not running")
184   assert_vmcommand_success($vm.execute(
185     "pgrep --uid #{info[:user]} --full --exact '#{info[:cmd_regex]}'"),
186     "The #{browser} is not running as the #{info[:user]} user")
189 When /^I download some file in the Tor Browser$/ do
190   @some_file = 'tails-signing.key'
191   some_url = "https://tails.boum.org/#{@some_file}"
192   step "I open the address \"#{some_url}\" in the Tor Browser"
195 Then /^I get the browser download dialog$/ do
196   @screen.wait('BrowserDownloadDialog.png', 60)
197   @screen.wait('BrowserDownloadDialogSaveAsButton.png', 10)
200 When /^I save the file to the default Tor Browser download directory$/ do
201   @screen.click('BrowserDownloadDialogSaveAsButton.png')
202   @screen.wait('Gtk3SaveFileDialog.png', 10)
203   @screen.type(Sikuli::Key.ENTER)
206 Then /^the file is saved to the default Tor Browser download directory$/ do
207   assert_not_nil(@some_file)
208   expected_path = "/home/#{LIVE_USER}/Tor Browser/#{@some_file}"
209   try_for(10) { $vm.file_exist?(expected_path) }
212 When /^I open Tails homepage in the (.+)$/ do |browser|
213   step "I open the address \"https://tails.boum.org\" in the #{browser}"
216 Then /^Tails homepage loads in the Unsafe Browser$/ do
217   @screen.wait('TailsHomepage.png', 60)
220 Then /^the Tor Browser shows the "([^"]+)" error$/ do |error|
221   page = @torbrowser.child("Problem loading page - Tor Browser", roleName: "frame")
222   headers = page.children(roleName: "heading")
223   found = headers.any? { |heading| heading.text == error }
224   raise "Could not find the '#{error}' error in the Tor Browser" unless found
227 Then /^I can listen to an Ogg audio track in Tor Browser$/ do
228   test_url = 'https://archive.org/download/MussorgskyPicturesAtAnExhibitionorch.Ravel/09Mussorgsky_PicturesAtAnExhibition-LimogesTheMarketPlace.ogg'
229   info = xul_application_info('Tor Browser')
230   open_test_url = Proc.new do
231     step "I open the address \"#{test_url}\" in the Tor Browser"
232   end
233   recovery_on_failure = Proc.new do
234     @screen.type(Sikuli::Key.ESC)
235     @screen.waitVanish(info[:browser_stop_button_image], 3)
236     open_test_url.call
237   end
238   step "no application is playing audio"
239   open_test_url.call
240   retry_tor(recovery_on_failure) do
241     step "1 application is playing audio after 30 seconds"
242   end
245 Then /^I can watch a WebM video in Tor Browser$/ do
246   test_url = 'https://tails.boum.org/lib/test_suite/test.webm'
247   info = xul_application_info('Tor Browser')
248   open_test_url = Proc.new do
249     step "I open the address \"#{test_url}\" in the Tor Browser"
250   end
251   recovery_on_failure = Proc.new do
252     @screen.type(Sikuli::Key.ESC)
253     @screen.waitVanish(info[:browser_stop_button_image], 3)
254     open_test_url.call
255   end
256   open_test_url.call
257   retry_tor(recovery_on_failure) do
258     @screen.wait("TorBrowserSampleRemoteWebMVideoFrame.png", 30)
259   end