wda_lib 0.0.16 → 0.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/LICENSE +201 -0
- data/README.md +10 -5
- data/lib/selenium_patch/bridge_patch.rb +115 -0
- data/lib/selenium_patch/commands_patch.rb +34 -0
- data/lib/selenium_patch/element_patch.rb +13 -8
- data/lib/wda_lib/alert.rb +4 -0
- data/lib/wda_lib/custom.rb +7 -3
- data/lib/wda_lib/debug.rb +9 -4
- data/lib/wda_lib/element.rb +18 -26
- data/lib/wda_lib/error.rb +5 -1
- data/lib/wda_lib/find_element.rb +15 -12
- data/lib/wda_lib/orientation.rb +5 -3
- data/lib/wda_lib/screenshot.rb +4 -0
- data/lib/wda_lib/session.rb +13 -9
- data/lib/wda_lib/touch_id.rb +5 -1
- data/lib/wda_lib/type.rb +5 -1
- data/lib/wda_lib/version.rb +6 -2
- data/lib/wda_lib.rb +28 -12
- data/wda_lib.gemspec +2 -2
- metadata +8 -7
- data/lib/selenium_patch/commands.rb +0 -136
- data/lib/selenium_patch/w3c_bridge_patch.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7bd726e001942bb862ef2a84530479e09931b7a
|
4
|
+
data.tar.gz: 9995494131ba577468193824c67a0a038391fd9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 340e97cdc8d0cabfbd4fc5c2432fbb0422b6e2de21406571098be320ddb3aa0bea6501eba7247cd598ea166e5ab4b4cabf60d523a705e888a61f0bbedd4867fa
|
7
|
+
data.tar.gz: 72404538b6fb11a977ec3a9f4299b94b6f67f7fefcfd54aa6bd6b951c71ac766bfe84a82e487005f63a1c2e935c8014f66c5c23a404296c23fd6043c734219b2
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
Apache License
|
2
|
+
Version 2.0, January 2004
|
3
|
+
http://www.apache.org/licenses/
|
4
|
+
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6
|
+
|
7
|
+
1. Definitions.
|
8
|
+
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
11
|
+
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13
|
+
the copyright owner that is granting the License.
|
14
|
+
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
16
|
+
other entities that control, are controlled by, or are under common
|
17
|
+
control with that entity. For the purposes of this definition,
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
19
|
+
direction or management of such entity, whether by contract or
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22
|
+
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24
|
+
exercising permissions granted by this License.
|
25
|
+
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
27
|
+
including but not limited to software source code, documentation
|
28
|
+
source, and configuration files.
|
29
|
+
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
31
|
+
transformation or translation of a Source form, including but
|
32
|
+
not limited to compiled object code, generated documentation,
|
33
|
+
and conversions to other media types.
|
34
|
+
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
36
|
+
Object form, made available under the License, as indicated by a
|
37
|
+
copyright notice that is included in or attached to the work
|
38
|
+
(an example is provided in the Appendix below).
|
39
|
+
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46
|
+
the Work and Derivative Works thereof.
|
47
|
+
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
49
|
+
the original version of the Work and any modifications or additions
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
61
|
+
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
64
|
+
subsequently incorporated within the Work.
|
65
|
+
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
72
|
+
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78
|
+
where such license applies only to those patent claims licensable
|
79
|
+
by such Contributor that are necessarily infringed by their
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
82
|
+
institute patent litigation against any entity (including a
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
85
|
+
or contributory patent infringement, then any patent licenses
|
86
|
+
granted to You under this License for that Work shall terminate
|
87
|
+
as of the date such litigation is filed.
|
88
|
+
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
91
|
+
modifications, and in Source or Object form, provided that You
|
92
|
+
meet the following conditions:
|
93
|
+
|
94
|
+
(a) You must give any other recipients of the Work or
|
95
|
+
Derivative Works a copy of this License; and
|
96
|
+
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
98
|
+
stating that You changed the files; and
|
99
|
+
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
102
|
+
attribution notices from the Source form of the Work,
|
103
|
+
excluding those notices that do not pertain to any part of
|
104
|
+
the Derivative Works; and
|
105
|
+
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
108
|
+
include a readable copy of the attribution notices contained
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
111
|
+
of the following places: within a NOTICE text file distributed
|
112
|
+
as part of the Derivative Works; within the Source form or
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
114
|
+
within a display generated by the Derivative Works, if and
|
115
|
+
wherever such third-party notices normally appear. The contents
|
116
|
+
of the NOTICE file are for informational purposes only and
|
117
|
+
do not modify the License. You may add Your own attribution
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
120
|
+
that such additional attribution notices cannot be construed
|
121
|
+
as modifying the License.
|
122
|
+
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
124
|
+
may provide additional or different license terms and conditions
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
128
|
+
the conditions stated in this License.
|
129
|
+
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
133
|
+
this License, without any additional terms or conditions.
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135
|
+
the terms of any separate license agreement you may have executed
|
136
|
+
with Licensor regarding such Contributions.
|
137
|
+
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
140
|
+
except as required for reasonable and customary use in describing the
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
142
|
+
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
152
|
+
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
158
|
+
incidental, or consequential damages of any character arising as a
|
159
|
+
result of this License or out of the use or inability to use the
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
162
|
+
other commercial damages or losses), even if such Contributor
|
163
|
+
has been advised of the possibility of such damages.
|
164
|
+
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168
|
+
or other liability obligations and/or rights consistent with this
|
169
|
+
License. However, in accepting such obligations, You may act only
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
174
|
+
of your accepting any such warranty or additional liability.
|
175
|
+
|
176
|
+
END OF TERMS AND CONDITIONS
|
177
|
+
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
179
|
+
|
180
|
+
To apply the Apache License to your work, attach the following
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "{}"
|
182
|
+
replaced with your own identifying information. (Don't include
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
184
|
+
comment syntax for the file format. We also recommend that a
|
185
|
+
file or class name and description of purpose be included on the
|
186
|
+
same "printed page" as the copyright notice for easier
|
187
|
+
identification within third-party archives.
|
188
|
+
|
189
|
+
Copyright 2016 Zenly SAS
|
190
|
+
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192
|
+
you may not use this file except in compliance with the License.
|
193
|
+
You may obtain a copy of the License at
|
194
|
+
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
196
|
+
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200
|
+
See the License for the specific language governing permissions and
|
201
|
+
limitations under the License.
|
data/README.md
CHANGED
@@ -21,19 +21,19 @@ A simple test to show all actions on WDA IntegrationApp
|
|
21
21
|
|
22
22
|
|
23
23
|
## Options
|
24
|
-
|
25
|
-
#####Update: I have to disable selenium-webdriver gem since wda_lib was using selenium-webdriver 3.0 beta which has conflict with Appium's one(2.x), I did try to downgrade for wda_lib, but doesn't work currently, need more time to give a try to find a way to handle it.
|
26
|
-
This lib is also providing access of selenium-webdriver method find_element and find_elements.
|
24
|
+
This lib is also providing access of selenium-webdriver methods, for example find_element and find_elements.
|
27
25
|
You can do:
|
28
26
|
|
29
27
|
```ruby
|
30
|
-
element = app.find_element(:link_text, 'label=
|
28
|
+
element = app.driver.find_element(:link_text, 'label=xxxx')
|
31
29
|
```
|
32
30
|
|
33
31
|
Then you can use all methods for selenium element object:
|
34
32
|
```
|
35
33
|
element.click
|
36
34
|
element.name
|
35
|
+
element.label
|
36
|
+
element.tag_name
|
37
37
|
element.size
|
38
38
|
element.rect
|
39
39
|
element.location
|
@@ -62,4 +62,9 @@ Welcome to get your contributions, to help improving the lib.
|
|
62
62
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
63
63
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
64
64
|
4. Push to the branch (`git push origin my-new-feature`)
|
65
|
-
5. Create new Pull Request
|
65
|
+
5. Create new Pull Request
|
66
|
+
|
67
|
+
## Contact Information
|
68
|
+
|
69
|
+
Author: Yi MIN
|
70
|
+
E-mail: yi@zen.ly
|
@@ -0,0 +1,115 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
5
|
+
# Patch or add methods for Bridge. Called by Element instance or Bridge instance
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
Selenium::WebDriver::Remote::Bridge.class_eval do
|
9
|
+
|
10
|
+
# Patch Bridge create_session method
|
11
|
+
def create_session(desired_capabilities)
|
12
|
+
@session_id = desired_capabilities[:session_id]
|
13
|
+
if !desired_capabilities[:session_valid]
|
14
|
+
resp = raw_execute :new_session, {}, {desiredCapabilities: desired_capabilities}
|
15
|
+
desired_capabilities[:session_id] = resp['session_id']
|
16
|
+
desired_capabilities[:session_valid] = true
|
17
|
+
@session_id = resp['session_id']
|
18
|
+
end
|
19
|
+
return desired_capabilities
|
20
|
+
end
|
21
|
+
|
22
|
+
# # Add status method
|
23
|
+
# def session_status
|
24
|
+
# execute :session_status
|
25
|
+
# end
|
26
|
+
|
27
|
+
# Add element_rect method
|
28
|
+
def element_rect(element)
|
29
|
+
data = execute :get_element_rect, id: element
|
30
|
+
return data
|
31
|
+
end
|
32
|
+
|
33
|
+
# Add element_scroll method
|
34
|
+
def scroll_element(element, direction)
|
35
|
+
execute :scroll_element, {id: element}, {direction: direction}
|
36
|
+
end
|
37
|
+
|
38
|
+
def element_location(element)
|
39
|
+
data = execute :get_element_rect, id: element
|
40
|
+
|
41
|
+
Selenium::WebDriver::Point.new data['x'], data['y']
|
42
|
+
end
|
43
|
+
|
44
|
+
def element_size(element)
|
45
|
+
data = execute :get_element_rect, id: element
|
46
|
+
|
47
|
+
Selenium::WebDriver::Dimension.new data['width'], data['height']
|
48
|
+
end
|
49
|
+
|
50
|
+
# # Patch Bridge element_attribute method
|
51
|
+
# def element_attribute(element, name)
|
52
|
+
# execute :get_element_attribute, id: element['ELEMENT'], name: name
|
53
|
+
# end
|
54
|
+
|
55
|
+
# # Add get_page_source method with accept_type to Bridge
|
56
|
+
# def source(accept_type)
|
57
|
+
# if accept_type == 'json'
|
58
|
+
# execute :get_page_source_json
|
59
|
+
# elsif accept_type == 'xml'
|
60
|
+
# execute :get_page_source_xml
|
61
|
+
# else
|
62
|
+
# raise "Unknown source type. Only 'xml' and 'json' source types are supported."
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
|
66
|
+
# # Add missing bindings
|
67
|
+
# # https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Commands/FBElementCommands.m
|
68
|
+
# # Add tap_element method
|
69
|
+
# def tap_element(element)
|
70
|
+
# execute :click_element, id: element['ELEMENT']
|
71
|
+
# end
|
72
|
+
|
73
|
+
# # Add double_tap_element method
|
74
|
+
# def double_tap_element(element)
|
75
|
+
# execute :double_click_element, id: element['ELEMENT']
|
76
|
+
# end
|
77
|
+
|
78
|
+
# # Add two_finger_tap_element method
|
79
|
+
# def two_finger_tap_element(element)
|
80
|
+
# execute :two_finger_click_element, id: element['ELEMENT']
|
81
|
+
# end
|
82
|
+
|
83
|
+
# # Add touch_and_hold_element method
|
84
|
+
# def touch_and_hold_element(element)
|
85
|
+
# execute :touch_and_hold, id: element['ELEMENT']
|
86
|
+
# end
|
87
|
+
|
88
|
+
|
89
|
+
# # Add drag_from_to_for_duration method
|
90
|
+
# def drag_from_to_for_duration(element, toX, toY, duration = 0)
|
91
|
+
# el_location = element_location(element)
|
92
|
+
# fromX = el_location[:x]
|
93
|
+
# fromY = el_location[:y]
|
94
|
+
# execute :drag_from_to_for_duration, {id: element['ELEMENT']}, { fromX: fromX, toX: toX, fromY: fromY, toY: toY, duration: duration }
|
95
|
+
# end
|
96
|
+
|
97
|
+
# # Add single tap method
|
98
|
+
# def tap(x,y, element = nil)
|
99
|
+
# if element.nil?
|
100
|
+
# execute :tap, {id: 0}, { x: x, y: y }
|
101
|
+
# else
|
102
|
+
# execute :tap, {id: element['ELEMENT']}, { x: x, y: y }
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
|
106
|
+
# # Add double tap method
|
107
|
+
# def double_tap(x,y)
|
108
|
+
# execute :double_tap, {}, { x: x, y: y }
|
109
|
+
# end
|
110
|
+
|
111
|
+
# def touch_and_hold(x, y)
|
112
|
+
# execute :touch_and_hold, {}, { x: x, y: y }
|
113
|
+
# end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
5
|
+
|
6
|
+
module Selenium
|
7
|
+
module WebDriver
|
8
|
+
module Remote
|
9
|
+
class Bridge
|
10
|
+
#
|
11
|
+
# http://www.w3.org/TR/2015/WD-webdriver-20150918/#list-of-endpoints
|
12
|
+
#
|
13
|
+
unfrozen_COMMANDS = COMMANDS.dup
|
14
|
+
unfrozen_COMMANDS.merge!({
|
15
|
+
get_page_source_json: [:get, 'source/json'.freeze],
|
16
|
+
get_page_source_xml: [:get, 'source/xml'.freeze],
|
17
|
+
session_status: [:get, 'status'.freeze],
|
18
|
+
get_element_rect: [:get, 'session/:session_id/element/:id/rect'.freeze],
|
19
|
+
is_element_accessible: [:get, 'session/:session_id/element/:id/accessible'.freeze],
|
20
|
+
element_accessibility_container: [:get, 'session/:session_id/element/:id/accessibilityContainer'.freeze],
|
21
|
+
double_click_element: [:post, 'session/:session_id/element/:id/doubleTap'.freeze],
|
22
|
+
two_finger_click_element: [:post, 'session/:session_id/element/:id/twoFingerTap'.freeze],
|
23
|
+
touch_and_hold_element: [:post, 'session/:session_id/element/:id/touchAndHold'.freeze],
|
24
|
+
scroll_element: [:post, 'session/:session_id/uiaElement/:id/scroll'.freeze],
|
25
|
+
drag_from_to_for_duration: [:post, 'session/:session_id/uiaTarget/:uuid/dragfromtoforduration'.freeze],
|
26
|
+
tap: [:post, 'session/:session_id/doubleTap/:id'.freeze],
|
27
|
+
tap_and_hold: [:post, 'session/:session_id/touchAndHold'.freeze],
|
28
|
+
double_tap: [:post, 'session/:session_id/doubleTap'.freeze]
|
29
|
+
})
|
30
|
+
COMMANDS = unfrozen_COMMANDS.freeze
|
31
|
+
end
|
32
|
+
end # Remote
|
33
|
+
end # WebDriver
|
34
|
+
end # Selenium
|
@@ -1,16 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
5
|
+
|
1
6
|
# require 'selenium-webdriver'
|
2
7
|
|
3
8
|
# Patch or add methods for Element instance
|
4
9
|
Selenium::WebDriver::Element.class_eval do
|
5
|
-
def
|
6
|
-
|
10
|
+
def id
|
11
|
+
ref
|
7
12
|
end
|
8
13
|
|
9
14
|
# Scroll on an element with its id
|
10
15
|
# @param id [String], direction [String] up, down, left, right
|
11
16
|
# @return {}
|
12
17
|
def scroll(direction)
|
13
|
-
bridge.element_scroll
|
18
|
+
bridge.element_scroll self, direction
|
14
19
|
end
|
15
20
|
|
16
21
|
# Get wdRect by id
|
@@ -22,23 +27,23 @@ Selenium::WebDriver::Element.class_eval do
|
|
22
27
|
|
23
28
|
# Get element type attribute
|
24
29
|
# @return [String] example: "XCUIElementTypePageIndicator", "XCUIElementTypeButton"
|
25
|
-
def
|
30
|
+
def tag_name
|
26
31
|
bridge.element_tag_name @id
|
27
32
|
end
|
28
33
|
|
29
34
|
# Get element value attribute
|
30
35
|
def value
|
31
|
-
bridge.element_attribute
|
36
|
+
bridge.element_attribute self, 'value'
|
32
37
|
end
|
33
38
|
|
34
39
|
# Get element name attribute
|
35
40
|
def name
|
36
|
-
bridge.element_attribute
|
41
|
+
bridge.element_attribute self, 'name'
|
37
42
|
end
|
38
43
|
|
39
44
|
# Get element name attribute
|
40
45
|
def label
|
41
|
-
bridge.element_attribute
|
46
|
+
bridge.element_attribute self, 'label'
|
42
47
|
end
|
43
48
|
|
44
49
|
# Get the value of a the given attribute of the element.
|
@@ -47,7 +52,7 @@ Selenium::WebDriver::Element.class_eval do
|
|
47
52
|
# @return [String,nil]
|
48
53
|
# attribute value
|
49
54
|
def attribute(name)
|
50
|
-
bridge.element_attribute
|
55
|
+
bridge.element_attribute self, name
|
51
56
|
end
|
52
57
|
|
53
58
|
end
|
data/lib/wda_lib/alert.rb
CHANGED
data/lib/wda_lib/custom.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
class WDA
|
2
6
|
module Custome
|
3
7
|
|
@@ -17,16 +21,16 @@ class WDA
|
|
17
21
|
end
|
18
22
|
|
19
23
|
# Timeout(without Session)
|
20
|
-
# @param
|
24
|
+
# @param duration [Float] the timeout in milliseconds
|
21
25
|
# @return [void]
|
22
|
-
def timeout(
|
26
|
+
def timeout(duration)
|
23
27
|
post(@base_url + '/timeout', { type: 'xctevent', ms: duration })
|
24
28
|
end
|
25
29
|
|
26
30
|
# Timeout(with Session)
|
27
31
|
# @param duration [Float] the timeout in milliseconds
|
28
32
|
# @return [void]
|
29
|
-
def timeout_in_session(
|
33
|
+
def timeout_in_session(duration)
|
30
34
|
post '/timeout', { type: 'xctevent', ms: duration }
|
31
35
|
end
|
32
36
|
|
data/lib/wda_lib/debug.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
class WDA
|
2
6
|
module Debug
|
3
7
|
|
4
8
|
# Get all elements on current screen
|
5
|
-
# @param
|
9
|
+
# @param session_id [String], accessible [Boolean], visible [Boolean]
|
6
10
|
# When accessible is true, ignore all elements except for the main window for accessibility tree
|
7
11
|
# When accessible is false, and visible is true, ignore all invisible elements
|
8
12
|
# @return [Hash]
|
@@ -28,13 +32,12 @@ class WDA
|
|
28
32
|
|
29
33
|
# Had issue when there is app shortcut in SIRI search or Today's extention,
|
30
34
|
# having duplication app text, have to find the visibile one
|
35
|
+
# Try to find app on current screen, if can't find, click home button to get first page of springboard
|
31
36
|
def find_app(app_name)
|
32
|
-
max =
|
37
|
+
max = 0
|
33
38
|
app_found = false
|
34
39
|
app = nil
|
35
|
-
homescreen
|
36
40
|
while !app_found && max < 10 do
|
37
|
-
max += 1
|
38
41
|
icons(app_name).each do |e|
|
39
42
|
app = e
|
40
43
|
if e.displayed?
|
@@ -43,7 +46,9 @@ class WDA
|
|
43
46
|
end
|
44
47
|
end
|
45
48
|
break if app_found
|
49
|
+
homescreen if max == 1 # Get back to first page if first try failed
|
46
50
|
swipe(@win_x*4/5, 10, @win_y/2, @win_y/2)
|
51
|
+
max += 1
|
47
52
|
end
|
48
53
|
|
49
54
|
app.nil?? (fail "Can't find app :#{app_name}") : app
|
data/lib/wda_lib/element.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
class WDA
|
2
6
|
class Element
|
3
7
|
|
@@ -20,112 +24,101 @@ class WDA
|
|
20
24
|
end
|
21
25
|
|
22
26
|
# Check if element is enabled?
|
23
|
-
# @
|
24
|
-
# @return isEnabled? [Boolean]
|
27
|
+
# @return is isEnabled? [Boolean]
|
25
28
|
def enabled?
|
26
29
|
client.get('/element/' + eid + '/enabled')['value']
|
27
30
|
end
|
28
31
|
|
29
32
|
# Get wdRect by id
|
30
|
-
# @
|
31
|
-
# @return wdRect
|
33
|
+
# @return is wdRect
|
32
34
|
def rect
|
33
35
|
client.get('/element/' + eid + '/rect')['value']
|
34
36
|
end
|
35
37
|
|
36
38
|
# Get attribute value
|
37
|
-
# @param
|
38
|
-
# @return attributeValue [String]
|
39
|
+
# @param name [String]
|
40
|
+
# @return is attributeValue [String]
|
39
41
|
def attribute(name)
|
40
42
|
client.get '/element/' + eid + '/attribute/' + name
|
41
43
|
end
|
42
44
|
|
43
45
|
# Get text from an element(StaticText or Button)
|
44
|
-
# @
|
45
|
-
# @return text [String]
|
46
|
+
# @return is text [String]
|
46
47
|
def text
|
47
48
|
client.get('/element/' + eid + '/text')['value']
|
48
49
|
end
|
49
50
|
|
50
51
|
# Check if element is displayed?
|
51
|
-
# @
|
52
|
-
# @return isVisible? [Boolean]
|
52
|
+
# @return is isVisible? [Boolean]
|
53
53
|
def displayed?
|
54
54
|
client.get('/element/' + eid + '/displayed')['value']
|
55
55
|
end
|
56
56
|
|
57
57
|
# Check if element is accessible?
|
58
|
-
# @param id [String] Element uuid
|
59
58
|
# @return is accessible? [Boolean]
|
60
59
|
def accessible?
|
61
60
|
client.get('/element/' + eid + '/accessible')['value']
|
62
61
|
end
|
63
62
|
|
64
63
|
# Check if element is accessibilityContainer?
|
65
|
-
# @param id [String] Element uuid
|
66
64
|
# @return is accessibilityContainer? [Boolean]
|
67
65
|
def accessible_container?
|
68
66
|
client.get('/element/' + eid + '/accessibilityContainer')['value']
|
69
67
|
end
|
70
68
|
|
71
69
|
# Get type from an element, ex: type => "Icon"(XCUIElementTypeIcon)
|
72
|
-
# @
|
73
|
-
# @return type [String]
|
70
|
+
# @return is type [String]
|
74
71
|
def type
|
75
72
|
client.get('/element/' + eid + '/name')['value']
|
76
73
|
end
|
77
74
|
|
78
75
|
# Set value to an element
|
79
|
-
# @param
|
76
|
+
# @param value [String]
|
80
77
|
# @return element uuid [String]
|
81
78
|
def send_keys(value)
|
82
79
|
client.post '/element/' + eid + '/value', { value: value.chars }
|
83
80
|
end
|
84
81
|
|
85
82
|
# Tap on an element with its id
|
86
|
-
# @param id [String] Element uuid
|
87
83
|
# @return element uuid [String]
|
88
84
|
def click
|
89
85
|
client.post '/element/' + eid + '/click'
|
90
86
|
end
|
91
87
|
|
92
88
|
# Clearing text of an given element
|
93
|
-
# @param id [String] Element uuid
|
94
89
|
# @return element uuid [String]
|
95
90
|
def clear
|
96
91
|
client.post '/element/' + eid + '/clear'
|
97
92
|
end
|
98
93
|
|
99
94
|
# Double tap on an element with its id
|
100
|
-
# @param id [String] Element uuid
|
101
95
|
# @return element uuid [String]
|
102
96
|
def double_tap
|
103
97
|
client.post '/uiaElement/' + eid + '/doubleTap'
|
104
98
|
end
|
105
99
|
|
106
100
|
# Two finger tap on an element with its id
|
107
|
-
# @param id [String] Element uuid
|
108
101
|
# @return element uuid [String]
|
109
102
|
def two_finger_tap
|
110
103
|
client.post '/uiaElement/' + eid + '/twoFingerTap'
|
111
104
|
end
|
112
105
|
|
113
106
|
# Touch and hold on for a while finger tap on an element with its id
|
114
|
-
# @param
|
107
|
+
# @param duration [Double]
|
115
108
|
# @return element uuid [String]
|
116
109
|
def touch_hold(duration)
|
117
110
|
client.post '/uiaElement/' + eid + '/touchAndHold', { duration: duration }
|
118
111
|
end
|
119
112
|
|
120
113
|
# Scroll on an element with its id
|
121
|
-
# @param
|
114
|
+
# @param direction [String] up, down, left, right
|
122
115
|
# @return [Hash]
|
123
116
|
def scroll(direction = nil)
|
124
117
|
client.post '/uiaElement/' + eid + '/scroll', { direction: direction }
|
125
118
|
end
|
126
119
|
|
127
120
|
# Drag on an element with its id and position
|
128
|
-
# @param
|
121
|
+
# @param toX [String], toY [String], duration [Double]
|
129
122
|
def drag_to(toX, toY, duration = 0)
|
130
123
|
fromX = location[:x]
|
131
124
|
fromY = location[:y]
|
@@ -155,13 +148,13 @@ class WDA
|
|
155
148
|
end
|
156
149
|
|
157
150
|
# Swipe on an element with its id and position
|
158
|
-
# @param [Integer]
|
151
|
+
# @param fromX [Integer], toX [Integer], fromY [Integer], toY [Integer]
|
159
152
|
def swipe(fromX, toX, fromY, toY)
|
160
153
|
post '/uiaTarget/0/dragfromtoforduration', { fromX: fromX, toX: toX, fromY: fromY, toY: toY, duration: 0 }
|
161
154
|
end
|
162
155
|
|
163
156
|
# Tap on a given positon
|
164
|
-
# @param
|
157
|
+
# @param x [Integer], y [Integer]
|
165
158
|
def tap_on(x, y)
|
166
159
|
post '/tap/0', { x: x, y: y }
|
167
160
|
end
|
@@ -180,5 +173,4 @@ class WDA
|
|
180
173
|
Dimension.new(win_size['width'], win_size['height'])
|
181
174
|
end
|
182
175
|
|
183
|
-
end
|
184
|
-
|
176
|
+
end
|
data/lib/wda_lib/error.rb
CHANGED
data/lib/wda_lib/find_element.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
class WDA
|
2
6
|
module FindElement
|
3
7
|
### Searching for elements
|
@@ -76,49 +80,49 @@ class WDA
|
|
76
80
|
|
77
81
|
# Search with given name
|
78
82
|
# @param value [String]
|
79
|
-
# @
|
83
|
+
# @return [Hash]
|
80
84
|
def name(value)
|
81
85
|
find :name, value
|
82
86
|
end
|
83
87
|
|
84
88
|
# Search all element with given name
|
85
89
|
# @param value [String]
|
86
|
-
# @
|
90
|
+
# @return [Array]
|
87
91
|
def names(value)
|
88
92
|
finds :name, value
|
89
93
|
end
|
90
94
|
|
91
95
|
# Search with given id
|
92
96
|
# @param value [String]
|
93
|
-
# @
|
97
|
+
# @return [Hash]
|
94
98
|
def id(value)
|
95
99
|
find :id, value
|
96
100
|
end
|
97
101
|
|
98
102
|
# Search all element with given id
|
99
103
|
# @param value [String]
|
100
|
-
# @
|
104
|
+
# @return [Array]
|
101
105
|
def ids(value)
|
102
106
|
finds :id, value
|
103
107
|
end
|
104
108
|
|
105
109
|
# Search with given accessibility_id
|
106
110
|
# @param value [String]
|
107
|
-
# @
|
111
|
+
# @return [Hash]
|
108
112
|
def accessibility_id(value)
|
109
113
|
find :accessibility_id, value
|
110
114
|
end
|
111
115
|
|
112
116
|
# Search all element with given accessibility_id
|
113
117
|
# @param value [String]
|
114
|
-
# @
|
118
|
+
# @return [Array]
|
115
119
|
def accessibility_ids(value)
|
116
120
|
finds :accessibility_id, value
|
117
121
|
end
|
118
122
|
|
119
123
|
# Search with given value (Complete value)
|
120
124
|
# @param value [String]
|
121
|
-
# @
|
125
|
+
# @return [Hash]
|
122
126
|
def text(value)
|
123
127
|
find :link_text, "label=#{value}"
|
124
128
|
end
|
@@ -132,7 +136,7 @@ class WDA
|
|
132
136
|
|
133
137
|
# Search with given partial value (partial link text)
|
134
138
|
# @param value [String]
|
135
|
-
# @
|
139
|
+
# @return [Hash]
|
136
140
|
def partial_text(value)
|
137
141
|
find :partial_link_text, "label=#{value}"
|
138
142
|
end
|
@@ -178,7 +182,7 @@ class WDA
|
|
178
182
|
end
|
179
183
|
|
180
184
|
# Search predicate string, return first found element
|
181
|
-
# @param
|
185
|
+
# @param predicate_value [String] 'isWDVisible=1'
|
182
186
|
# example: 'isWDAccessible=1', 'isWDEnabled=0'
|
183
187
|
# @return [Hash]
|
184
188
|
def predicate_text(predicate_value)
|
@@ -186,7 +190,7 @@ class WDA
|
|
186
190
|
end
|
187
191
|
|
188
192
|
# Search with predicate string
|
189
|
-
# @param
|
193
|
+
# @param predicate_value [String] 'isWDVisible=1'
|
190
194
|
# example: 'isWDAccessible=1', 'isWDEnabled=0', 'isWDAccessibilityContainer=1'
|
191
195
|
# @return [Array]
|
192
196
|
def predicate_texts(predicate_value)
|
@@ -404,5 +408,4 @@ class WDA
|
|
404
408
|
@timeout = second
|
405
409
|
end
|
406
410
|
end
|
407
|
-
end
|
408
|
-
|
411
|
+
end
|
data/lib/wda_lib/orientation.rb
CHANGED
data/lib/wda_lib/screenshot.rb
CHANGED
data/lib/wda_lib/session.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
class WDA
|
2
6
|
module Session
|
3
7
|
|
@@ -11,8 +15,8 @@ class WDA
|
|
11
15
|
end
|
12
16
|
|
13
17
|
# Update current running sessionId to @session_id
|
14
|
-
# @param
|
15
|
-
# @return
|
18
|
+
# @param status_response [object] : http GET session response body
|
19
|
+
# @return [object]
|
16
20
|
def update_status(status_response)
|
17
21
|
@session_valid = true
|
18
22
|
@session_id = status_response['sessionId']
|
@@ -37,14 +41,14 @@ class WDA
|
|
37
41
|
end
|
38
42
|
else
|
39
43
|
@session_id = response['sessionId']
|
40
|
-
@caps[:
|
41
|
-
@caps[:
|
44
|
+
@caps[:desired_capabilities][:session_id] = @session_id
|
45
|
+
@caps[:desired_capabilities][:session_valid] = true
|
42
46
|
@url = @base_url + "/session/#{@session_id}"
|
43
47
|
end
|
44
48
|
response
|
45
49
|
end
|
46
50
|
|
47
|
-
# Post
|
51
|
+
# Post desired_capabilities to wda server to create a session
|
48
52
|
# This is not realy needed since we can find and click app icon to start app
|
49
53
|
# @return [self]
|
50
54
|
def launch_app(app_name_or_id)
|
@@ -54,9 +58,9 @@ class WDA
|
|
54
58
|
@session_id = nil # Prepare to create new session
|
55
59
|
@session_valid = false # Prepare to create new session
|
56
60
|
post(@base_url + '/session', { desiredCapabilities: { bundleId: app_name_or_id }})
|
57
|
-
|
58
|
-
|
59
|
-
|
61
|
+
# Temporarily disabled
|
62
|
+
capabilities
|
63
|
+
@driver = Selenium::WebDriver::Driver.for(:remote, :url => @base_url, :desired_capabilities => @caps[:desired_capabilities])
|
60
64
|
else
|
61
65
|
app_name = app_name_or_id
|
62
66
|
find_app(app_name).click
|
@@ -76,7 +80,7 @@ class WDA
|
|
76
80
|
end
|
77
81
|
|
78
82
|
# Exit current app by delete session with given session_id
|
79
|
-
# @
|
83
|
+
# @param session_id [String]
|
80
84
|
# @return delete session response [Json]
|
81
85
|
def quit(session_id = nil)
|
82
86
|
(session_id.nil?)? sessionId = @session_id : sessionId = session_id
|
data/lib/wda_lib/touch_id.rb
CHANGED
data/lib/wda_lib/type.rb
CHANGED
data/lib/wda_lib/version.rb
CHANGED
data/lib/wda_lib.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
#
|
2
|
+
# Created by Yi MIN<yi@zen.ly>
|
3
|
+
# Copyright © 2016 Zenly. All rights reserved.
|
4
|
+
#
|
1
5
|
Dir[File.dirname(__FILE__) + '/wda_lib/*.rb'].each {|file| require file }
|
2
6
|
require 'json'
|
3
7
|
require 'httparty'
|
@@ -43,9 +47,15 @@ class WDA
|
|
43
47
|
# Start wda client
|
44
48
|
# opts = { caps: { bundleId: @bundle_id }, device_url: 'http://x.x.x.x:8100' }
|
45
49
|
# WDA.new(opts).start_session
|
46
|
-
def initialize(
|
50
|
+
def initialize(opt)
|
47
51
|
# fail 'opts should be a hash' unless opts.is_a? Hash
|
48
|
-
# fail 'bundleId should be provided' if opts[:
|
52
|
+
# fail 'bundleId should be provided' if opts[:bundle_id].nil?
|
53
|
+
if opt.is_a? String
|
54
|
+
url = opt
|
55
|
+
opts = {:device_url => url}
|
56
|
+
else
|
57
|
+
opts = opt
|
58
|
+
end
|
49
59
|
url = opts[:device_url] || BASE_URL
|
50
60
|
parsed_url = URI.parse(url)
|
51
61
|
@base_url = parsed_url.scheme + '://' + parsed_url.host + ':' + parsed_url.port.to_s
|
@@ -53,28 +63,34 @@ class WDA
|
|
53
63
|
@server_host = parsed_url.host
|
54
64
|
@server_port = parsed_url.port
|
55
65
|
@timeout = 10
|
66
|
+
@listener = opts.fetch :listener, nil
|
56
67
|
status
|
57
68
|
window_size
|
58
|
-
capabilities(opts)
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
p capabilities(opts)
|
70
|
+
@http_client ||= Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 999_999, read_timeout: 999_999)
|
71
|
+
@driver = Selenium::WebDriver.for(:remote,
|
72
|
+
http_client: @http_client,
|
73
|
+
:url => @base_url,
|
74
|
+
:desired_capabilities => @caps[:desired_capabilities],
|
75
|
+
:listener => @listener)
|
62
76
|
end
|
63
77
|
|
64
78
|
# Build desired_capabilities with options
|
65
79
|
# @param opts [Hash]
|
66
80
|
# @return attribute caps [Hash]
|
67
|
-
def capabilities(opts = {})
|
68
|
-
@bundle_id = opts[:
|
69
|
-
selenium_capabilities = Selenium::WebDriver::Remote::
|
70
|
-
browser_name: 'iphone',
|
81
|
+
def capabilities(opts = {})
|
82
|
+
@bundle_id = opts[:bundle_id] if !opts[:bundle_id].nil?
|
83
|
+
selenium_capabilities = Selenium::WebDriver::Remote::Capabilities.new(
|
71
84
|
platform_name: @platform_name,
|
72
85
|
platform_version: @platform_version,
|
73
86
|
session_id: @session_id,
|
74
87
|
session_valid: @session_valid,
|
75
|
-
bundleId: @bundle_id
|
88
|
+
bundleId: @bundle_id,
|
89
|
+
javascript_enabled: true,
|
90
|
+
takes_screenshot: true,
|
91
|
+
css_selectors_enabled: true
|
76
92
|
)
|
77
|
-
@caps = {
|
93
|
+
@caps = { desired_capabilities: selenium_capabilities }
|
78
94
|
end
|
79
95
|
|
80
96
|
# HTTP methods for dealing with all supported motheds in FB WDA
|
data/wda_lib.gemspec
CHANGED
@@ -17,11 +17,11 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.homepage =
|
19
19
|
'https://github.com/znly/wda'
|
20
|
-
s.license = '
|
20
|
+
s.license = 'Apache-2.0'
|
21
21
|
|
22
22
|
s.add_development_dependency "rake", "~> 10.0"
|
23
23
|
s.add_development_dependency "rspec", "~> 3.5"
|
24
24
|
s.add_dependency "bundler", "~> 1.12"
|
25
25
|
s.add_dependency "httparty", "~> 0.14"
|
26
|
-
s.add_dependency "selenium-webdriver", "~>
|
26
|
+
s.add_dependency "selenium-webdriver", "~> 3.0"
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wda_lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MIN Yi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '3.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '3.0'
|
83
83
|
description: A simple ruby lib of binding methods for WebDriverAgent
|
84
84
|
email: yi@zen.ly
|
85
85
|
executables: []
|
@@ -89,12 +89,13 @@ files:
|
|
89
89
|
- ".gitignore"
|
90
90
|
- ".rspec"
|
91
91
|
- Gemfile
|
92
|
+
- LICENSE
|
92
93
|
- README.md
|
93
94
|
- example/multiple_devices.rb
|
94
95
|
- example/single_device.rb
|
95
|
-
- lib/selenium_patch/
|
96
|
+
- lib/selenium_patch/bridge_patch.rb
|
97
|
+
- lib/selenium_patch/commands_patch.rb
|
96
98
|
- lib/selenium_patch/element_patch.rb
|
97
|
-
- lib/selenium_patch/w3c_bridge_patch.rb
|
98
99
|
- lib/wda_lib.rb
|
99
100
|
- lib/wda_lib/alert.rb
|
100
101
|
- lib/wda_lib/custom.rb
|
@@ -112,7 +113,7 @@ files:
|
|
112
113
|
- wda_lib.gemspec
|
113
114
|
homepage: https://github.com/znly/wda
|
114
115
|
licenses:
|
115
|
-
-
|
116
|
+
- Apache-2.0
|
116
117
|
metadata: {}
|
117
118
|
post_install_message:
|
118
119
|
rdoc_options: []
|
@@ -1,136 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
#
|
3
|
-
# Licensed to the Software Freedom Conservancy (SFC) under one
|
4
|
-
# or more contributor license agreements. See the NOTICE file
|
5
|
-
# distributed with this work for additional information
|
6
|
-
# regarding copyright ownership. The SFC licenses this file
|
7
|
-
# to you under the Apache License, Version 2.0 (the
|
8
|
-
# "License"); you may not use this file except in compliance
|
9
|
-
# with the License. You may obtain a copy of the License at
|
10
|
-
#
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
13
|
-
# Unless required by applicable law or agreed to in writing,
|
14
|
-
# software distributed under the License is distributed on an
|
15
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
16
|
-
# KIND, either express or implied. See the License for the
|
17
|
-
# specific language governing permissions and limitations
|
18
|
-
# under the License.
|
19
|
-
|
20
|
-
module Selenium
|
21
|
-
module WebDriver
|
22
|
-
module Remote
|
23
|
-
class W3CBridge
|
24
|
-
#
|
25
|
-
# http://www.w3.org/TR/2015/WD-webdriver-20150918/#list-of-endpoints
|
26
|
-
#
|
27
|
-
|
28
|
-
#
|
29
|
-
# session handling
|
30
|
-
#
|
31
|
-
|
32
|
-
command :newSession, :post, 'session'
|
33
|
-
command :deleteSession, :delete, 'session/:session_id'
|
34
|
-
|
35
|
-
#
|
36
|
-
# basic driver
|
37
|
-
#
|
38
|
-
|
39
|
-
command :get, :post, 'session/:session_id/url'
|
40
|
-
command :getCurrentUrl, :get, 'session/:session_id/url'
|
41
|
-
command :back, :post, 'session/:session_id/back'
|
42
|
-
command :forward, :post, 'session/:session_id/forward'
|
43
|
-
command :refresh, :post, 'session/:session_id/refresh'
|
44
|
-
command :getTitle, :get, 'session/:session_id/title'
|
45
|
-
|
46
|
-
#
|
47
|
-
# window and Frame handling
|
48
|
-
#
|
49
|
-
|
50
|
-
command :getWindowHandle, :get, 'session/:session_id/window'
|
51
|
-
command :closeWindow, :delete, 'session/:session_id/window'
|
52
|
-
command :switchToWindow, :post, 'session/:session_id/window'
|
53
|
-
command :getWindowHandles, :get, 'session/:session_id/window/handles'
|
54
|
-
command :fullscreenWindow, :post, 'session/:session_id/window/fullscreen'
|
55
|
-
command :maximizeWindow, :post, 'session/:session_id/window/maximize'
|
56
|
-
command :setWindowSize, :post, 'session/:session_id/window/size'
|
57
|
-
command :getWindowSize, :get, 'session/:session_id/window/size'
|
58
|
-
command :switchToFrame, :post, 'session/:session_id/frame'
|
59
|
-
command :switchToParentFrame, :post, 'session/:session_id/frame/parent'
|
60
|
-
|
61
|
-
#
|
62
|
-
# element
|
63
|
-
#
|
64
|
-
|
65
|
-
command :findElement, :post, 'session/:session_id/element'
|
66
|
-
command :findElements, :post, 'session/:session_id/elements'
|
67
|
-
command :findChildElement, :post, 'session/:session_id/element/:id/element'
|
68
|
-
command :findChildElements, :post, 'session/:session_id/element/:id/elements'
|
69
|
-
command :getActiveElement, :get, 'session/:session_id/element/active'
|
70
|
-
command :isElementSelected, :get, 'session/:session_id/element/:id/selected'
|
71
|
-
command :getElementAttribute, :get, 'session/:session_id/element/:id/attribute/:name'
|
72
|
-
command :getElementProperty, :get, 'session/:session_id/element/:id/property/:name'
|
73
|
-
command :getElementCssValue, :get, 'session/:session_id/element/:id/css/:property_name'
|
74
|
-
command :getElementText, :get, 'session/:session_id/element/:id/text'
|
75
|
-
command :getElementTagName, :get, 'session/:session_id/element/:id/name'
|
76
|
-
command :getElementRect, :get, 'session/:session_id/element/:id/rect'
|
77
|
-
command :isElementEnabled, :get, 'session/:session_id/element/:id/enabled'
|
78
|
-
|
79
|
-
#
|
80
|
-
# document handling
|
81
|
-
#
|
82
|
-
|
83
|
-
command :getPageSource, :get, '/session/:session_id/source'
|
84
|
-
command :executeScript, :post, 'session/:session_id/execute/sync'
|
85
|
-
command :executeAsyncScript, :post, 'session/:session_id/execute/async'
|
86
|
-
|
87
|
-
#
|
88
|
-
# cookies
|
89
|
-
#
|
90
|
-
|
91
|
-
command :getAllCookies, :get, 'session/:session_id/cookie'
|
92
|
-
command :getCookie, :get, 'session/:session_id/cookie/:name'
|
93
|
-
command :addCookie, :post, 'session/:session_id/cookie'
|
94
|
-
command :deleteCookie, :delete, 'session/:session_id/cookie/:name'
|
95
|
-
|
96
|
-
#
|
97
|
-
# timeouts
|
98
|
-
#
|
99
|
-
|
100
|
-
command :setTimeout, :post, 'session/:session_id/timeouts'
|
101
|
-
|
102
|
-
#
|
103
|
-
# actions
|
104
|
-
#
|
105
|
-
|
106
|
-
command :actions, :post, 'session/:session_id/actions'
|
107
|
-
|
108
|
-
#
|
109
|
-
# Element Operations
|
110
|
-
#
|
111
|
-
|
112
|
-
command :elementClick, :post, 'session/:session_id/element/:id/click'
|
113
|
-
command :elementTap, :post, 'session/:session_id/element/:id/tap'
|
114
|
-
command :elementClear, :post, 'session/:session_id/element/:id/clear'
|
115
|
-
command :elementSendKeys, :post, 'session/:session_id/element/:id/value'
|
116
|
-
command :elementScroll, :post, 'session/:session_id/uiaElement/:id/scroll'
|
117
|
-
|
118
|
-
#
|
119
|
-
# alerts
|
120
|
-
#
|
121
|
-
|
122
|
-
command :dismissAlert, :post, 'session/:session_id/alert/dismiss'
|
123
|
-
command :acceptAlert, :post, 'session/:session_id/alert/accept'
|
124
|
-
command :getAlertText, :get, 'session/:session_id/alert/text'
|
125
|
-
command :sendAlertText, :post, 'session/:session_id/alert/text'
|
126
|
-
|
127
|
-
#
|
128
|
-
# screenshot
|
129
|
-
#
|
130
|
-
|
131
|
-
command :takeScreenshot, :get, 'session/:session_id/screenshot'
|
132
|
-
command :takeElementScreenshot, :get, 'session/:session_id/element/:id/screenshot'
|
133
|
-
end
|
134
|
-
end # Remote
|
135
|
-
end # WebDriver
|
136
|
-
end # Selenium
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# Patch or add methods for Bridge. Called by Element instance or Bridge instance
|
2
|
-
|
3
|
-
Selenium::WebDriver::Remote::W3CBridge.class_eval do
|
4
|
-
# Patch W3CBridge create_session method
|
5
|
-
def create_session(desired_capabilities)
|
6
|
-
@session_id = desired_capabilities[:session_id]
|
7
|
-
if !desired_capabilities[:session_valid]
|
8
|
-
resp = raw_execute :newSession, {}, {desiredCapabilities: desired_capabilities}
|
9
|
-
desired_capabilities[:session_id] = resp['sessionId']
|
10
|
-
desired_capabilities[:session_valid] = true
|
11
|
-
@session_id = resp['sessionId']
|
12
|
-
end
|
13
|
-
return desired_capabilities
|
14
|
-
end
|
15
|
-
|
16
|
-
# Add element_scroll method
|
17
|
-
def element_scroll(element, direction)
|
18
|
-
execute :elementScroll, {id: element.values.first}, {direction: direction}
|
19
|
-
end
|
20
|
-
|
21
|
-
# Add element_rect method
|
22
|
-
def element_rect(element)
|
23
|
-
data = execute :getElementRect, id: element['ELEMENT']
|
24
|
-
return data
|
25
|
-
end
|
26
|
-
|
27
|
-
# Patch W3CBridge element_attribute method
|
28
|
-
def element_attribute(element, name)
|
29
|
-
execute :getElementAttribute, id: element['ELEMENT'], name: name
|
30
|
-
end
|
31
|
-
end
|