diff --git a/.travis.yml b/.travis.yml index 05b96b18..c44bb8e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,15 @@ language: ruby sudo: false rvm: - - 2.3 + - 2.4 services: - - xvfb - mysql - redis-server addons: apt: packages: - libmagic-dev - - qt5-default - - libqt5webkit5-dev - - gstreamer1.0-plugins-base - - gstreamer1.0-tools + chrome: stable env: COVERALLS=1 cache: bundler bundler_args: @@ -24,4 +20,4 @@ before_script: - "mysql -e 'grant all on foodsoft_test.* to travis;'" - 'printf "test:\n adapter: mysql2\n database: foodsoft_test\n username: travis\n encoding: utf8\n" >config/database.yml' - 'bundle exec rake db:schema:load RAILS_ENV=test' -script: xvfb-run -a bundle exec rake rspec-rerun:spec +script: bundle exec rake rspec-rerun:spec diff --git a/Dockerfile b/Dockerfile index 27b6f078..ef9bbfff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.3 +FROM ruby:2.4 RUN supercronicUrl=https://github.com/aptible/supercronic/releases/download/v0.1.3/supercronic-linux-amd64 && \ supercronicBin=/usr/local/bin/supercronic && \ @@ -34,14 +34,14 @@ RUN export DATABASE_URL=mysql2://localhost/temp && \ export SECRET_KEY_BASE=thisisnotimportantnow && \ export DEBIAN_FRONTEND=noninteractive && \ apt-get update && \ - apt-get install -y mysql-server && \ + apt-get install -y mariadb-server && \ /etc/init.d/mysql start && \ cp config/app_config.yml.SAMPLE config/app_config.yml && \ bundle exec rake db:setup assets:precompile && \ rm -Rf config/app_config.yml tmp/* && \ /etc/init.d/mysql stop && \ rm -Rf /run/mysqld /tmp/* /var/tmp/* /var/lib/mysql /var/log/mysql* && \ - apt-get purge -y --auto-remove mysql-server && \ + apt-get purge -y --auto-remove mariadb-server && \ rm -Rf /var/lib/apt/lists/* /var/cache/apt/* # Make relevant dirs writable for app user diff --git a/Dockerfile-dev b/Dockerfile-dev index 7e784e2a..1b06757b 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -1,7 +1,7 @@ -FROM ruby:2.3 +FROM ruby:2.4 # Install dependencies -RUN deps='libmagic-dev xvfb qt5-default libqt5webkit5-dev gstreamer1.0-plugins-base gstreamer1.0-tools gstreamer1.0-x' && \ +RUN deps='libmagic-dev chromium' && \ apt-get update && \ apt-get install --no-install-recommends -y $deps && \ rm -Rf /var/lib/apt/lists/* /var/cache/apt/* @@ -12,6 +12,8 @@ ENV PORT=3000 \ RAILS_LOG_TO_STDOUT=true \ RAILS_SERVE_STATIC_FILES=true \ \ + CHROMIUM_FLAGS=--no-sandbox \ + \ BUNDLE_PATH=/home/app/bundle \ BUNDLE_APP_CONFIG=/home/app/bundle/config diff --git a/Gemfile b/Gemfile index 65846095..45f348f2 100644 --- a/Gemfile +++ b/Gemfile @@ -101,7 +101,8 @@ group :test do gem 'factory_bot_rails' gem 'faker' gem 'capybara' - gem 'capybara-webkit' + gem 'puma' # for faster Capybara tests + gem 'apparition' # Capybara javascript driver gem 'database_cleaner' gem 'connection_pool' # need to include rspec components before i18n-spec or rake fails in test environment diff --git a/Gemfile.lock b/Gemfile.lock index 5ddac57e..71916a1d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -101,6 +101,9 @@ GEM rspec (~> 3) rspec-expectations (~> 3.1) rspec-mocks (~> 3.1) + apparition (0.4.0) + capybara (~> 3.13, < 4) + websocket-driver (>= 0.6.5) arel (6.0.4) attribute_normalizer (1.2.0) base32 (0.3.2) @@ -116,16 +119,14 @@ GEM bullet (6.0.2) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - capybara (2.13.0) + capybara (3.29.0) addressable - mime-types (>= 1.16) - nokogiri (>= 1.3.3) - rack (>= 1.0.0) - rack-test (>= 0.5.4) - xpath (~> 2.0) - capybara-webkit (1.14.0) - capybara (>= 2.3.0, < 2.14.0) - json + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (~> 1.5) + xpath (~> 3.2) case_transform (0.2) activesupport chronic (0.10.2) @@ -274,6 +275,7 @@ GEM mono_logger (1.1.0) multi_json (1.14.1) mysql2 (0.4.10) + nio4r (2.5.2) nokogiri (1.10.4) mini_portile2 (~> 2.4.0) pdf-core (0.7.0) @@ -295,6 +297,8 @@ GEM binding_of_caller (>= 0.7) pry (>= 0.9.11) public_suffix (4.0.1) + puma (4.2.1) + nio4r (~> 2.0) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) rack (1.6.11) @@ -355,6 +359,7 @@ GEM redis-namespace (1.6.0) redis (>= 3.0.4) ref (2.0.0) + regexp_parser (1.6.0) responders (2.4.1) actionpack (>= 4.2.0, < 6.0) railties (>= 4.2.0, < 6.0) @@ -484,6 +489,9 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + websocket-driver (0.7.1) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.4) whenever (1.0.0) chronic (>= 0.6.3) wikicloth (0.8.3) @@ -503,13 +511,13 @@ DEPENDENCIES acts_as_tree acts_as_versioned! apivore + apparition attribute_normalizer better_errors binding_of_caller bootstrap-datepicker-rails bullet capybara - capybara-webkit connection_pool coveralls daemons @@ -546,6 +554,7 @@ DEPENDENCIES protected_attributes (= 1.1.0) pry-rescue pry-stack_explorer + puma quiet_assets rack-cors rails (~> 4.2) diff --git a/Procfile b/Procfile index 5e384550..d8e51467 100644 --- a/Procfile +++ b/Procfile @@ -1,4 +1,4 @@ -web: bundle exec rails server --binding=0.0.0.0 --port=$PORT +web: bundle exec rails server thin --binding=0.0.0.0 --port=$PORT worker: QUEUE=foodsoft_notifier bundle exec rake resque:work mail: bundle exec rake foodsoft:reply_email_smtp_server cron: supercronic crontab diff --git a/app/views/articles/index.html.haml b/app/views/articles/index.html.haml index 8e9bef3c..7c42276b 100644 --- a/app/views/articles/index.html.haml +++ b/app/views/articles/index.html.haml @@ -53,9 +53,9 @@ - content_for :javascript do :javascript // keep import button pressed when import section is shown - $(document).on('touchclick', 'a[data-toggle-this=#import]', function() { + $(document).on('touchclick', 'a[data-toggle-this="#import"]', function() { var state = $('#import').is(':visible'); - $('.btn-toolbar a[data-toggle-this=#import]').toggleClass('active', !state); + $('.btn-toolbar a[data-toggle-this="#import"]').toggleClass('active', !state); if (!state) { // also load articles when shown $('#import form').submit(); diff --git a/bin/test b/bin/test index f6746a0c..cfffaa9b 100755 --- a/bin/test +++ b/bin/test @@ -5,13 +5,5 @@ unset DATABASE_URL; export DATABASE_URL [ "$TEST_DATABASE_URL" ] && export DATABASE_URL="$TEST_DATABASE_URL" export RAILS_ENV=test -# Start virtuals X environment to allow integration testing via firefox/iceweasel -export DISPLAY=:99 -Xvfb $DISPLAY -nolisten tcp & -XVFB_PID=$! - # Start tests bundle exec rspec $@ - -# Cleanup -kill $XVFB_PID diff --git a/doc/SETUP_DEVELOPMENT.md b/doc/SETUP_DEVELOPMENT.md index f73518fa..3bb9640e 100644 --- a/doc/SETUP_DEVELOPMENT.md +++ b/doc/SETUP_DEVELOPMENT.md @@ -29,13 +29,13 @@ If instead you just want to run Foodsoft without changing its code, please refer unfinished parts. If you want to be safe, choose the last release: `git checkout $(git tag -l | grep ^v | sort -rn | head -n1)` -1. Install RVM and Ruby 2+ (if you have not done so before): +1. Install RVM and Ruby 2.4+ (if you have not done so before): \curl -L https://get.rvm.io | bash source ~/.rvm/scripts/rvm - rvm install 2.3 + rvm install 2.4 - We try to keep Foodsoft compatible with Ruby 2.3 as well as any later versions, + We try to keep Foodsoft compatible with Ruby 2.4 as well as any later versions, so if you use this and don't want to use RVM, that might actually work. 2. Install system dependencies. @@ -47,11 +47,10 @@ If instead you just want to run Foodsoft without changing its code, please refer [libxslt1-dev](https://packages.debian.org/stable/libxslt1-dev) [libffi-dev](https://packages.debian.org/stable/libffi-dev) [libreadline-dev](https://packages.debian.org/stable/libreadline-dev) - [libmagic-dev](https://packages.debian.org/stable/libmagic-dev) - [libqtwebkit-dev](https://packages.debian.org/stable/libqtwebkit-dev): + [libmagic-dev](https://packages.debian.org/stable/libmagic-dev): # Debian/Ubuntu - sudo apt-get install libv8-dev libmysqlclient-dev libxml2-dev libxslt1-dev libffi-dev libreadline-dev libmagic-dev libqtwebkit-dev + sudo apt-get install libv8-dev libmysqlclient-dev libxml2-dev libxslt1-dev libffi-dev libreadline-dev libmagic-dev For CentOS/Redhat you need [v8](https://apps.fedoraproject.org/packages/v8) @@ -60,11 +59,10 @@ If instead you just want to run Foodsoft without changing its code, please refer [libxslt-devel](https://apps.fedoraproject.org/packages/libxslt-devel) [libffi-devel](https://apps.fedoraproject.org/packages/libffi-devel) [readline-devel](https://apps.fedoraproject.org/packages/readline-devel) - [file-devel](https://apps.fedoraproject.org/packages/file-devel) - [qtwebkit-devel](https://apps.fedoraproject.org/packages/qtwebkit-devel): + [file-devel](https://apps.fedoraproject.org/packages/file-devel): # CentOS/Redhat - sudo yum install v8 community-mysql-devel libxml2-devel libxslt-devel libffi-devel readline-devel file-devel qtwebkit-devel + sudo yum install v8 community-mysql-devel libxml2-devel libxslt-devel libffi-devel readline-devel file-devel 3. Install Ruby dependencies: @@ -99,6 +97,9 @@ If instead you just want to run Foodsoft without changing its code, please refer 9. Have phun! +For running integration tests, you also need the Chromium/Chrome web browser. +On Debian that would be `sudo apt-get install chromium`, on Ubuntu +`sudo apt-get install chromium-browser`. ### Manual configuration diff --git a/doc/SETUP_DEVELOPMENT_DOCKER.md b/doc/SETUP_DEVELOPMENT_DOCKER.md index cbfce496..2dd1d0ae 100644 --- a/doc/SETUP_DEVELOPMENT_DOCKER.md +++ b/doc/SETUP_DEVELOPMENT_DOCKER.md @@ -57,7 +57,7 @@ Open a rails console Setup the test database - docker-compose-dev run --rm foodsoft bundle exec rake db:setup RAILS_ENV=test DATABASE_URL=mysql2://root:secret@mariadb/test + docker-compose-dev run --rm foodsoft bundle exec rake db:setup RAILS_ENV=test DATABASE_URL=mysql2://root:secret@mariadb/test?encoding=utf8 Run the tests diff --git a/spec/integration/balancing_spec.rb b/spec/integration/balancing_spec.rb index 55434622..6fc1966a 100644 --- a/spec/integration/balancing_spec.rb +++ b/spec/integration/balancing_spec.rb @@ -53,7 +53,9 @@ feature 'settling an order', js: true do it 'keeps ordered quantities when article is deleted from resulting order' do within("#order_article_#{oa.id}") do - click_link I18n.t('ui.delete') + accept_confirm do + click_link I18n.t('ui.delete') + end end expect(page).to_not have_selector("#order_article_#{oa.id}") expect(OrderArticle.exists?(oa.id)).to be true @@ -69,7 +71,9 @@ feature 'settling an order', js: true do goa1.destroy goa2.destroy within("#order_article_#{oa.id}") do - click_link I18n.t('ui.delete') + accept_confirm do + click_link I18n.t('ui.delete') + end end expect(page).to_not have_selector("#order_article_#{oa.id}") expect(OrderArticle.exists?(oa.id)).to be false @@ -107,10 +111,10 @@ feature 'settling an order', js: true do click_link I18n.t('ui.edit') end within("#edit_order_article_#{oa.id}") do - fill_in :order_article_units_to_order, :with => 0 + find('#order_article_units_to_order').set(0) + sleep 0.2 find('input[type="submit"]').click end - sleep 0.5 # workaround "javascript error" "e is null" expect(page).to have_selector("#order_article_#{oa.id}") # make sure it still works after reloading visit new_finance_order_path(order_id: order.id) @@ -129,7 +133,8 @@ feature 'settling an order', js: true do expect(page).to have_selector('form#new_group_order_article') within('#new_group_order_article') do select user.ordergroup.name, :from => 'group_order_article_ordergroup_id' - fill_in 'group_order_article_result', :with => 8 + find('#group_order_article_result').set(8) + sleep 0.2 find('input[type="submit"]').click end expect(page).to_not have_selector('form#new_group_order_article') @@ -144,7 +149,7 @@ feature 'settling an order', js: true do it 'can modify an ordergroup result' do click_link article.name within("#group_order_articles_#{oa.id}") do - fill_in "r_#{goa1.id}", :with => 5 + find("#r_#{goa1.id}").set(5).send_keys(:tab) # tab to blur and let js update end expect(page).to have_selector('#summaryChangedWarning') # becomes visible after request is done expect(goa1.reload.result).to eq 5 @@ -167,8 +172,10 @@ feature 'settling an order', js: true do click_link I18n.t('finance.balancing.edit_results_by_articles.add_article') expect(page).to have_selector('form#new_order_article') within('#new_order_article') do - select new_article.name, :from => 'order_article_article_id' + find('#order_article_article_id').select(new_article.name) + sleep 0.1 find('input[type="submit"]').click + sleep 0.1 end expect(page).to_not have_selector('form#new_order_article') expect(page).to have_content(new_article.name) diff --git a/spec/integration/order_spec.rb b/spec/integration/order_spec.rb index bf7aa903..2c8df500 100644 --- a/spec/integration/order_spec.rb +++ b/spec/integration/order_spec.rb @@ -50,7 +50,9 @@ feature Order, js: true do oa.update_results! # and close the order visit orders_path - click_link_or_button I18n.t('orders.index.action_end') + accept_confirm do + click_link_or_button I18n.t('orders.index.action_end') + end expect(page).to have_selector('.alert-success') order.reload oa.reload diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 016ce61e..fe954f1c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -5,8 +5,10 @@ require_relative 'support/coverage' # needs to be first require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'capybara/rails' +require 'capybara/apparition' -Capybara.javascript_driver = :webkit +Capybara.server = :puma, { Silent: true } +Capybara.javascript_driver = :apparition # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories.