selwet 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/selwet.rb +1040 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f8720c4cffa2e62abbecc43b2aad890a34334826
|
4
|
+
data.tar.gz: 639eef52da75979f0fac7bf3c24e3f77fb71a97f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f8f473682e8fb6b9ae03b177fd4354dd6def56182f9e05f813f5dfa8d029bb6d604c0bfca9626db28d6022b1c0a853b8532a9fc49e8270374f4c11ab7b1f710d
|
7
|
+
data.tar.gz: 87689728ceca18daf17b58b5d85aa838f1a750a7ced743ccc9b9c183340f2a803ae46a1f32ebf0a538fddbb564aea36b889dec6ee9f4b2add45514833038559f
|
data/lib/selwet.rb
ADDED
@@ -0,0 +1,1040 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'selenium-webdriver'
|
4
|
+
require 'test-unit'
|
5
|
+
require 'shoulda-context'
|
6
|
+
#Модуль SelWeT (Selenium Web Test) позволяет тестировать веб-страницы в одном, или нескольких браузерах. Если тестирование производится в нескольких браузерах, то оно проводится параллельно.
|
7
|
+
module SelWeT
|
8
|
+
#Класс Unit содержит методы для проверки элементов страницы, получения их текстового содержимого и значения поля href для ссылок, заполнения полей, select-ов и форм, указания файлов для загрузки, кликов по элементам и кнопкам алерта, проверки статуса для radio и checkbox, перехода на другую страницу, обновления страницы, проверки текущего URL, открытие ссылки в новом окне, смены и закрытия окна, создания скриншотов.
|
9
|
+
#
|
10
|
+
#Тесты пишутся с использованием shoulda-context.
|
11
|
+
#@example
|
12
|
+
# #!/usr/bin/env ruby
|
13
|
+
# # encoding: UTF-8
|
14
|
+
# require 'selwet'
|
15
|
+
#
|
16
|
+
# class SelWeT::Unit
|
17
|
+
#
|
18
|
+
# setBrowsers [:firefox, :chrome]
|
19
|
+
# setSeleniumServerUrl 'http://127.0.0.1:4444/wd/hub'
|
20
|
+
#
|
21
|
+
# context "Example" do
|
22
|
+
# should "About Us" do
|
23
|
+
# Unit.followTheLink "http://inventos.ru/"
|
24
|
+
# Unit.click '#menu-item-3795 a'
|
25
|
+
# status, error = Unit.checkLocation 'http://inventos.ru/about/#top'
|
26
|
+
# assert_equal true, status, error
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# end
|
31
|
+
class Unit < Test::Unit::TestCase
|
32
|
+
include SelWeT
|
33
|
+
private
|
34
|
+
@@url_selenium = nil
|
35
|
+
@@start_url = nil
|
36
|
+
@@browsers = nil
|
37
|
+
@@opened_window = {}
|
38
|
+
@@win_num = 0
|
39
|
+
|
40
|
+
class << self
|
41
|
+
#Запускает браузеры перед выполнением тестов.
|
42
|
+
#Выполняется автоматически непосредственно перед запуском тестов.
|
43
|
+
def startup
|
44
|
+
@@driver = {}
|
45
|
+
url = nil
|
46
|
+
unless @@url_selenium
|
47
|
+
puts 'URL for selenium server not specified!'
|
48
|
+
exit 1
|
49
|
+
else
|
50
|
+
url = @@url_selenium
|
51
|
+
end
|
52
|
+
if @@browsers.nil?
|
53
|
+
puts 'Browsers not specified!'
|
54
|
+
exit 1
|
55
|
+
end
|
56
|
+
begin
|
57
|
+
@@browsers.each do |browser|
|
58
|
+
if [:firefox, :chrome, :ie, :safari].include? browser
|
59
|
+
@@driver[browser.to_s] = Selenium::WebDriver.for(:remote, :desired_capabilities => browser, :url => url)
|
60
|
+
@@driver[browser.to_s].manage.timeouts.implicit_wait = 15
|
61
|
+
@@driver[browser.to_s].manage.timeouts.script_timeout = 15
|
62
|
+
@@driver[browser.to_s].manage.timeouts.page_load = 15
|
63
|
+
@@driver[browser.to_s].manage.window.maximize
|
64
|
+
else
|
65
|
+
puts "Bad browser #{browser}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue Exception => e
|
69
|
+
puts "ERROR: #{e.to_s}"
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
if @@start_url
|
73
|
+
followTheLink @@start_url
|
74
|
+
end
|
75
|
+
end
|
76
|
+
#Закрывает все используемые браузеры после выполнения всех тестов.
|
77
|
+
#Выполняется автоматически.
|
78
|
+
def shutdown
|
79
|
+
@@driver.each do |name, driver|
|
80
|
+
begin
|
81
|
+
driver.close
|
82
|
+
driver.quit
|
83
|
+
rescue
|
84
|
+
puts 'Browser '+name+' not closed ...'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
#Устанавливает URL Selenium Server. Необходимо использовать перед блоками тестов.
|
89
|
+
#
|
90
|
+
#@param url [String] URL запущенного Selenium Server
|
91
|
+
#@example
|
92
|
+
# class SelWeT::Unit
|
93
|
+
# setBrowsers [:firefox, :chrome]
|
94
|
+
# setSeleniumServerUrl "http://localhost:4444/wd/hub"
|
95
|
+
# ...
|
96
|
+
def setSeleniumServerUrl url
|
97
|
+
@@url_selenium = url
|
98
|
+
end
|
99
|
+
#Устанавливает стартовую страницу при запуске браузеров. Использовать только перед блоками тестов.
|
100
|
+
#@param url [String] URL тестируемого сайта
|
101
|
+
#@example
|
102
|
+
# class SelWeT::Unit
|
103
|
+
# setBrowsers [:firefox, :chrome]
|
104
|
+
# setSeleniumServerUrl "http://localhost:4444/wd/hub"
|
105
|
+
# openLink "http://inventos.ru/"
|
106
|
+
# ...
|
107
|
+
def openLink url
|
108
|
+
@@start_url = url
|
109
|
+
end
|
110
|
+
#Устанавливает используемые для тестирования браузеры. Необходимо использовать перед блоками тестов.
|
111
|
+
#@param params [Array] массив, содержащий одно или несколько из следующий значений: :firefox, :chrome, :ie, :safari. Для :chrome и :ie Selenium Server следует запускать с соответствующими драйверами.
|
112
|
+
#@example
|
113
|
+
# class SelWeT::Unit
|
114
|
+
# setBrowsers [:firefox, :chrome]
|
115
|
+
# ...
|
116
|
+
def setBrowsers params
|
117
|
+
@@browsers = params
|
118
|
+
end
|
119
|
+
#Переход по ссылке. Используется только в блоках should или setup
|
120
|
+
#@param url [String] ссылка, по которой необходимо перейти.
|
121
|
+
#@example
|
122
|
+
# class SelWeT::Unit
|
123
|
+
#
|
124
|
+
# setBrowsers [:firefox, :chrome]
|
125
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
126
|
+
# @@somePage = 'http://inventos.ru/produkty/#top'
|
127
|
+
#
|
128
|
+
# context "Example" do
|
129
|
+
#
|
130
|
+
# setup do
|
131
|
+
# Unit.followTheLink @@somePage
|
132
|
+
# end
|
133
|
+
# ...
|
134
|
+
#@see refresh
|
135
|
+
def followTheLink url
|
136
|
+
threads = []
|
137
|
+
@@driver.each do |name, driver|
|
138
|
+
threads << Thread.new do
|
139
|
+
driver.navigate.to url
|
140
|
+
end
|
141
|
+
end
|
142
|
+
threads.each(&:join)
|
143
|
+
end
|
144
|
+
#Переключиться на iframe. Используется только в блоках should или setup. Для дальнейшего взаимодействия с основной страницей необходимо выполнить {switchToPage}.
|
145
|
+
#@param selector [String] css селектор на нужный iframe.
|
146
|
+
#@example
|
147
|
+
# class SelWeT::Unit
|
148
|
+
#
|
149
|
+
# ...
|
150
|
+
#
|
151
|
+
# context "Example" do
|
152
|
+
#
|
153
|
+
# should 'Show popup' do
|
154
|
+
# Unit.switchToFrame 'iframe#frame1'
|
155
|
+
# ...
|
156
|
+
#@see switchToPage
|
157
|
+
def switchToFrame selector
|
158
|
+
threads = []
|
159
|
+
status, message, tags = getTag selector
|
160
|
+
unless status
|
161
|
+
return false, "switchToFrame: "+message
|
162
|
+
end
|
163
|
+
bad_values = []
|
164
|
+
tags.each do |name, tag|
|
165
|
+
if tag != 'iframe'
|
166
|
+
bad_values << name +" : "+tag
|
167
|
+
end
|
168
|
+
end
|
169
|
+
if bad_values.size != 0
|
170
|
+
return false, "switchToFrame: #{bad_values.join(", ")} - It is not 'iframe'! "
|
171
|
+
end
|
172
|
+
@@driver.each do |name, driver|
|
173
|
+
threads << Thread.new do
|
174
|
+
element = driver.find_element(:css => selector)
|
175
|
+
driver.action.move_to(element).perform
|
176
|
+
driver.switch_to.frame element
|
177
|
+
end
|
178
|
+
end
|
179
|
+
threads.each(&:join)
|
180
|
+
return true
|
181
|
+
end
|
182
|
+
#Очистить кэш браузера
|
183
|
+
#@example
|
184
|
+
# class SelWeT::Unit
|
185
|
+
#
|
186
|
+
# ...
|
187
|
+
#
|
188
|
+
# context "Example" do
|
189
|
+
#
|
190
|
+
# should 'Do something' do
|
191
|
+
# ...
|
192
|
+
# Unit.clearCache
|
193
|
+
# ...
|
194
|
+
def clearCache
|
195
|
+
threads = []
|
196
|
+
@@driver.each do |name, driver|
|
197
|
+
threads << Thread.new do
|
198
|
+
driver.manage.delete_all_cookies
|
199
|
+
end
|
200
|
+
end
|
201
|
+
threads.each(&:join)
|
202
|
+
end
|
203
|
+
#Переключиться на основную страницу. Используется только в блоках should или setup.
|
204
|
+
#@example
|
205
|
+
# class SelWeT::Unit
|
206
|
+
#
|
207
|
+
# ...
|
208
|
+
#
|
209
|
+
# context "Example" do
|
210
|
+
#
|
211
|
+
# should 'Show popup' do
|
212
|
+
# ...
|
213
|
+
# Unit.switchToPage
|
214
|
+
# ...
|
215
|
+
#@see switchToFrame
|
216
|
+
def switchToPage
|
217
|
+
threads = []
|
218
|
+
@@driver.each do |name, driver|
|
219
|
+
threads << Thread.new do
|
220
|
+
driver.switch_to.default_content
|
221
|
+
end
|
222
|
+
end
|
223
|
+
threads.each(&:join)
|
224
|
+
end
|
225
|
+
#Выбирает элементы в select. Используется только в блоках should или setup. Работает как с обычными select, так и с select с множественным выбором. Если для select с множественным выбором не указать аргумент items, то выделение будет снято со всех option.
|
226
|
+
# @param selector [String] css селектор select.
|
227
|
+
# @param items [Array] массив значений, которые необходимо выбрать.
|
228
|
+
#@example
|
229
|
+
# class SelWeT::Unit
|
230
|
+
#
|
231
|
+
# ...
|
232
|
+
#
|
233
|
+
# context "Example" do
|
234
|
+
#
|
235
|
+
# should "TODO something" do
|
236
|
+
# Unit.selectItemsFromTheSelect 'select[name="some_name"]', ['value 1', 'value2']
|
237
|
+
# ...
|
238
|
+
def selectItemsFromTheSelect selector, items = nil
|
239
|
+
threads = []
|
240
|
+
status = true
|
241
|
+
errors = []
|
242
|
+
@@driver.each do |name, driver|
|
243
|
+
threads << Thread.new do
|
244
|
+
thread_status = true
|
245
|
+
begin
|
246
|
+
element = driver.find_element(:css => selector)
|
247
|
+
rescue Exception => e
|
248
|
+
errors << name+' : Bad selector : '+selector
|
249
|
+
thread_status = false
|
250
|
+
status = false
|
251
|
+
end
|
252
|
+
if thread_status
|
253
|
+
unless element.tag_name == 'select'
|
254
|
+
status = false
|
255
|
+
errors << "#{name} - selectItemsFromTheSelect using only for select!"
|
256
|
+
else
|
257
|
+
option = Selenium::WebDriver::Support::Select.new(element)
|
258
|
+
if option.multiple?
|
259
|
+
option.deselect_all
|
260
|
+
if items
|
261
|
+
options = element.find_elements(:css => 'option')
|
262
|
+
options.each do |item|
|
263
|
+
if items.include? item.text
|
264
|
+
items.delete item.text
|
265
|
+
driver.action.key_down(:shift).click(item).key_up(:shift).perform
|
266
|
+
end
|
267
|
+
end
|
268
|
+
if items.size > 0
|
269
|
+
status = false
|
270
|
+
errors << "selectItemsFromTheSelect: Some passed option values were not found (#{name}): "+items.join(' ')
|
271
|
+
end
|
272
|
+
end
|
273
|
+
else
|
274
|
+
if items
|
275
|
+
if items.size == 1
|
276
|
+
begin
|
277
|
+
option.select_by(:text, items[0])
|
278
|
+
rescue
|
279
|
+
status = false
|
280
|
+
errors << "selectItemsFromTheSelect: Option '#{items}' does not exist!"
|
281
|
+
end
|
282
|
+
else
|
283
|
+
status = false
|
284
|
+
errors << "selectItemsFromTheSelect: '#{selector}' is not multiple! You must pass a single value."
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
threads.each(&:join)
|
293
|
+
return [status, errors.uniq.join("\n")]
|
294
|
+
end
|
295
|
+
#Кликает по элементу. Используется только в блоках should или setup. Селектор должен указывать только на один конкретный элемент.
|
296
|
+
#@param selector [String] селектор элемента
|
297
|
+
#@param browserName [Symbol] используется, если в разных браузерах нужно кликнуть на разные элементы. Принимает одно из следующих значений: :firefox, :chrome, :ie, :safari
|
298
|
+
#@return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст сообщения об ошибке, если она возникнет
|
299
|
+
#@example
|
300
|
+
# class SelWeT::Unit
|
301
|
+
#
|
302
|
+
# ...
|
303
|
+
#
|
304
|
+
# context "Example" do
|
305
|
+
#
|
306
|
+
# should "TODO something" do
|
307
|
+
# ...
|
308
|
+
# Unit.click 'input[type="submit"]'
|
309
|
+
# ...
|
310
|
+
#@see clickOkOnTheAlert
|
311
|
+
#@see clickCancelOnTheAlert
|
312
|
+
def click selector, browserName = nil
|
313
|
+
threads = []
|
314
|
+
status = true
|
315
|
+
@@driver.each do |name, driver|
|
316
|
+
if browserName.nil? or name == browserName.to_s
|
317
|
+
threads << Thread.new do
|
318
|
+
begin
|
319
|
+
element = driver.find_element(:css => selector)
|
320
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
|
321
|
+
wait.until { driver.find_element(:css => selector).displayed? }
|
322
|
+
driver.action.move_to(element).perform
|
323
|
+
element.click
|
324
|
+
rescue Exception => e
|
325
|
+
status = false
|
326
|
+
puts 'click: '+name+' : Bad selector : '+selector
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
threads.each(&:join)
|
332
|
+
if status
|
333
|
+
return status
|
334
|
+
else
|
335
|
+
return [status, "click: Bad selector : #{selector}"]
|
336
|
+
end
|
337
|
+
end
|
338
|
+
#Кликает на кнопку 'Ok' в окне алерта. Используется только в блоках should или setup.
|
339
|
+
#@return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст сообщения об ошибке, если она возникнет
|
340
|
+
#@example
|
341
|
+
# class SelWeT::Unit
|
342
|
+
#
|
343
|
+
# ...
|
344
|
+
#
|
345
|
+
# context "Example" do
|
346
|
+
#
|
347
|
+
# should "TODO something" do
|
348
|
+
# ...
|
349
|
+
# Unit.clickOkOnTheAlert
|
350
|
+
# ...
|
351
|
+
#@see click
|
352
|
+
#@see clickCancelOnTheAlert
|
353
|
+
def clickOkOnTheAlert
|
354
|
+
status = true
|
355
|
+
error = nil
|
356
|
+
threads = []
|
357
|
+
@@driver.each_value do |driver|
|
358
|
+
threads << Thread.new do
|
359
|
+
begin
|
360
|
+
driver.switch_to.alert.accept
|
361
|
+
rescue
|
362
|
+
status = false
|
363
|
+
error = 'clickOkOnTheAlert: No alert!'
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
threads.each(&:join)
|
368
|
+
return status, error
|
369
|
+
end
|
370
|
+
#Кликает на кнопку 'Cancel' в окне алерта. Используется только в блоках should или setup.
|
371
|
+
#@return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст сообщения об ошибке, если она возникнет
|
372
|
+
#@example
|
373
|
+
# class SelWeT::Unit
|
374
|
+
#
|
375
|
+
# setBrowsers [:firefox, :chrome]
|
376
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
377
|
+
# @@somePage = 'http://inventos.ru/produkty/#top'
|
378
|
+
#
|
379
|
+
# context "Example" do
|
380
|
+
#
|
381
|
+
# should "TODO something" do
|
382
|
+
# ...
|
383
|
+
# Unit.clickOkOnTheAlert
|
384
|
+
# ...
|
385
|
+
#@see click
|
386
|
+
#@see clickOkOnTheAlert
|
387
|
+
def clickCancelOnTheAlert
|
388
|
+
status = true
|
389
|
+
error = nil
|
390
|
+
threads = []
|
391
|
+
@@driver.each_value do |driver|
|
392
|
+
threads << Thread.new do
|
393
|
+
begin
|
394
|
+
driver.switch_to.alert.dismiss
|
395
|
+
rescue
|
396
|
+
puts 'clickOkOnTheAlert: No alert!'
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
threads.each(&:join)
|
401
|
+
return status, error
|
402
|
+
end
|
403
|
+
#Проверяет наличие элемента. Используется только в блоках should или setup. Возвращает первым аргументом статус выполнения операции (Boolean), вторым - сообщение об ошибке, если она возникнет (String), третьим - текст, содержащийся в элементе (Hash). Третий аргумент имеет следующую структуру: !{"имя_браузера_1" =>["текст"], "имя_браузера_2" =>["текст"],...}. Если по данному селектору найдено более одного элемента, то количество элементов в массиве будет соответствовать их числу, то есть !{"имя_браузера_1" =>["текст_элемента_1", "текст_элемента_2", ...],...}. При установке параметра link
|
404
|
+
# @param selector [String] css селектор элемента.
|
405
|
+
# @param link [Boolean] параметр, позволяющий получить значение поля href. Работает только для ссылок.
|
406
|
+
#@return [[Boolean, String, Hash]]
|
407
|
+
#@example
|
408
|
+
# class SelWeT::Unit
|
409
|
+
#
|
410
|
+
# setBrowsers [:firefox, :chrome]
|
411
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
412
|
+
# @@somePage = 'http://inventos.ru/produkty/#top'
|
413
|
+
#
|
414
|
+
# context "Example" do
|
415
|
+
#
|
416
|
+
# should "TODO something" do
|
417
|
+
# status, error, data = Unit.checkElement 'a.menu'
|
418
|
+
# status, error, data = Unit.checkElement 'a.toolbar', true
|
419
|
+
# ...
|
420
|
+
#@see checkElements
|
421
|
+
def checkElement selector, link = nil
|
422
|
+
result = [true, "", []]
|
423
|
+
threads = []
|
424
|
+
data = {}
|
425
|
+
@@driver.each do |name, driver|
|
426
|
+
threads << Thread.new do
|
427
|
+
begin
|
428
|
+
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
|
429
|
+
wait.until { driver.find_element(:css => selector) }
|
430
|
+
elements = driver.find_elements(:css => selector)
|
431
|
+
rescue
|
432
|
+
Thread.current["issue"] = name
|
433
|
+
end
|
434
|
+
if elements.nil? or elements.size == 0
|
435
|
+
Thread.current["no_elems"] = name
|
436
|
+
else
|
437
|
+
elements.each do |element|
|
438
|
+
unless link
|
439
|
+
if element.attribute('type') == 'submit' or element.attribute('type') == 'button' or element.attribute('type') == 'reset'
|
440
|
+
data[name].nil? ? data[name] = [element.attribute('value')] : data[name] << element.attribute('value')
|
441
|
+
else
|
442
|
+
if element.tag_name == 'select'
|
443
|
+
opts = element.text.split("\n")
|
444
|
+
opts.each do |opt|
|
445
|
+
opt.strip!
|
446
|
+
end
|
447
|
+
opts.delete ''
|
448
|
+
data[name].nil? ? data[name] = [opts] : data[name] << opts
|
449
|
+
else
|
450
|
+
data[name].nil? ? data[name] = [element.text] : data[name] << element.text
|
451
|
+
end
|
452
|
+
end
|
453
|
+
else
|
454
|
+
data[name].nil? ? data[name] = [{"link"=>element.attribute('href'), "text"=>element.text}] : data[name] << {"link"=>element.attribute('href'), "text"=>element.text}
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
threads.each(&:join)
|
461
|
+
threads.each do |i|
|
462
|
+
unless i["issue"].nil?
|
463
|
+
result[1] = (result[1].empty? ? "Bad selector '#{selector}'! Browsers: "+i["issue"].to_s : result[1]+" "+i["issue"].to_s)
|
464
|
+
else
|
465
|
+
unless i["no_elems"].nil?
|
466
|
+
result[1] = (result[1].empty? ? "Element '#{selector}' is missing. Browsers: "+i["no_elems"].to_s : result[1]+" "+i["no_elems"].to_s)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
unless result[1].empty?
|
471
|
+
result[0] = false
|
472
|
+
return result
|
473
|
+
end
|
474
|
+
result[2] = data
|
475
|
+
return result
|
476
|
+
end
|
477
|
+
#Проверяет наличие элементов. Используется только в блоках should или setup. Возвращает первым аргументом статус выполнения операции (Boolean), вторым - сообщение об ошибке, если она возникнет (String), третьим - текст, содержащийся в элементах ([Hash, Hash, ...]). Хеши имеют ту же структуру, что и в {checkElement}.
|
478
|
+
# @param selectors [Array] массив css селекторов элементов.
|
479
|
+
# @param link [Boolean] параметр, позволяющий получить значение поля href. Работает только для ссылок.
|
480
|
+
#@return [[Boolean, String, [Hash, Hash,...]]]
|
481
|
+
#@example
|
482
|
+
# class SelWeT::Unit
|
483
|
+
#
|
484
|
+
# setBrowsers [:firefox]
|
485
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
486
|
+
# @@somePage = 'http://inventos.ru/produkty/#top'
|
487
|
+
#
|
488
|
+
# context "Example" do
|
489
|
+
#
|
490
|
+
# should "TODO something" do
|
491
|
+
# status, error, data = Unit.checkElements ['input#email','input#password','a']
|
492
|
+
# #Получим количество ссылок
|
493
|
+
# a_num = data[2]["firefox"].size
|
494
|
+
# ...
|
495
|
+
#@see checkElement
|
496
|
+
def checkElements selectors, link = nil
|
497
|
+
result = [true, "", []]
|
498
|
+
return [false, "Argument 'selectors' must be Array!", []] unless selectors.class == Array
|
499
|
+
selectors.each do |selector|
|
500
|
+
status, message, data = checkElement(selector, link)
|
501
|
+
unless status
|
502
|
+
result[1] = (result[1].empty? ? message+"\n" : result[1]+message+"\n")
|
503
|
+
end
|
504
|
+
result[2] << data
|
505
|
+
end
|
506
|
+
unless result[1].empty?
|
507
|
+
result[0] = false
|
508
|
+
end
|
509
|
+
return result
|
510
|
+
end
|
511
|
+
#Обновляет страницу. Используется только в блоках should или setup.
|
512
|
+
#@example
|
513
|
+
# class SelWeT::Unit
|
514
|
+
#
|
515
|
+
# ...
|
516
|
+
# @@somePage = 'http://inventos.ru/produkty/#top'
|
517
|
+
#
|
518
|
+
# context "Example" do
|
519
|
+
#
|
520
|
+
# should "TODO something" do
|
521
|
+
# Unit.refresh
|
522
|
+
# ...
|
523
|
+
#@see followTheLink
|
524
|
+
def refresh
|
525
|
+
threads = []
|
526
|
+
@@driver.each_value do |driver|
|
527
|
+
threads << Thread.new do
|
528
|
+
driver.navigate.refresh
|
529
|
+
end
|
530
|
+
end
|
531
|
+
threads.each(&:join)
|
532
|
+
end
|
533
|
+
#Возвращает тег по заданному селектору. Используется только в блоках should или setup.
|
534
|
+
# @param selector [String] css селектор
|
535
|
+
# @return [[Boolean, String, Hash]] первый аргумент - статус, второй - сообщение об ошибке, если она возникает, третий - хеш вида !{имя браузера => тег}.
|
536
|
+
# @example
|
537
|
+
# class SelWeT::Unit
|
538
|
+
#
|
539
|
+
# ...
|
540
|
+
#
|
541
|
+
# context "Example" do
|
542
|
+
#
|
543
|
+
# should 'TODO something' do
|
544
|
+
# Unit.followTheLink @@somePage
|
545
|
+
# ...
|
546
|
+
# status, message, tags = Unit.getTag '#some_id'
|
547
|
+
# ...
|
548
|
+
def getTag selector
|
549
|
+
threads = []
|
550
|
+
tags = {}
|
551
|
+
status, message = checkElement selector
|
552
|
+
return [false, "getTag: "+message] unless status
|
553
|
+
@@driver.each do |name, driver|
|
554
|
+
threads << Thread.new do
|
555
|
+
tags[name] = driver.find_element(:css => selector).tag_name
|
556
|
+
end
|
557
|
+
end
|
558
|
+
threads.each(&:join)
|
559
|
+
return [true, "", tags]
|
560
|
+
end
|
561
|
+
#Заполнить поле или выбирает файл для загрузки. Используется только в блоках should или setup.
|
562
|
+
# @param selector [String] css селектор
|
563
|
+
# @param value [String] значение, которое необходимо ввести.
|
564
|
+
# @param postfix [Boolean] используется, если в разных браузерах необходимо ввести разные значения. К value добавляется '_имя_браузера'.
|
565
|
+
# @return [[Boolean,String]] - первый аргумент - статус выполнения, второй - сообщение об ошибке, если она произойдёт.
|
566
|
+
#@example
|
567
|
+
# class SelWeT::Unit
|
568
|
+
#
|
569
|
+
# ...
|
570
|
+
#
|
571
|
+
# context "Example" do
|
572
|
+
#
|
573
|
+
# should 'TODO something' do
|
574
|
+
# Unit.followTheLink @@somePage
|
575
|
+
# ...
|
576
|
+
# status, error = Unit.fillTheField 'input#some_id', 'some text' #заполнить текстовое поле
|
577
|
+
# status, error = Unit.fillTheField 'input#[type={"file"}]', 'C:\\path\to\file' #выбрать файл для загрузки
|
578
|
+
# ...
|
579
|
+
#@see followTheLink
|
580
|
+
#@see postForm
|
581
|
+
def fillTheField selector, value, postfix = nil
|
582
|
+
result = [true, ""]
|
583
|
+
threads = []
|
584
|
+
status, message, data = checkElement selector
|
585
|
+
unless status
|
586
|
+
return [false, message]
|
587
|
+
end
|
588
|
+
data.each_value do |i|
|
589
|
+
if i.size>1
|
590
|
+
return [false, "fillTheField: Element with selector #{selector} not uniq!"]
|
591
|
+
end
|
592
|
+
end
|
593
|
+
@@driver.each do |name, driver|
|
594
|
+
threads << Thread.new do
|
595
|
+
element = driver.find_element(:css => selector)
|
596
|
+
driver.action.move_to(element).perform
|
597
|
+
begin
|
598
|
+
element.clear if element.attribute('type') != 'file'
|
599
|
+
rescue
|
600
|
+
#skip this
|
601
|
+
end
|
602
|
+
driver.find_element(:css => selector).send_keys((postfix.nil? ? value : value+"_"+name))
|
603
|
+
end
|
604
|
+
end
|
605
|
+
threads.each(&:join)
|
606
|
+
return result
|
607
|
+
end
|
608
|
+
#Возвращает состояние для radio и checkbox. Используется только в блоках should или setup.
|
609
|
+
# @param selector [String] css селектор
|
610
|
+
# @return [[Boolean,String/Hash] первый аргумент - статус выполнения, второй - хеш вида !{имя_браузера=>статус} (если radio или checkbox: 1. checked, то статус принимает значение true; 2. unchecked, то статус принимает значение false), или, если первый аргумент равен false - содержит текст ошибки.
|
611
|
+
#@example
|
612
|
+
# class SelWeT::Unit
|
613
|
+
#
|
614
|
+
# ...
|
615
|
+
#
|
616
|
+
# context "Example" do
|
617
|
+
#
|
618
|
+
# should 'TODO something' do
|
619
|
+
# Unit.followTheLink @@somePage
|
620
|
+
# ...
|
621
|
+
# status, check = Unit.getStatus 'input[type="checkbox"]'
|
622
|
+
# ...
|
623
|
+
def getStatus selector
|
624
|
+
threads = []
|
625
|
+
status, message, data = checkfElement selector
|
626
|
+
return [false, 'getStatus: Element not uniq!'] if data.values[0].size>1
|
627
|
+
return [false, "getStatus: "+message, tag] unless status
|
628
|
+
status = true
|
629
|
+
@@driver.each do |name, driver|
|
630
|
+
threads << Thread.new do
|
631
|
+
element = driver.find_element(:css => selector)
|
632
|
+
Thread.current['name'] = name
|
633
|
+
if element.attribute('type') == 'checkbox' or element.attribute('type') == 'radio'
|
634
|
+
Thread.current['status'] = driver.find_element(:css => selector).selected?.inspect
|
635
|
+
else
|
636
|
+
Thread.current['status'] = "#{element.attribute('type')} is not a checkbox or radio!"
|
637
|
+
status = false
|
638
|
+
end
|
639
|
+
end
|
640
|
+
end
|
641
|
+
threads.each(&:join)
|
642
|
+
statuses = {}
|
643
|
+
threads.each do |i|
|
644
|
+
statuses[i['name']] = (i['status'] == "true" ? true : i['status'] == "false" ? false : i['status'])
|
645
|
+
end
|
646
|
+
return [status, statuses]
|
647
|
+
end
|
648
|
+
#Заполнить и отправить форму.
|
649
|
+
# @param selector [String] css селектор формы.
|
650
|
+
# @param fields [Hash] хеш. В качестве ключа передается css селектор элемента (String), в качестве значения: 1) для текстовых полей - строка со значением(String). Если в разных браузерах требуется ввести разные значения, то вначале строки необходимо поставить символ &. Тогда в поле запишется данная строка без символа &, но в конце будет добавлен постфикс "_имя браузера"; 2) для checkbox, radio и кнопок(не submit!) - значение :click; 3) для кнопки отправки формы - :submit. Если не будет указана кнопка для отправки формы, то форма всё равно будет отправлена; 4) для select - массив значений(String), которые необходимо выбрать; 5) для file - путь до файла.
|
651
|
+
# @return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
652
|
+
#@example
|
653
|
+
# class SelWeT::Unit
|
654
|
+
#
|
655
|
+
# ...
|
656
|
+
#
|
657
|
+
# context "Example" do
|
658
|
+
#
|
659
|
+
# should "Successfull authorization" do
|
660
|
+
# status, error = Unit.postForm ".form", {'#email' => 'admin@example.ru', '#password' => 'admin', '.checkbox' => :click, '.submit'=>:submit}
|
661
|
+
# ...
|
662
|
+
#@see click
|
663
|
+
#@see fillTheField
|
664
|
+
def postForm selector, fields = nil
|
665
|
+
result = [true, ""]
|
666
|
+
fields = {} if fields.nil?
|
667
|
+
status, message, data = checkElement selector
|
668
|
+
unless status
|
669
|
+
return [false, message]
|
670
|
+
end
|
671
|
+
data.each do |key, value|
|
672
|
+
if value.size>1
|
673
|
+
return [false, "postForm: (#{key}) Found more than one form with selector '#{selector}'"]
|
674
|
+
end
|
675
|
+
end
|
676
|
+
check_elements = ''
|
677
|
+
fields.keys.each do |key|
|
678
|
+
status, message, data = checkElement key
|
679
|
+
unless status
|
680
|
+
check_elements = (check_elements.empty? ? message+' : '+key+"\n" : check_elements+message+' : '+key+"\n")
|
681
|
+
end
|
682
|
+
data.each do |browser, value|
|
683
|
+
if value.size>1
|
684
|
+
check_elements = (check_elements.empty? ? "postForm:(#{browser}) Element of form not uniq : "+key+"\n" : check_elements+"postForm:(#{browser}) Element of form not uniq : "+key+"\n")
|
685
|
+
end
|
686
|
+
end
|
687
|
+
end
|
688
|
+
unless check_elements.empty?
|
689
|
+
return [false, check_elements]
|
690
|
+
end
|
691
|
+
submit_button = nil
|
692
|
+
bad_args = {}
|
693
|
+
fields.each do |key, value|
|
694
|
+
if value.class != String and value.class != Symbol
|
695
|
+
bad_args[key] = value
|
696
|
+
end
|
697
|
+
if value.class == Symbol
|
698
|
+
if value != :click and value != :submit
|
699
|
+
bad_args[key] = value
|
700
|
+
end
|
701
|
+
end
|
702
|
+
end
|
703
|
+
return [false, 'postForm: Bad args was passed: '+bad_args.to_s] unless bad_args.empty?
|
704
|
+
fields.each do |key, value|
|
705
|
+
if value == :click
|
706
|
+
click key
|
707
|
+
end
|
708
|
+
if value == :submit
|
709
|
+
submit_button = key
|
710
|
+
end
|
711
|
+
if value.class == Array
|
712
|
+
status, error = selectItemsFromTheSelect(key, value)
|
713
|
+
return [false, error] unless status
|
714
|
+
end
|
715
|
+
end
|
716
|
+
fields.delete_if { |key,value| value == :click or value == :submit or value.class == Array }
|
717
|
+
threads = []
|
718
|
+
errors = nil
|
719
|
+
@@driver.each do |name, driver|
|
720
|
+
threads << Thread.new do
|
721
|
+
form = driver.find_element(:css => selector)
|
722
|
+
fields.each do |key, value|
|
723
|
+
tag = form.find_element(:css => key).tag_name
|
724
|
+
errors = true if tag == 'select'
|
725
|
+
begin
|
726
|
+
form.find_element(:css => key).clear
|
727
|
+
rescue
|
728
|
+
#skip this
|
729
|
+
end
|
730
|
+
if value[0] == '&'
|
731
|
+
send_value = value+'_'+name
|
732
|
+
send_value.slice! '&'
|
733
|
+
form.find_element(:css => key).send_keys(send_value)
|
734
|
+
else
|
735
|
+
form.find_element(:css => key).send_keys(value)
|
736
|
+
end
|
737
|
+
end
|
738
|
+
unless errors
|
739
|
+
form.submit unless submit_button
|
740
|
+
end
|
741
|
+
end
|
742
|
+
end
|
743
|
+
threads.each(&:join)
|
744
|
+
return [false, 'postForm: For "select" you must pass array with selected values!'] if errors
|
745
|
+
click submit_button unless !submit_button
|
746
|
+
return result
|
747
|
+
end
|
748
|
+
#Сверяет переданный url с текущим. Используется только в блоках should или setup.
|
749
|
+
# @param url [String] url, с которым будет сравинваться текущий url.
|
750
|
+
# @return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
751
|
+
#@example
|
752
|
+
# class SelWeT::Unit
|
753
|
+
#
|
754
|
+
# setBrowsers [:firefox, :chrome]
|
755
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
756
|
+
# @@somePage = 'http://www.example.com'
|
757
|
+
#
|
758
|
+
# context "Example" do
|
759
|
+
#
|
760
|
+
# should 'Correct link' do
|
761
|
+
# Unit.followTheLink @@somePage
|
762
|
+
# ...
|
763
|
+
# status, error = Unit.checkLocation 'http://www.example.com/other_page'
|
764
|
+
# ...
|
765
|
+
#@see followTheLink
|
766
|
+
#@see getLocation
|
767
|
+
def checkLocation url
|
768
|
+
result = [true, ""]
|
769
|
+
threads = []
|
770
|
+
@@driver.each do |name, driver|
|
771
|
+
threads << Thread.new do
|
772
|
+
unless driver.current_url == url
|
773
|
+
Thread.current["value"] = name
|
774
|
+
Thread.current["real"] = driver.current_url
|
775
|
+
end
|
776
|
+
end
|
777
|
+
end
|
778
|
+
threads.each(&:join)
|
779
|
+
threads.each do |i|
|
780
|
+
unless i["value"].nil?
|
781
|
+
result[1] = (result[1].empty? ? "Wrong location '#{i['real']}': "+i["value"].to_s : result[1]+" "+i["value"].to_s)
|
782
|
+
end
|
783
|
+
end
|
784
|
+
unless result[1].empty?
|
785
|
+
result[0] = false
|
786
|
+
end
|
787
|
+
return result
|
788
|
+
end
|
789
|
+
#Возвращает текущий url. Используется только в блоках should или setup.
|
790
|
+
# @return [Hash] ключ - имя браузера, значение - URL.
|
791
|
+
#@example
|
792
|
+
# class SelWeT::Unit
|
793
|
+
#
|
794
|
+
# setBrowsers [:firefox, :chrome]
|
795
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
796
|
+
# @@somePage = 'http://www.example.com'
|
797
|
+
#
|
798
|
+
# context "Example" do
|
799
|
+
#
|
800
|
+
# should 'Correct link' do
|
801
|
+
# Unit.followTheLink @@somePage
|
802
|
+
# ...
|
803
|
+
# location = Unit.getLocation
|
804
|
+
# ...
|
805
|
+
#@see checkLocation
|
806
|
+
#@see followTheLink
|
807
|
+
def getLocation
|
808
|
+
result = {}
|
809
|
+
threads = []
|
810
|
+
@@driver.each do |name, driver|
|
811
|
+
threads << Thread.new do
|
812
|
+
Thread.current["name"] = name
|
813
|
+
Thread.current["url"] = driver.current_url
|
814
|
+
end
|
815
|
+
end
|
816
|
+
threads.each(&:join)
|
817
|
+
threads.each do |i|
|
818
|
+
result[i['name']] = i['url']
|
819
|
+
end
|
820
|
+
return result
|
821
|
+
end
|
822
|
+
#Сохраняет скриншот текущего состояния браузеров рядом со скриптом. Имя файла будет иметь следующий вид: browsername_filename.png
|
823
|
+
# @param filename [String] часть имени выходного файла.
|
824
|
+
#@example
|
825
|
+
# class SelWeT::Unit
|
826
|
+
#
|
827
|
+
# setBrowsers [:firefox, :chrome]
|
828
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
829
|
+
# @@somePage = 'http://www.example.com'
|
830
|
+
#
|
831
|
+
# context "Example" do
|
832
|
+
#
|
833
|
+
# should 'Make screenshot' do
|
834
|
+
# Unit.followTheLink @@somePage
|
835
|
+
# ...
|
836
|
+
# Unit.screenshot 'TestScreenshot'
|
837
|
+
# ...
|
838
|
+
def screenshot filename
|
839
|
+
threads = []
|
840
|
+
@@driver.each do |name, driver|
|
841
|
+
threads << Thread.new do
|
842
|
+
driver.save_screenshot("./"+name+"_"+filename+".png")
|
843
|
+
end
|
844
|
+
end
|
845
|
+
threads.each(&:join)
|
846
|
+
end
|
847
|
+
#Открывает ссылку в новом окне и переключается на него.
|
848
|
+
#@param selector [String] css селектор ссылки.
|
849
|
+
# @return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
850
|
+
#@example
|
851
|
+
# class SelWeT::Unit
|
852
|
+
#
|
853
|
+
# setBrowsers [:firefox, :chrome]
|
854
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
855
|
+
# @@somePage = 'http://www.example.com'
|
856
|
+
#
|
857
|
+
# context "Example" do
|
858
|
+
#
|
859
|
+
# should 'TODO somethin' do
|
860
|
+
# Unit.followTheLink @@somePage
|
861
|
+
# ...
|
862
|
+
# Unit.openInNewWindow 'a.someclass'
|
863
|
+
# ...
|
864
|
+
#@see switchToWindow
|
865
|
+
#@see closeWindow
|
866
|
+
def openInNewWindow selector
|
867
|
+
threads = []
|
868
|
+
not_opened = false
|
869
|
+
status, message = checkElement selector
|
870
|
+
unless status
|
871
|
+
return [false, message]
|
872
|
+
end
|
873
|
+
@@driver.each do |name, driver|
|
874
|
+
threads << Thread.new do
|
875
|
+
a = driver.find_element :css => selector
|
876
|
+
if @@win_num == 0
|
877
|
+
@@opened_window[name] = {@@win_num => driver.window_handle}
|
878
|
+
end
|
879
|
+
driver.action.key_down(:shift).perform
|
880
|
+
a.click
|
881
|
+
driver.action.key_up(:shift).perform
|
882
|
+
old_handle = @@opened_window[name].values
|
883
|
+
new_handle = (driver.window_handles - old_handle)[0]
|
884
|
+
unless new_handle.nil?
|
885
|
+
driver.switch_to.window new_handle
|
886
|
+
@@opened_window[name][@@win_num+1] = new_handle
|
887
|
+
else
|
888
|
+
not_opened = true
|
889
|
+
end
|
890
|
+
end
|
891
|
+
end
|
892
|
+
threads.each(&:join)
|
893
|
+
return [false, "Window not opened!"] if not_opened
|
894
|
+
@@win_num += 1
|
895
|
+
return true
|
896
|
+
end
|
897
|
+
#Переключиться на другое окно. Окна нумируются в порядке их открытия. Нумирация начинается с 0.
|
898
|
+
#@param num [Integer] номер окна.
|
899
|
+
# @return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
900
|
+
#@example
|
901
|
+
# class SelWeT::Unit
|
902
|
+
#
|
903
|
+
# setBrowsers [:firefox, :chrome]
|
904
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
905
|
+
# @@somePage = 'http://www.example.com'
|
906
|
+
#
|
907
|
+
# context "Example" do
|
908
|
+
#
|
909
|
+
# should 'TODO something' do
|
910
|
+
# Unit.openInNewTab 'a.someclass'
|
911
|
+
# ...
|
912
|
+
# Unit.switchToWindow 0
|
913
|
+
# Unit.closeWindow 1
|
914
|
+
# ...
|
915
|
+
#@see openInNewWindow
|
916
|
+
#@see closeWindow
|
917
|
+
def switchToWindow num
|
918
|
+
threads = []
|
919
|
+
status = true
|
920
|
+
@@driver.each do |name, driver|
|
921
|
+
threads << Thread.new do
|
922
|
+
if @@opened_window[name].has_key? num
|
923
|
+
driver.switch_to.window @@opened_window[name][num]
|
924
|
+
else
|
925
|
+
status = false
|
926
|
+
end
|
927
|
+
end
|
928
|
+
end
|
929
|
+
threads.each(&:join)
|
930
|
+
return status, (status ? "" : "Invalid num: '#{num}'")
|
931
|
+
end
|
932
|
+
#Закрыть окно с номером num. Окна нумируются в порядке их открытия. Нумирация начинается с 0. Если необходимо закрыть текущее окно, то перед закрытием необходимо переключиться на другое окно.
|
933
|
+
#@param num [Integer] номер окна.
|
934
|
+
# @return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
935
|
+
#@example
|
936
|
+
# class SelWeT::Unit
|
937
|
+
#
|
938
|
+
# setBrowsers [:firefox, :chrome]
|
939
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
940
|
+
# @@somePage = 'http://www.example.com'
|
941
|
+
#
|
942
|
+
# context "Example" do
|
943
|
+
#
|
944
|
+
# should 'TODO somethin' do
|
945
|
+
# Unit.closeWindow 2
|
946
|
+
# ...
|
947
|
+
#@see openInNewTab
|
948
|
+
#@see switchToWindow
|
949
|
+
def closeWindow num
|
950
|
+
threads = []
|
951
|
+
status = true
|
952
|
+
@@driver.each do |name, driver|
|
953
|
+
threads << Thread.new do
|
954
|
+
current = driver.window_handle
|
955
|
+
if current != @@opened_window[name][num]
|
956
|
+
driver.switch_to.window @@opened_window[name][num]
|
957
|
+
driver.close
|
958
|
+
@@opened_window[name].delete_if do |key, value|
|
959
|
+
key == num
|
960
|
+
end
|
961
|
+
driver.switch_to.window current
|
962
|
+
else
|
963
|
+
status = false
|
964
|
+
end
|
965
|
+
end
|
966
|
+
end
|
967
|
+
threads.each(&:join)
|
968
|
+
if status
|
969
|
+
return true
|
970
|
+
else
|
971
|
+
return [false, "You must switch to other window before closing this window"]
|
972
|
+
end
|
973
|
+
end
|
974
|
+
#Навести курсор на элемент.
|
975
|
+
#@param selector [String] css селектор элемента.
|
976
|
+
#@return [[Boolean,String]] Первый аргумент - статус выполнения, второй - текст ошибки, если она возникнет.
|
977
|
+
#@example
|
978
|
+
# class SelWeT::Unit
|
979
|
+
#
|
980
|
+
# setBrowsers [:firefox, :chrome]
|
981
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
982
|
+
# @@somePage = 'http://www.example.com'
|
983
|
+
#
|
984
|
+
# context "Example" do
|
985
|
+
#
|
986
|
+
# should 'TODO somethin' do
|
987
|
+
# Unit.hoverOverElement "div.menu"
|
988
|
+
# Unit.click "a.some_url"
|
989
|
+
# ...
|
990
|
+
def hoverOverElement selector
|
991
|
+
status, message = checkElement selector
|
992
|
+
unless status
|
993
|
+
return [false, message]
|
994
|
+
end
|
995
|
+
threads = []
|
996
|
+
@@driver.each do |name, driver|
|
997
|
+
threads << Thread.new do
|
998
|
+
element = driver.find_element(:css => selector)
|
999
|
+
driver.action.move_to(element).perform
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
threads.each(&:join)
|
1003
|
+
return true
|
1004
|
+
end
|
1005
|
+
#Получить заголовок окна.
|
1006
|
+
#@return Hash ключ - имя браузера, аргумент - title.
|
1007
|
+
#@example
|
1008
|
+
# class SelWeT::Unit
|
1009
|
+
#
|
1010
|
+
# setBrowsers [:firefox, :chrome]
|
1011
|
+
# setSeleniumServerUrl 'http://localhost:4444/wd/hub'
|
1012
|
+
# @@somePage = 'http://www.example.com'
|
1013
|
+
#
|
1014
|
+
# context "Example" do
|
1015
|
+
#
|
1016
|
+
# should 'TODO somethin' do
|
1017
|
+
# ...
|
1018
|
+
# titles = Unit.getTitle
|
1019
|
+
# ...
|
1020
|
+
def getTitle
|
1021
|
+
threads = []
|
1022
|
+
status = true
|
1023
|
+
@@driver.each do |name, driver|
|
1024
|
+
threads << Thread.new do
|
1025
|
+
Thread.current["name"] = name
|
1026
|
+
Thread.current["title"] = driver.title
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
threads.each(&:join)
|
1030
|
+
titles = {}
|
1031
|
+
threads.each do |i|
|
1032
|
+
titles[i["name"]] = i["title"]
|
1033
|
+
end
|
1034
|
+
return titles
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
end
|
1040
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: selwet
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Motin Artem
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: selenium-webdriver
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.44'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.44'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 3.0.6
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '3.0'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.0.6
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: shoulda-context
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.2'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.2.1
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '1.2'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.2.1
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: bundler
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.6'
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '1.6'
|
81
|
+
description: '["Gem for creating web tests"]'
|
82
|
+
email: a.motin@inventos.ru
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files: []
|
86
|
+
files:
|
87
|
+
- lib/selwet.rb
|
88
|
+
homepage:
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.2.2
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Selenium Web Test
|
112
|
+
test_files: []
|
113
|
+
has_rdoc:
|