golden_silk 0.0.3.cardboard → 0.0.4.builders

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dae16601c21ac170ec594b547db698302e6d58f3
4
- data.tar.gz: 5905ee2e8c0ad150ec94327571b701969bf1280e
3
+ metadata.gz: 126e16c8f9f102e4822151c6f325316430b1f441
4
+ data.tar.gz: 8fd0d2c891234ae8be26681d755b5fe3138eb71f
5
5
  SHA512:
6
- metadata.gz: 3088cfb1e1119af61efae609d9d70d8d9d3b9b2d4cf00de6d118f14876f53011658087c54e1ff9f75c990adc4ee6f7ae8644a1f67b66f623b5a13ea9a491a1b5
7
- data.tar.gz: 93c1e903ca9010115a7e90277811db631f68b0199a85e849ec10ae0ac63eeee81b6f221a635518f76b44dde1ee0ebbdb4b7c757eca8f5786ad0e302e2e4b68ca
6
+ metadata.gz: 50fc6ebeb33b7966711d9ac51be11da1112e09d0b69615132ff0e96566827e1019f3298ec05ed31cb1766c9a1d095d97a2f593305fdaa57d0471494a300a692e
7
+ data.tar.gz: 6165461801b143f4c15698c9de5f21c4752e8f9ad6a9bbe9bccfa65942e1acf456d42ce147712481493b9a8f913ed1a8d56a7e139e7e68ecd2644f93ae6f3483
data/bin/golden_silk CHANGED
@@ -1,7 +1,42 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'golden_silk'
4
+ require 'optparse'
4
5
 
5
- # TODO: quiet mode (or quiet by default and verbose mode)
6
- # TODO: take URL as an argument
7
- GoldenSilk::Spinner.new('http://0.0.0.0:9001/avatar_builder').run
6
+ # TODO: Add a pretty progress bar when verbose is off
7
+ options = {}
8
+
9
+ opt_parser = OptionParser.new do |opts|
10
+ opts.banner = "Usage: golden_silk [options] starting_url"
11
+
12
+ opts.separator ""
13
+ opts.separator "Options:"
14
+
15
+ opts.on("-v", "--verbose", "Run verbosely. Default is no output.") do |v|
16
+ options[:verbose] = true
17
+ end
18
+
19
+ opts.on("-d", "--depth NUM", Integer, "The maximum depth (number of steps) from the starting URL that should be explored. Default is 3.") do |d|
20
+ options[:depth] = d
21
+ end
22
+
23
+ opts.on_tail("-h", "--help", "Show this message") do
24
+ puts opts
25
+ exit
26
+ end
27
+
28
+ opts.on_tail("--version", "Show version") do
29
+ puts GoldenSilk::VERSION
30
+ exit
31
+ end
32
+ end
33
+
34
+ opt_parser.parse!(ARGV)
35
+
36
+ starting_url = ARGV.first
37
+ if starting_url
38
+ GoldenSilk::Spinner.new(starting_url, options).run
39
+ else
40
+ puts "Starting URL is required."
41
+ exit
42
+ end
@@ -15,10 +15,12 @@ module GoldenSilk
15
15
  #{@steps.last}
16
16
  sleep 2
17
17
  html_after = html
18
- diff = Diffy::Diff.new(html_before, html_after, context: 1).to_s
19
- expect(diff).to eql('#{@diff.gsub("'", "\\\\'")}')
20
- end
18
+ diff = Diffy::Diff.new(html_before, html_after, context: 0).each_chunk.to_a
21
19
  RSPEC
20
+ @diff.each_chunk do |chunk|
21
+ s << " expect(diff).to include('#{chunk.gsub("'", "\\\\'")}')\n"
22
+ end
23
+ s << " end\n"
22
24
  end
23
25
  end
24
26
  end
@@ -7,7 +7,7 @@ module GoldenSilk
7
7
 
8
8
  def to_s
9
9
  s = <<RSPEC
10
- it 'has no effect' do
10
+ it 'has no effect, consider disabling this action in this case' do
11
11
  #{@steps[0...-1].join("\n sleep 2\n ")}
12
12
  sleep 2
13
13
  html_before = html
@@ -6,39 +6,39 @@ module GoldenSilk
6
6
  class Spinner
7
7
  include Capybara::DSL
8
8
 
9
- # TODO: configurable depth
10
- MAX_DEPTH = 3
11
-
12
9
  # TODO: configurable capybara driver
13
10
  Capybara.default_driver = :webkit
14
11
 
15
12
  Diffy::Diff.default_format = :text
16
13
 
17
- def initialize(root_url)
18
- @root_url = root_url
19
- # TODO: configurable click selector, take into account disabled states
14
+ # TODO: allow for the thing we start with to be calling a method in your test_helper? Maybe?
15
+ # If the interesting part to test requires you to do a few steps like visit and log in...
16
+ def initialize(root_url, options = {})
17
+ @root_url = root_url
18
+ @verbose = options.fetch(:verbose, false)
19
+ @max_depth = options.fetch(:depth, 3)
20
+
21
+ # TODO: configurable click selector
22
+ # TODO: have the default take into account disabled states
20
23
  @click_selector = 'button, .store-accessory'
24
+
21
25
  @results = []
22
26
  @queue = []
23
27
  end
24
28
 
25
29
  def run
26
- # TODO: get host from root_url
27
- page.driver.allow_url("0.0.0.0")
30
+ host = URI(@root_url).host
31
+ page.driver.allow_url(host)
28
32
  page.driver.block_unknown_urls
29
33
 
30
34
  visit @root_url
31
35
  # TODO: configurable wait time
32
36
  sleep 2
33
- all(@click_selector).each { |node|
34
- @queue << [
35
- Step::Visit.new(url: @root_url, on: self),
36
- Step::Click.new(xpath: node.path, text: node.text, on: self)
37
- ]
38
- }
39
- stuff(@queue, @results)
37
+ enqueue_clickables([Step::Visit.new(url: @root_url, on: self)])
38
+ crawl
40
39
 
41
40
  # TODO: configurable output dir, test file(s), preamble
41
+ # TODO: provide helper methods so that diffy doesn't have to be required explicitly
42
42
  # TODO: stream results so that all is not lost if you have to kill the generation
43
43
  FileUtils.mkdir_p("test/integration")
44
44
  File.open('test/integration/golden_silk_spec.rb', 'w') do |f|
@@ -49,51 +49,67 @@ module GoldenSilk
49
49
  end
50
50
  end
51
51
 
52
+ def output(str)
53
+ puts str if @verbose
54
+ end
55
+
52
56
  private
53
57
 
54
- # TODO: better name, don't take queue/results as arguments
55
- def stuff(queue, results)
56
- if queue.empty?
57
- puts "Queue is empty, we're done!"
58
+ def enqueue_clickables(previous_steps)
59
+ all(@click_selector).each { |node|
60
+ steps_to_queue = previous_steps.clone
61
+ # TODO: check for Ambiguous matches that may need more identification
62
+ if node.tag_name == 'button'
63
+ steps_to_queue << Step::ButtonClick.new(text: node.text, on: self)
64
+ else
65
+ steps_to_queue << Step::Click.new(xpath: node.path, text: node.text, on: self)
66
+ end
67
+ @queue << steps_to_queue
68
+ }
69
+ end
70
+
71
+ def crawl
72
+ if @queue.empty?
73
+ output "Queue is empty, we're done!"
58
74
  return
59
75
  end
60
76
 
61
- current_action_set = queue.shift
77
+ current_action_set = @queue.shift
62
78
  depth = current_action_set.length
63
79
 
64
- last_action = current_action_set.pop
80
+ all_but_the_last_action = current_action_set[0...-1]
81
+ last_action = current_action_set.last
65
82
 
66
- current_action_set.each { |a| a.execute }
83
+ all_but_the_last_action.each { |a| a.execute }
67
84
  sleep 2
68
85
  before_snapshot = html
69
86
  last_action.execute
70
87
  sleep 2
71
88
  after_snapshot = html
72
- diff = Diffy::Diff.new(before_snapshot, after_snapshot, context: 1).to_s
73
89
 
74
- if diff.empty?
75
- puts "No change, adding to results but not queue."
76
- results << Result::NoEffect.new(steps: current_action_set + [last_action])
90
+ # Do a (quicker?) simple string comparison to see if there was a change in the page
91
+ if before_snapshot == after_snapshot
92
+ output "No change, adding to results but not queue."
93
+ @results << Result::NoEffect.new(steps: current_action_set)
77
94
  else
78
- puts "Change, adding to results."
79
- results << Result::Diff.new(diff: diff, steps: current_action_set + [last_action])
95
+ # If there is a change, try and get the smallest change we can
96
+ before_html = before_snapshot.gsub(/>\s+</, "><").gsub("<", "\n<").gsub(">", ">\n").gsub(/\n\n+/, "\n")
97
+ after_html = after_snapshot.gsub(/>\s+</, "><").gsub("<", "\n<").gsub(">", ">\n").gsub(/\n\n+/, "\n")
98
+ diff = Diffy::Diff.new(before_html, after_html, context: 0)
99
+
100
+ output "Change, adding to results."
101
+ @results << Result::Diff.new(diff: diff, steps: current_action_set)
80
102
 
81
- if depth == MAX_DEPTH
82
- puts "Hit max depth."
103
+ if depth == @max_depth
104
+ output "Hit max depth."
83
105
  else
84
- puts "Looking for more steps to take."
85
-
86
- all(@click_selector).map { |node|
87
- queue << current_action_set + [
88
- last_action,
89
- Step::Click.new(xpath: node.path, text: node.text, on: self)
90
- ]
91
- }
106
+ output "Looking for more steps to take."
107
+ enqueue_clickables(current_action_set)
92
108
  end
93
109
  end
94
110
 
95
- puts "Recursing. Queue length: #{queue.length}, Results length: #{results.length}"
96
- stuff(queue, results)
111
+ output "Recursing. Queue length: #{@queue.length}, Results length: #{@results.length}"
112
+ crawl
97
113
  end
98
114
  end
99
115
  end
@@ -0,0 +1,20 @@
1
+ module GoldenSilk
2
+ module Step
3
+ class ButtonClick
4
+ def initialize(options = {})
5
+ @text = options[:text]
6
+ @tag = options[:tag]
7
+ @object = options[:on]
8
+ end
9
+
10
+ def execute
11
+ @object.output "Following instructions to click button #{@text}"
12
+ @object.click_button @text
13
+ end
14
+
15
+ def to_s
16
+ "click_button \"#{@text}\""
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,13 +2,13 @@ module GoldenSilk
2
2
  module Step
3
3
  class Click
4
4
  def initialize(options = {})
5
- @xpath = options[:xpath]
6
- @text = options[:text]
5
+ @xpath = options[:xpath]
6
+ @text = options[:text]
7
7
  @object = options[:on]
8
8
  end
9
9
 
10
10
  def execute
11
- puts "Following instructions to click #{@text}"
11
+ @object.output "Following instructions to click #{@text}"
12
12
  @object.find(:xpath, @xpath).click
13
13
  end
14
14
 
@@ -2,12 +2,12 @@ module GoldenSilk
2
2
  module Step
3
3
  class Visit
4
4
  def initialize(options = {})
5
- @url = options[:url]
5
+ @url = options[:url]
6
6
  @object = options[:on]
7
7
  end
8
8
 
9
9
  def execute
10
- puts "Visiting #{@url}"
10
+ @object.output "Visiting #{@url}"
11
11
  @object.visit @url
12
12
  end
13
13
 
@@ -1,3 +1,3 @@
1
1
  module GoldenSilk
2
- VERSION = "0.0.3.cardboard"
2
+ VERSION = "0.0.4.builders"
3
3
  end
data/lib/golden_silk.rb CHANGED
@@ -3,4 +3,5 @@ require "golden_silk/spinner"
3
3
  require "golden_silk/result/diff"
4
4
  require "golden_silk/result/no_effect"
5
5
  require "golden_silk/step/click"
6
+ require "golden_silk/step/button_click"
6
7
  require "golden_silk/step/visit"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: golden_silk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3.cardboard
4
+ version: 0.0.4.builders
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carol (Nichols || Goulding)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-15 00:00:00.000000000 Z
11
+ date: 2015-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -101,6 +101,7 @@ files:
101
101
  - lib/golden_silk/result/diff.rb
102
102
  - lib/golden_silk/result/no_effect.rb
103
103
  - lib/golden_silk/spinner.rb
104
+ - lib/golden_silk/step/button_click.rb
104
105
  - lib/golden_silk/step/click.rb
105
106
  - lib/golden_silk/step/visit.rb
106
107
  - lib/golden_silk/version.rb