Merge branch 'master' into 4523-search-index
[arvados.git] / apps / workbench / test / integration_helper.rb
1 require 'test_helper'
2 require 'capybara/rails'
3 require 'capybara/poltergeist'
4 require 'uri'
5 require 'yaml'
6
7 Capybara.register_driver :poltergeist do |app|
8   Capybara::Poltergeist::Driver.new app, {
9     window_size: [1200, 800],
10     phantomjs_options: ['--ignore-ssl-errors=true'],
11     inspector: true,
12   }
13 end
14
15 module WaitForAjax
16   Capybara.default_wait_time = 5
17   def wait_for_ajax
18     Timeout.timeout(Capybara.default_wait_time) do
19       loop until finished_all_ajax_requests?
20     end
21   end
22
23   def finished_all_ajax_requests?
24     page.evaluate_script('jQuery.active').zero?
25   end
26 end
27
28 module AssertDomEvent
29   # Yield the supplied block, then wait for an event to arrive at a
30   # DOM element.
31   def assert_triggers_dom_event events, target='body'
32     magic = 'RXC0lObcVwEXwSvA-' + rand(2**20).to_s(36)
33     page.evaluate_script <<eos
34       $('#{target}').one('#{events}', function() {
35         $('body').append('<div id="#{magic}"></div>');
36       });
37 eos
38     yield
39     assert_selector "##{magic}"
40     page.evaluate_script "$('##{magic}').remove();";
41   end
42 end
43
44 module HeadlessHelper
45   class HeadlessSingleton
46     def self.get
47       @headless ||= Headless.new reuse: false
48     end
49   end
50
51   Capybara.default_driver = :rack_test
52
53   def self.included base
54     base.class_eval do
55       setup do
56         Capybara.use_default_driver
57         @headless = false
58       end
59
60       teardown do
61         if @headless
62           @headless.stop
63           @headless = false
64         end
65       end
66     end
67   end
68
69   def need_selenium reason=nil
70     Capybara.current_driver = :selenium
71     unless ENV['ARVADOS_TEST_HEADFUL'] or @headless
72       @headless = HeadlessSingleton.get
73       @headless.start
74     end
75   end
76
77   def need_javascript reason=nil
78     unless Capybara.current_driver == :selenium
79       Capybara.current_driver = :poltergeist
80     end
81   end
82 end
83
84 class ActionDispatch::IntegrationTest
85   # Make the Capybara DSL available in all integration tests
86   include Capybara::DSL
87   include ApiFixtureLoader
88   include WaitForAjax
89   include AssertDomEvent
90   include HeadlessHelper
91
92   @@API_AUTHS = self.api_fixture('api_client_authorizations')
93
94   def page_with_token(token, path='/')
95     # Generate a page path with an embedded API token.
96     # Typical usage: visit page_with_token('token_name', page)
97     # The token can be specified by the name of an api_client_authorizations
98     # fixture, or passed as a raw string.
99     api_token = ((@@API_AUTHS.include? token) ?
100                  @@API_AUTHS[token]['api_token'] : token)
101     path_parts = path.partition("#")
102     sep = (path_parts.first.include? '?') ? '&' : '?'
103     q_string = URI.encode_www_form('api_token' => api_token)
104     path_parts.insert(1, "#{sep}#{q_string}")
105     path_parts.join("")
106   end
107
108   # Find a page element, but return false instead of raising an
109   # exception if not found. Use this with assertions to explain that
110   # the error signifies a failed test rather than an unexpected error
111   # during a testing procedure.
112   def find? *args
113     begin
114       find *args
115     rescue Capybara::ElementNotFound
116       false
117     end
118   end
119
120   @@screenshot_count = 1
121   def screenshot
122     image_file = "./tmp/workbench-fail-#{@@screenshot_count}.png"
123     begin
124       page.save_screenshot image_file
125     rescue Capybara::NotSupportedByDriverError
126       # C'est la vie.
127     else
128       puts "Saved #{image_file}"
129       @@screenshot_count += 1
130     end
131   end
132
133   teardown do
134     if not passed?
135       screenshot
136     end
137     if Capybara.current_driver == :selenium
138       page.execute_script("window.localStorage.clear()")
139     end
140     Capybara.reset_sessions!
141   end
142 end