Removing all things Selenium from mobile Appium specs
- extracted environment setup code from selenium_driver_setup and common.rb, removed all things selenium - current specs modified to include new environment setup Change-Id: I0b2ea90374c2a7317671c09944ce47e30376a0d3 Reviewed-on: https://gerrit.instructure.com/61488 Reviewed-by: Caleb Guanzon <cguanzon@instructure.com> Product-Review: Caleb Guanzon <cguanzon@instructure.com> QA-Review: Caleb Guanzon <cguanzon@instructure.com> Tested-by: Jenkins
This commit is contained in:
parent
b9323ed9a5
commit
7ca12824c4
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../../helpers/landing_page_common'
|
||||
|
||||
describe 'candroid landing page' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'candroid'
|
||||
let(:default_url){ 'Find your school or district' }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../../helpers/login_common'
|
||||
|
||||
describe 'candroid login credentials' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'candroid'
|
||||
let(:app_login_message){ /(Canvas for Android)/ }
|
||||
let(:app_access_message){ /Canvas for Android is requesting access.*/ }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../../helpers/landing_page_common'
|
||||
|
||||
describe 'speedgrader for android landing page' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'speedgrader_android'
|
||||
let(:default_url){ 'myschool.instructure.com' }
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../../helpers/login_common'
|
||||
|
||||
describe 'speedgrader login credentials' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'speedgrader_android'
|
||||
let(:app_login_message){ /(Canvas for Android)/ } # TODO: ask dev team to modify this for Speedgrader
|
||||
let(:app_access_message){ /Canvas for Android is requesting access.*/ } # TODO: ask dev team to modify this for Speedgrader
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require 'socket'
|
||||
require 'timeout'
|
||||
require_relative '../../spec_helper'
|
||||
require_relative '../test_setup/common_helper_methods/login_and_session_methods'
|
||||
require_relative '../test_setup/common_helper_methods/other_helper_methods'
|
||||
|
||||
module EnvironmentSetup
|
||||
|
||||
$appium_config = ConfigFile.load('appium')
|
||||
|
||||
# All test environments must be seeded with this Developer Key. The only attribute allowed
|
||||
# to change is the *redirect_uri* which contains the static IP address of the Canvas-lms
|
||||
# environment, but do not change it; modify the *host_url* method instead.
|
||||
|
@ -68,4 +71,201 @@ module EnvironmentSetup
|
|||
def implicit_wait_time
|
||||
3
|
||||
end
|
||||
|
||||
# ====================================================================================================================
|
||||
# Extracted from spec/selenium/test_setup/selenium_driver_setup.rb
|
||||
# Modified for Mobile App automation: all things Selenium removed
|
||||
# ====================================================================================================================
|
||||
|
||||
include I18nUtilities
|
||||
|
||||
$appium_config = ConfigFile.load("appium") || {}
|
||||
SERVER_IP = $appium_config[:server_ip] || UDPSocket.open do |s|
|
||||
s.connect('8.8.8.8', 1)
|
||||
s.addr.last
|
||||
end
|
||||
BIND_ADDRESS = $appium_config[:bind_address] || '0.0.0.0'
|
||||
SECONDS_UNTIL_COUNTDOWN = 5
|
||||
SECONDS_UNTIL_GIVING_UP = 20
|
||||
MAX_SERVER_START_TIME = 60
|
||||
THIS_ENV = ENV['TEST_ENV_NUMBER'].to_i
|
||||
THIS_ENV = 1 if ENV['TEST_ENV_NUMBER'].blank?
|
||||
WEBSERVER = (ENV['WEBSERVER'] || 'thin').freeze
|
||||
|
||||
$server_port = nil
|
||||
$app_host_and_port = nil
|
||||
|
||||
def host_and_port
|
||||
if $appium_config[:host] && $appium_config[:port] && !$appium_config[:host_and_port]
|
||||
$appium_config[:host_and_port] = "#{$appium_config[:host]}:#{$appium_config[:port]}"
|
||||
end
|
||||
end
|
||||
|
||||
# Runs a port scan unless the appium.yml file defines :server_port
|
||||
def self.setup_host_and_port
|
||||
ENV['CANVAS_CDN_HOST'] = "canvas.instructure.com"
|
||||
if $appium_config[:server_port]
|
||||
$server_port = $appium_config[:server_port]
|
||||
$app_host_and_port = "#{SERVER_IP}:#{$server_port}"
|
||||
return $server_port
|
||||
end
|
||||
|
||||
# find an available socket
|
||||
s = Socket.new(:INET, :STREAM)
|
||||
s.setsockopt(:SOCKET, :REUSEADDR, true)
|
||||
s.bind(Addrinfo.tcp(SERVER_IP, 0))
|
||||
|
||||
$server_port = s.local_address.ip_port
|
||||
if $appium_config[:browser] == 'ie'
|
||||
# makes default URL for selenium the external IP of the box for standalone sel servers
|
||||
server_ip = `curl http://instance-data/latest/meta-data/public-ipv4` # command for aws boxes gets external ip
|
||||
else
|
||||
server_ip = s.local_address.ip_address
|
||||
end
|
||||
|
||||
$app_host_and_port = "#{server_ip}:#{s.local_address.ip_port}"
|
||||
puts "Found available port: #{$app_host_and_port}"
|
||||
|
||||
return $server_port
|
||||
ensure
|
||||
s.close() if s
|
||||
end
|
||||
|
||||
def self.start_webserver(webserver)
|
||||
setup_host_and_port
|
||||
case webserver
|
||||
when 'thin'
|
||||
self.start_in_process_thin_server
|
||||
when 'webrick'
|
||||
self.start_in_process_webrick_server
|
||||
else
|
||||
puts "No web server specified, defaulting to WEBrick"
|
||||
self.start_in_process_webrick_server
|
||||
end
|
||||
end
|
||||
|
||||
def self.shutdown_webserver(server)
|
||||
shutdown = lambda do
|
||||
server.shutdown
|
||||
HostUrl.default_host = nil
|
||||
HostUrl.file_host = nil
|
||||
end
|
||||
at_exit { shutdown.call }
|
||||
shutdown
|
||||
end
|
||||
|
||||
def self.rack_app
|
||||
app = Rack::Builder.new do
|
||||
use Rails::Rack::Debugger unless Rails.env.test?
|
||||
run CanvasRails::Application
|
||||
end.to_app
|
||||
|
||||
lambda do |env|
|
||||
nope = [503, {}, [""]]
|
||||
return nope unless allow_requests?
|
||||
|
||||
# wrap request in a mutex so we can ensure it doesn't span spec
|
||||
# boundaries (see clear_requests!)
|
||||
result = request_mutex.synchronize { app.call(env) }
|
||||
|
||||
# check if the spec just finished while we ran, and if so prevent
|
||||
# side effects like redirects (and thus moar requests)
|
||||
if allow_requests?
|
||||
result
|
||||
else
|
||||
# make sure we clean up the body of requests we throw away
|
||||
# https://github.com/rack/rack/issues/658#issuecomment-38476120
|
||||
result.last.close if result.last.respond_to?(:close)
|
||||
nope
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def disallow_requests!
|
||||
# ensure the current in-flight request (if any, AJAX or otherwise)
|
||||
# finishes up its work, and prevent any subsequent requests before the
|
||||
# next spec gets underway. otherwise race conditions can cause sadness
|
||||
# with our shared conn and transactional fixtures (e.g. special
|
||||
# accounts and their caching)
|
||||
@allow_requests = false
|
||||
request_mutex.synchronize { }
|
||||
end
|
||||
|
||||
def allow_requests!
|
||||
@allow_requests = true
|
||||
end
|
||||
|
||||
def allow_requests?
|
||||
@allow_requests
|
||||
end
|
||||
|
||||
def request_mutex
|
||||
@request_mutex ||= Mutex.new
|
||||
end
|
||||
end
|
||||
|
||||
def self.start_in_process_thin_server
|
||||
require_relative '../test_setup/servers/thin_server'
|
||||
SpecFriendlyThinServer.run(self.rack_app, BindAddress: BIND_ADDRESS, Port: $server_port, AccessLog: [])
|
||||
self.shutdown_webserver(SpecFriendlyThinServer)
|
||||
end
|
||||
|
||||
def self.start_in_process_webrick_server
|
||||
require_relative '../test_setup/servers/webrick_server'
|
||||
SpecFriendlyWEBrickServer.run(self.rack_app, BindAddress: BIND_ADDRESS, Port: $server_port, AccessLog: [])
|
||||
self.shutdown_webserver(SpecFriendlyWEBrickServer)
|
||||
end
|
||||
|
||||
# ====================================================================================================================
|
||||
# Extracted from spec/selenium/common.rb
|
||||
# Modified for Mobile App automation: all things Selenium removed
|
||||
# ====================================================================================================================
|
||||
|
||||
shared_context 'in-process server appium tests' do
|
||||
include OtherHelperMethods
|
||||
include LoginAndSessionMethods
|
||||
|
||||
# set up so you can use rails urls helpers in your selenium tests
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
prepend_before :all do
|
||||
$in_proc_webserver_shutdown ||= EnvironmentSetup.start_webserver(WEBSERVER)
|
||||
end
|
||||
|
||||
# tricksy tricksy. grab the current connection, and then always return the same one
|
||||
# (even if on a different thread - i.e. the server's thread), so that it will be in
|
||||
# the same transaction and see the same data
|
||||
before do
|
||||
if self.use_transactional_fixtures
|
||||
@db_connection = ActiveRecord::Base.connection
|
||||
@dj_connection = Delayed::Backend::ActiveRecord::Job.connection
|
||||
|
||||
# synchronize db connection methods for a modicum of thread safety
|
||||
methods_to_sync = %w{execute exec_cache exec_no_cache query}
|
||||
[@db_connection, @dj_connection].each do |conn|
|
||||
methods_to_sync.each do |method_name|
|
||||
if conn.respond_to?(method_name, true) && !conn.respond_to?("#{method_name}_with_synchronization", true)
|
||||
conn.class.class_eval <<-RUBY
|
||||
def #{method_name}_with_synchronization(*args)
|
||||
@mutex ||= Mutex.new
|
||||
@mutex.synchronize { #{method_name}_without_synchronization(*args) }
|
||||
end
|
||||
alias_method_chain :#{method_name}, :synchronization
|
||||
RUBY
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecord::ConnectionAdapters::ConnectionPool.any_instance.stubs(:connection).returns(@db_connection)
|
||||
Delayed::Backend::ActiveRecord::Job.stubs(:connection).returns(@dj_connection)
|
||||
Delayed::Backend::ActiveRecord::Job::Failed.stubs(:connection).returns(@dj_connection)
|
||||
end
|
||||
end
|
||||
|
||||
after(:each) do
|
||||
EnvironmentSetup.disallow_requests!
|
||||
truncate_all_tables unless self.use_transactional_fixtures
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
require_relative '../../../helpers/landing_page_common'
|
||||
|
||||
describe 'icanvas landing page' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_examples 'appium mobile specs', 'icanvas'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'icanvas'
|
||||
|
||||
it_behaves_like 'icanvas and speedgrader landing page', 'icanvas'
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
require_relative '../../../helpers/login_common'
|
||||
|
||||
describe 'user logging into icanvas app' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_examples 'appium mobile specs', 'icanvas'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'icanvas'
|
||||
let(:app_login_message){ 'Canvas for iOS' }
|
||||
let(:app_access_message){ 'Canvas for iOS is requesting access to your account.' }
|
||||
let(:app_login_success){ 'Profile' }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
require_relative '../../../helpers/landing_page_common'
|
||||
|
||||
describe 'speedgrader for ios landing page' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_examples 'appium mobile specs', 'speedgrader_ios'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'speedgrader_ios'
|
||||
|
||||
it_behaves_like 'icanvas and speedgrader landing page', 'speedgrader_ios'
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
require_relative '../../../helpers/login_common'
|
||||
|
||||
describe 'user logging into speedgrader app' do
|
||||
include_examples 'in-process server selenium tests'
|
||||
include_examples 'appium mobile specs', 'speedgrader_ios'
|
||||
include_context 'in-process server appium tests'
|
||||
include_context 'appium mobile specs', 'speedgrader_ios'
|
||||
let(:app_login_message){ 'SpeedGrader' }
|
||||
let(:app_access_message){ 'SpeedGrader is requesting access to your account.' }
|
||||
let(:app_login_success){ 'CSGSlideMenuView' }
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require 'appium_lib'
|
||||
require_relative '../common'
|
||||
require_relative 'environment_setup'
|
||||
|
||||
include EnvironmentSetup
|
||||
|
|
Loading…
Reference in New Issue