refactor and move to selenium
This commit is contained in:
@@ -37,3 +37,5 @@ chromedriver.log
|
||||
/old_cap
|
||||
gem_graph.png
|
||||
erl_crash.dump
|
||||
/db/*.couch
|
||||
/db/*_design
|
||||
|
||||
+27
-28
@@ -1,28 +1,27 @@
|
||||
FROM rails:onbuild
|
||||
#FROM bterkuile/ruby-base
|
||||
#
|
||||
#MAINTAINER Benjamin ter Kuile <bterkuile@gmail.com>
|
||||
#
|
||||
## Add 'web' user which will run the application
|
||||
#RUN adduser web --home /home/web --shell /bin/bash --disabled-password --gecos ""
|
||||
#
|
||||
## Separate Gemfile ADD so that `bundle install` can be cached more effectively
|
||||
#ADD Gemfile /var/www/
|
||||
#ADD Gemfile.lock /var/www/
|
||||
#RUN chown -R web:web /var/www &&\
|
||||
# mkdir -p /var/bundle &&\
|
||||
# chown -R web:web /var/bundle
|
||||
#RUN su -c "cd /var/www && bundle install --deployment --without development test assets --path /var/bundle" -s /bin/bash -l web
|
||||
#
|
||||
## Add application source
|
||||
#ADD . /var/www
|
||||
#RUN chown -R web:web /var/www
|
||||
#
|
||||
#USER web
|
||||
#
|
||||
#WORKDIR /var/www
|
||||
#
|
||||
##VOLUME ['/Users/bterkuile/companytools/development/rails/mozo_bar/public/system:/var/www/public/system']
|
||||
#EXPOSE 3000
|
||||
#
|
||||
#CMD ["bundle", "exec", "foreman", "start"]
|
||||
FROM ruby:2.2.0
|
||||
|
||||
# throw errors if Gemfile has been modified since Gemfile.lock
|
||||
RUN bundle config --global frozen 1
|
||||
|
||||
RUN mkdir -p /usr/src/app/vendor
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Test
|
||||
RUN apt-get update && apt-get install -y qt5-default libqt5webkit5-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
# Standard
|
||||
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
# Specific
|
||||
RUN apt-get update && apt-get install -y dos2unix --no-install-recommends && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY Gemfile /usr/src/app/
|
||||
COPY Gemfile.lock /usr/src/app/
|
||||
#COPY vendor/cache /usr/src/app/vendor/cache
|
||||
#RUN bundle install --local
|
||||
RUN bundle install
|
||||
|
||||
COPY . /usr/src/app
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["rails", "server", '-b', '0.0.0.0']
|
||||
|
||||
@@ -104,7 +104,8 @@ group :test do
|
||||
# gem 'database_cleaner'
|
||||
# gem 'capybara' #, '2.0.3'
|
||||
#gem 'selenium-webdriver'
|
||||
gem 'capybara-webkit' #, '~>0.14.2' # version 1.1.0 does not yet compile in mavericks
|
||||
#gem 'capybara-webkit' #, '~>0.14.2' # version 1.1.0 does not yet compile in mavericks
|
||||
gem 'selenium-webdriver'
|
||||
gem 'capybara-screenshot'
|
||||
gem 'turnip'
|
||||
gem 'rspec-its'
|
||||
|
||||
+11
-4
@@ -142,9 +142,8 @@ GEM
|
||||
capybara (>= 1.0, < 3)
|
||||
colored
|
||||
launchy
|
||||
capybara-webkit (1.3.1)
|
||||
capybara (>= 2.0.2, < 2.5.0)
|
||||
json
|
||||
childprocess (0.5.5)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cocaine (0.5.5)
|
||||
@@ -222,6 +221,7 @@ GEM
|
||||
faye-websocket (0.9.2)
|
||||
eventmachine (>= 0.12.0)
|
||||
websocket-driver (>= 0.5.1)
|
||||
ffi (1.9.6)
|
||||
font-awesome-rails (4.2.0.0)
|
||||
railties (>= 3.2, < 5.0)
|
||||
foundation-rails (5.5.0.0)
|
||||
@@ -369,6 +369,7 @@ GEM
|
||||
rspec-support (~> 3.1.0)
|
||||
rspec-support (3.1.2)
|
||||
ruby-progressbar (1.7.1)
|
||||
rubyzip (1.1.6)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.3.14)
|
||||
sass-rails (5.0.0.beta1)
|
||||
@@ -376,6 +377,11 @@ GEM
|
||||
sass (~> 3.2)
|
||||
sprockets (~> 2.12)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
selenium-webdriver (2.44.0)
|
||||
childprocess (~> 0.5)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0)
|
||||
simplecov (0.9.1)
|
||||
docile (~> 1.1.0)
|
||||
multi_json (~> 1.0)
|
||||
@@ -431,6 +437,7 @@ GEM
|
||||
webmock (1.20.4)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
websocket (1.2.1)
|
||||
websocket-driver (0.5.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.1)
|
||||
@@ -450,7 +457,6 @@ DEPENDENCIES
|
||||
capistrano-rails (~> 1.1)
|
||||
capistrano-rvm (~> 0.1)
|
||||
capybara-screenshot
|
||||
capybara-webkit
|
||||
cmtool!
|
||||
coffee-rails
|
||||
couch_potato!
|
||||
@@ -484,6 +490,7 @@ DEPENDENCIES
|
||||
rspec-its
|
||||
rspec-rails
|
||||
sass-rails (= 5.0.0.beta1)
|
||||
selenium-webdriver
|
||||
simplecov
|
||||
simply_stored!
|
||||
slim-rails
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
App.MenuProductCategoriesComponent = Ember.Component.extend
|
||||
orderProducts: false
|
||||
timestamp: 0 # invalidation param
|
||||
active_product_categories: (->
|
||||
list = @get('product_categories')
|
||||
).property('product_categories.@each', 'timestamp')
|
||||
|
||||
actions:
|
||||
toggleProductCategory: (product_category) -> product_category.toggleProperty('collapsed')
|
||||
@@ -0,0 +1,14 @@
|
||||
App.MenuProductComponent = Ember.Component.extend
|
||||
tagName: 'li'
|
||||
classNameBindings: ['specific_id']
|
||||
specific_id: (-> "order-product-#{@get('product.id')}").property('product.id')
|
||||
orderProducts: false
|
||||
target: -> @get('parentView.targetObject')
|
||||
actions:
|
||||
addProduct: (product)->
|
||||
if existing = @target().store.all('product_order').find((po)-> po.get('product') == product and not po.get('order'))
|
||||
existing.increment()
|
||||
else
|
||||
@target().store.createRecord 'product_order', product: product, price: product.get('price')
|
||||
showProductDescription: (product)->
|
||||
@target().modal 'product_info', model: product, title: product.get('name')
|
||||
@@ -108,6 +108,8 @@ App.ApplicationController = Ember.Controller.extend
|
||||
if error_list = @store.all('list').findBy('id', 'current')
|
||||
error_list.eraseRecord()
|
||||
@set 'list', null
|
||||
@redirect_to 'index'
|
||||
switch @currentRouteName
|
||||
when 'table' then # nothing
|
||||
else @redirect_to 'index'
|
||||
|
||||
@store.find('list', 'current').then(success, error)
|
||||
|
||||
@@ -17,15 +17,6 @@ App.TableController = Ember.ObjectController.extend
|
||||
if @get('model.occupied') then true else false # no point in joining tables that are not occupied
|
||||
).property('controllers.application.list.id', 'supplier.can_take_orders', 'model.occupied', 'model.id', 'controllers.application.list.table.id')
|
||||
actions:
|
||||
addProduct: (product)->
|
||||
if existing = @store.all('product_order').find((po)-> po.get('product') == product and not po.get('order'))
|
||||
existing.increment()
|
||||
else
|
||||
@store.createRecord 'product_order', product: product, price: product.get('price')
|
||||
joinOccupiedTable: ->
|
||||
Ember.$.post("#{$data_host}/user/join_occupied_table.json", table_id: @get('model.id'))
|
||||
@set 'controllers.application.join_request_sent', true # keeps the button deactivated
|
||||
toggleProductCategory: (product_category)->
|
||||
product_category.set 'collapsed', not product_category.get('collapsed')
|
||||
showProductDescription: (product)->
|
||||
@modal 'product_info', model: product, title: product.get('name')
|
||||
|
||||
@@ -3,7 +3,7 @@ ControllerExtensions = Ember.Mixin.create
|
||||
ajaxError: (callback)->
|
||||
handler = (emberError)=>
|
||||
console.log "Error: status #{emberError.status}"
|
||||
if emberError.status == 401
|
||||
if emberError.status is 401
|
||||
App.__container__.lookup('route:application').unauthorized()
|
||||
else
|
||||
callback.call(@, emberError)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
each product_category in active_product_categories
|
||||
.product-category-container
|
||||
if orderProducts
|
||||
h4 OderProducts
|
||||
if product_category.products
|
||||
h4.product_category-title{action "toggleProductCategory" product_category}
|
||||
if product_category.collapsed
|
||||
span.icon.collapsed
|
||||
else
|
||||
span.icon
|
||||
= product_category.name
|
||||
unless product_category.collapsed
|
||||
ul.product_category-products
|
||||
each product in product_category.products
|
||||
= menu-product product=product orderProducts=orderProducts
|
||||
@@ -0,0 +1,12 @@
|
||||
if product.description
|
||||
button.show-product-description{action "showProductDescription" product}
|
||||
span
|
||||
else
|
||||
span.no-product-description
|
||||
if orderProducts
|
||||
a{action "addProduct" product}= product.name
|
||||
button.add-product-to-list{action "addProduct" product}
|
||||
span
|
||||
else
|
||||
span= product.name
|
||||
span.product-price.currency=currency product.price
|
||||
@@ -12,41 +12,7 @@
|
||||
else
|
||||
button.join-table-button{action "joinOccupiedTable"}=t 'join_request.requestor.join_this_table'
|
||||
if tableCanTakeOrders
|
||||
.large-6.columns
|
||||
each product_category in supplier.product_categories
|
||||
.product-category-container
|
||||
if product_category.products
|
||||
h4.product_category-title{action "toggleProductCategory" product_category}
|
||||
if product_category.collapsed
|
||||
span.icon.collapsed
|
||||
else
|
||||
span.icon
|
||||
= product_category.name
|
||||
unless product_category.collapsed
|
||||
ul.product_category-products
|
||||
each product in product_category.products
|
||||
li class="order-product-#{unbound product.id}"
|
||||
if product.description
|
||||
button.show-product-description{action "showProductDescription" product}
|
||||
span
|
||||
else
|
||||
span.no-product-description
|
||||
a{action "addProduct" product}= product.name
|
||||
button.add-product-to-list{action "addProduct" product}
|
||||
span
|
||||
span.product-price.currency=currency product.price
|
||||
.large-6.columns= menu-product-categories product_categories=supplier.product_categories orderProducts=true
|
||||
.large-6.columns= render 'product_orders'
|
||||
else
|
||||
.large12
|
||||
each product_category in supplier.product_categories
|
||||
if product_category.products
|
||||
.product_category-container
|
||||
h4.product-category-title= product_category.name
|
||||
ul.product_category-products
|
||||
each product in product_category.products
|
||||
li class="order-product-#{unbound product.id}"
|
||||
if product.description
|
||||
button.show-product-description{action "showProductDescription" product}
|
||||
span
|
||||
span= product.name
|
||||
span.right.currency=currency product.price
|
||||
.large12= menu-product-categories product_categories=supplier.product_categories orderProducts=false
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module Admin
|
||||
class SuppliersController < Admin::ApplicationController
|
||||
before_filter :set_relation_options, only: [:new, :edit, :create, :update]
|
||||
skip_before_filter :authenticate_administrator!, only: :test_login
|
||||
skip_before_filter :set_locale, only: :test_login
|
||||
# GET /suppliers
|
||||
# GET /suppliers.json
|
||||
def index
|
||||
@@ -12,6 +14,13 @@ module Admin
|
||||
end
|
||||
end
|
||||
|
||||
def test_login
|
||||
if Rails.env.test? and supplier = Supplier.find_by_email(params[:email])
|
||||
sign_in supplier
|
||||
end
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
# GET /suppliers/1
|
||||
# GET /suppliers/1.json
|
||||
def show
|
||||
|
||||
@@ -50,6 +50,8 @@ class InMemoryQCounter
|
||||
def reload_stats!
|
||||
require 'yaml'
|
||||
require 'couchrest'
|
||||
require 'pry'
|
||||
binding.pry
|
||||
couch_settings_path = File.join(ENV['MOZO_PATH'], 'config/couchdb.yml')
|
||||
puts "Couch settings path: #{couch_settings_path}"
|
||||
puts "Environment: #{environment.inspect}"
|
||||
|
||||
+5
-1
@@ -9,7 +9,11 @@ Qwaiter::Application.routes.draw do
|
||||
get :test_login
|
||||
end
|
||||
end
|
||||
resources :suppliers
|
||||
resources :suppliers do
|
||||
collection do
|
||||
get :test_login
|
||||
end
|
||||
end
|
||||
resources :tables
|
||||
resources :orders
|
||||
resources :sections
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
db:
|
||||
image: bterkuile/couchdb
|
||||
volumes:
|
||||
- .db:/usr/local/var/lib/couchdb
|
||||
- db:/usr/local/var/lib/couchdb
|
||||
expose:
|
||||
- 5984
|
||||
net: host
|
||||
counters:
|
||||
image: ruby:2.2
|
||||
web:
|
||||
build: .
|
||||
#command: bundle exec unicorn -p 3000 -c ./config/unicorn.rb
|
||||
@@ -12,5 +15,5 @@ web:
|
||||
- .:/usr/src/app
|
||||
ports:
|
||||
- "3000:3000"
|
||||
links:
|
||||
- db
|
||||
#links:
|
||||
# #- db
|
||||
|
||||
@@ -54,6 +54,7 @@ Feature: Supplier main board
|
||||
Given there is an active list and order
|
||||
And there is another section with table
|
||||
And I am signed in as supplier
|
||||
When I visit the supplier root path
|
||||
And a new order on a table in another section is created
|
||||
Then I should see the list and the new list
|
||||
And I should see the order and the new order
|
||||
@@ -69,7 +70,8 @@ Feature: Supplier main board
|
||||
Scenario: Selecting a specific section and jumping towards section view
|
||||
Given there is an active list and order
|
||||
And I am signed in as supplier
|
||||
When I select the section in the supplier dashboard
|
||||
When I visit the supplier root path
|
||||
And I select the section in the supplier dashboard
|
||||
And I click on the section main board section jumper
|
||||
Then I should be redirected to the supplier section view
|
||||
|
||||
@@ -78,6 +80,7 @@ Feature: Supplier main board
|
||||
Given there is an active list and order
|
||||
And there is another section with table
|
||||
And I am signed in as supplier
|
||||
When I visit the supplier root path
|
||||
# wait until page is fully loaded, could be a pure ruby command inside a within :selector statement since the browser will wait for the selector to be present and then the lists are loaded
|
||||
And I wait 4 seconds
|
||||
When the active list changes to another table in another section
|
||||
@@ -89,7 +92,8 @@ Feature: Supplier main board
|
||||
Scenario: Remove an order
|
||||
Given there is an active list and order
|
||||
And I am signed in as supplier
|
||||
When the supplier marks the order as wrong in the main board view
|
||||
When I visit the supplier root path
|
||||
And the supplier marks the order as wrong in the main board view
|
||||
Then the supplier main board order should not be visible anymore
|
||||
And the supplier main board list total should be updated
|
||||
And the supplier placed orders counter should be reduced
|
||||
@@ -98,7 +102,8 @@ Feature: Supplier main board
|
||||
Scenario: Closing list with active orders updates supplier counters
|
||||
Given there is an active list and order
|
||||
And I am signed in as supplier
|
||||
When I click on the close list button in the supplier dashboard
|
||||
When I visit the supplier root path
|
||||
And I click on the close list button in the supplier dashboard
|
||||
And confirm the supplier close list modal
|
||||
Then the supplier placed orders counter should be reduced
|
||||
|
||||
@@ -107,7 +112,8 @@ Feature: Supplier main board
|
||||
Given there is an active list and order
|
||||
And there is another section with table
|
||||
And I am signed in as supplier
|
||||
When a new order on a table in another section is created
|
||||
When I visit the supplier root path
|
||||
And a new order on a table in another section is created
|
||||
Then I should see the list and the new list
|
||||
And I should see the order and the new order
|
||||
When I select the section in the supplier dashboard
|
||||
|
||||
@@ -5,8 +5,8 @@ Feature: Adding product category
|
||||
Given there is a confirmed and open supplier
|
||||
And I am signed in as supplier
|
||||
#And there are 2 supplier products
|
||||
And the supplier visits the menu page
|
||||
When the supplier clicks on the new product category button
|
||||
When the supplier visits the menu page
|
||||
And the supplier clicks on the new product category button
|
||||
And the supplier fills in the new product category form selecting not available on tuesdays
|
||||
And the supplier submits the product category form
|
||||
Then then new product category with proper properties should have been created
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
step "I am signed in as supplier" do
|
||||
step 'visit the supplier sign in path'
|
||||
find('#supplier_email').set @supplier.email
|
||||
find('#supplier_password').set @supplier_password
|
||||
click_on 'Inloggen'
|
||||
|
||||
visit test_login_admin_suppliers_path(email: @supplier.email)
|
||||
#step 'visit the supplier sign in path'
|
||||
#find('#supplier_email').set @supplier.email
|
||||
#find('#supplier_password').set @supplier_password
|
||||
#click_on 'Inloggen'
|
||||
end
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
step "the section table should be positioned in the section" do
|
||||
table = page.find(".section-table-#{@table.id}")
|
||||
left = table['style'].to_s.match(/left:(\d+)/)
|
||||
left.should be_present
|
||||
left[1].to_i.should > 10
|
||||
top = table['style'].to_s.match(/top:(\d+)/)
|
||||
top.should be_present
|
||||
top[1].to_i.should > 10
|
||||
page.find(".section-table-#{@table.id}") # wait for table presence
|
||||
|
||||
left = page.evaluate_script("$('.section-table-#{@table.id}').position().left")
|
||||
left.to_i.should > 0
|
||||
|
||||
top = page.evaluate_script("$('.section-table-#{@table.id}').position().top")
|
||||
top.to_i.should > 0
|
||||
end
|
||||
|
||||
step "the section table should be marked as having an active order" do
|
||||
table = page.find(".section-table-#{@table.id}")
|
||||
table['class'].should include 'active_order'
|
||||
assert_element_class ".section-table-#{@table.id}", 'active_order'
|
||||
end
|
||||
|
||||
step "the section table should still be marked as having an active order" do
|
||||
step "the section table should be marked as having an active order"
|
||||
end
|
||||
|
||||
step "the section table should be marked as occupied" do
|
||||
table = page.find(".section-table-#{@table.id}")
|
||||
table['class'].should include 'occupied'
|
||||
assert_element_class ".section-table-#{@table.id}", 'occupied'
|
||||
end
|
||||
|
||||
step "the section table should be marked as in need of help" do
|
||||
table = page.find(".section-table-#{@table.id}")
|
||||
table['class'].should include 'needs_help'
|
||||
assert_element_class ".section-table-#{@table.id}", 'needs_help'
|
||||
end
|
||||
|
||||
step "the section table should not be marked as in need of help" do
|
||||
@@ -97,9 +95,9 @@ step "I click the supplier section normal mode button" do
|
||||
end
|
||||
|
||||
step "I fill in the supplier edit section form with new values" do
|
||||
find('.section-edit-title-field').set 'RenamedSection'
|
||||
find('.section-edit-width-field').set '40'
|
||||
find('.section-edit-height-field').set '52.7'
|
||||
js_set_field '.section-edit-title-field', 'RenamedSection'
|
||||
js_set_field '.section-edit-width-field', 40
|
||||
js_set_field '.section-edit-height-field', 52.7
|
||||
end
|
||||
|
||||
step "the last section tab header should have the newly filled in name" do
|
||||
|
||||
@@ -66,6 +66,7 @@ step "the user order :product_name should be in the order list with price" do |p
|
||||
concerning_product = Product.find_by_name(product_name)
|
||||
#ember_order = ember_store['product_orders'].find{|po| po['product_id'] == concerning_product.id}
|
||||
#ember_order = ember_find('product_order', concerning_product.id)
|
||||
sleep 0.1
|
||||
ember_order = ember_all('product_order').find{|po| po['product_id'] == concerning_product.id }
|
||||
quantity = ember_order['quantity']
|
||||
order_price = quantity * concerning_product.price
|
||||
|
||||
+2
-1
@@ -19,7 +19,8 @@ Dir.glob("spec/acceptance_steps/**/*steps.rb") { |f| load f, true }
|
||||
|
||||
I18n.locale =I18n.default_locale
|
||||
Devise.stretches = 1
|
||||
Capybara.javascript_driver = :webkit
|
||||
#Capybara.javascript_driver = :webkit
|
||||
Capybara.javascript_driver = :selenium
|
||||
Capybara.default_wait_time = 4 # ember needs more time than the default of 2
|
||||
Capybara::Screenshot.webkit_options = { width: 1024, height: 768 }
|
||||
WebMock.disable_net_connect!(allow_localhost: true)
|
||||
|
||||
@@ -15,18 +15,31 @@ module SpecEmberHelpers
|
||||
JSON.parse(h)
|
||||
end
|
||||
|
||||
def assert_element_class(selector, class_name)
|
||||
find selector # capybara wait for element
|
||||
time = 0
|
||||
classes = page.evaluate_script("$('#{selector}').attr('class')")
|
||||
while !classes.include?(class_name) and time < 10
|
||||
sleep 0.1
|
||||
classes = page.evaluate_script("$('#{selector}').attr('class')")
|
||||
time += 1
|
||||
end
|
||||
classes.should include class_name
|
||||
end
|
||||
|
||||
def js_set_field(selector, value)
|
||||
page.execute_script("$('#{selector}').val('#{value}').trigger('change')")
|
||||
end
|
||||
|
||||
def ember_find(typeKey, id)
|
||||
h = page.evaluate_script <<-SCRIPT
|
||||
$s = App.__container__.lookup('store:main');
|
||||
record = $s.all('#{typeKey}').findBy('id', '#{id}');
|
||||
record ? record.serialize() : null
|
||||
App.__container__.lookup('store:main').all('#{typeKey}').findBy('id', '#{id}').serialize()
|
||||
SCRIPT
|
||||
end
|
||||
|
||||
def ember_all(typeKey)
|
||||
h = page.evaluate_script <<-SCRIPT
|
||||
$s = App.__container__.lookup('store:main');
|
||||
$s.all('#{typeKey}').invoke('serialize')
|
||||
App.__container__.lookup('store:main').all('#{typeKey}').invoke('serialize')
|
||||
SCRIPT
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user