quke_demo_app 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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