metry 2.0.3 → 2.0.4
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.
- data/History.txt +7 -0
- data/TODO +0 -4
- data/features/psycho/goals.feature +33 -4
- data/lib/metry.rb +1 -1
- data/lib/metry/psycho.rb +48 -6
- data/lib/metry/psycho/dashboard.erb +2 -2
- data/lib/metry/psycho/new_goal.erb +3 -3
- data/lib/metry/storage.rb +9 -1
- data/vendor/webrat/History.txt +2 -0
- data/vendor/webrat/lib/webrat/rack_test.rb +8 -2
- data/vendor/webrat/lib/webrat/selenium.rb +1 -1
- data/vendor/webrat/lib/webrat/selenium/selenium_rc_server.rb +4 -2
- data/vendor/webrat/spec/integration/rack/rack_app.rb +67 -1
- data/vendor/webrat/spec/integration/rack/test/test_helper.rb +2 -0
- data/vendor/webrat/spec/integration/rack/test/webrat_rack_test.rb +25 -51
- metadata +2 -2
data/History.txt
CHANGED
data/TODO
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
Figure out why Psycho events are not being ignored in production
|
2
|
-
Allow goals to have N paths
|
3
1
|
Limit visitors on dashboard to 10 most recent
|
4
2
|
Add full listing of visitors
|
5
3
|
Show more details about visitors
|
@@ -8,8 +6,6 @@ Add display of last 10 events to dashboard
|
|
8
6
|
Show goal conversion for each experiment
|
9
7
|
Allow manually viewing a particular alternatively
|
10
8
|
|
11
|
-
Switch to submodules for vendor'd libs
|
12
|
-
|
13
9
|
More unit tests
|
14
10
|
|
15
11
|
Add support for non-pageview event tracking
|
@@ -11,14 +11,43 @@ Feature: Track Goals
|
|
11
11
|
Scenario: Create a goal
|
12
12
|
Given I view "/admin/metry"
|
13
13
|
And I follow "New Goal"
|
14
|
-
And I fill in "name" with "Cool
|
14
|
+
And I fill in "name" with "Cool"
|
15
15
|
And I fill in "path" with "/goal"
|
16
16
|
And I press "Create"
|
17
|
-
Then I should be on "/admin/metry/"
|
18
|
-
And
|
17
|
+
Then I should be on "/admin/metry/goals/1"
|
18
|
+
And I should see "Cool"
|
19
19
|
|
20
20
|
Scenario: Goal count
|
21
21
|
Given I add a goal named "My Goal" with path "/"
|
22
22
|
And I view "/"
|
23
23
|
When I view "/admin/metry"
|
24
|
-
Then I should see "My Goal: 1 visits"
|
24
|
+
Then I should see "My Goal: 1 visits"
|
25
|
+
|
26
|
+
Scenario: Goal Regexp
|
27
|
+
Given I add a goal named "Subpage" with path "/subpage/?"
|
28
|
+
When I view "/subpage"
|
29
|
+
And I view "/subpage/"
|
30
|
+
And I view "/admin/metry"
|
31
|
+
Then I should see "Subpage: 2 visits"
|
32
|
+
|
33
|
+
Scenario: View Goal Detail
|
34
|
+
Given I add a goal named "Root" with path "/"
|
35
|
+
And I view "/"
|
36
|
+
And I view "/"
|
37
|
+
When I view "/admin/metry"
|
38
|
+
And I follow "Root"
|
39
|
+
Then I should see "Root"
|
40
|
+
And I should see "Path: /"
|
41
|
+
And I should see "Visitor 1"
|
42
|
+
|
43
|
+
Scenario: Edit a Goal
|
44
|
+
Given I add a goal named "Bogus" with path "/"
|
45
|
+
When I view "/admin/metry"
|
46
|
+
And I follow "Bogus"
|
47
|
+
And I follow "Edit"
|
48
|
+
And I fill in "name" with "Right"
|
49
|
+
And I fill in "path" with "/subpage"
|
50
|
+
And I press "Save"
|
51
|
+
Then I should be on "/admin/metry/goals/1"
|
52
|
+
And I should see "Right"
|
53
|
+
And I should see "Path: /subpage"
|
data/lib/metry.rb
CHANGED
data/lib/metry/psycho.rb
CHANGED
@@ -30,46 +30,88 @@ module Metry
|
|
30
30
|
erb :dashboard
|
31
31
|
end
|
32
32
|
|
33
|
-
get "#{path}/
|
33
|
+
get "#{path}/visitors/:id" do
|
34
34
|
@visitor = Visitor.find(params["id"])
|
35
35
|
erb :visitor
|
36
36
|
end
|
37
37
|
|
38
38
|
post "#{path}/goals" do
|
39
|
-
Goal.create!(params[:name], params[:path])
|
40
|
-
redirect url(
|
39
|
+
goal = Goal.create!(params[:name], params[:path])
|
40
|
+
redirect url("/goals/#{goal.id}")
|
41
41
|
end
|
42
42
|
|
43
43
|
get "#{path}/goals/new" do
|
44
44
|
erb :new_goal
|
45
45
|
end
|
46
|
+
|
47
|
+
get "#{path}/goals/:id" do
|
48
|
+
@goal = Goal.find(params[:id])
|
49
|
+
erb :goal
|
50
|
+
end
|
51
|
+
|
52
|
+
get "#{path}/goals/:id/edit" do
|
53
|
+
@goal = Goal.find(params[:id])
|
54
|
+
erb :edit_goal
|
55
|
+
end
|
56
|
+
|
57
|
+
post "#{path}/goals/:id" do
|
58
|
+
goal = Goal.find(params[:id])
|
59
|
+
goal.name = params[:name]
|
60
|
+
goal.path = params[:path]
|
61
|
+
goal.save
|
62
|
+
redirect url("/goals/#{goal.id}")
|
63
|
+
end
|
46
64
|
|
47
65
|
helpers do
|
48
66
|
define_method(:url) do |url|
|
49
67
|
"#{path}#{url}"
|
50
68
|
end
|
69
|
+
|
70
|
+
include ::Rack::Utils
|
71
|
+
alias_method :h, :escape_html
|
51
72
|
end
|
52
73
|
end
|
53
74
|
end
|
54
75
|
|
55
76
|
class Goal
|
77
|
+
def self.find(id)
|
78
|
+
new(Metry.current.goal(id))
|
79
|
+
end
|
80
|
+
|
56
81
|
def self.create!(name, path)
|
57
|
-
Metry.current.add_goal('name' => name, 'path' => path)
|
82
|
+
new(Metry.current.add_goal('name' => name, 'path' => path))
|
58
83
|
end
|
59
84
|
|
60
85
|
def self.all
|
61
86
|
Metry.current.goals.collect{|e| new(e)}
|
62
87
|
end
|
63
88
|
|
64
|
-
|
89
|
+
attr_accessor :path, :id, :name
|
65
90
|
|
66
91
|
def initialize(hash)
|
92
|
+
@id = hash['_id'].to_s
|
67
93
|
@name = hash['name']
|
68
94
|
@path = hash['path']
|
69
95
|
end
|
70
96
|
|
97
|
+
def save
|
98
|
+
Metry.current.save_goal({'_id' => id, 'name' => name, 'path' => path})
|
99
|
+
end
|
100
|
+
|
101
|
+
def path_regexp
|
102
|
+
Regexp.new("^#{path}$")
|
103
|
+
end
|
104
|
+
|
71
105
|
def visits
|
72
|
-
|
106
|
+
events.size
|
107
|
+
end
|
108
|
+
|
109
|
+
def events
|
110
|
+
Metry.current.all_events({'path' => path_regexp})
|
111
|
+
end
|
112
|
+
|
113
|
+
def visitors
|
114
|
+
events.collect{|e| e['visitor']}.uniq.collect{|e| Visitor.find(e)}
|
73
115
|
end
|
74
116
|
end
|
75
117
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<h1>Goals</h1>
|
2
2
|
<ul id="goals">
|
3
3
|
<% @goals.each do |goal| %>
|
4
|
-
<li class="goal"><%= goal.name
|
4
|
+
<li class="goal"><a href="<%= url "/goals/#{goal.id}" %>"><%= goal.name %></a>: <%= goal.visits %> visits</li>
|
5
5
|
<% end %>
|
6
6
|
</ul>
|
7
7
|
<p><a href="<%= url "/goals/new" %>">New Goal</a></p>
|
@@ -9,6 +9,6 @@
|
|
9
9
|
<h1>Recent Visitors</h1>
|
10
10
|
<ul>
|
11
11
|
<% @visitors.each do |v| %>
|
12
|
-
<li><a href="<%= url "/
|
12
|
+
<li><a href="<%= url "/visitors/#{v.id}" %>">Visitor <%= v.id %></a> (<%= v.events.size %> events)</li>
|
13
13
|
<% end %>
|
14
14
|
</ul>
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<h1>New Goal</h1>
|
2
2
|
|
3
|
-
<form action="<%= url "/goals" %>" method="
|
3
|
+
<form action="<%= url "/goals" %>" method="post">
|
4
4
|
<fieldset>
|
5
|
-
<p><label for="name">Name</label
|
6
|
-
<p><label for="path">Path</label
|
5
|
+
<p><label for="name">Name</label> <input type="text" name="name" /></p>
|
6
|
+
<p><label for="path">Path</label> <input type="text" name="path" /></p>
|
7
7
|
<p><input type="submit" value="Create" /></p>
|
8
8
|
</fieldset>
|
9
9
|
</form>
|
data/lib/metry/storage.rb
CHANGED
@@ -74,12 +74,20 @@ module Metry
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def add_goal(goal)
|
77
|
-
@db.collection('goals')
|
77
|
+
goal(@db.collection('goals').insert(goal))
|
78
78
|
end
|
79
79
|
|
80
80
|
def goals
|
81
81
|
@db.collection('goals').find.to_a
|
82
82
|
end
|
83
|
+
|
84
|
+
def goal(id)
|
85
|
+
@db.collection('goals').find(prep_selector('_id' => id)).next_object
|
86
|
+
end
|
87
|
+
|
88
|
+
def save_goal(goal)
|
89
|
+
@db.collection('goals').repsert(prep_selector('_id' => goal['_id']), goal)
|
90
|
+
end
|
83
91
|
|
84
92
|
def clear
|
85
93
|
%w(visitors events goals).each{|e| @db.drop_collection(e)}
|
data/vendor/webrat/History.txt
CHANGED
@@ -9,6 +9,8 @@
|
|
9
9
|
|
10
10
|
* Minor enhancements
|
11
11
|
|
12
|
+
* Upgrade to selenium-client to 1.2.16 (Brian Landau)
|
13
|
+
* Upgrade selenium-server.jar to 1.0.1 (Brian Landau)
|
12
14
|
* Make redirect detection work in the face of rational maths (like when ruby-units is active) (Piers Cawley)
|
13
15
|
* Use Launchy to handle opening pages in the browser with cross-platform compatibility (Bryan Helmkamp)
|
14
16
|
* Added support for field_labeled_locators ending in non word characters
|
@@ -23,8 +23,14 @@ module Webrat
|
|
23
23
|
def process_request(http_method, url, data = {}, headers = {})
|
24
24
|
headers ||= {}
|
25
25
|
data ||= {}
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
params = data.inject({}) do |data, (key,value)|
|
28
|
+
data[key] = Rack::Utils.unescape(value)
|
29
|
+
data
|
30
|
+
end
|
31
|
+
|
32
|
+
headers["HTTP_HOST"] = "www.example.com"
|
33
|
+
env = headers.merge(:params => params, :method => http_method.to_s.upcase)
|
28
34
|
@rack_test_session.request(url, env)
|
29
35
|
end
|
30
36
|
|
@@ -34,7 +34,7 @@ module Webrat
|
|
34
34
|
|
35
35
|
@remote_control = ::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
|
36
36
|
Webrat.configuration.selenium_server_port,
|
37
|
-
Webrat.configuration.selenium_browser_startup_timeout)
|
37
|
+
:timeout => Webrat.configuration.selenium_browser_startup_timeout)
|
38
38
|
@remote_control.jar_file = jar_path
|
39
39
|
|
40
40
|
return @remote_control
|
@@ -74,7 +74,9 @@ module Webrat
|
|
74
74
|
|
75
75
|
def stop
|
76
76
|
silence_stream(STDOUT) do
|
77
|
-
::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
|
77
|
+
::Selenium::RemoteControl::RemoteControl.new("0.0.0.0",
|
78
|
+
Webrat.configuration.selenium_server_port,
|
79
|
+
:timeout => 5).stop
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -2,8 +2,74 @@ require "rubygems"
|
|
2
2
|
require "sinatra/base"
|
3
3
|
|
4
4
|
class RackApp < Sinatra::Default
|
5
|
+
template :layout do
|
6
|
+
<<TEMPLATE
|
7
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
8
|
+
<html>
|
9
|
+
<title>sinatra testing with webrat</title>
|
10
|
+
<body>
|
11
|
+
<%= yield %>
|
12
|
+
</body>
|
13
|
+
</html>
|
14
|
+
TEMPLATE
|
15
|
+
end
|
16
|
+
|
17
|
+
template :home do
|
18
|
+
<<TEMPLATE
|
19
|
+
<p> visit <a href="/go">there</a></p>
|
20
|
+
|
21
|
+
<form>
|
22
|
+
<label>
|
23
|
+
Prefilled
|
24
|
+
<input type="text" name="prefilled" value="text" />
|
25
|
+
</label>
|
26
|
+
</form>
|
27
|
+
TEMPLATE
|
28
|
+
end
|
29
|
+
|
30
|
+
template :go do
|
31
|
+
<<TEMPLATE
|
32
|
+
<form method="post" action="/go">
|
33
|
+
<div>
|
34
|
+
<label for="name">Name</label>
|
35
|
+
<input type="text" name="name" id="name">
|
36
|
+
</div>
|
37
|
+
<div>
|
38
|
+
<label for="email">Email</label>
|
39
|
+
<input type="text" name="email" id="email">
|
40
|
+
</div>
|
41
|
+
<input type="submit" value="Submit" />
|
42
|
+
</form>
|
43
|
+
TEMPLATE
|
44
|
+
end
|
45
|
+
|
46
|
+
template :hello do
|
47
|
+
<<TEMPLATE
|
48
|
+
<p>Hello, <%= @user %></p>
|
49
|
+
<p>Your email is: <%= @email %></p>
|
50
|
+
TEMPLATE
|
51
|
+
end
|
52
|
+
|
5
53
|
get "/" do
|
6
|
-
|
54
|
+
erb :home
|
55
|
+
end
|
56
|
+
|
57
|
+
get "/go" do
|
58
|
+
erb :go
|
59
|
+
end
|
60
|
+
|
61
|
+
get "/internal_redirect" do
|
62
|
+
redirect "/"
|
63
|
+
end
|
64
|
+
|
65
|
+
get "/external_redirect" do
|
66
|
+
redirect "http://google.com"
|
67
|
+
end
|
68
|
+
|
69
|
+
post "/go" do
|
70
|
+
@user = params[:name]
|
71
|
+
@email = params[:email]
|
72
|
+
erb :hello
|
7
73
|
end
|
8
74
|
|
9
75
|
get "/redirect_absolute_url" do
|
@@ -2,66 +2,40 @@ require File.dirname(__FILE__) + "/test_helper"
|
|
2
2
|
require File.dirname(__FILE__) + "/../rack_app"
|
3
3
|
|
4
4
|
class WebratRackTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
|
7
|
-
assert
|
5
|
+
def test_visits_pages
|
6
|
+
visit "/"
|
7
|
+
assert response_body.include?("visit")
|
8
|
+
|
9
|
+
click_link "there"
|
10
|
+
assert response_body.include?('<form method="post" action="/go">')
|
8
11
|
end
|
9
12
|
|
10
|
-
def
|
11
|
-
visit "/"
|
12
|
-
|
13
|
+
def test_submits_form
|
14
|
+
visit "/go"
|
15
|
+
fill_in "Name", :with => "World"
|
16
|
+
fill_in "Email", :with => "world@example.org"
|
17
|
+
click_button "Submit"
|
18
|
+
assert response_body.include?("Hello, World")
|
19
|
+
assert response_body.include?("Your email is: world@example.org")
|
13
20
|
end
|
14
21
|
|
15
|
-
def
|
22
|
+
def test_check_value_of_field
|
16
23
|
visit "/"
|
17
|
-
|
24
|
+
assert field_labeled("Prefilled").value, "text"
|
18
25
|
end
|
19
26
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# end
|
24
|
-
|
25
|
-
def test_assertions_after_visit
|
26
|
-
visit "/"
|
27
|
-
assert_contain "Hello World"
|
27
|
+
def test_follows_internal_redirects
|
28
|
+
visit "/internal_redirect"
|
29
|
+
assert response_body.include?("visit")
|
28
30
|
end
|
29
31
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
32
|
+
def test_does_not_follow_external_redirects
|
33
|
+
visit "/external_redirect"
|
34
|
+
assert response_code == 302
|
33
35
|
end
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# click_link "there"
|
40
|
-
# assert response_body.include?('<form method="post" action="/go">')
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# def test_submits_form
|
44
|
-
# visit "/go"
|
45
|
-
# fill_in "Name", :with => "World"
|
46
|
-
# fill_in "Email", :with => "world@example.org"
|
47
|
-
# click_button "Submit"
|
48
|
-
#
|
49
|
-
# assert response_body.include?("Hello, World")
|
50
|
-
# assert response_body.include?("Your email is: world@example.org")
|
51
|
-
# end
|
52
|
-
#
|
53
|
-
# def test_check_value_of_field
|
54
|
-
# visit "/"
|
55
|
-
# assert field_labeled("Prefilled").value, "text"
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# def test_follows_internal_redirects
|
59
|
-
# visit "/internal_redirect"
|
60
|
-
# assert response_body.include?("visit")
|
61
|
-
# end
|
62
|
-
#
|
63
|
-
# def test_does_not_follow_external_redirects
|
64
|
-
# visit "/external_redirect"
|
65
|
-
# assert response_code == 302
|
66
|
-
# end
|
37
|
+
def test_redirects
|
38
|
+
visit "/redirect_absolute_url"
|
39
|
+
assert_equal "spam", response_body
|
40
|
+
end
|
67
41
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathaniel Talbott
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-09 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|