page_magic 1.0.0.alpha3 → 1.0.0.alpha4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +183 -1
- data/VERSION +1 -1
- data/lib/page_magic/elements.rb +2 -1
- data/spec/page_magic/session_spec.rb +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a6a5a8192c367103828b5dd1a471cd38f8d2440
|
4
|
+
data.tar.gz: 93107e43e4697a659d38e6d41875c52698e6caf9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fb9a1fc03dca9d10af4b854d0f968de74b57269bcfd2d6bf8e6f8db452e336173096e678a4619f8c55be8fc2234016369ff6cd66209a7e023590e5d16d4e8af
|
7
|
+
data.tar.gz: 676d99b55ed4baa40dc576a6277393f54e9d77225f9f8f73a3680d7a290a5d44fd89c515144e94d5d559643ab386adcf099ad64a135cdc4ab6482eefd2576b72
|
data/README.md
CHANGED
@@ -3,4 +3,186 @@ PageMagic is an API for testing web applications.
|
|
3
3
|
|
4
4
|
It has a simple but powerful DSL which makes modelling and interacting with your pages easy.
|
5
5
|
|
6
|
-
|
6
|
+
Wouldn't it be great if there was a framework that could:
|
7
|
+
- Model your pages
|
8
|
+
- Define custom wait activity that should occur before or after you interact with a page element at the point the element is defined
|
9
|
+
- Map the paths to pages so that when you transition from one page to another, you don't have to do awkward things to work out which page object you need to use next?
|
10
|
+
- Be really really dynamic so that you could do even more things at runtime?
|
11
|
+
|
12
|
+
Well PageMagic might just be the answer!
|
13
|
+
|
14
|
+
Give it a try and let us know what you think! It's there will undoubtedly be things that can be improved and issues that we are not aware of so your feedback/pull requests are greatly appreciated!
|
15
|
+
|
16
|
+
# Installation
|
17
|
+
`gem install page_magic --pre`
|
18
|
+
|
19
|
+
# An Example
|
20
|
+
Imagine the scene. You've written a web based mail client and now you want to test it...
|
21
|
+
You have a scenario in mind that goes something along the lines of:
|
22
|
+
- Send yourself an email with a unique subject
|
23
|
+
- Go to the Login page and login
|
24
|
+
- Find the message using it's unique subject and read it
|
25
|
+
- delete the message
|
26
|
+
|
27
|
+
You're mail client is total 21st century so there is loads of lovely ajax etc...
|
28
|
+
|
29
|
+
Writing robust, nice looking code for this could be a real pain...
|
30
|
+
Here's how you might do it with PageMagic (note that the following code would work if we you had a compatible mail web app but in this case is purely illustrative)
|
31
|
+
|
32
|
+
What we really want to write is something like
|
33
|
+
```ruby
|
34
|
+
test_subject = send_test_mail('test@21st-century-mail.com')
|
35
|
+
#Visit your site using a PageMagic session we prepared earlier
|
36
|
+
session.visit(LoginPage, url: 'https://21st-century-mail.com')
|
37
|
+
|
38
|
+
#Login using some handy helper method on our page object
|
39
|
+
session.login('username', 'password')
|
40
|
+
|
41
|
+
#Find the message amongst all the other messages that are on screen and read it
|
42
|
+
session.message(subject: test_subject).read.click
|
43
|
+
|
44
|
+
#Now we are on the message screen lets delete it without having to worry about the ajax.
|
45
|
+
session.delete_message
|
46
|
+
|
47
|
+
fail "message is still there!" if session.message(subject: test_subject).exists?
|
48
|
+
|
49
|
+
# Sweet :)
|
50
|
+
```
|
51
|
+
## Starting a session
|
52
|
+
To start a PageMagic session simply decide what browser you want to use and pass it to PageMagic's `.session` method
|
53
|
+
```ruby
|
54
|
+
session = PageMagic.session(browser: :chrome)
|
55
|
+
```
|
56
|
+
Out of the box, PageMagic knows how to work with:
|
57
|
+
- Chrome and Firefox
|
58
|
+
- poltergeist
|
59
|
+
- RackTest - Read more on testing rack compliant object's directly later on
|
60
|
+
|
61
|
+
Under the hood, PageMagic is using [Capybara](https://github.com/jnicklas/capybara) so you can register any Capybara specific driver you want. See below for how to do this.
|
62
|
+
|
63
|
+
**Note:** We don't want to impose particular driver versions so PageMagic does not list any as dependencies. Therefore you will need add the requiste gem to your Gemfile.
|
64
|
+
|
65
|
+
## Defining Pages
|
66
|
+
To define something that PageMagic can work with, simply include PageMagic in to a class. Here are the classes we would need for the example above.
|
67
|
+
```ruby
|
68
|
+
class LoginPage
|
69
|
+
include PageMagic
|
70
|
+
end
|
71
|
+
|
72
|
+
class MailBox
|
73
|
+
include PageMagic
|
74
|
+
end
|
75
|
+
|
76
|
+
class MessageView
|
77
|
+
include PageMagic
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
## Visiting a page
|
82
|
+
To use a page ojbect you need to 'visit' it.
|
83
|
+
```ruby
|
84
|
+
session.visit(LoginPage, url: 'https://21st-century-mail.com')
|
85
|
+
```
|
86
|
+
**Note:** soon you won't even have to specify the page class :)
|
87
|
+
|
88
|
+
##Defining elements
|
89
|
+
Your pages are going to have elements on them that you will want to interact with. In the case of the Login page, it's easy to imagine that it will have text fields for a username and password and a button to login in with.
|
90
|
+
```ruby
|
91
|
+
class LoginPage
|
92
|
+
include PageMagic
|
93
|
+
text_field(:username, label: 'username')
|
94
|
+
text_field(:password, label: 'password')
|
95
|
+
button(:login_button, text: 'login')
|
96
|
+
end
|
97
|
+
```
|
98
|
+
##Interacting with elements
|
99
|
+
Elements are defined with a id which is the name of the method you will use to reference it. In the above example, the textfields and button were defined with the id's, `:username`, `:password`, and `:login_button`
|
100
|
+
|
101
|
+
After visiting a page with a PageMagic session, you can access all of the elements of that page through the session itself.
|
102
|
+
```ruby
|
103
|
+
session.username.set 'joe@blogs.com'
|
104
|
+
session.password.set 'passw0rd'
|
105
|
+
session.login_button.click
|
106
|
+
```
|
107
|
+
##Defining helper methods
|
108
|
+
Using elements that are defined on a page is great, but if you are enacting a procedure through interacting with a few of them then your code could end up with some pretty repetitive code. In this case you can define helper methods instead.
|
109
|
+
|
110
|
+
In the above [example](#an example) we used a helper called `login`.
|
111
|
+
```ruby
|
112
|
+
class LoginPage
|
113
|
+
# ... code defining elements as shown above
|
114
|
+
|
115
|
+
def login(user, pass)
|
116
|
+
username.set user
|
117
|
+
password.set pass
|
118
|
+
login_button.click
|
119
|
+
end
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
We can interact with helper in the same way as we did page elements.
|
124
|
+
```ruby
|
125
|
+
session.login('joe', 'blogs')
|
126
|
+
```
|
127
|
+
##Defining sub elements
|
128
|
+
If your pages are complex you can use PageMagic to compose pages, their elements and subelements to as many levels as you need to.
|
129
|
+
|
130
|
+
In the example we accessed a read link that resided with a particular message
|
131
|
+
```ruby
|
132
|
+
class MailBox
|
133
|
+
include PageMagic
|
134
|
+
|
135
|
+
element :message, id: 'message_id' do
|
136
|
+
link(:read, text: 'read')
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
Sub elements can be accessed through their parent elements e.g:
|
141
|
+
```
|
142
|
+
session.message.read.click
|
143
|
+
```
|
144
|
+
## Dynamic Selectors
|
145
|
+
In our scenario we actually selected a message based on a subject that was randomly generated. In this case we would not be able to hard code the selector for our message but instead would need to set the selector dynamically.
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
class MailBox
|
149
|
+
include PageMagic
|
150
|
+
|
151
|
+
element :message do |subject:|
|
152
|
+
selector xpath: '//tr[text()="#{subject}"]'
|
153
|
+
link(:read, text: 'read')
|
154
|
+
end
|
155
|
+
end
|
156
|
+
```
|
157
|
+
Here we have defined the 'message' element using a block that takes subject argument. This is passed in at run time and given to the xpath selector.
|
158
|
+
```ruby
|
159
|
+
session.message(subject: 'test message')
|
160
|
+
```
|
161
|
+
## Interaction hooks
|
162
|
+
Frequently, you are going to have to work with pages that make heavy use of ajax. This means that just because you've clicked something, it doesn't mean that the action is finished. For these occasions PageMagic provides `before` and `after` hooks that you use to perform custom actions and wait for things to happen. In the case of our web based mail client, we could imagine that when deleting the email, a fancy spinner is displayed whilst the application sends an ajax request to have the message deleted. In this case we wouldn't want to proceed until this has disappeared.
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
class MessagePage
|
166
|
+
include PageMagic
|
167
|
+
## code defining other elements, such as subject and body
|
168
|
+
|
169
|
+
link(:delete, id: 'delete-message') do
|
170
|
+
after do
|
171
|
+
wait_until{fancy_animation_has_disappeared?}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
```
|
176
|
+
## Page Mapping
|
177
|
+
You will have noticed that, that we have been performing actions that would move us from page to page but have not done anything to tell PageMagic to use the `MailBox` or `MessagePage`. With PageMagic you can map which pages should be used to handle which URL paths. This is a pretty killer feature that will remove a lot of the juggling and bring back fluency to your code!
|
178
|
+
```ruby
|
179
|
+
# define what pages map to what
|
180
|
+
browser.define_page_mappings %r{/messages/\d+} => MessagePage,
|
181
|
+
'/login' => LoginPage,
|
182
|
+
'/' => MailBox
|
183
|
+
```
|
184
|
+
You can use even use regular expressions to map multiple paths to the same page. In the above example we are mapping paths that that starts with '/messages/' and are followed by one ore more digits to the `MessagePage` class.
|
185
|
+
|
186
|
+
##What else can you do with PageMagic?
|
187
|
+
PageMagic has lots of other useful features. I'm writing up the documentation so check back here soon!
|
188
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.alpha4
|
data/lib/page_magic/elements.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ext/string'
|
2
|
+
require 'active_support/inflector'
|
2
3
|
module PageMagic
|
3
4
|
module Elements
|
4
5
|
class InvalidElementNameException < Exception
|
@@ -52,7 +53,7 @@ module PageMagic
|
|
52
53
|
|
53
54
|
unless selector
|
54
55
|
selector = section_class.selector
|
55
|
-
name = section_class.name.to_snake_case.to_sym
|
56
|
+
name = section_class.name.demodulize.to_snake_case.to_sym
|
56
57
|
end
|
57
58
|
|
58
59
|
add_element_definition(name) do |parent_browser_element|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: page_magic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.alpha4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leon Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: capybara
|