quke_demo_app 0.1.0

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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +68 -0
  3. data/Rakefile +34 -0
  4. data/bin/console +13 -0
  5. data/bin/setup +8 -0
  6. data/exe/quke_demo_app +43 -0
  7. data/lib/quke.rb +7 -0
  8. data/lib/quke/demo_app.rb +11 -0
  9. data/lib/quke/demo_app/app.rb +79 -0
  10. data/lib/quke/demo_app/cli.rb +19 -0
  11. data/lib/quke/demo_app/concerns/can_have_search_results.rb +33 -0
  12. data/lib/quke/demo_app/public/assets/css/bootstrap.min.css +6 -0
  13. data/lib/quke/demo_app/public/assets/css/custom.css +3 -0
  14. data/lib/quke/demo_app/public/assets/css/ie10-viewport-bug-workaround.css +15 -0
  15. data/lib/quke/demo_app/public/assets/images/favicon.ico +0 -0
  16. data/lib/quke/demo_app/public/assets/images/quke.png +0 -0
  17. data/lib/quke/demo_app/public/assets/javascript/bootstrap.min.js +7 -0
  18. data/lib/quke/demo_app/public/assets/javascript/ie10-viewport-bug-workaround.js +23 -0
  19. data/lib/quke/demo_app/public/assets/javascript/jquery.min.js +6 -0
  20. data/lib/quke/demo_app/version.rb +7 -0
  21. data/lib/quke/demo_app/views/_partial_example.erb +5 -0
  22. data/lib/quke/demo_app/views/about.erb +2 -0
  23. data/lib/quke/demo_app/views/contact.erb +2 -0
  24. data/lib/quke/demo_app/views/css_selector.erb +67 -0
  25. data/lib/quke/demo_app/views/index.erb +17 -0
  26. data/lib/quke/demo_app/views/javascript_error.erb +19 -0
  27. data/lib/quke/demo_app/views/layout.erb +71 -0
  28. data/lib/quke/demo_app/views/radio_button.erb +55 -0
  29. data/lib/quke/demo_app/views/request.erb +20 -0
  30. data/lib/quke/demo_app/views/search.erb +39 -0
  31. data/spec/quke/demo_app/app_spec.rb +153 -0
  32. data/spec/quke/demo_app/cli_spec.rb +35 -0
  33. data/spec/quke/demo_app_spec.rb +12 -0
  34. data/spec/spec_helper.rb +83 -0
  35. data/spec/support/aruba.rb +3 -0
  36. data/spec/support/pry.rb +7 -0
  37. data/spec/support/quke_demo_app.rb +4 -0
  38. data/spec/support/rack_test.rb +22 -0
  39. data/spec/support/simplecov.rb +17 -0
  40. metadata +250 -0
@@ -0,0 +1,17 @@
1
+ <!-- Main jumbotron for a primary marketing message or call to action -->
2
+ <header>
3
+ <div class="jumbotron">
4
+ <h1><%= @title %> <img src="/assets/images/quke.png" width="65px" align="middle" /></h1>
5
+ <p class="lead">This demo app is what the example features run against.<br /> Use it along with the features to explore how to interact with your web sites using Quke.</p>
6
+ </div>
7
+ </header>
8
+
9
+ <ul>
10
+ <li><a href="/search">Search</a></li>
11
+ <li><a href="/radiobutton">Radio button</a></li>
12
+ <li><a href="/cssselector">CSS selector</a></li>
13
+ <li><a href="/request">Request details</a></li>
14
+ <li><a href="/jserror">JavaScript error</a></li>
15
+ </ul>
16
+
17
+ <%= erb '_partial_example'.to_sym %>
@@ -0,0 +1,19 @@
1
+ <!-- Main jumbotron for a primary marketing message or call to action -->
2
+ <div class="jumbotron">
3
+ <h1><%= @title %></h1>
4
+ <p class="lead">This page can be used for checking what happens when you test a page with a JavaScript error.</p>
5
+ <p class="lead">There are examples of how to test against the data in this page, but essentially they are just
6
+ using <strong>Capybara's</strong> <code>find()</code> method.</p>
7
+ <ul>
8
+ <li><code>features/quke/javascript_error.feature</code></li>
9
+ <li><code>features/step_definitions/quke/javascript_error_steps.rb</code></li>
10
+ <li><code>quke_demo_app/views/javascript_error.erb</code></li>
11
+ </ul>
12
+ </div>
13
+ <script>
14
+ throw ({'error':'boom'});
15
+ </script>
16
+ <div id="result">
17
+ <h2>Results</h2>
18
+ <p><%= @results %></p>
19
+ </div>
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1"/ >
7
+ <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8
+
9
+ <meta name="description" content="The Quke demo web site" />
10
+ <meta name="author" content="Defra" />
11
+
12
+ <!-- Icon for Quke was created by combining the following images -->
13
+ <!-- http://cliparts.co/clipart/2895339 -->
14
+ <!-- http://www.clker.com/clipart-magnifying-glass-40.html -->
15
+ <link rel="icon" href="/assets/images/favicon.ico" />
16
+
17
+ <title>Quke - <%= @title %></title>
18
+
19
+ <!-- Bootstrap core CSS -->
20
+ <link href="/assets/css/bootstrap.min.css" rel="stylesheet" />
21
+
22
+ <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
23
+ <link href="/assets/css/ie10-viewport-bug-workaround.css" rel="stylesheet" />
24
+
25
+ <!-- Custom styles for this template -->
26
+ <link href="/assets/css/custom.css" rel="stylesheet" />
27
+ </head>
28
+
29
+ <body>
30
+ <nav class="navbar navbar-inverse navbar-fixed-top">
31
+ <div class="container">
32
+ <div class="navbar-header">
33
+ <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
34
+ <span class="sr-only">Toggle navigation</span>
35
+ <span class="icon-bar"></span>
36
+ <span class="icon-bar"></span>
37
+ </button>
38
+ <a class="navbar-brand" href="/">Quke</a>
39
+ </div>
40
+ <div id="navbar" class="collapse navbar-collapse">
41
+ <ul class="nav navbar-nav">
42
+ <li><a href="/about">About</a></li>
43
+ <li><a href="/contact">Contact</a></li>
44
+ </ul>
45
+ </div><!--/.nav-collapse -->
46
+ </div>
47
+ </nav>
48
+
49
+ <div class="container">
50
+
51
+ <div class="starter-template">
52
+ <%= yield %>
53
+ </div>
54
+
55
+ </div><!-- /.container -->
56
+
57
+ <!-- Bootstrap core JavaScript
58
+ ================================================== -->
59
+ <!-- Placed at the end of the document so the pages load faster -->
60
+
61
+ <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
62
+ <script src="/assets/javascript/jquery.min.js"></script>
63
+ <script>window.jQuery || document.write('<script src="/assets/javascript/jquery.min.js"><\/script>')</script>
64
+
65
+ <!-- Latest compiled and minified JavaScript -->
66
+ <script src="/assets/javascript/bootstrap.min.js"></script>
67
+
68
+ <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
69
+ <script src="/assets/javascript/ie10-viewport-bug-workaround.js"></script>
70
+ </body>
71
+ </html>
@@ -0,0 +1,55 @@
1
+ <!-- Main jumbotron for a primary marketing message or call to action -->
2
+ <div class="jumbotron">
3
+ <h1><%= @title %></h1>
4
+ <p class="lead">Tests for this page are all about working with collections of elements like radio buttons.
5
+ The steps behind <code>radio_button.feature</code> show getting a collection of linked elements, checking
6
+ you have the right number, and for something like a radio button how to select a specific one.</p>
7
+ <p class="lead">Though the examples are for radio buttons, the same selecting and checking logic can be
8
+ used with any elements e.g. <code>&lt;div&gt;</code>, <code>&lt;a&gt;</code>, <code>&lt;tr&gt;</code>.
9
+ It just comes down to the CSS selector you use. See the following for details</p>
10
+ <ul>
11
+ <li><code>features/quke/radio_button.feature</code></li>
12
+ <li><code>features/step_definitions/quke/radio_button_steps.rb</code></li>
13
+ <li><code>quke_demo_app/views/radio_button.erb</code></li>
14
+ </ul>
15
+ </div>
16
+
17
+ <form id="radio_button_example" action="/radiobutton" accept-charset="UTF-8" method="post">
18
+ <fieldset>
19
+
20
+ <div id="form_group_organisation_type" role="group" aria-labelledby="groupLabel" class="form">
21
+ <label class="radio" for="organisation_limited_company">
22
+ <input id="organisation_limited_company" type="radio" value="WasteExemptionsShared::OrganisationType::LimitedCompany" name="enrollment[organisation_attributes][type]" />
23
+ Limited company
24
+ </label>
25
+ <label class="radio" for="organisation_limited_liability_partnership">
26
+ <input id="organisation_limited_liability_partnership" type="radio" value="WasteExemptionsShared::OrganisationType::LimitedLiabilityPartnership" name="enrollment[organisation_attributes][type]" />
27
+ Limited liability partnership
28
+ </label>
29
+ <label class="radio" for="organisation_partnership">
30
+ <input id="organisation_partnership" type="radio" value="WasteExemptionsShared::OrganisationType::Partnership" name="enrollment[organisation_attributes][type]" />
31
+ Partnership
32
+ </label>
33
+ <label class="radio" for="organisation_other">
34
+ <input id="organisation_other" type="radio" value="WasteExemptionsShared::OrganisationType::Other" name="enrollment[organisation_attributes][type]" />
35
+ Other (trust, club or public body)
36
+ </label>
37
+ <label class="radio" for="organisation_not_known">
38
+ <input id="organisation_not_known" type="radio" value="WasteExemptionsShared::OrganisationType::NotKnown" name="enrollment[organisation_attributes][type]" />
39
+ I don’t know
40
+ </label>
41
+ </div>
42
+ </fieldset>
43
+
44
+ <div class="actions">
45
+ <input type="submit" id="commit" name="commit" value="Continue" class="button"/>
46
+ </div>
47
+ </form>
48
+ <% if @result %>
49
+ <div id="results">
50
+ <h2>Results</h2>
51
+ <div id="selected-option" class="result">
52
+ <p class="result-desc"><span id="result">You selected <strong><%= @result %></strong></span></p>
53
+ </div>
54
+ </div>
55
+ <% end %>
@@ -0,0 +1,20 @@
1
+ <!-- Main jumbotron for a primary marketing message or call to action -->
2
+ <div class="jumbotron">
3
+ <h1><%= @title %></h1>
4
+ <p class="lead">This page can be used for checking that the request you formulated in <strong>Quke</strong> is as
5
+ expected. It will display the details for each item in the request.</p>
6
+ <p class="lead">There are examples of how to test against the data in this page, but essentially they are just
7
+ using <strong>Capybara's</strong> <code>find()</code> method.</p>
8
+ <ul>
9
+ <li><code>features/quke/request_details.feature</code></li>
10
+ <li><code>features/step_definitions/quke/request_details_steps.rb</code></li>
11
+ <li><code>quke_demo_app/views/request_details.erb</code></li>
12
+ </ul>
13
+ </div>
14
+
15
+ <div id="results">
16
+ <h2>Results</h2>
17
+ <% @results.each do | key, value | %>
18
+ <div><strong><%= key %></strong> <code id="<%= key %>"><%= value %></code></div>
19
+ <% end %>
20
+ </div>
@@ -0,0 +1,39 @@
1
+ <!-- Main jumbotron for a primary marketing message or call to action -->
2
+ <div class="jumbotron">
3
+ <h1><%= @title %></h1>
4
+ <p class="lead">The steps for <code>search.feature</code> demonstrate how to fill in a form, submit it and then
5
+ test the response is what you expected. In this case that's confirming you got the right number of results and that they
6
+ contained the correct data. See the following for details</p>
7
+ <ul>
8
+ <li><code>features/quke/search.feature</code></li>
9
+ <li><code>features/step_definitions/quke/search_steps.rb</code></li>
10
+ <li><code>quke_demo_app/views/search.erb</code></li>
11
+ </ul>
12
+ </div>
13
+
14
+ <form class="edit_grid_reference" id="edit_grid_reference" action="/search" accept-charset="UTF-8" method="post">
15
+ <fieldset>
16
+
17
+ <div id="form_group_search_input" role="group" aria-labelledby="groupLabel" class="form-group">
18
+ <label class="form-label" for="search_input">
19
+ Enter your search
20
+ </label>
21
+ <input class="form-control form-control-char-25" aria-describedby="search-help" type="text" name="search_input" id="search_input"/>
22
+ </div>
23
+ </fieldset>
24
+
25
+ <div class="form-group">
26
+ <input type="submit" id="commit" name="commit" value="Continue" class="button"/>
27
+ </div>
28
+ </form>
29
+ <% if @results %>
30
+ <div id="results">
31
+ <h2>Results</h2>
32
+ <% @results.each do | title, desc | %>
33
+ <div id="<%= title %>" class="result">
34
+ <h3 class="result-title"><%= title %></h3>
35
+ <p class="result-desc"><%= desc %></p>
36
+ </div>
37
+ <% end %>
38
+ </div>
39
+ <% end %>
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Quke
6
+ module DemoApp
7
+ RSpec.describe App do
8
+
9
+ it "includes CanHaveSearchResults" do
10
+ included_modules = described_class.ancestors.select { |ancestor| ancestor.instance_of?(Module) }
11
+
12
+ expect(included_modules)
13
+ .to include(Quke::DemoApp::CanHaveSearchResults)
14
+ end
15
+
16
+ context "/" do
17
+ it "GET displays the page" do
18
+ get "/"
19
+
20
+ expect(last_response.body).to include("Welcome to Quke")
21
+ end
22
+
23
+ it "GET returns the status 200" do
24
+ get "/"
25
+
26
+ expect(last_response).to be_ok
27
+ end
28
+ end
29
+
30
+ context "/about" do
31
+ it "GET displays the page" do
32
+ get "/about"
33
+
34
+ expect(last_response.body).to include("The about page.")
35
+ end
36
+
37
+ it "GET returns the status 200" do
38
+ get "/about"
39
+
40
+ expect(last_response).to be_ok
41
+ end
42
+ end
43
+
44
+ context "/contact" do
45
+ it "GET displays the page" do
46
+ get "/contact"
47
+
48
+ expect(last_response.body).to include("The contact page.")
49
+ end
50
+
51
+ it "GET returns the status 200" do
52
+ get "/contact"
53
+
54
+ expect(last_response).to be_ok
55
+ end
56
+ end
57
+
58
+ context "/cssselector" do
59
+ it "GET displays the page" do
60
+ get "/cssselector"
61
+
62
+ expect(last_response.body).to include("rely on using CSS selectors to locate elements")
63
+ end
64
+
65
+ it "GET returns the status 200" do
66
+ get "/cssselector"
67
+
68
+ expect(last_response).to be_ok
69
+ end
70
+ end
71
+
72
+ context "/jserror" do
73
+ it "GET displays the page" do
74
+ get "/jserror"
75
+
76
+ expect(last_response.body).to include("page with a JavaScript error")
77
+ end
78
+
79
+ it "GET returns the status 200" do
80
+ get "/jserror"
81
+
82
+ expect(last_response).to be_ok
83
+ end
84
+ end
85
+
86
+ context "/request" do
87
+ it "GET displays the page" do
88
+ get "/request"
89
+
90
+ expect(last_response.body).to include("checking that the request")
91
+ end
92
+
93
+ it "GET returns the status 200" do
94
+ get "/request"
95
+
96
+ expect(last_response).to be_ok
97
+ end
98
+ end
99
+
100
+ context "/radiobutton" do
101
+ it "GET displays the page" do
102
+ get "/radiobutton"
103
+
104
+ expect(last_response.body).to include("elements like radio buttons")
105
+ end
106
+
107
+ it "GET returns the status 200" do
108
+ get "/radiobutton"
109
+
110
+ expect(last_response).to be_ok
111
+ end
112
+
113
+ it "POST to the page displays selected option" do
114
+ post "/radiobutton", "enrollment[organisation_attributes][type]=WasteExemptionsShared::OrganisationType::Partnership"
115
+
116
+ expect(last_response.body).to include("You selected <strong>Partnership</strong>")
117
+ end
118
+
119
+ it "POST returns the status 200" do
120
+ post "/radiobutton", "enrollment[organisation_attributes][type]=WasteExemptionsShared::OrganisationType::Partnership"
121
+
122
+ expect(last_response).to be_ok
123
+ end
124
+ end
125
+
126
+ context "/search" do
127
+ it "GET displays the page" do
128
+ get "/search"
129
+
130
+ expect(last_response.body).to include("confirming you got the right number of results")
131
+ end
132
+
133
+ it "GET returns the status 200" do
134
+ get "/search"
135
+
136
+ expect(last_response).to be_ok
137
+ end
138
+
139
+ it "POST to the page displays selected option" do
140
+ post "/search", "search_input=capybara"
141
+
142
+ expect(last_response.body).to include("Hydrochoerus hydrochaeris")
143
+ end
144
+
145
+ it "POST returns the status 200" do
146
+ post "/search", "search_input=capybara"
147
+
148
+ expect(last_response).to be_ok
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Quke
6
+ module DemoApp
7
+ # We make use of https://github.com/cucumber/aruba here to allow us to test
8
+ # the CLI for our demo app. Because we are kicking off a long lived process
9
+ # (Sinatra web server) we need someway to kill the process but still
10
+ # capture a result. That's what the `exit_timeout` arg does for us.
11
+ RSpec.describe Cli, type: :aruba, exit_timeout: 2 do
12
+ context "Start the demo app" do
13
+ let(:port_args) { "" }
14
+ before(:each) do
15
+ # We have to set the env var to invoke the simplecov section of our
16
+ # quke_demo_app exe file in order to capture test coverage accurately.
17
+ # set_environment_variable() is a method provided by Aruba, as is
18
+ # run_command
19
+ set_environment_variable("COVERAGE", "true")
20
+ run_command("exe/quke_demo_app #{port_args}")
21
+ end
22
+
23
+ it { expect(last_command_started).to be_successfully_executed }
24
+ it { expect(last_command_started).to have_output(/has taken the stage on 4567/) }
25
+
26
+ context "and set a custom port" do
27
+ let(:port_args) { "--port 9876" }
28
+
29
+ it { expect(last_command_started).to be_successfully_executed }
30
+ it { expect(last_command_started).to have_output(/has taken the stage on 9876/) }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Quke::DemoApp do
6
+ describe "VERSION" do
7
+ it "is a version string in the correct format" do
8
+ expect(Quke::DemoApp::VERSION).to be_a(String)
9
+ expect(Quke::DemoApp::VERSION).to match(/\d+\.\d+\.\d+/)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+
5
+ # Require and run our simplecov initializer as the very first thing we do.
6
+ # This is as per its docs https://github.com/colszowka/simplecov#getting-started
7
+ require_relative "support/simplecov"
8
+
9
+ # Requires supporting ruby files with custom matchers and macros, etc, in
10
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
11
+ # run as spec files by default. This means that files in spec/support that end
12
+ # in _spec.rb will both be required and run as specs, causing the specs to be
13
+ # run twice. It is recommended that you do not name files matching this glob to
14
+ # end with _spec.rb. You can configure this pattern with the --pattern
15
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
16
+ #
17
+ # We make an exception for simplecov because that will already have been
18
+ # required and run at the very top of spec_helper.rb
19
+ support_files = Dir["./spec/support/**/*.rb"].reject { |file| file == "./spec/support/simplecov.rb" }
20
+ support_files.each { |f| require f }
21
+
22
+ RSpec.configure do |config|
23
+ # rspec-expectations config goes here. You can use an alternate
24
+ # assertion/expectation library such as wrong or the stdlib/minitest
25
+ # assertions if you prefer.
26
+ config.expect_with :rspec do |expectations|
27
+ # This option will default to `true` in RSpec 4. It makes the `description`
28
+ # and `failure_message` of custom matchers include text for helper methods
29
+ # defined using `chain`, e.g.:
30
+ # be_bigger_than(2).and_smaller_than(4).description
31
+ # # => "be bigger than 2 and smaller than 4"
32
+ # ...rather than:
33
+ # # => "be bigger than 2"
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ # rspec-mocks config goes here. You can use an alternate test double
38
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
39
+ config.mock_with :rspec do |mocks|
40
+ # Prevents you from mocking or stubbing a method that does not exist on
41
+ # a real object. This is generally recommended, and will default to
42
+ # `true` in RSpec 4.
43
+ mocks.verify_partial_doubles = true
44
+ end
45
+
46
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
47
+ # have no way to turn it off -- the option exists only for backwards
48
+ # compatibility in RSpec 3). It causes shared context metadata to be
49
+ # inherited by the metadata hash of host groups and examples, rather than
50
+ # triggering implicit auto-inclusion in groups with matching metadata.
51
+ config.shared_context_metadata_behavior = :apply_to_host_groups
52
+
53
+ # This allows you to limit a spec run to individual examples or groups
54
+ # you care about by tagging them with `:focus` metadata. When nothing
55
+ # is tagged with `:focus`, all examples get run. RSpec also provides
56
+ # aliases for `it`, `describe`, and `context` that include `:focus`
57
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
58
+ config.filter_run_when_matching :focus
59
+
60
+ # Allows RSpec to persist some state between runs in order to support
61
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
62
+ # you configure your source control system to ignore this file.
63
+ config.example_status_persistence_file_path = "spec/examples.txt"
64
+
65
+ # Limits the available syntax to the non-monkey patched syntax that is
66
+ # recommended. For more details, see:
67
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
68
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
69
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
70
+ config.disable_monkey_patching!
71
+
72
+ # Run specs in random order to surface order dependencies. If you find an
73
+ # order dependency and want to debug it, you can fix the order by providing
74
+ # the seed, which is printed after each run.
75
+ # --seed 1234
76
+ config.order = :random
77
+
78
+ # Seed global randomization in this process using the `--seed` CLI option.
79
+ # Setting this allows you to use `--seed` to deterministically reproduce
80
+ # test failures related to randomization by passing the same `--seed` value
81
+ # as the one that triggered the failure.
82
+ Kernel.srand config.seed
83
+ end