actir 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c7b0a489730d193f8c5bffcd60dfe8b3d7da3bdc
4
+ data.tar.gz: 1de0ba72345bc6b04ef8b7b51b011934b9765e7e
5
+ SHA512:
6
+ metadata.gz: d8fd820b3ead55edbe520a4f2dbca6d8208402d38643def11e85ffb5057dcb01522e2b3ce7aa7688206f47cf21684a97bc5e0f12518e8eed8acbecb50a0de4e2
7
+ data.tar.gz: e9014a2c7c424a93c6f4864e46e9deb607eb22ace0bee67216da77d5ccf77e33e078bc75b06d724010c94f5efc1836b9efcba6e1e031cf1cb09ebac65c41d5c2
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.gem
15
+ .DS_Store
16
+ mkmf.log
17
+ /.travis/
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ before_install: gem install bundler -v 1.10.3
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://ruby.taobao.org'
2
+
3
+ # Specify your gem's dependencies in actir.gemspec
4
+ gemspec
5
+ gem 'bundler'
6
+ gem 'rake'
7
+ gem 'test-unit'
8
+ gem 'watir-webdriver'
9
+ gem 'selenium-webdriver'
10
+ gem 'parallel'
11
+ gem 'facets'
@@ -0,0 +1,56 @@
1
+ # Actir
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/actir`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ git clone code and then execute:
10
+
11
+ $ rake install
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install actir
16
+
17
+ ## Usage
18
+
19
+ 使用须知:
20
+ 1. 对应测试工程结构如下
21
+  config -- 配置文件
22
+   |-config.yaml -- 总体配置文件,test_mode相关的配置项必须要填
23
+  elements
24
+   |-components -- 公用页面元素方法
25
+   |-pages -- 页面元素封装的方法.如果是Web页面,可以直接继承自Actir::WebPage,已经封装了部分公用方法
26
+  testcode -- 测试用例,执行之前需要初始化 Actir::Initializer.new(project_path)
27
+
28
+ 2.project_path:测试工程根目录
29
+
30
+ 3.Browser.new(type, *args):
31
+  Browser重新封装了watir以及selenium的初始化浏览器的方法
32
+  1).type指定初始化浏览器的类型,可以指定www/wap两类
33
+  2).*args:
34
+  :browser - 浏览器类型,可以支持 :chrome/:phantomjs/:firefox, 默认为chrome
35
+  :agent - user agent类型,可以支持 :iphone/:andriod_phone, 默认为iphone
36
+  :mode - 启动模式,支持 :local/:remote, 默认为local
37
+  :url - 配合mode为remote的模式,指定远程机器的url,需要 IP+端口号
38
+
39
+ 4.初始化会自动require所有的elements内的文件并自动定义每个页面类对应的方法
40
+  如: 某页面类名为LoginPage,则会自动定义出login_page方法
41
+  3中初始化出的browser对象,可以直接调用login_page方法
42
+  也可以直接调用Watir::Browser对应的所有方法
43
+  如:browser = Browser.new(type, *args)
44
+    browser.login_page.xxx (xxx为LoginPage中定义的方法)
45
+
46
+ ## Development
47
+
48
+ .
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it ( https://github.com/[my-github-username]/actir/fork )
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create a new Pull Request
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+ require 'rake'
3
+
4
+ def is_taobao_gemsource?
5
+ source = `gem sources -l`
6
+ source.include? "taobao"
7
+ end
8
+
9
+ unless is_taobao_gemsource?
10
+ # 修改RubyGems源
11
+ sh "gem sources --remove https://rubygems.org/"
12
+ sh "gem sources -a https://ruby.taobao.org/"
13
+ sh "gem sources -l"
14
+ end
15
+
16
+ def check_gem_available(gemName, versionLimit=nil)
17
+ isAvailable = false
18
+ begin
19
+ if versionLimit == nil
20
+ gem gemName
21
+ else
22
+ gem gemName, versionLimit
23
+ end
24
+ isAvailable = true
25
+ rescue LoadError
26
+ end
27
+ isAvailable
28
+ end
29
+
30
+ def is_root?
31
+ name = `whoami`
32
+ name.include? "root"
33
+ end
34
+
35
+ def sudo_str
36
+ "sudo" unless is_root?
37
+ end
38
+
39
+ # 判断是否安装bundler包,若没有,则安装,并require
40
+ sh "#{sudo_str} gem install bundler" if check_gem_available("bundler") == false
41
+
42
+ lib = File.expand_path('../lib', __FILE__)
43
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
44
+ require 'actir/version'
45
+
46
+ # Defines gem name.
47
+ def repo_name
48
+ 'actir'
49
+ end
50
+
51
+ def version
52
+ Actir::VERSION
53
+ end
54
+
55
+ task :package do
56
+ sh "#{sudo_str} bundle update"
57
+ end
58
+
59
+ task :gem do
60
+ sh "#{sudo_str} rm -rf #{repo_name}-#{version}.gem"
61
+ sh "#{sudo_str} gem build #{repo_name}.gemspec"
62
+ end
63
+
64
+ task :uninstall do
65
+ sh "#{sudo_str} gem uninstall #{repo_name} -a -x"
66
+ end
67
+
68
+ task :install => [:package, :gem, :uninstall] do
69
+ sh "#{sudo_str} gem install #{repo_name}"
70
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'actir/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "actir"
8
+ spec.version = Actir::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.authors = ["hub"]
11
+ spec.email = ["hub@qima-inc.com"]
12
+
13
+ spec.summary = %q{Application Concurrence Test in Ruby.}
14
+ spec.description = %q{Distribut automated testing framework for Web or App.}
15
+ spec.homepage = "http://git.qima-inc.com/qa/ants.git"
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.files += Dir.glob("{bin,lib}/**/*")
20
+ spec.executables = %w(actir ants)
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "test-unit", "~> 3.0"
27
+ spec.add_development_dependency "watir-webdriver", "~> 0.6.11"
28
+ spec.add_development_dependency "selenium-webdriver", "~> 2.45"
29
+ spec.add_development_dependency "parallel", "~> 1.4"
30
+ spec.add_development_dependency "facets", "~>2.9"
31
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path("../..", __FILE__)
4
+ $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
5
+
6
+ require "actir"
7
+
8
+ #开始执行
9
+ Actir::ParallelTests::CLI.new.run(ARGV)
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path("../..", __FILE__)
4
+ $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
5
+
6
+ require "actir"
7
+
8
+ #开始执行
9
+ Actir::ParallelTests::CLI.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "actir"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,41 @@
1
+ require 'test/unit'
2
+ require 'watir-webdriver'
3
+ require 'selenium-webdriver'
4
+ lib = File.dirname(__FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'actir/config'
7
+ require 'actir/initializer'
8
+ require 'actir/remote'
9
+ require 'actir/basic_page'
10
+ require 'actir/parallel_tests/parallel_tests'
11
+ require 'actir/webdriver/browser'
12
+ require 'actir/script/cookies_baidu'
13
+ require 'actir/version'
14
+
15
+ module Actir
16
+
17
+ #测试用例基础类,读取配置文件定义常量
18
+ class Test < Test::Unit::TestCase
19
+
20
+ #IP地址的正则表达式
21
+ num = /\d|[01]?\d\d|2[0-4]\d|25[0-5]/
22
+ ip = /^(#{num}\.){3}#{num}/
23
+ #遍历所有的入参,取出IP作为传给测试脚本的IPAddress
24
+ ARGV.each do |arg|
25
+ if arg =~ ip
26
+ $address = arg
27
+ end
28
+ end
29
+
30
+ #若用例执行失败则进行截图,在每个用例的teardown方法中直接调用,传入浏览器对象实例
31
+ def screenshot_if_failed(browser)
32
+ unless self.passed?
33
+ Dir::mkdir('screenshots') if not File.directory?('screenshots')
34
+ time = Time.now.strftime('%Y%m%d-%H%M%S')
35
+ screenshot = "./screenshots/FAILED_#{self.name}_#{time}.png"
36
+ browser.screenshot.save screenshot
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,49 @@
1
+ module Actir
2
+
3
+ class BasicPage
4
+
5
+ #include PageObject
6
+
7
+ def initialize(driver)
8
+ case driver
9
+ #若是浏览器对象
10
+ when Watir::Browser, Browser
11
+ @browser = driver
12
+ #Appium TO-DO
13
+ when Appium::Driver
14
+ @appium = driver
15
+ else
16
+ raise "wrong driver"
17
+ end
18
+ end
19
+
20
+ def method_missing(m, *args, &blk)
21
+ if @browser.respond_to? m
22
+ @browser.send(m, *args, &blk)
23
+ elsif @appium.respond_to? m
24
+ @appium.send(m, *args, &blk)
25
+ else
26
+ super
27
+ end
28
+ end
29
+
30
+ def turn_to kls
31
+ raise "Invalid Page Error" unless kls <= Actir::BasicPage
32
+ kls.new(@browser)
33
+ end
34
+
35
+ def data_driven hash, &blk
36
+ raise "Argument Error" unless hash.is_a?(Hash)
37
+ hash.each do |mtd, data|
38
+ m_with_eql = (mtd.to_s + '=').to_sym
39
+ if respond_to?(m_with_eql)
40
+ eval "self.#{m_with_eql.to_s}(data)"
41
+ elsif respond_to?(mtd.to_sym)
42
+ self.send(mtd.to_sym).send(data.to_sym)
43
+ end #if
44
+ end #each
45
+ class_eval &blk if block_given?
46
+ end
47
+
48
+ end #BasicPage
49
+ end #Actir
@@ -0,0 +1,192 @@
1
+ require 'yaml'
2
+ require 'ostruct'
3
+
4
+ module Actir
5
+
6
+ #
7
+ # 读取yaml文件中配置的内容
8
+ #
9
+ # @author: Hub
10
+ #
11
+ # @Date: 2015-1-20
12
+ #
13
+ module Config
14
+
15
+ class << self
16
+
17
+ attr_accessor :config_dir
18
+
19
+ #
20
+ # 从yaml文件中读取youzan的cookies
21
+ #
22
+ # @example : youzan_cookies
23
+ #
24
+ # @return [Hash] youzan的cookies的hash
25
+ #
26
+ def youzan_cookies(youzan_user)
27
+ cfg_str = "cookies." + youzan_user
28
+ get(cfg_str)
29
+ end
30
+
31
+ #
32
+ # 从yaml文件中读取出所有内容
33
+ #
34
+ # @example : get_content(path)
35
+ #
36
+ # @return [OpenStruct] 所有配置文件内容
37
+ #
38
+ def get_content(filepath)
39
+ f ||= filepath if valid?(filepath)
40
+ File.open(f) {|handle| @hash_content = YAML.load(handle)}
41
+ content = OpenStruct.new(@hash_content)
42
+ content
43
+ end
44
+
45
+ #
46
+ # 从config文件夹下的配置文件中读取对应的配置项,以hash形式返回
47
+ #
48
+ # @example : get "safeguard.mode"
49
+ #
50
+ # @param [String] : 指定配置项的字符串,形如safeguard.safeguard_type,以点衔接
51
+ #
52
+ # 第一个字符串表示配置文件的名字,之后表示在该文件中的配置项名称
53
+ #
54
+ # @return [Hash] 对应配置项的hash
55
+ #
56
+ def get(key)
57
+ #按照点分割字符串
58
+ key_array = key.split(".")
59
+ #先取出数组中的第一个元素当做配置文件名称,并从数组中移除此元素
60
+ file_name = key_array.shift
61
+ #再取出第二个元素,指定配置项,并移除
62
+ cfg_name = key_array.shift
63
+ hash = {}
64
+ #加载yaml配置文件,加锁
65
+ lock(file_name) do
66
+ hash = cfg_name ? load_file(file(file_name))[cfg_name] : load_file(file(file_name))
67
+ end
68
+ #遍历key数组
69
+ until key_array.empty? do
70
+ key = key_array.shift
71
+ hash = hash[key]
72
+ end
73
+ hash
74
+ end
75
+
76
+ #
77
+ # 更新配置文件中的key对应的value值
78
+ #
79
+ # 改文件加锁,解决多进程同时写文件的问题
80
+ #
81
+ # @example : set("config.test_mode.env", ":remote")
82
+ #
83
+ # @param key : [String] 指定配置项的字符串,形如config.test_mode.env,以点衔接
84
+ #
85
+ # value : [String] 要修改的值的字符串
86
+ #
87
+ def set(key, value)
88
+ #按照点分割字符串
89
+ key_array = key.split(".")
90
+ #先取出数组中的第一个元素当做配置文件名称,并从数组中移除此元素
91
+ file_name = key_array.shift
92
+ cfg_str = key_array.shift
93
+ old_value = ""
94
+ lock(file_name) do
95
+ #先读出所有的内容
96
+ str_array = IO.readlines(file(file_name))
97
+ str_array.each_with_index do |line, index|
98
+ if ( cfg_str != "" && line =~ /(\s*#{cfg_str}\:\s*)(.*)/ )
99
+ cfg_key = $1
100
+ old_value = $2
101
+ #找对了父节点,继续取下一个
102
+ if key_array.size > 0
103
+ cfg_str = key_array.shift
104
+ else
105
+ #只剩最后一个配置项了,说明找到了唯一的配置项,修改之
106
+ replace_str = cfg_key.chomp + value
107
+ str_array[index] = replace_str
108
+ cfg_str = ""
109
+ end
110
+ end
111
+ end
112
+ config_file = File.open(file(file_name), "w")
113
+ str_array.each do |line|
114
+ config_file.puts line
115
+ end
116
+ config_file.close
117
+ end
118
+ puts "Already set [" + key + "]'s value form " + old_value + " into " + value
119
+ end
120
+
121
+ #
122
+ # 判断配置文件的上一次修改时间和当前时间是否一样
123
+ #
124
+ # @example : is_same_day?("config")
125
+ #
126
+ # @param file_name : [String] 配置文件的名字,后缀省略
127
+ #
128
+ # @return : [Boolean] 同一天则返回true
129
+ #
130
+ # 不同则返回false
131
+ #
132
+ def is_same_day?(file_name)
133
+ now_date = Time.new.strftime("%m-%d")
134
+ modify_date = get_modify_time(file_name)
135
+ now_date == modify_date
136
+ end
137
+
138
+ #获取配置文件的修改时间(只精确到日期,不考虑具体时间)
139
+ #返回String,格式为:04-27... 12-29
140
+ def get_modify_time(file_name)
141
+ sh_str = "ls -l " + file(file_name) + " | awk '{print $6 \"-\" $7}'"
142
+ stat_str = `#{sh_str}`
143
+ #从中取出月份和日期
144
+ stat_str =~ /(\d+).*\-(\d+)/
145
+ month = $1
146
+ day = $2
147
+ #若果是1-9,则在前面加个0
148
+ month = "0" + month if month.to_i <= 9 && month.to_i >= 1
149
+ day = "0" + day if day.to_i <= 9 && day.to_i >= 1
150
+ month + "-" + day
151
+ end
152
+
153
+ # 多进程操作文件时加锁
154
+ def lock(file_name)
155
+ File.open(file(file_name), 'r') do |f|
156
+ begin
157
+ f.flock File::LOCK_EX
158
+ yield
159
+ ensure
160
+ f.flock File::LOCK_UN
161
+ end
162
+ end
163
+ end
164
+
165
+ #配置文件路径
166
+ def file(file_name)
167
+ File.expand_path(File.join(config_dir, "/#{file_name}.yaml"), __FILE__)
168
+ end
169
+
170
+ #默认配置文件夹路径
171
+ def config_dir
172
+ @config_dir ||= File.join($project_path, "config")
173
+ end
174
+
175
+ private
176
+
177
+ #读取yaml配置文件
178
+ def load_file(file)
179
+ YAML.load_file file
180
+ end
181
+
182
+ def valid?(filepath)
183
+ raise "file didn't exist!" unless File.exists?(filepath)
184
+ true
185
+ end
186
+
187
+ end
188
+ end
189
+ end
190
+
191
+ #Actir::Config.set("cookies.baidu.card2.available", "false")
192
+ #puts Actir::Config.is_same_day?("cookies")