druid-ts 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +21 -0
- data/README.md +42 -32
- data/features/button.feature +1 -0
- data/features/element.feature +4 -0
- data/features/generic_elements.feature +24 -0
- data/features/html/multi_elements.html +4 -0
- data/features/html/nested_elements.html +3 -0
- data/features/html/static_elements.html +14 -1
- data/features/javascript.feature +6 -0
- data/features/label.feature +44 -0
- data/features/link.feature +1 -0
- data/features/multi_elements.feature +7 -0
- data/features/nested_elements.feature +4 -0
- data/features/page_level_actions.feature +12 -0
- data/features/select_list.feature +5 -3
- data/features/step_definations/element_steps.rb +14 -0
- data/features/step_definations/generic_element_steps.rb +19 -0
- data/features/step_definations/javasript_steps.rb +8 -0
- data/features/step_definations/label_steps.rb +19 -0
- data/features/step_definations/multi_elements_steps.rb +12 -0
- data/features/step_definations/nested_elements_steps.rb +9 -1
- data/features/step_definations/page_level_actions_steps.rb +17 -0
- data/features/step_definations/select_list_steps.rb +5 -0
- data/features/support/page.rb +21 -0
- data/lib/druid.rb +17 -0
- data/lib/druid/accessors.rb +110 -2
- data/lib/druid/assist.rb +26 -1
- data/lib/druid/element_locators.rb +42 -6
- data/lib/druid/elements.rb +2 -1
- data/lib/druid/elements/button.rb +1 -1
- data/lib/druid/elements/element.rb +1 -1
- data/lib/druid/elements/label.rb +11 -0
- data/lib/druid/elements/link.rb +1 -1
- data/lib/druid/nested_elements.rb +9 -1
- data/lib/druid/page_factory.rb +6 -0
- data/lib/druid/version.rb +1 -1
- data/spec/druid/accessors_spec.rb +48 -4
- data/spec/druid/druid_spec.rb +11 -0
- data/spec/druid/element_locators_spec.rb +12 -0
- data/spec/druid/elements/button_spec.rb +1 -1
- data/spec/druid/elements/label_spec.rb +19 -0
- data/spec/druid/elements/link_spec.rb +1 -1
- data/spec/druid/page_factory_spec.rb +26 -0
- metadata +12 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c83e03d267731768c34e5a6e686dc2105e9a94ad
|
4
|
+
data.tar.gz: b4f5d3fa5dac92cb3f107cd78d4cc7026ce4d7e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00a48ae184bbc2008cc8acd0c886690fd6b52b4854f7c1e2317ed02e6104e4e27fec356d75bdcbf9b714a38260973e36431a220ade40afc46058a40deef783bd
|
7
|
+
data.tar.gz: 9bedf55e94feacfa9b04eb2dcc6532b30fc36cc16071d9892c4720849c0f6337d145cd13605b9253554f0dea7bf15b64784b3c224f43240920793e427058a555
|
data/ChangeLog
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
=== 2016-12-26
|
2
|
+
* Enhancement
|
3
|
+
* Changed page_url to accept a symbol that will cause it to call a corresponding method
|
4
|
+
=== 2016-12-23
|
5
|
+
* Enhancement
|
6
|
+
* Added #execute_script method to Druid
|
7
|
+
* Added support for finding the following using :css
|
8
|
+
Button
|
9
|
+
Link
|
10
|
+
* Added method to fetch generic element
|
11
|
+
* Support alias method 'on' for 'on_page', 'visit' for 'visit_page' on PageFactory
|
12
|
+
* Changed Elements.element_class_for so parameters can be strings or symbols
|
13
|
+
* Added element_with_focus method to return the element that has focus
|
14
|
+
* Added support for the label element
|
15
|
+
=== 2016-12-20
|
16
|
+
* Fixes
|
17
|
+
WARNING: This change breaks existing code
|
18
|
+
* Changed the generated getter for select_list to return the text instead of the value
|
19
|
+
* Enhancements
|
20
|
+
* Added #expected_title method to Druid
|
21
|
+
* Added #expected_element method to Druid
|
1
22
|
=== Version 1.1.2 /2016-12-19
|
2
23
|
* Enhancements
|
3
24
|
* Added #include? and #selected? to SelectList
|
data/README.md
CHANGED
@@ -2,66 +2,76 @@
|
|
2
2
|
[![Build Status](https://travis-ci.org/timsheng/druid.png)](https://travis-ci.org/timsheng)
|
3
3
|
|
4
4
|
|
5
|
-
A simple gem that assists in creating flexible page objects for testing browser based applications.
|
5
|
+
A simple gem that assists in creating flexible page objects for testing browser based applications. The goal is to facilitate creating abstraction layers in your tests to decouple the tests from the item they are testing and to provide a simple interface to the elements on a page. It works with watir-webdriver
|
6
6
|
|
7
7
|
### Defining your page object
|
8
8
|
|
9
9
|
You define a new druid by including the Druid module:
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
````ruby
|
12
|
+
class LoginPage
|
13
|
+
include Druid
|
14
|
+
end
|
15
|
+
````
|
14
16
|
|
15
17
|
When you include this module numerous methods are added to your class that allow you to easily define your page. For the login page you might add the following:
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
````ruby
|
20
|
+
class LoginPage
|
21
|
+
include Druid
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
text_field(:username, :id => 'username')
|
24
|
+
text_field(:password, :id => 'password')
|
25
|
+
button(:login, :id => 'login')
|
26
|
+
end
|
27
|
+
````
|
24
28
|
|
25
29
|
Calling the _text_field_ and _button_ methods adds several methods to our druid that allow us to interact with the items on the page. To login using this page we could simply write the following code:
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
31
|
+
````ruby
|
32
|
+
login_page.username = 'cheezy'
|
33
|
+
login_page.password = 'secret'
|
34
|
+
login_page.login
|
35
|
+
````
|
30
36
|
|
31
37
|
Another approach might be to create higher level methods on our druid that hide the implementation details even further. Our druid might look like this:
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
39
|
+
````ruby
|
40
|
+
class LoginPage
|
41
|
+
include Druid
|
42
|
+
|
43
|
+
text_field(:username, :id => 'username')
|
44
|
+
text_field(:password, :id => 'password')
|
45
|
+
button(:login, :id => 'login')
|
46
|
+
|
47
|
+
def login_with(username, password)
|
48
|
+
self.username = username
|
49
|
+
self.password = password
|
50
|
+
login
|
51
|
+
end
|
52
|
+
end
|
53
|
+
````
|
47
54
|
and your usage of the page would become:
|
48
55
|
|
49
|
-
|
56
|
+
````ruby
|
57
|
+
login_page.login_with 'cheezy', 'secret'
|
58
|
+
````
|
50
59
|
|
51
60
|
### Creating your druid
|
52
61
|
druid supports [watir-webdriver](https://github.com/jarib/watir-webdriver)
|
53
62
|
The page object can be create like this:
|
54
63
|
|
55
|
-
|
56
|
-
|
57
|
-
|
64
|
+
````ruby
|
65
|
+
browser = Watir::Browser.new :firefox
|
66
|
+
my_druid = MyDruid.new(browser)
|
67
|
+
````
|
58
68
|
|
59
69
|
|
60
70
|
|
61
71
|
## Contribute
|
62
72
|
|
63
73
|
* Fork the project.
|
64
|
-
* Test drive your feature addition or bug fix.
|
74
|
+
* Test drive your feature addition or bug fix. Adding specs is important and I will not accept a pull request that does not have tests
|
65
75
|
* Make sure you describe your new feature with a cucumber feature.
|
66
76
|
* Commit, do not mess with rakefile, version, or history.
|
67
77
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
data/features/button.feature
CHANGED
data/features/element.feature
CHANGED
@@ -11,6 +11,10 @@ Feature: Elements
|
|
11
11
|
Then it should know it is not enabled
|
12
12
|
And it should know that it is disabled
|
13
13
|
|
14
|
+
Scenario: Setting focus and finding the element with focus
|
15
|
+
When I set the focus to the test text_field
|
16
|
+
Then I should know that the text_field has the focus
|
17
|
+
|
14
18
|
Scenario: Link element methods
|
15
19
|
When I retrieve a link element
|
16
20
|
Then I should know it exists
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Feature: Generic Elements
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on the static elements page
|
5
|
+
|
6
|
+
Scenario: Getting the text from the article element
|
7
|
+
When I get the text from the article
|
8
|
+
Then the text should be "HTML 5 Article"
|
9
|
+
|
10
|
+
Scenario: Getting the text from the header element
|
11
|
+
When I get the text from the header
|
12
|
+
Then the text should be "HTML 5 Header"
|
13
|
+
|
14
|
+
Scenario: Getting the text from the footer element
|
15
|
+
When I get the text from the footer
|
16
|
+
Then the text should be "HTML 5 Footer"
|
17
|
+
|
18
|
+
Scenario: Getting the text from the summary element
|
19
|
+
When I get the text from the summary
|
20
|
+
Then the text should be "The summary"
|
21
|
+
|
22
|
+
Scenario: Getting the text from the details element
|
23
|
+
When I get the text from the details
|
24
|
+
Then the text should be "The summary The details"
|
@@ -49,6 +49,10 @@
|
|
49
49
|
<span class="span">Span 2</span>
|
50
50
|
<span class="span">Span 3</span>
|
51
51
|
|
52
|
+
<label class="label">Label 1</label>
|
53
|
+
<label class="label">Label 2</label>
|
54
|
+
<label class="label">Label 3</label>
|
55
|
+
|
52
56
|
<table class="table" border='1'>
|
53
57
|
<tr>
|
54
58
|
<td class="td">Data 1</td>
|
@@ -12,7 +12,7 @@
|
|
12
12
|
|
13
13
|
<textarea rows="2" cols="20" id="text_area_id" class="text_area_class" name="text_area_name"></textarea>
|
14
14
|
|
15
|
-
<select name="sel_list_name" id="sel_list_id"
|
15
|
+
<select name="sel_list_name" id="sel_list_id" class="sel_list_class">
|
16
16
|
<option value="option1">Test 1</option>
|
17
17
|
<option value="option2">Test 2</option>
|
18
18
|
</select>
|
@@ -33,6 +33,10 @@
|
|
33
33
|
My alert
|
34
34
|
</span>
|
35
35
|
|
36
|
+
<label id="label_id" name="label_name" class="label_class">
|
37
|
+
page-object is the best!
|
38
|
+
</label>
|
39
|
+
|
36
40
|
<table id='table_id' name='table_name' class='table_class' border='1'>
|
37
41
|
<tr>
|
38
42
|
<td>Data1</td><td>Data2</td>
|
@@ -91,5 +95,14 @@
|
|
91
95
|
<a href="success.html" id="child">Success</a>
|
92
96
|
</div>
|
93
97
|
|
98
|
+
<article id="article_id">HTML 5 Article</article>
|
99
|
+
<header id="header_id">HTML 5 Header</header>
|
100
|
+
<footer id="footer_id">HTML 5 Footer</footer>
|
101
|
+
|
102
|
+
<details id="details_id">
|
103
|
+
<summary id="summary_id">The summary</summary>
|
104
|
+
The details
|
105
|
+
</details>
|
106
|
+
|
94
107
|
</body>
|
95
108
|
</html>
|
data/features/javascript.feature
CHANGED
@@ -11,3 +11,9 @@ Feature: Handling javascript events
|
|
11
11
|
Given I am on the Prototype example page
|
12
12
|
When I ask to compute "2+2"
|
13
13
|
Then I should be able to wait for the answer "4"
|
14
|
+
|
15
|
+
Scenario: Executing javascript in the browser
|
16
|
+
Given I am on the static elements page
|
17
|
+
Given I execute the javascript "return 2 + 2;"
|
18
|
+
Then I should get the answer "4"
|
19
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Feature: Handling labels with page object
|
2
|
+
|
3
|
+
In order to interact with labels,
|
4
|
+
Testers will need to access the element
|
5
|
+
and the ability to interrogate
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given I am on the static elements page
|
9
|
+
|
10
|
+
Scenario: Getting the text from a label
|
11
|
+
When I get the text from the label
|
12
|
+
Then the text should be "page-object is the best!"
|
13
|
+
|
14
|
+
Scenario: Getting the label element
|
15
|
+
When I retrieve the label element
|
16
|
+
Then I should know it exists
|
17
|
+
And I should know it is visible
|
18
|
+
|
19
|
+
Scenario Outline: Locating labels on the page
|
20
|
+
When I search for the label by "<search_by>"
|
21
|
+
Then the text should be "page-object is the best!"
|
22
|
+
|
23
|
+
Examples:
|
24
|
+
| search_by |
|
25
|
+
| id |
|
26
|
+
| class |
|
27
|
+
| xpath |
|
28
|
+
| index |
|
29
|
+
| name |
|
30
|
+
| text |
|
31
|
+
|
32
|
+
Scenario Outline: Locating lables using multiple parameters
|
33
|
+
When I search for the label by "<param1>" and "<param2>"
|
34
|
+
Then the text should be "page-object is the best!"
|
35
|
+
|
36
|
+
Examples:
|
37
|
+
| param1 | param2 |
|
38
|
+
| class | index |
|
39
|
+
| name | index |
|
40
|
+
|
41
|
+
Scenario: Finding a label dynamically
|
42
|
+
When I get the text from a label while the script is executing
|
43
|
+
Then I should see that the label exists
|
44
|
+
And the text should be "page-object is the best!"
|
data/features/link.feature
CHANGED
@@ -171,3 +171,10 @@ Feature: Multi Elements
|
|
171
171
|
And the text for paragraph 1 should be "Paragraph One"
|
172
172
|
And the text for paragraph 2 should be "Paragraph Two"
|
173
173
|
And the text for paragraph 3 should be "Paragraph Three"
|
174
|
+
|
175
|
+
Scenario: Selecting labels
|
176
|
+
When I select the labels with class "label"
|
177
|
+
Then I should have 3 labels
|
178
|
+
And the text for label 1 should be "Label 1"
|
179
|
+
And the text for label 2 should be "Label 2"
|
180
|
+
And the text for label 3 should be "Label 3"
|
@@ -104,6 +104,10 @@ Feature: Nested Elements
|
|
104
104
|
When I search for a file field located in a div
|
105
105
|
Then I should be able to retrieve the nested file field
|
106
106
|
|
107
|
+
Scenario: Finding a label within a div
|
108
|
+
When I search for a label located in a div
|
109
|
+
Then I should see the nested labels text should be "page-object is the best!"
|
110
|
+
|
107
111
|
Scenario: Unordered list nested in another Unordered list
|
108
112
|
When I get the outter unordered list
|
109
113
|
Then I should see "One" for list item 1
|
@@ -30,6 +30,18 @@ Feature: Page level actions
|
|
30
30
|
Given I can goto baidu.com using visit_page with block
|
31
31
|
Then the page should have the title "百度" using on_page with block
|
32
32
|
|
33
|
+
Scenario: Validating the page title
|
34
|
+
Given I am on the static elements page
|
35
|
+
Then the page should have the expected title
|
36
|
+
|
37
|
+
Scenario: Validating the expected element
|
38
|
+
Given I am on the static elements page
|
39
|
+
Then the page should have the expected element
|
40
|
+
|
41
|
+
Scenario: Validating that an expected element does not exist
|
42
|
+
Given I am on the static elements page
|
43
|
+
Then the page should not have the expected element
|
44
|
+
|
33
45
|
Scenario: Waiting for something
|
34
46
|
Given I am on the static elements page
|
35
47
|
Then I should be able to wait for a block to return true
|
@@ -7,12 +7,13 @@ Feature: Select List
|
|
7
7
|
|
8
8
|
Scenario: Selecting an element on the select list
|
9
9
|
When I select "Test 2" from the select list
|
10
|
-
Then the current item should be "
|
10
|
+
Then the current item should be "Test 2"
|
11
11
|
|
12
12
|
Scenario Outline: Locating select lists on the Page
|
13
13
|
When I locate the select list by "<locate_by>"
|
14
14
|
Then I should be able to select "Test 2"
|
15
|
-
And the value for the selected item should be "
|
15
|
+
And the value for the selected item should be "Test 2"
|
16
|
+
And the value for the option should be "option2"
|
16
17
|
|
17
18
|
Examples:
|
18
19
|
| locate_by |
|
@@ -40,7 +41,8 @@ Feature: Select List
|
|
40
41
|
Scenario Outline: Locating a select list using multiple parameters
|
41
42
|
When I search for the select list bys "<param1>" and "<param2>"
|
42
43
|
Then I should be able to select "Test 2"
|
43
|
-
And the value for the selected item should be "
|
44
|
+
And the value for the selected item should be "Test 2"
|
45
|
+
And the value for the option should be "option2"
|
44
46
|
|
45
47
|
Examples:
|
46
48
|
| param1 | param2 |
|
@@ -89,3 +89,17 @@ end
|
|
89
89
|
Then(/^it should know that it is disabled$/) do
|
90
90
|
expect(@element).to be_disabled
|
91
91
|
end
|
92
|
+
|
93
|
+
When(/^I set the focus to the test text_field$/) do
|
94
|
+
@page.text_field_element(:id => 'onfocus_text_field').focus
|
95
|
+
end
|
96
|
+
|
97
|
+
Then(/^I should know that the text_field has the focus$/) do
|
98
|
+
element = @page.element_with_focus
|
99
|
+
expect(element).not_to be nil
|
100
|
+
expect(element.class).to be Druid::Elements::TextField
|
101
|
+
end
|
102
|
+
|
103
|
+
When(/^I retrieve the label element$/) do
|
104
|
+
@element = @page.label_id_element
|
105
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
When(/^I get the text from the article$/) do
|
2
|
+
@text = @page.article_id
|
3
|
+
end
|
4
|
+
|
5
|
+
When(/^I get the text from the header$/) do
|
6
|
+
@text = @page.header_id
|
7
|
+
end
|
8
|
+
|
9
|
+
When(/^I get the text from the footer$/) do
|
10
|
+
@text = @page.footer_id
|
11
|
+
end
|
12
|
+
|
13
|
+
When(/^I get the text from the summary$/) do
|
14
|
+
@text = @page.summary_id
|
15
|
+
end
|
16
|
+
|
17
|
+
When(/^I get the text from the details$/) do
|
18
|
+
@text = @page.details_id
|
19
|
+
end
|
@@ -27,3 +27,11 @@ Then(/^I should be able to wait for the answer "([^"]*)"$/) do |answer|
|
|
27
27
|
@page.wait_for_ajax
|
28
28
|
expect(@page.results).to eql answer
|
29
29
|
end
|
30
|
+
|
31
|
+
Given(/^I execute the javascript "([^"]*)"$/) do |script|
|
32
|
+
@answer = @page.execute_script script
|
33
|
+
end
|
34
|
+
|
35
|
+
Then(/^I should get the answer "([^"]*)"$/) do |answer|
|
36
|
+
expect(@answer).to eql answer.to_i
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
When(/^I get the text from the label$/) do
|
2
|
+
@text = @page.label_id
|
3
|
+
end
|
4
|
+
|
5
|
+
When(/^I search for the label by "([^"]*)"$/) do |how|
|
6
|
+
@text = @page.send "label_#{how}".to_sym
|
7
|
+
end
|
8
|
+
|
9
|
+
When(/^I search for the label by "([^"]*)" and "([^"]*)"$/) do |param1, param2|
|
10
|
+
@text = @page.send "label_#{param1}_#{param2}".to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
When(/^I get the text from a label while the script is executing$/) do
|
14
|
+
@text = @page.label_element(:id => 'label_id').text
|
15
|
+
end
|
16
|
+
|
17
|
+
Then(/^I should see that the label exists$/) do
|
18
|
+
expect(@page.label_id?).to be true
|
19
|
+
end
|