workarea-testing 3.4.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +52 -0
- data/README.md +19 -0
- data/app/assets/javascripts/workarea/admin/spec_helper.js +1 -0
- data/app/assets/javascripts/workarea/core/feature_test_helper.js +15 -0
- data/app/assets/javascripts/workarea/core/spec_helper.js +45 -0
- data/app/assets/javascripts/workarea/storefront/spec_helper.js +2 -0
- data/app/assets/stylesheets/workarea/admin/_feature_test_helper.scss +16 -0
- data/app/assets/stylesheets/workarea/core/_feature_test_helper.scss +8 -0
- data/lib/workarea/admin/integration_test.rb +15 -0
- data/lib/workarea/core/discount_condition_tests.rb +100 -0
- data/lib/workarea/core/featured_products_test.rb +30 -0
- data/lib/workarea/core/navigable_test.rb +68 -0
- data/lib/workarea/generator_test.rb +5 -0
- data/lib/workarea/integration_test.rb +45 -0
- data/lib/workarea/performance_test.rb +135 -0
- data/lib/workarea/storefront/breakpoint_helpers.rb +27 -0
- data/lib/workarea/storefront/catalog_customization_test_class.rb +28 -0
- data/lib/workarea/storefront/integration_test.rb +82 -0
- data/lib/workarea/storefront/pagination_view_model_test.rb +56 -0
- data/lib/workarea/storefront/product_browsing_view_model_test.rb +38 -0
- data/lib/workarea/storefront/system_test.rb +142 -0
- data/lib/workarea/system_test.rb +161 -0
- data/lib/workarea/test_case.rb +197 -0
- data/lib/workarea/test_help.rb +67 -0
- data/lib/workarea/testing/cassette_persister.rb +40 -0
- data/lib/workarea/testing/custom_capybara_matchers.rb +18 -0
- data/lib/workarea/testing/decoration_reporter.rb +37 -0
- data/lib/workarea/testing/deferred_garbage_collection.rb +21 -0
- data/lib/workarea/testing/elasticsearch_response.json +1 -0
- data/lib/workarea/testing/engine.rb +6 -0
- data/lib/workarea/testing/example_document.pdf +0 -0
- data/lib/workarea/testing/factories/bulk_action.rb +17 -0
- data/lib/workarea/testing/factories/catalog.rb +66 -0
- data/lib/workarea/testing/factories/comment.rb +12 -0
- data/lib/workarea/testing/factories/content.rb +38 -0
- data/lib/workarea/testing/factories/data_file.rb +21 -0
- data/lib/workarea/testing/factories/fulfillment.rb +21 -0
- data/lib/workarea/testing/factories/insights.rb +32 -0
- data/lib/workarea/testing/factories/metrics.rb +25 -0
- data/lib/workarea/testing/factories/navigation.rb +30 -0
- data/lib/workarea/testing/factories/order.rb +77 -0
- data/lib/workarea/testing/factories/payment.rb +37 -0
- data/lib/workarea/testing/factories/performance/catalog.rb +92 -0
- data/lib/workarea/testing/factories/pricing.rb +59 -0
- data/lib/workarea/testing/factories/recommendation.rb +17 -0
- data/lib/workarea/testing/factories/search.rb +72 -0
- data/lib/workarea/testing/factories/user.rb +24 -0
- data/lib/workarea/testing/factories.rb +146 -0
- data/lib/workarea/testing/factory_configuration.rb +90 -0
- data/lib/workarea/testing/indexes.rb +22 -0
- data/lib/workarea/testing/locale_routing_fixes.rb +33 -0
- data/lib/workarea/testing/product_image.jpg +0 -0
- data/lib/workarea/testing/teaspoon.rb +186 -0
- data/lib/workarea/testing/user_avatar.jpg +0 -0
- data/lib/workarea/testing/warning_suppressor.rb +59 -0
- data/lib/workarea/view_test.rb +40 -0
- data/workarea-testing.gemspec +29 -0
- metadata +240 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
module IntegrationTest
|
4
|
+
def product
|
5
|
+
@product ||= create_product(
|
6
|
+
name: 'Integration Product',
|
7
|
+
variants: [
|
8
|
+
{ sku: 'SKU1', tax_code: '001', regular: 5.to_m }
|
9
|
+
]
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def complete_checkout(email = nil, password = nil)
|
14
|
+
if Shipping::Service.blank?
|
15
|
+
create_shipping_service(
|
16
|
+
name: 'Ground',
|
17
|
+
tax_code: '001',
|
18
|
+
rates: [{ price: 7.to_m }]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
post storefront.cart_items_path,
|
23
|
+
headers: checkout_headers,
|
24
|
+
params: {
|
25
|
+
product_id: product.id,
|
26
|
+
sku: product.skus.first,
|
27
|
+
quantity: 2
|
28
|
+
}
|
29
|
+
|
30
|
+
if email.present? && password.present?
|
31
|
+
post storefront.login_path,
|
32
|
+
headers: checkout_headers,
|
33
|
+
params: { email: email, password: password }
|
34
|
+
end
|
35
|
+
|
36
|
+
patch storefront.checkout_addresses_path,
|
37
|
+
headers: checkout_headers,
|
38
|
+
params: {
|
39
|
+
email: 'bcrouse@workarea.com',
|
40
|
+
billing_address: {
|
41
|
+
first_name: 'Ben',
|
42
|
+
last_name: 'Crouse',
|
43
|
+
street: '12 N. 3rd St.',
|
44
|
+
city: 'Philadelphia',
|
45
|
+
region: 'PA',
|
46
|
+
postal_code: '19106',
|
47
|
+
country: 'US',
|
48
|
+
phone_number: '2159251800'
|
49
|
+
},
|
50
|
+
shipping_address: {
|
51
|
+
first_name: 'Ben',
|
52
|
+
last_name: 'Crouse',
|
53
|
+
street: '22 S. 3rd St.',
|
54
|
+
city: 'Philadelphia',
|
55
|
+
region: 'PA',
|
56
|
+
postal_code: '19106',
|
57
|
+
country: 'US',
|
58
|
+
phone_number: '2159251800'
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
patch storefront.checkout_place_order_path,
|
63
|
+
headers: checkout_headers,
|
64
|
+
params: {
|
65
|
+
payment: 'new_card',
|
66
|
+
credit_card: {
|
67
|
+
number: '1',
|
68
|
+
month: 1,
|
69
|
+
year: 2020,
|
70
|
+
cvv: '999'
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def checkout_headers
|
78
|
+
{ 'HTTP_USER_AGENT' => 'Mozilla' }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
module PaginationViewModelTest
|
4
|
+
def pagination_view_model
|
5
|
+
@pagination_view_model ||= pagination_view_model_class.new(
|
6
|
+
stub_everything(:model)
|
7
|
+
)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_total_pages
|
11
|
+
pagination_view_model.expects(:total).returns(2)
|
12
|
+
pagination_view_model.expects(:per_page).returns(1)
|
13
|
+
assert_equal(2, pagination_view_model.total_pages)
|
14
|
+
|
15
|
+
pagination_view_model.expects(:total).returns(20)
|
16
|
+
pagination_view_model.expects(:per_page).returns(15)
|
17
|
+
assert_equal(2, pagination_view_model.total_pages)
|
18
|
+
|
19
|
+
pagination_view_model.expects(:total).returns(1)
|
20
|
+
pagination_view_model.expects(:per_page).returns(15)
|
21
|
+
assert_equal(1, pagination_view_model.total_pages)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_first_page
|
25
|
+
pagination_view_model.expects(:page).returns(1)
|
26
|
+
assert(pagination_view_model.first_page?)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_last_page
|
30
|
+
pagination_view_model.expects(:page).returns(2)
|
31
|
+
pagination_view_model.expects(:per_page).returns(15)
|
32
|
+
pagination_view_model.expects(:total).returns(30)
|
33
|
+
assert(pagination_view_model.last_page?)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_next_page
|
37
|
+
pagination_view_model.expects(:per_page).returns(15).at_least_once
|
38
|
+
pagination_view_model.expects(:total).returns(30).at_least_once
|
39
|
+
|
40
|
+
pagination_view_model.expects(:page).returns(1).at_least_once
|
41
|
+
assert_equal(2, pagination_view_model.next_page)
|
42
|
+
|
43
|
+
pagination_view_model.expects(:page).returns(2).at_least_once
|
44
|
+
assert_nil(pagination_view_model.next_page)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_prev_page
|
48
|
+
pagination_view_model.expects(:page).returns(1).at_least_once
|
49
|
+
assert_nil(pagination_view_model.prev_page)
|
50
|
+
|
51
|
+
pagination_view_model.expects(:page).returns(2).at_least_once
|
52
|
+
assert_equal(1, pagination_view_model.prev_page)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
module ProductBrowsingViewModelTest
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include PaginationViewModelTest
|
6
|
+
|
7
|
+
def pagination_view_model_class
|
8
|
+
product_browsing_view_model_class
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_has_filters
|
12
|
+
view_model = product_browsing_view_model_class.new(stub_everything)
|
13
|
+
facet = mock
|
14
|
+
view_model.expects(:facets).returns([facet]).twice
|
15
|
+
|
16
|
+
facet.expects(:selected?).returns(true)
|
17
|
+
assert(view_model.has_filters?)
|
18
|
+
|
19
|
+
facet.expects(:selected?).returns(false)
|
20
|
+
refute(view_model.has_filters?)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_facets
|
24
|
+
view_model = product_browsing_view_model_class.new(stub_everything)
|
25
|
+
facets = [mock, mock]
|
26
|
+
search = Search::ProductSearch.new
|
27
|
+
search.expects(:facets).returns(facets).at_least_once
|
28
|
+
view_model.expects(:search_query).returns(search).twice
|
29
|
+
|
30
|
+
facets.first.stubs(:useless?).returns(true)
|
31
|
+
facets.second.stubs(:useless?).returns(false)
|
32
|
+
|
33
|
+
assert_equal(1, view_model.facets.size)
|
34
|
+
refute(view_model.facets.first.useless?)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
module SystemTest
|
4
|
+
def setup_checkout_specs
|
5
|
+
create_supporting_data
|
6
|
+
add_product_to_cart
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_supporting_data
|
10
|
+
create_tax_category(
|
11
|
+
name: 'Sales Tax',
|
12
|
+
code: '001',
|
13
|
+
rates: [{ percentage: 0.07, country: 'US', region: 'PA' }]
|
14
|
+
)
|
15
|
+
|
16
|
+
create_shipping_service(
|
17
|
+
name: 'Ground',
|
18
|
+
tax_code: '001',
|
19
|
+
rates: [{ price: 7.to_m }]
|
20
|
+
)
|
21
|
+
|
22
|
+
create_inventory(id: 'SKU', policy: 'standard', available: 5)
|
23
|
+
|
24
|
+
@product = create_product(
|
25
|
+
id: 'INT_PRODUCT',
|
26
|
+
name: 'Integration Product',
|
27
|
+
variants: [{ sku: 'SKU', tax_code: '001', regular: 5.to_m }]
|
28
|
+
)
|
29
|
+
|
30
|
+
create_user(email: 'bcrouse@workarea.com', password: 'W3bl1nc!')
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_user_data
|
34
|
+
user = User.find_by_email('bcrouse@workarea.com')
|
35
|
+
|
36
|
+
user.auto_save_shipping_address(
|
37
|
+
first_name: 'Ben',
|
38
|
+
last_name: 'Crouse',
|
39
|
+
street: '22 S. 3rd St.',
|
40
|
+
city: 'Philadelphia',
|
41
|
+
region: 'PA',
|
42
|
+
postal_code: '19106',
|
43
|
+
country: 'US',
|
44
|
+
phone_number: '2159251800'
|
45
|
+
)
|
46
|
+
|
47
|
+
user.auto_save_billing_address(
|
48
|
+
first_name: 'Ben',
|
49
|
+
last_name: 'Crouse',
|
50
|
+
street: '1019 S. 47th St.',
|
51
|
+
city: 'Philadelphia',
|
52
|
+
region: 'PA',
|
53
|
+
postal_code: '19143',
|
54
|
+
country: 'US',
|
55
|
+
phone_number: '2159251800'
|
56
|
+
)
|
57
|
+
|
58
|
+
profile = Payment::Profile.lookup(PaymentReference.new(user))
|
59
|
+
profile.credit_cards.create!(
|
60
|
+
first_name: 'Ben',
|
61
|
+
last_name: 'Crouse',
|
62
|
+
number: '1',
|
63
|
+
month: 1,
|
64
|
+
year: Time.current.year + 1,
|
65
|
+
cvv: '999'
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_product_to_cart
|
70
|
+
product = Catalog::Product.find('INT_PRODUCT')
|
71
|
+
visit storefront.product_path(product)
|
72
|
+
click_button t('workarea.storefront.products.add_to_cart')
|
73
|
+
end
|
74
|
+
|
75
|
+
def start_guest_checkout
|
76
|
+
visit storefront.checkout_path
|
77
|
+
end
|
78
|
+
|
79
|
+
def start_user_checkout
|
80
|
+
visit storefront.checkout_path
|
81
|
+
click_link t('workarea.storefront.checkouts.login_title')
|
82
|
+
|
83
|
+
within '#login_form' do
|
84
|
+
fill_in 'email', with: 'bcrouse@workarea.com'
|
85
|
+
fill_in 'password', with: 'W3bl1nc!'
|
86
|
+
click_button t('workarea.storefront.users.login')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def fill_in_email
|
91
|
+
fill_in 'email', with: 'bcrouse-new-account@workarea.com'
|
92
|
+
end
|
93
|
+
|
94
|
+
def fill_in_shipping_address
|
95
|
+
fill_in 'shipping_address[first_name]', with: 'Ben'
|
96
|
+
fill_in 'shipping_address[last_name]', with: 'Crouse'
|
97
|
+
fill_in 'shipping_address[street]', with: '22 S. 3rd St.'
|
98
|
+
fill_in 'shipping_address[city]', with: 'Philadelphia'
|
99
|
+
|
100
|
+
if page.has_field?('shipping_address[region]')
|
101
|
+
fill_in 'shipping_address[region]', with: 'PA'
|
102
|
+
else
|
103
|
+
select 'Pennsylvania', from: 'shipping_address_region_select'
|
104
|
+
end
|
105
|
+
|
106
|
+
fill_in 'shipping_address[postal_code]', with: '19106'
|
107
|
+
fill_in 'shipping_address[phone_number]', with: '2159251800'
|
108
|
+
end
|
109
|
+
|
110
|
+
def fill_in_new_card_cvv
|
111
|
+
fill_in 'cvv[new_card]', with: '999'
|
112
|
+
end
|
113
|
+
|
114
|
+
def fill_in_credit_card
|
115
|
+
fill_in 'credit_card[number]', with: '1'
|
116
|
+
next_year = (Time.current.year + 1).to_s
|
117
|
+
select next_year, from: 'credit_card[year]'
|
118
|
+
fill_in 'credit_card[cvv]', with: '999'
|
119
|
+
end
|
120
|
+
|
121
|
+
def fill_in_billing_address
|
122
|
+
fill_in 'billing_address[first_name]', with: 'Ben'
|
123
|
+
fill_in 'billing_address[last_name]', with: 'Crouse'
|
124
|
+
fill_in 'billing_address[street]', with: '1019 S. 47th St.'
|
125
|
+
fill_in 'billing_address[city]', with: 'Philadelphia'
|
126
|
+
|
127
|
+
if page.has_field?('billing_address[region]')
|
128
|
+
fill_in 'billing_address[region]', with: 'PA'
|
129
|
+
else
|
130
|
+
select 'Pennsylvania', from: 'billing_address_region_select'
|
131
|
+
end
|
132
|
+
|
133
|
+
fill_in 'billing_address[postal_code]', with: '19143'
|
134
|
+
fill_in 'billing_address[phone_number]', with: '2159251800'
|
135
|
+
end
|
136
|
+
|
137
|
+
def select_shipping_service
|
138
|
+
choose 'Ground'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'capybara/rails'
|
2
|
+
require 'webdrivers'
|
3
|
+
require 'puma'
|
4
|
+
require 'workarea/integration_test'
|
5
|
+
require 'workarea/testing/custom_capybara_matchers'
|
6
|
+
|
7
|
+
# get options on load to ensure initial configuration is captured.
|
8
|
+
# Capybara.register_driver does not execute the passed block immediately, which
|
9
|
+
# can cause issues with the aliasing of Workarea.config.headless_chrome_options.
|
10
|
+
# This can be removed in the upcoming minor to rename that configuration.
|
11
|
+
chrome_options = Workarea::Configuration::HeadlessChrome.options
|
12
|
+
|
13
|
+
Capybara.server_errors = [Exception]
|
14
|
+
Capybara.automatic_label_click = true
|
15
|
+
Capybara.register_driver :headless_chrome do |app|
|
16
|
+
Capybara::Selenium::Driver.new(
|
17
|
+
app,
|
18
|
+
browser: :chrome,
|
19
|
+
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(
|
20
|
+
chromeOptions: chrome_options
|
21
|
+
)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
Capybara.server = :puma, { Silent: true }
|
26
|
+
Capybara.javascript_driver = :headless_chrome
|
27
|
+
|
28
|
+
# If builds want to stick to poltegeist to avoid the pain of upgrading, see if
|
29
|
+
# we can define the driver for them. TODO remove in v4
|
30
|
+
if defined?(Capybara::Poltergeist)
|
31
|
+
Capybara.register_driver :poltergeist do |app|
|
32
|
+
Capybara::Poltergeist::Driver.new(app, js_errors: true)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Because each plugin adds more time to template resolution, more plugins mean
|
37
|
+
# slower tests. This is accommodate that slowdown :(
|
38
|
+
default = ENV['WORKAREA_CAPYBARA_MAX_WAIT_TIME'].presence || 10
|
39
|
+
Capybara.default_max_wait_time = [Workarea::Plugin.installed.size, default.to_i].max
|
40
|
+
|
41
|
+
# When you change a route, it doesn't see that JS routes needs to be expired.
|
42
|
+
FileUtils.rm_rf(Rails.root.join('tmp', 'cache', 'assets', 'sprockets'))
|
43
|
+
|
44
|
+
# Default screenshots to simple output of file path
|
45
|
+
ENV["RAILS_SYSTEM_TESTING_SCREENSHOT"] ||= 'simple'
|
46
|
+
|
47
|
+
module Workarea
|
48
|
+
class SystemTest < ActionDispatch::SystemTestCase
|
49
|
+
extend TestCase::Decoration
|
50
|
+
include TestCase::Workers
|
51
|
+
include TestCase::SearchIndexing
|
52
|
+
include TestCase::Mail
|
53
|
+
include TestCase::RunnerLocation
|
54
|
+
include TestCase::Locales
|
55
|
+
include TestCase::S3
|
56
|
+
include Factories
|
57
|
+
include IntegrationTest::Configuration
|
58
|
+
|
59
|
+
driven_by :headless_chrome
|
60
|
+
|
61
|
+
setup do
|
62
|
+
reset_window_size
|
63
|
+
end
|
64
|
+
|
65
|
+
teardown do
|
66
|
+
assert_no_js_errors if javascript?
|
67
|
+
end
|
68
|
+
|
69
|
+
# This is to make sure Chrome chills out and allows XHR requests to finish
|
70
|
+
# before going nuts on the page. Theoretically, Capybara does this for you.
|
71
|
+
# Of course in theory, theory works.
|
72
|
+
#
|
73
|
+
(%i(visit refresh go_back go_forward within) + Capybara::Session::NODE_METHODS).each do |method|
|
74
|
+
class_eval <<-ruby
|
75
|
+
def #{method}(*)
|
76
|
+
return super unless javascript?
|
77
|
+
|
78
|
+
wait_for_xhr
|
79
|
+
super.tap { wait_for_xhr }
|
80
|
+
end
|
81
|
+
ruby
|
82
|
+
end
|
83
|
+
|
84
|
+
# Waits until all XHR requests have finished, according
|
85
|
+
# to jQuery. Times out according to Capybara's set timeout.
|
86
|
+
# Used to solve race conditions between XHR requests and
|
87
|
+
# assertions.
|
88
|
+
#
|
89
|
+
def wait_for_xhr(time=Capybara.default_max_wait_time)
|
90
|
+
Timeout.timeout(time) do
|
91
|
+
loop until finished_all_xhr_requests?
|
92
|
+
end
|
93
|
+
rescue Timeout::Error => error
|
94
|
+
javascript_errors = page.driver.browser.manage.logs.get(:browser).each do |log_entry|
|
95
|
+
log_entry.level == 'SEVERE' && /Uncaught/.match?(log_entry.message)
|
96
|
+
end
|
97
|
+
if javascript_errors.present?
|
98
|
+
raise(
|
99
|
+
Timeout::Error,
|
100
|
+
<<~eos
|
101
|
+
Problem:
|
102
|
+
JavaScript errors were detected during Workarea::SystemTest#wait_for_xhr.
|
103
|
+
You might have an error in an XHR callback. wait_for_xhr is a test helper
|
104
|
+
that checks if there are any unfinished XHR requests. This is called
|
105
|
+
automatically throughout testing in Capybara interactions to ensure
|
106
|
+
consistency in test results.
|
107
|
+
Errors:
|
108
|
+
#{javascript_errors.map(&:message).join("\r")}
|
109
|
+
eos
|
110
|
+
)
|
111
|
+
else
|
112
|
+
raise error
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Resets the dimensions of the testing browser
|
117
|
+
def reset_window_size
|
118
|
+
return unless javascript?
|
119
|
+
|
120
|
+
page.driver.browser.manage.window.resize_to(
|
121
|
+
Workarea.config.capybara_browser_width,
|
122
|
+
Workarea.config.capybara_browser_height
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
def javascript?
|
127
|
+
Capybara.current_driver == Capybara.javascript_driver
|
128
|
+
end
|
129
|
+
|
130
|
+
def scroll_to_bottom
|
131
|
+
page.execute_script('window.scrollBy(0, 9999999)')
|
132
|
+
end
|
133
|
+
|
134
|
+
def scroll_to_bottom
|
135
|
+
page.execute_script('window.scrollBy(0, 9999999)')
|
136
|
+
end
|
137
|
+
|
138
|
+
# Intentionally fails, providing a custom error message, if
|
139
|
+
# any JavaScript errors are thrown during a test run.
|
140
|
+
def assert_no_js_errors
|
141
|
+
page.driver.browser.manage.logs.get(:browser).each do |log_entry|
|
142
|
+
# Bad responses (like 422 or 401) show as errors as well, which are OK
|
143
|
+
# for system tests because they indicate the site is functioning properly.
|
144
|
+
if log_entry.level == 'SEVERE' && log_entry.message =~ /Uncaught/
|
145
|
+
assert(false, log_entry.message)
|
146
|
+
elsif log_entry.level == 'WARNING'
|
147
|
+
STDERR.puts 'WARN: Browser warning'
|
148
|
+
STDERR.puts log_entry.message
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def finished_all_xhr_requests?
|
156
|
+
return unless javascript?
|
157
|
+
|
158
|
+
page.evaluate_script("!window['jQuery'] || jQuery.active === 0")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module Workarea
|
2
|
+
class TestCase < ActiveSupport::TestCase
|
3
|
+
module Decoration
|
4
|
+
mattr_accessor :loaded_decorators
|
5
|
+
self.loaded_decorators = []
|
6
|
+
|
7
|
+
def self.load_decorator(path)
|
8
|
+
unless loaded_decorators.include?(path) || !File.file?(path)
|
9
|
+
load path
|
10
|
+
loaded_decorators << path
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def inherited(subclass)
|
15
|
+
super
|
16
|
+
|
17
|
+
absolute_path = caller[0].split(':').first
|
18
|
+
# Don't try to find decorators for classes in the testing gem
|
19
|
+
return if absolute_path.include?('workarea-testing') ||
|
20
|
+
absolute_path.include?('workarea/testing')
|
21
|
+
|
22
|
+
relative_path = absolute_path.match(/(\/test.*)/).to_s
|
23
|
+
decorator_relative = relative_path.gsub(
|
24
|
+
'.rb',
|
25
|
+
".#{Rails::Decorators.extension}"
|
26
|
+
)
|
27
|
+
|
28
|
+
(Plugin.installed.map(&:root) + [Rails.root]).each do |root|
|
29
|
+
decorator_location = [root, decorator_relative].join
|
30
|
+
|
31
|
+
if File.exist?(decorator_location)
|
32
|
+
TestCase::Decoration.load_decorator(decorator_location)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
module Workers
|
39
|
+
extend ActiveSupport::Concern
|
40
|
+
|
41
|
+
included do
|
42
|
+
setup do
|
43
|
+
@_worker_state =
|
44
|
+
Sidekiq::CallbacksWorker.workers.reduce({}) do |memo, worker|
|
45
|
+
memo[worker] = [worker.enabled?, worker.inlined?]
|
46
|
+
memo
|
47
|
+
end
|
48
|
+
|
49
|
+
Sidekiq::Testing.inline!
|
50
|
+
Sidekiq::Callbacks.inline
|
51
|
+
end
|
52
|
+
|
53
|
+
teardown do
|
54
|
+
Sidekiq::CallbacksWorker.workers.each do |worker|
|
55
|
+
worker.enabled = @_worker_state[worker].first
|
56
|
+
worker.inlined = @_worker_state[worker].second
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module SearchIndexing
|
63
|
+
extend ActiveSupport::Concern
|
64
|
+
|
65
|
+
included do
|
66
|
+
setup do
|
67
|
+
Workarea.config.auto_refresh_search = true
|
68
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
69
|
+
Workarea::Elasticsearch::Document.all.each(&:reset_indexes!)
|
70
|
+
Workarea::Search::Storefront.ensure_dynamic_mappings
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Mail
|
76
|
+
extend ActiveSupport::Concern
|
77
|
+
|
78
|
+
included do
|
79
|
+
setup do
|
80
|
+
Workarea.config.send_email = true
|
81
|
+
Workarea.config.send_transactional_emails = true
|
82
|
+
end
|
83
|
+
|
84
|
+
teardown do
|
85
|
+
Workarea.config.send_email = false
|
86
|
+
Workarea.config.send_transactional_emails = false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module RunnerLocation
|
92
|
+
def running_from_source?
|
93
|
+
return false unless running_in_dummy_app?
|
94
|
+
|
95
|
+
calling_test = caller.detect do |path|
|
96
|
+
/_test\.(rb|#{Rails::Decorators.extension})/.match?(path)
|
97
|
+
end
|
98
|
+
|
99
|
+
Rails.root.to_s.include?('test/dummy') &&
|
100
|
+
Rails.root.to_s.split('/test/').first.eql?(calling_test.split('/test/').first)
|
101
|
+
end
|
102
|
+
|
103
|
+
def running_in_gem?
|
104
|
+
warn <<~eos
|
105
|
+
DEPRECATION WARNING: running_in_gem? is deprecated, use running_from_dummy_app? if
|
106
|
+
you want to know if the test suite is running from a plugin or
|
107
|
+
running_from_source? if you want to know if the currently executing test
|
108
|
+
is defined in the current Rails project.
|
109
|
+
eos
|
110
|
+
running_from_source?
|
111
|
+
end
|
112
|
+
|
113
|
+
def running_in_dummy_app?
|
114
|
+
return @running_in_dummy_app if defined?(@running_in_dummy_app)
|
115
|
+
@running_in_dummy_app = Rails.root.to_s.include?('test/dummy')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
module Locales
|
120
|
+
extend ActiveSupport::Concern
|
121
|
+
|
122
|
+
included do
|
123
|
+
setup :save_locales
|
124
|
+
teardown :restore_locales
|
125
|
+
|
126
|
+
delegate :t, to: :I18n
|
127
|
+
end
|
128
|
+
|
129
|
+
def set_locales(available:, default:, current: nil)
|
130
|
+
Rails.application.config.i18n.available_locales = I18n.available_locales = available
|
131
|
+
Rails.application.config.i18n.default_locale = I18n.default_locale = default
|
132
|
+
I18n.locale = current || default
|
133
|
+
end
|
134
|
+
|
135
|
+
def save_locales
|
136
|
+
@current_rails_available_locales = Rails.application.config.i18n.available_locales
|
137
|
+
@current_rails_default_locale = Rails.application.config.i18n.default_locale
|
138
|
+
|
139
|
+
@current_i18n_available_locales = I18n.available_locales
|
140
|
+
@current_i18n_default_locale = I18n.default_locale
|
141
|
+
@current_i18n_locale = I18n.default_locale
|
142
|
+
end
|
143
|
+
|
144
|
+
def restore_locales
|
145
|
+
Rails.application.config.i18n.available_locales = @current_rails_available_locales
|
146
|
+
Rails.application.config.i18n.default_locale = @current_rails_default_locale
|
147
|
+
|
148
|
+
I18n.available_locales = @current_i18n_available_locales
|
149
|
+
I18n.default_locale = @current_i18n_default_locale
|
150
|
+
I18n.locale = @current_i18n_locale
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
module S3
|
155
|
+
extend ActiveSupport::Concern
|
156
|
+
|
157
|
+
included do
|
158
|
+
setup :mock_s3
|
159
|
+
teardown :reset_s3
|
160
|
+
end
|
161
|
+
|
162
|
+
def mock_s3
|
163
|
+
Fog.mock!
|
164
|
+
Workarea.s3.directories.create(key: Configuration::S3.bucket)
|
165
|
+
end
|
166
|
+
|
167
|
+
def reset_s3
|
168
|
+
Fog::Mock.reset
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
extend Decoration
|
173
|
+
extend RunnerLocation
|
174
|
+
include Factories
|
175
|
+
include Workers
|
176
|
+
include RunnerLocation
|
177
|
+
include Locales
|
178
|
+
include S3
|
179
|
+
|
180
|
+
setup do
|
181
|
+
Mongoid.truncate!
|
182
|
+
Workarea.redis.flushdb
|
183
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
184
|
+
Workarea.config.send_email = false
|
185
|
+
Workarea.config.send_transactional_emails = false
|
186
|
+
ActionMailer::Base.deliveries.clear
|
187
|
+
|
188
|
+
Sidekiq::Testing.inline!
|
189
|
+
Sidekiq::Callbacks.inline
|
190
|
+
Sidekiq::Callbacks.disable
|
191
|
+
end
|
192
|
+
|
193
|
+
teardown do
|
194
|
+
travel_back
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|