workarea-testing 3.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|