mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 21:27:48 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
.idea/
|
||||
Gemfile.lock
|
||||
results.html
|
||||
areports/
|
||||
ireports/
|
||||
coverage/
|
||||
@@ -0,0 +1,49 @@
|
||||
# AllCops:
|
||||
# TargetRubyVersion: 2.0
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Lint/Debugger:
|
||||
Exclude:
|
||||
- 'lib/pages/common.rb'
|
||||
|
||||
# Offense count: 6
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'lib/data_helper.rb'
|
||||
- 'lib/page_helper.rb'
|
||||
- 'lib/pages/game.rb'
|
||||
- 'lib/pages/generic_base_page.rb'
|
||||
- 'lib/pages/launch.rb'
|
||||
- 'lib/pages/login.rb'
|
||||
- 'lib/pages/logout.rb'
|
||||
- 'lib/pages/signup.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Metrics/AbcSize:
|
||||
Max: 58
|
||||
|
||||
# Offense count: 12
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 154
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 37
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: AllowedVariables.
|
||||
Style/GlobalVars:
|
||||
Exclude:
|
||||
- 'features/support/hooks.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
# IgnoredMethods: respond_to
|
||||
Style/SymbolProc:
|
||||
Exclude:
|
||||
- 'lib/pages/launch.rb'
|
||||
- 'lib/pages/login.rb'
|
||||
@@ -0,0 +1,55 @@
|
||||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2016-02-09 19:31:02 -0800 using RuboCop version 0.37.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# Offense count: 1
|
||||
# Cop supports --auto-correct.
|
||||
Lint/Debugger:
|
||||
Exclude:
|
||||
- 'lib/pages/common.rb'
|
||||
|
||||
# Offense count: 3
|
||||
Metrics/AbcSize:
|
||||
Max: 58
|
||||
|
||||
# Offense count: 12
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 154
|
||||
|
||||
# Offense count: 2
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 37
|
||||
|
||||
# Offense count: 6
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'test/**/*'
|
||||
- 'lib/pages/game.rb'
|
||||
- 'lib/pages/generic_base_page.rb'
|
||||
- 'lib/pages/launch.rb'
|
||||
- 'lib/pages/login.rb'
|
||||
- 'lib/pages/logout.rb'
|
||||
- 'lib/pages/signup.rb'
|
||||
|
||||
# Offense count: 5
|
||||
# Configuration parameters: AllowedVariables.
|
||||
Style/GlobalVars:
|
||||
Exclude:
|
||||
- 'features/support/env.rb'
|
||||
|
||||
# Offense count: 3
|
||||
# Cop supports --auto-correct.
|
||||
# Configuration parameters: IgnoredMethods.
|
||||
# IgnoredMethods: respond_to
|
||||
Style/SymbolProc:
|
||||
Exclude:
|
||||
- 'lib/pages/launch.rb'
|
||||
- 'lib/pages/login.rb'
|
||||
@@ -0,0 +1,16 @@
|
||||
source 'http://rubygems.org'
|
||||
|
||||
gem 'rspec'
|
||||
gem 'cucumber'
|
||||
gem 'random_data'
|
||||
gem 'appium_lib'
|
||||
gem 'pry'
|
||||
gem 'rake'
|
||||
gem 'yard-cucumber'
|
||||
gem 'parallel_tests'
|
||||
gem 'teamcity_formatter'
|
||||
gem 'require_all'
|
||||
gem 'simplecov'
|
||||
gem 'simplecov-rcov'
|
||||
gem 'cuke_sniffer'
|
||||
gem 'rubocop', '~> 0.37.1', require: false
|
||||
@@ -0,0 +1,88 @@
|
||||
require 'rubygems'
|
||||
require 'cucumber'
|
||||
require 'cucumber/rake/task'
|
||||
require 'parallel'
|
||||
require 'json'
|
||||
require 'yard'
|
||||
require 'fileutils'
|
||||
|
||||
task :cleanup do
|
||||
puts ' ========Deleting old reports and logs========='
|
||||
FileUtils.rm_rf('reports')
|
||||
File.delete('cucumber_failures.log') if File.exist?('cucumber_failures.log')
|
||||
File.new('cucumber_failures.log', 'w')
|
||||
Dir.mkdir('reports')
|
||||
end
|
||||
|
||||
task :parallel_run do
|
||||
puts '===== Executing Tests in parallel'
|
||||
system 'bundle exec parallel_cucumber features/ -o "-p android" -n 1'
|
||||
puts ' ====== Parallel execution finished and cucumber_failure.log created ========='
|
||||
end
|
||||
|
||||
task :rerun do
|
||||
if File.size('cucumber_failures.log') == 0
|
||||
puts '==== No failures. Everything Passed ========='
|
||||
else
|
||||
puts ' =========Re-running Failed Scenarios============='
|
||||
system 'bundle exec cucumber @cucumber_failures.log -f pretty'
|
||||
end
|
||||
end
|
||||
|
||||
task parallel_cucumber: [:cleanup, :parallel_run, :rerun]
|
||||
|
||||
YARD::Rake::YardocTask.new(:yard) do |t|
|
||||
t.files = ['features/**/*.feature', 'features/**/*.rb, lib/**/*.rb']
|
||||
end
|
||||
|
||||
Cucumber::Rake::Task.new(:sauce) do |t|
|
||||
t.cucumber_opts = 'features -p sauce --format pretty --profile html'
|
||||
end
|
||||
|
||||
Cucumber::Rake::Task.new(:ios) do |t|
|
||||
t.cucumber_opts = 'features OS=ios features -t @ios'
|
||||
end
|
||||
|
||||
Cucumber::Rake::Task.new(:android) do |t|
|
||||
t.cucumber_opts = 'features OS=android features -t @android'
|
||||
end
|
||||
|
||||
task :cuke_sniffer do
|
||||
system('bundle exec cuke_sniffer --out html reports/cuke_sniffer.html')
|
||||
end
|
||||
|
||||
task :rubocop do
|
||||
system('bundle exec rubocop')
|
||||
end
|
||||
|
||||
def run_android_tests
|
||||
system('bundle exec cucumber OS=android features -t @android')
|
||||
end
|
||||
|
||||
def run_android_tests_tc
|
||||
system('bundle exec cucumber OS=android features -t @android -f TeamCityFormatter::Formatter -f html -o reports/report.html')
|
||||
end
|
||||
|
||||
def run_ios_tests
|
||||
system('bundle exec cucumber OS=ios features -t @ios')
|
||||
end
|
||||
|
||||
def run_ios_tests_tc
|
||||
system('bundle exec cucumber OS=ios FF=tablet features -t @ios -f TeamCityFormatter::Formatter -f html -o reports/report.html')
|
||||
end
|
||||
|
||||
task :Nexus_9_Device do
|
||||
run_android_tests_tc
|
||||
end
|
||||
|
||||
task :iPad_mini_Device do
|
||||
run_ios_tests_tc
|
||||
end
|
||||
|
||||
multitask test_android: [:Nexus_9_Device] do
|
||||
puts 'Running Android devices automation'
|
||||
end
|
||||
|
||||
multitask test_ios: [:iPad_mini_Device] do
|
||||
puts 'Running iOS devices automation'
|
||||
end
|
||||
@@ -0,0 +1,3 @@
|
||||
default: --no-source --color --format pretty --format html --out results.html
|
||||
ios: OS=ios -t @ios
|
||||
android: OS=android -t @android
|
||||
@@ -0,0 +1,9 @@
|
||||
@ios
|
||||
Feature: Basic Character Automation
|
||||
|
||||
Scenario: Basic Character Automation
|
||||
Given I login using "wei" and "sanmateo"
|
||||
And I should see "Hello, wei!" texts displayed
|
||||
When I enter profile game
|
||||
And I tap chat
|
||||
Then I should see "return" enable
|
||||
@@ -0,0 +1,19 @@
|
||||
Feature: Game Launch
|
||||
|
||||
@android
|
||||
Scenario: Game Launch
|
||||
Given I logout
|
||||
And I login as "usertest01"
|
||||
And I should see "Home" texts displayed
|
||||
When I enter a game
|
||||
And I tap chat
|
||||
Then I should see id "wtf.watrbx.client.dev:id/gl_edit_text" enable
|
||||
And I hide keyboard
|
||||
|
||||
@ios
|
||||
Scenario: Game Launch
|
||||
Given I login as "usertest01"
|
||||
And I should see "Hello, usertest01!" texts displayed
|
||||
When I enter a game
|
||||
And I tap chat
|
||||
Then I should see "return" enable
|
||||
@@ -0,0 +1,14 @@
|
||||
Feature: Login
|
||||
|
||||
Scenario Outline: Login
|
||||
Given I logout
|
||||
When I login using "<Username>" and "<Password>"
|
||||
Then I should see "<Result>" texts
|
||||
|
||||
@ios@android
|
||||
Examples:
|
||||
| Username | Password | Result |
|
||||
| usertest01 | b0dPasswd | Invalid username or password|
|
||||
| Badusrname | hackproof | Invalid username or password|
|
||||
| Badusrn0me | badPasswd | Invalid username or password|
|
||||
| usertest01 | hackproof | Home |
|
||||
@@ -0,0 +1,13 @@
|
||||
Feature: Play Now
|
||||
|
||||
@android
|
||||
Scenario: Tap the "Play Now" button and play games
|
||||
Given I logout
|
||||
When I play now
|
||||
Then I should see "Popular"
|
||||
|
||||
@ios
|
||||
Scenario: Tap the "Play Now" button and play games
|
||||
Given I logout
|
||||
When I play now
|
||||
Then I should see "Popular" texts displayed
|
||||
@@ -0,0 +1,8 @@
|
||||
@android@ios
|
||||
Feature: Signup
|
||||
|
||||
Scenario: Tap the "Sign Up" button to sign up
|
||||
Given I logout
|
||||
When I tap "Sign Up" button
|
||||
Then I should see "SIGNUP" texts
|
||||
And I sign up as a "new" user
|
||||
@@ -0,0 +1,147 @@
|
||||
Then(/^I should see "(.*?)" enable$/) do |data|
|
||||
expect(wait { find_element(:accessibility_id, data) }.enabled?).to be true
|
||||
end
|
||||
|
||||
Then(/^I should see id "(.*?)" enable$/) do |data|
|
||||
expect(wait { find_element(:id, data) }.enabled?).to be true
|
||||
end
|
||||
|
||||
Then(/^I should see "(.*?)"$/) do |text|
|
||||
found_text = wait { find_element(:accessibility_id, text) }
|
||||
expect(found_text.enabled? || found_text.displayed?).to be true
|
||||
end
|
||||
|
||||
Then(/^I should see "(.*?)" texts$/) do |texts|
|
||||
if ENV['OS'] == 'ios'
|
||||
found_text = find_element(:xpath, "//UIAStaticText[@name='" + texts + "']")
|
||||
expect(found_text.enabled? || found_text.displayed?).to be true
|
||||
else
|
||||
wait_true { text(texts) }.displayed?
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^I should see "(.*?)" texts displayed$/) do |data|
|
||||
wait_true { text(data) }.displayed?
|
||||
end
|
||||
|
||||
Given(/^I login as "(.*?)"$/) do |username|
|
||||
on(LoginPage).launch_login username, 'hackproof'
|
||||
end
|
||||
|
||||
Given(/^I login using "(.*?)" and "(.*?)"$/) do |username, password|
|
||||
on(LoginPage).launch_login username, password
|
||||
end
|
||||
|
||||
When(/^I tap (\d+),(\d+)$/) do |x, y|
|
||||
Appium::TouchAction.new.tap(x: x, y: y).perform
|
||||
end
|
||||
|
||||
When(/^I tap "(.*?)" button$/) do |data|
|
||||
wait { button(data) }.click
|
||||
end
|
||||
|
||||
# On iPad mini, have to hardcode tap on play button link since it looks disable in appium inspector
|
||||
When(/^I enter a game$/) do
|
||||
wait { on(GamePage).game_button }.click
|
||||
if ENV['OS'] == 'ios'
|
||||
if ENV['FF'] == 'phone'
|
||||
wait { on(GamePage).play_button }.click
|
||||
else
|
||||
wait { on(GamePage).play_button }
|
||||
step 'I tap 815,315'
|
||||
end
|
||||
else
|
||||
wait { on(GamePage).play_button }.click
|
||||
end
|
||||
end
|
||||
|
||||
When(/^I enter profile game$/) do
|
||||
on(ProfilePage).profile_game
|
||||
end
|
||||
|
||||
When(/^I tap chat$/) do
|
||||
sleep 15 # wait till it loads the game
|
||||
if ENV['OS'] == 'ios'
|
||||
if ENV['FF'] == 'phone'
|
||||
step 'I tap 127,20' # iPhone6
|
||||
else
|
||||
step 'I tap 132,24' # iPad mini
|
||||
end
|
||||
else
|
||||
step 'I tap 255,51' # Nexus 9 # 259,45 # Nexus 7
|
||||
end
|
||||
end
|
||||
|
||||
Then(/^I logout$/) do
|
||||
on(LogoutPage).logout
|
||||
end
|
||||
|
||||
Then(/^I play now$/) do
|
||||
on(LaunchPage).playnow.click
|
||||
end
|
||||
|
||||
When(/^I sign up as a "(.*?)" user$/) do |data|
|
||||
signupname = 'Hello, ' + on(SignupPage).sign_up(data, 'appium123') + '!'
|
||||
puts 'AUTO: ' + signupname
|
||||
if ENV['OS'] == 'ios'
|
||||
wait_true { exists { text signupname } }
|
||||
else
|
||||
wait_true { exists { text 'Home' } }
|
||||
end
|
||||
end
|
||||
|
||||
And(/^I hide keyboard$/) do
|
||||
hide_keyboard
|
||||
end
|
||||
|
||||
# When(/^I wait to debug$/) do
|
||||
# debug
|
||||
# end
|
||||
#
|
||||
# When(/^I tap "(.*?)"$/) do |data|
|
||||
# wait { find_element(:accessibility_id, data) }.click
|
||||
# end
|
||||
#
|
||||
# Then(/^I should not see "(.*?)"$/) do |text|
|
||||
# expect(something_present(text)).to be false
|
||||
# end
|
||||
#
|
||||
# When(/^I sleep (\d+)$/) do |second|
|
||||
# sleep second.to_i
|
||||
# end
|
||||
#
|
||||
# When(/^I wait for "(.*?)"$/) do |elementname|
|
||||
# wait { find_element(:accessibility_id, elementname) }
|
||||
# end
|
||||
#
|
||||
# When(/^I tap xpath "(.*?)"$/) do |data|
|
||||
# wait { xpath(data) }.click
|
||||
# end
|
||||
#
|
||||
# When(/^I tap button (\d+)$/) do |number|
|
||||
# wait { button(number.to_i) }.click
|
||||
# end
|
||||
#
|
||||
# Then(/^I tap button "(.*?)"$/) do |name|
|
||||
# wait { button_exact(name) }.click
|
||||
# end
|
||||
#
|
||||
# When(/^I tap text (\d+)$/) do |number|
|
||||
# wait { text_exact(number.to_i) }.click
|
||||
# end
|
||||
#
|
||||
# Then(/^I tap text "(.*?)"$/) do |name|
|
||||
# wait { text_exact(name) }.click
|
||||
# end
|
||||
#
|
||||
# Then(/^I should see "(.*?)" disable$/) do |data|
|
||||
# expect(wait { find_element(:accessibility_id, data) }.enabled?).to be false
|
||||
# end
|
||||
#
|
||||
# Then(/^I should see Login button$/) do
|
||||
# expect(login_button_present).to be true
|
||||
# end
|
||||
#
|
||||
# When(/^I enter "(.*?)"$/) do |something|
|
||||
# driver.keyboard.send_keys something
|
||||
# end
|
||||
@@ -0,0 +1,9 @@
|
||||
[caps]
|
||||
platformName = "Android"
|
||||
#deviceName = "06df4e0e"
|
||||
deviceName = "HT4A1JT02469"
|
||||
platformVersion = "6.0.1"
|
||||
app= "./ROBLOX_CI_GT2.apk"
|
||||
appPackage = "wtf.watrbx.client.dev"
|
||||
appWaitActivity = "wtf.watrbx.client.ActivitySplash"
|
||||
appActivity = "wtf.watrbx.client.ActivitySplash"
|
||||
@@ -0,0 +1,41 @@
|
||||
# encoding: utf-8
|
||||
require 'rspec/expectations'
|
||||
require 'appium_lib'
|
||||
require 'cucumber/ast'
|
||||
require 'page_helper'
|
||||
require 'random_data'
|
||||
require 'require_all'
|
||||
require 'simplecov'
|
||||
require 'simplecov-rcov'
|
||||
SimpleCov.formatters = [
|
||||
SimpleCov::Formatter::HTMLFormatter,
|
||||
SimpleCov::Formatter::RcovFormatter
|
||||
]
|
||||
SimpleCov.start
|
||||
|
||||
require './lib/page_helper'
|
||||
require './lib/data_helper'
|
||||
require_all './lib/pages'
|
||||
|
||||
class AppiumWorld
|
||||
end
|
||||
|
||||
case ENV['OS']
|
||||
when 'ios'
|
||||
caps = Appium.load_appium_txt file: File.expand_path('../ios/appium.txt', __FILE__), verbose: true
|
||||
when 'android'
|
||||
caps = Appium.load_appium_txt file: File.expand_path('../android/appium.txt', __FILE__), verbose: true
|
||||
end
|
||||
|
||||
WAITTIME = 35
|
||||
|
||||
Appium::Driver.new(caps)
|
||||
Appium.promote_appium_methods AppiumWorld
|
||||
Appium.promote_singleton_appium_methods [DataHelper, PageHelper]
|
||||
|
||||
World do
|
||||
AppiumWorld.new
|
||||
end
|
||||
|
||||
World PageHelper
|
||||
World DataHelper
|
||||
@@ -0,0 +1,36 @@
|
||||
system 'killall node'
|
||||
system 'appium --log-level error&'
|
||||
sleep 15
|
||||
|
||||
begin
|
||||
at_exit do
|
||||
system 'killall node'
|
||||
end
|
||||
rescue
|
||||
puts 'AUTO: appium not killed at exit'
|
||||
end
|
||||
|
||||
Before do
|
||||
begin
|
||||
$driver.start_driver
|
||||
@browser = $driver
|
||||
rescue
|
||||
puts 'AUTO: driver not initialized'
|
||||
end
|
||||
end
|
||||
|
||||
After do |scenario|
|
||||
begin
|
||||
if $driver
|
||||
if scenario.failed?
|
||||
filename = "FAIL-#{scenario.__id__}.png"
|
||||
filename = 'reports/' + filename
|
||||
screenshot(filename)
|
||||
embed(filename, 'image/png', 'SCREENSHOT')
|
||||
end
|
||||
$driver.driver_quit
|
||||
end
|
||||
rescue
|
||||
puts 'AUTO: driver not exist'
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,8 @@
|
||||
[caps]
|
||||
platformName = "iOS"
|
||||
deviceName = "iPad Mini"
|
||||
platformVersion = "9.2.1"
|
||||
sendKeyStrategy = "setValue"
|
||||
udid = "e4b31a41fab6a4ad9ccd98891d92e517f462a922"
|
||||
#udid = "b2fb181e04d7b46a6461d692f035be6ea04b8875"
|
||||
bundleId="wtf.watrbx.robloxmobile"
|
||||
@@ -0,0 +1,2 @@
|
||||
username: abc1@xyz.com
|
||||
password: Test@123
|
||||
@@ -0,0 +1,2 @@
|
||||
username: abc@xyz.com
|
||||
password: Test@123
|
||||
@@ -0,0 +1,49 @@
|
||||
module DataHelper
|
||||
# Read basics on YAML - http://www.seleniumframework.com/test-data/test-data-with-yaml/
|
||||
def data_yml_hash
|
||||
@data_yml = YAML.load_file "#{data_default_directory}/#{yml_file}"
|
||||
end
|
||||
|
||||
# Read basics on excel parsing - http://www.seleniumframework.com/test-data/test-data-with-excel/
|
||||
def data_excel_hash(data_sheet)
|
||||
workbook = RubyXL::Parser.parse data_default_directory + '/' + excel_file
|
||||
sheet = workbook[data_sheet]
|
||||
header_row = sheet.sheet_data[0]
|
||||
@data_excel = sheet.get_table(header_row)
|
||||
end
|
||||
|
||||
# Json parsing reference - http://www.seleniumframework.com/test-data/test-data-with-json/
|
||||
def data_json_hash
|
||||
@data_json = JSON.parse data_default_directory + '/' + json_file
|
||||
end
|
||||
|
||||
def data_directory_set(dir)
|
||||
@data_directory = dir
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def yml_file
|
||||
ENV['DATA_YML_FILE'] ? ENV['DATA_YML_FILE'] : 'default.yml'
|
||||
end
|
||||
|
||||
def excel_file
|
||||
ENV['DATA_EXCEL_FILE'] ? ENV['DATA_EXCEL_FILE'] : 'default.xlsx'
|
||||
end
|
||||
|
||||
def json_file
|
||||
ENV['DATA_JSON_FILE'] ? ENV['DATA_JSON_FILE'] : 'default.json'
|
||||
end
|
||||
|
||||
def xml_file
|
||||
ENV['DATA_XML_FILE'] ? ENV['DATA_XML_FILE'] : 'default.xml'
|
||||
end
|
||||
|
||||
def data_default_directory
|
||||
@data_directory ||= 'lib/config/data'
|
||||
end
|
||||
|
||||
class << self
|
||||
attr_accessor :data_yml, :data_excel, :data_json, :data_xml, :data_directory
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
module PageHelper
|
||||
# http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/
|
||||
# http://stackoverflow.com/questions/3424782/ruby-on-rails-how-do-i-check-if-a-variable-in-an-instance-of-a-class
|
||||
# http://www.wellho.net/mouth/2601_Ruby-is-a-v-instance-of-what-is-the-difference-.html
|
||||
def visit(page_class, &block)
|
||||
on(page_class, true, &block)
|
||||
end
|
||||
|
||||
def on(page_class, visit = false, &block)
|
||||
page_class = class_from_string(page_class) if page_class.is_a? String
|
||||
page = page_class.new @browser, visit
|
||||
yield page if block
|
||||
page
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# http://stackoverflow.com/questions/3163641/get-a-class-by-name-in-ruby
|
||||
|
||||
def class_from_string(str)
|
||||
str.split('::').inject(Object) do |mod, class_name|
|
||||
mod.const_get(class_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
def something_present(text)
|
||||
begin
|
||||
@wait = Selenium::WebDriver::Wait.new(timeout: WAITTIME)
|
||||
@wait.until { find_element(:accessibility_id, text).displayed? }
|
||||
@something_displayed = find_element(:accessibility_id, text).displayed?
|
||||
rescue
|
||||
@something_displayed = false
|
||||
end
|
||||
@something_displayed
|
||||
end
|
||||
|
||||
def debug
|
||||
require 'pry'
|
||||
binding.pry
|
||||
end
|
||||
@@ -0,0 +1,14 @@
|
||||
class GamePage < GenericBasePage
|
||||
if ENV['OS'] == 'ios'
|
||||
element(:games_navbar) { |b| b.button_exact('GAMES') }
|
||||
element(:game_button) { |b| b.find_ele_by_attr('UIALink', 'name', 'Swimming test') }
|
||||
# element(:play_button) { |b| b.ele_index('UIALink', 2) }
|
||||
# element(:play_button) { |b| b.find_ele_by_attr('UIALink', 'name', 'Play') }
|
||||
# element(:play_button) { |b| b.find_element(:xpath, '//UIAApplication[1]/UIAWindow[1]/UIAScrollView[1]/UIAWebView[1]/UIALink[2]/UIAStaticText[1]') }
|
||||
element(:play_button) { |b| b.find_element(:xpath, "//UIAStaticText[@name='Play']") }
|
||||
else
|
||||
element(:games_navbar) { |b| b.text_exact('Games') }
|
||||
element(:game_button) { |b| b.find_element(:accessibility_id, 'Swimming test Swimming test 0 Playing ') }
|
||||
element(:play_button) { |b| b.find_element(:accessibility_id, 'Play') }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,51 @@
|
||||
class GenericBasePage
|
||||
def initialize(browser, visit = false)
|
||||
@browser = browser
|
||||
goto if visit
|
||||
# respond_to? is a Ruby method for detecting whether the class has a particular method on it
|
||||
expected_element if respond_to? :expected_element
|
||||
has_expected_title? if respond_to? :has_expected_title?
|
||||
end
|
||||
|
||||
def method_missing(sym, *args, &block)
|
||||
@browser.send sym, *args, &block
|
||||
end
|
||||
|
||||
def self.page_url(url)
|
||||
define_method 'goto' do
|
||||
@browser.goto url
|
||||
end
|
||||
end
|
||||
|
||||
# This is a class level method
|
||||
class << self
|
||||
alias direct_url page_url
|
||||
end
|
||||
|
||||
# Even this is a class method. Just another way to specify. So either class << self or self.method are same
|
||||
# Class methods are for anything that does not deal with an individual instance of a class
|
||||
def self.expected_element(type, identifier, timeout = 30)
|
||||
define_method 'expected_element' do
|
||||
@browser.send(type.to_s, identifier).wait_until_present timeout
|
||||
end
|
||||
end
|
||||
|
||||
def self.expected_title(expected_title)
|
||||
define_method 'has_expected_title?' do
|
||||
has_expected_title = expected_title.is_a?(Regexp) ? expected_title =~ @browser.title : expected_title == @browser.title
|
||||
raise "Expected title '#{expected_title}' instead of '#{@browser.title}'" unless has_expected_title
|
||||
end
|
||||
end
|
||||
|
||||
def self.element(element_name)
|
||||
define_method element_name.to_s do
|
||||
# yield self enters block, associated with method call, passing current object as argument to the block
|
||||
yield self
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
alias value element
|
||||
alias action element
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
class LaunchPage < GenericBasePage
|
||||
element(:login) { |b| b.button('Login') }
|
||||
element(:signup) { |b| b.button('Sign Up') }
|
||||
element(:playnow) { |b| b.button('Play Now') }
|
||||
element(:moreinfo) { |b| b.button('More Info') }
|
||||
element(:version) { |b| b.last_text }
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
class LoginPage < GenericBasePage
|
||||
include PageHelper
|
||||
include DataHelper
|
||||
|
||||
element(:username) { |b| b.first_textfield }
|
||||
element(:password) { |b| b.last_textfield }
|
||||
if ENV['OS'] == 'android'
|
||||
element(:signin_button) { |b| b.button_exact('Login') }
|
||||
else
|
||||
element(:signin_button) { |b| b.button_exact('Log in') }
|
||||
end
|
||||
|
||||
def login(usrname = 'usertest01', passwd = 'hackproof')
|
||||
username.send_keys usrname
|
||||
password.send_keys passwd
|
||||
hide_keyboard if ENV['OS'] == 'android'
|
||||
signin_button.click
|
||||
end
|
||||
|
||||
def login_yml(options = {})
|
||||
options = options.with_indifferent_access
|
||||
options.to_hash.reverse_merge! data_yml_hash.with_indifferent_access
|
||||
username.send_keys data_yml_hash['username']
|
||||
password.send_keys data_yml_hash['password']
|
||||
signin_button.click
|
||||
end
|
||||
|
||||
def launch_login(usrname, passwd)
|
||||
on(LogoutPage).logout unless login_button_present
|
||||
wait { on(LaunchPage).login }.click
|
||||
login(usrname, passwd)
|
||||
end
|
||||
|
||||
def login_button_present
|
||||
exists { on(LaunchPage).login }
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
class LogoutPage < GenericBasePage
|
||||
include PageHelper
|
||||
|
||||
element(:more) { |b| b.find_element(:accessibility_id, 'MORE') }
|
||||
# 9 for tablet, 7 for iphone
|
||||
if ENV['FF'] == 'phone'
|
||||
element(:settings) { |b| b.button(7) }
|
||||
else
|
||||
element(:settings) { |b| b.button(9) }
|
||||
end
|
||||
element(:logoutlink) { |b| b.find_element(:accessibility_id, 'Logout') }
|
||||
element(:confirm_logout) { |b| b.button_exact('Log Out') }
|
||||
|
||||
def logout
|
||||
if on(LoginPage).login_button_present
|
||||
sleep 20 if ENV['OS'] == 'android'
|
||||
puts 'AUTO: already logout'
|
||||
else
|
||||
more.click
|
||||
case ENV['OS']
|
||||
when 'ios'
|
||||
settings.click
|
||||
logoutlink.click
|
||||
when 'android'
|
||||
logoutimage.click
|
||||
end
|
||||
confirm_logout.click
|
||||
end
|
||||
wait_true { on(LaunchPage).login }.displayed?
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
class ProfilePage < GenericBasePage
|
||||
include PageHelper
|
||||
|
||||
element(:more) { |b| b.find_element(:accessibility_id, 'MORE') }
|
||||
# 1 for tablet, 2 for iphone
|
||||
if ENV['FF'] == 'phone'
|
||||
element(:profile) { |b| b.button(2) }
|
||||
element(:my_game) { |b| b.find_ele_by_attr('UIALink', 'name', 'Basic Character Automation') }
|
||||
element(:play_button) { |b| b.find_ele_by_attr('UIALink', 'name', 'Play') }
|
||||
else
|
||||
element(:profile) { |b| b.button(1) }
|
||||
element(:my_game) { |b| b.ele_index('UIALink', 9) }
|
||||
element(:play_button) { |b| b.find_element(:xpath, "//UIAStaticText[@name='Play']") }
|
||||
end
|
||||
element(:creations) { |b| b.find_ele_by_attr('UIALink', 'name', 'Creations') }
|
||||
element(:grid_view) { |b| b.button('Grid View') }
|
||||
|
||||
def profile_game
|
||||
more.click
|
||||
case ENV['OS']
|
||||
when 'ios'
|
||||
wait { profile }.click
|
||||
wait { creations }.click
|
||||
wait { grid_view }.click if ENV['FF'] == 'phone'
|
||||
wait { my_game }.click
|
||||
if ENV['FF'] == 'phone'
|
||||
wait { play_button }.click
|
||||
else
|
||||
wait { play_button }
|
||||
Appium::TouchAction.new.tap(x: 815, y: 315).perform
|
||||
end
|
||||
when 'android'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,65 @@
|
||||
class SignupPage < GenericBasePage
|
||||
include PageHelper
|
||||
include DataHelper
|
||||
|
||||
element(:accept_button) { |b| b.button_exact('Accept') }
|
||||
element(:signup_button) { |b| b.button_exact('Sign Up') }
|
||||
element(:validating_button) { |b| b.button('Validating') }
|
||||
case ENV['OS']
|
||||
when 'android'
|
||||
element(:username) { |b| b.textfield('signupUsername') }
|
||||
element(:password) { |b| b.textfield('signupPassword') }
|
||||
element(:confirm_password) { |b| b.textfield('signupPasswordConfirm') }
|
||||
element(:male_button) { |b| b.button('rbxGenderPickerMale') }
|
||||
element(:female_button) { |b| b.button('rbxGenderPickerFemale') }
|
||||
element(:month) { |b| b.find_element(:xpath, '//android.widget.RelativeLayout[1]/android.widget.Spinner[1]/android.widget.TextView[1]') }
|
||||
element(:day) { |b| b.text('--') }
|
||||
element(:year) { |b| b.text('----') }
|
||||
when 'ios'
|
||||
element(:username) { |b| b.textfield(1) }
|
||||
element(:password) { |b| b.textfield(2) }
|
||||
element(:confirm_password) { |b| b.textfield(3) }
|
||||
element(:male_button) { |b| b.button('Gender Male') }
|
||||
element(:female_button) { |b| b.button('Gender Female') }
|
||||
element(:birthday_button) { |b| b.button(4) }
|
||||
element(:month) { |b| b.first_ele('UIAPickerWheel') }
|
||||
element(:day) { |b| b.find_element(:xpath, '//UIAPickerWheel[2]') }
|
||||
element(:year) { |b| b.last_ele('UIAPickerWheel') }
|
||||
end
|
||||
|
||||
def sign_up(usrname, passwd)
|
||||
name = Random.firstname + Random.lastname + Random.number(999).to_s
|
||||
usrname = 'Appium' + name[0..13] if usrname == 'new'
|
||||
username.send_keys usrname
|
||||
password.send_keys passwd
|
||||
confirm_password.send_keys passwd
|
||||
case ENV['OS']
|
||||
when 'android'
|
||||
hide_keyboard
|
||||
male_button.click
|
||||
month.click
|
||||
wait { text('Aug.') }.click
|
||||
day.click
|
||||
wait { text('1') }.click
|
||||
year.click
|
||||
wait { text('2012') }.click
|
||||
# wait { signup_button }.click
|
||||
# sleep 20 # wait for processing in GT2 and click twice, maybe capcha issues.
|
||||
when 'ios'
|
||||
female_button.click
|
||||
birthday_button.click
|
||||
# workaround on iOS for issue https://groups.google.com/forum/#!topic/appium-discuss/uYdRTdQDvpU
|
||||
if ENV['FF'] == 'tablet' # iPad Mini
|
||||
swipe(start_x: 306, start_y: 405, end_x: 306, end_y: 329, duration: 500)
|
||||
swipe(start_x: 511, start_y: 405, end_x: 511, end_y: 329, duration: 500)
|
||||
else
|
||||
swipe(start_x: 80, start_y: 270, end_x: 80, end_y: 170, duration: 500) # June
|
||||
swipe(start_x: 150, start_y: 270, end_x: 150, end_y: 170, duration: 500) # 11
|
||||
end
|
||||
year.send_keys '2006'
|
||||
accept_button.click
|
||||
end
|
||||
wait { signup_button }.click
|
||||
usrname
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user