inferno_core 0.3.11 → 0.4.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/apps/cli/main.rb +13 -0
  3. data/lib/inferno/apps/cli/services.rb +56 -0
  4. data/lib/inferno/apps/web/application.rb +1 -0
  5. data/lib/inferno/apps/web/controllers/controller.rb +6 -8
  6. data/lib/inferno/apps/web/controllers/requests/show.rb +3 -3
  7. data/lib/inferno/apps/web/controllers/test_runs/create.rb +13 -17
  8. data/lib/inferno/apps/web/controllers/test_runs/destroy.rb +8 -10
  9. data/lib/inferno/apps/web/controllers/test_runs/results/index.rb +4 -4
  10. data/lib/inferno/apps/web/controllers/test_runs/show.rb +9 -7
  11. data/lib/inferno/apps/web/controllers/test_sessions/create.rb +9 -8
  12. data/lib/inferno/apps/web/controllers/test_sessions/last_test_run.rb +4 -4
  13. data/lib/inferno/apps/web/controllers/test_sessions/results/index.rb +6 -6
  14. data/lib/inferno/apps/web/controllers/test_sessions/session_data/apply_preset.rb +10 -10
  15. data/lib/inferno/apps/web/controllers/test_sessions/session_data/index.rb +5 -3
  16. data/lib/inferno/apps/web/controllers/test_sessions/show.rb +3 -3
  17. data/lib/inferno/apps/web/controllers/test_suites/check_configuration.rb +3 -3
  18. data/lib/inferno/apps/web/controllers/test_suites/index.rb +2 -2
  19. data/lib/inferno/apps/web/controllers/test_suites/show.rb +3 -3
  20. data/lib/inferno/apps/web/index.html.erb +4 -0
  21. data/lib/inferno/apps/web/router.rb +55 -41
  22. data/lib/inferno/apps/web/serializers/message.rb +2 -0
  23. data/lib/inferno/apps/web/serializers/preset.rb +2 -5
  24. data/lib/inferno/apps/web/serializers/request.rb +4 -1
  25. data/lib/inferno/apps/web/serializers/result.rb +5 -1
  26. data/lib/inferno/apps/web/serializers/session_data.rb +2 -0
  27. data/lib/inferno/apps/web/serializers/suite_option.rb +2 -0
  28. data/lib/inferno/apps/web/serializers/test.rb +3 -0
  29. data/lib/inferno/apps/web/serializers/test_group.rb +4 -2
  30. data/lib/inferno/apps/web/serializers/test_run.rb +3 -0
  31. data/lib/inferno/apps/web/serializers/test_suite.rb +5 -1
  32. data/lib/inferno/config/application.rb +1 -6
  33. data/lib/inferno/config/boot/web.rb +2 -7
  34. data/lib/inferno/config/boot.rb +6 -1
  35. data/lib/inferno/dsl/assertions.rb +2 -2
  36. data/lib/inferno/dsl/configurable.rb +4 -4
  37. data/lib/inferno/dsl/fhir_client.rb +3 -2
  38. data/lib/inferno/dsl/fhir_client_builder.rb +2 -2
  39. data/lib/inferno/dsl/fhir_validation.rb +5 -6
  40. data/lib/inferno/dsl/http_client.rb +17 -18
  41. data/lib/inferno/dsl/http_client_builder.rb +4 -4
  42. data/lib/inferno/dsl/input_output_handling.rb +1 -1
  43. data/lib/inferno/dsl/request_storage.rb +2 -2
  44. data/lib/inferno/dsl/resume_test_route.rb +36 -34
  45. data/lib/inferno/dsl/runnable.rb +13 -10
  46. data/lib/inferno/entities/header.rb +7 -7
  47. data/lib/inferno/entities/request.rb +35 -36
  48. data/lib/inferno/entities/session_data.rb +6 -6
  49. data/lib/inferno/entities/test.rb +4 -4
  50. data/lib/inferno/entities/test_group.rb +2 -2
  51. data/lib/inferno/entities/test_run.rb +1 -1
  52. data/lib/inferno/jobs/execute_test_run.rb +1 -1
  53. data/lib/inferno/jobs/resume_test_run.rb +1 -1
  54. data/lib/inferno/public/bundle.js +15 -15
  55. data/lib/inferno/repositories/messages.rb +1 -1
  56. data/lib/inferno/repositories/repository.rb +1 -1
  57. data/lib/inferno/repositories/requests.rb +6 -6
  58. data/lib/inferno/repositories/results.rb +16 -16
  59. data/lib/inferno/repositories/session_data.rb +6 -6
  60. data/lib/inferno/repositories/test_runs.rb +6 -6
  61. data/lib/inferno/repositories/test_sessions.rb +7 -7
  62. data/lib/inferno/test_runner.rb +3 -3
  63. data/lib/inferno/utils/preset_template_generator.rb +1 -1
  64. data/lib/inferno/version.rb +1 -1
  65. data/spec/factories/test_run.rb +1 -1
  66. data/spec/factories/test_session.rb +1 -1
  67. data/spec/fixtures/basic_test_suite.rb +1 -0
  68. metadata +25 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7e278b200d33582c51a4dcfcee3c7ef321162ecbc0c1c12225601b8b03627747
4
- data.tar.gz: 80a3cac6f4de4e9c191733bedc22e31182acc2ef135f1473a52ff971fd2ab0b2
3
+ metadata.gz: 987a2db725cb3b2517f392d2e566614f3e5fcd454f27164e6de64ec615b5661c
4
+ data.tar.gz: 1cce12a803e20d288e72f9f3b1dfd1def94f9cbe1fcb73f4c862f1063c3d5c8c
5
5
  SHA512:
6
- metadata.gz: 5834a48e2c99300e08a1acacc040fa7a96fc85b74c6b5de4d64a3f0265e9c79dad017d7becc927c6bfd3be9ab690008c48223c29e129e8d28bc70edfe3e75e59
7
- data.tar.gz: 7cfaa5b8d64596e7d245026cf35f93b2093c0517bcdcae7b14ed4778e369c3244ea1cf8ce8179153001ed82275293edea25379a9a0a5cf90aecd027ddb728b1f
6
+ metadata.gz: 646f385e975efc9eb957aa707934e7c3e04977c97bd73dae4a21a8dbfd60869c1662f1832bfac1a38cb534ed18ebc93d771937a8978a7fb5dba7e0b3db54b974
7
+ data.tar.gz: 106dc72ddaaba5f02be715aef376984adb7c97ae71c62668d45da094bcfe430ee1a7c5d940c99e92bfc645bc31c8bb2013406aaffb2a072fc1d0fc9771a3187f
@@ -1,5 +1,6 @@
1
1
  require_relative 'console'
2
2
  require_relative 'migration'
3
+ require_relative 'services'
3
4
  require_relative 'suite'
4
5
  require_relative 'suites'
5
6
 
@@ -16,11 +17,23 @@ module Inferno
16
17
  Migration.new.run
17
18
  end
18
19
 
20
+ desc 'start', 'Start Inferno'
21
+ def start
22
+ if `gem list -i foreman`.chomp == 'false'
23
+ puts "You must install foreman with 'gem install foreman' prior to running inferno."
24
+ end
25
+
26
+ system 'foreman start --env=/dev/null'
27
+ end
28
+
19
29
  desc 'suites', 'List available test suites'
20
30
  def suites
21
31
  Suites.new.run
22
32
  end
23
33
 
34
+ desc 'services stop/start', 'Start or stop background services'
35
+ subcommand 'services', Services
36
+
24
37
  desc 'suite SUBCOMMAND ...ARGS', 'Perform suite-based operations'
25
38
  subcommand 'suite', Suite
26
39
  end
@@ -0,0 +1,56 @@
1
+ module Inferno
2
+ module CLI
3
+ class Services < Thor
4
+ no_commands do
5
+ def base_command
6
+ 'docker-compose -f docker-compose.background.yml'
7
+ end
8
+ end
9
+
10
+ desc 'start', 'Start background services'
11
+ option :foreground,
12
+ default: false,
13
+ type: :boolean,
14
+ desc: 'Run services in foreground'
15
+ def start
16
+ command = "#{base_command} up"
17
+ command += ' -d' unless options[:foreground]
18
+
19
+ system command
20
+ end
21
+
22
+ desc 'stop', 'Stop background services'
23
+ def stop
24
+ system "#{base_command} down"
25
+ end
26
+
27
+ desc 'build', 'Build background service images'
28
+ def build
29
+ system "#{base_command} build"
30
+ end
31
+
32
+ desc 'pull', 'Pull background service images'
33
+ def pull
34
+ system "#{base_command} pull"
35
+ end
36
+
37
+ desc 'logs', 'Display the logs for the background services'
38
+ option :follow,
39
+ default: false,
40
+ aliases: [:f],
41
+ type: :boolean,
42
+ desc: 'Follow log output'
43
+ option :tail,
44
+ banner: 'string',
45
+ default: 'all',
46
+ desc: 'Number of lines to show from the end of the logs for each container'
47
+ def logs
48
+ command = "#{base_command} logs"
49
+ command += ' -f' if options[:follow]
50
+ command += " --tail #{options[:tail]}" if options[:tail]
51
+
52
+ system command
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,4 +1,5 @@
1
1
  require 'hanami/middleware/body_parser'
2
+ require_relative 'router'
2
3
 
3
4
  module Inferno
4
5
  module Web
@@ -1,20 +1,18 @@
1
1
  module Inferno
2
2
  module Web
3
3
  module Controllers
4
- class Controller
5
- # Ensure that each request gets a new instance of the controller.
6
- def self.call(params)
7
- new.call(params)
4
+ class Controller < Hanami::Action
5
+ def self.call(...)
6
+ new.call(...)
8
7
  end
9
8
 
10
9
  def self.inherited(subclass)
11
10
  super
12
11
 
13
- # This does some sort of magic that requires it be included in the
14
- # subclass rather than superclass.
15
- subclass.include Hanami::Action
12
+ subclass.include Import[repo: "inferno.repositories.#{subclass.resource_name}"]
16
13
 
17
- subclass.include Import[repo: "repositories.#{subclass.resource_name}"]
14
+ subclass.config.default_request_format = :json
15
+ subclass.config.default_response_format = :json
18
16
 
19
17
  subclass.define_method(:serialize) do |*args|
20
18
  Inferno::Web::Serializers.const_get(self.class.resource_class).render(*args)
@@ -3,11 +3,11 @@ module Inferno
3
3
  module Controllers
4
4
  module Requests
5
5
  class Show < Controller
6
- def call(params)
7
- request = repo.find_full_request(params[:id])
6
+ def handle(req, res)
7
+ request = repo.find_full_request(req.params[:id])
8
8
  halt 404 if request.nil?
9
9
 
10
- self.body = serialize(request, view: :full)
10
+ res.body = serialize(request, view: :full)
11
11
  end
12
12
  end
13
13
  end
@@ -4,9 +4,9 @@ module Inferno
4
4
  module TestRuns
5
5
  class Create < Controller
6
6
  include Import[
7
- test_sessions_repo: 'repositories.test_sessions',
8
- session_data_repo: 'repositories.session_data',
9
- test_runs_repo: 'repositories.test_runs'
7
+ test_sessions_repo: 'inferno.repositories.test_sessions',
8
+ session_data_repo: 'inferno.repositories.session_data',
9
+ test_runs_repo: 'inferno.repositories.test_runs'
10
10
  ]
11
11
 
12
12
  PARAMS = [:test_session_id, :test_suite_id, :test_group_id, :test_id].freeze
@@ -42,38 +42,34 @@ module Inferno
42
42
  end
43
43
  end
44
44
 
45
- def call(params)
46
- test_session = test_sessions_repo.find(params[:test_session_id])
45
+ def handle(req, res)
46
+ test_session = test_sessions_repo.find(req.params[:test_session_id])
47
47
 
48
48
  # if testsession.nil?
49
49
  if test_runs_repo.active_test_run_for_session?(test_session.id)
50
- self.status = 409
51
- self.body = { error: 'Cannot run new test while another test run is in progress' }.to_json
52
- return
50
+ halt 409, { error: 'Cannot run new test while another test run is in progress' }.to_json
53
51
  end
54
52
 
55
53
  verify_runnable(
56
- repo.build_entity(create_params(params)).runnable,
57
- params[:inputs],
54
+ repo.build_entity(create_params(req.params)).runnable,
55
+ req.params[:inputs],
58
56
  test_session.suite_options
59
57
  )
60
58
 
61
- test_run = repo.create(create_params(params).merge(status: 'queued'))
59
+ test_run = repo.create(create_params(req.params).merge(status: 'queued'))
62
60
 
63
- self.body = serialize(test_run, suite_options: test_session.suite_options)
61
+ res.body = serialize(test_run, suite_options: test_session.suite_options)
64
62
 
65
- persist_inputs(params, test_run)
63
+ persist_inputs(req.params, test_run)
66
64
 
67
65
  Jobs.perform(Jobs::ExecuteTestRun, test_run.id)
68
66
  rescue Sequel::ValidationFailed, Sequel::ForeignKeyConstraintViolation,
69
67
  Inferno::Exceptions::RequiredInputsNotFound,
70
68
  Inferno::Exceptions::NotUserRunnableException => e
71
- self.body = { errors: e.message }.to_json
72
- self.status = 422
69
+ halt 422, { errors: e.message }.to_json
73
70
  rescue StandardError => e
74
71
  Application['logger'].error(e.full_message)
75
- self.body = { errors: e.message }.to_json
76
- self.status = 500
72
+ halt 500, { errors: e.message }.to_json
77
73
  end
78
74
 
79
75
  def create_params(params)
@@ -4,21 +4,20 @@ module Inferno
4
4
  module TestRuns
5
5
  class Destroy < Controller
6
6
  include Import[
7
- test_runs_repo: 'repositories.test_runs',
8
- results_repo: 'repositories.results'
7
+ test_runs_repo: 'inferno.repositories.test_runs',
8
+ results_repo: 'inferno.repositories.results'
9
9
  ]
10
10
 
11
- def call(params)
12
- test_run = test_runs_repo.find(params[:id])
11
+ def handle(req, res)
12
+ test_run = test_runs_repo.find(req.params[:id])
13
13
 
14
14
  if test_run.nil? || ['done', 'cancelling'].include?(test_run.status)
15
15
  # If it doesn't exist, already finished, or currently being cancelled
16
- self.status = 204
17
- return
16
+ halt 204
18
17
  end
19
18
 
20
19
  test_run_is_waiting = (test_run.status == 'waiting')
21
- test_runs_repo.mark_as_cancelling(params[:id])
20
+ test_runs_repo.mark_as_cancelling(req.params[:id])
22
21
 
23
22
  if test_run_is_waiting
24
23
  waiting_result = results_repo.find_waiting_result(test_run_id: test_run.id)
@@ -26,11 +25,10 @@ module Inferno
26
25
  Jobs.perform(Jobs::ResumeTestRun, test_run.id)
27
26
  end
28
27
 
29
- self.status = 204
28
+ res.status = 204
30
29
  rescue StandardError => e
31
30
  Application['logger'].error(e.full_message)
32
- self.body = { errors: e.message }.to_json
33
- self.status = 500
31
+ halt 500, { errors: e.message }.to_json
34
32
  end
35
33
  end
36
34
  end
@@ -4,11 +4,11 @@ module Inferno
4
4
  module TestRuns
5
5
  module Results
6
6
  class Index < Controller
7
- include Import[test_runs_repo: 'repositories.test_runs']
7
+ include Import[test_runs_repo: 'inferno.repositories.test_runs']
8
8
 
9
- def call(params)
10
- results = test_runs_repo.results_for_test_run(params[:test_run_id])
11
- self.body = serialize(results)
9
+ def handle(req, res)
10
+ results = test_runs_repo.results_for_test_run(req.params[:test_run_id])
11
+ res.body = serialize(results)
12
12
  end
13
13
  end
14
14
  end
@@ -1,26 +1,28 @@
1
+ require_relative '../../serializers/test_run'
2
+
1
3
  module Inferno
2
4
  module Web
3
5
  module Controllers
4
6
  module TestRuns
5
7
  class Show < Controller
6
- include Import[test_sessions_repo: 'repositories.test_sessions']
8
+ include Import[test_sessions_repo: 'inferno.repositories.test_sessions']
7
9
 
8
- def call(params)
9
- test_run = repo.find(params[:id])
10
+ def handle(req, res)
11
+ test_run = repo.find(req.params[:id])
10
12
  halt 404 if test_run.nil?
11
13
 
12
- if params[:include_results] == 'true'
14
+ if req.params[:include_results] == 'true'
13
15
  results_repo = Inferno::Repositories::Results.new
14
16
  test_run.results =
15
- if params[:after].present?
16
- results_repo.test_run_results_after(test_run_id: test_run.id, after: Time.parse(params[:after]))
17
+ if req.params[:after].present?
18
+ results_repo.test_run_results_after(test_run_id: test_run.id, after: Time.parse(req.params[:after]))
17
19
  else
18
20
  repo.results_for_test_run(test_run.id)
19
21
  end
20
22
  end
21
23
 
22
24
  test_session = test_sessions_repo.find(test_run.test_session_id)
23
- self.body = serialize(test_run, suite_options: test_session.suite_options)
25
+ res.body = serialize(test_run, suite_options: test_session.suite_options)
24
26
  end
25
27
  end
26
28
  end
@@ -1,3 +1,6 @@
1
+ require_relative '../controller'
2
+ require_relative '../../serializers/test_session'
3
+
1
4
  module Inferno
2
5
  module Web
3
6
  module Controllers
@@ -5,22 +8,20 @@ module Inferno
5
8
  class Create < Controller
6
9
  PARAMS = [:test_suite_id, :suite_options].freeze
7
10
 
8
- def call(raw_params)
9
- params = raw_params.to_h
10
- params.merge!(JSON.parse(request.body.string).symbolize_keys) unless request.body.string.blank?
11
+ def handle(req, res)
12
+ params = req.params.to_h
13
+ params.merge!(JSON.parse(req.body.string).symbolize_keys) unless req.body.string.blank?
11
14
 
12
15
  session = repo.create(create_params(params))
13
16
 
14
17
  repo.apply_preset(session.id, params[:preset_id]) if params[:preset_id].present?
15
18
 
16
- self.body = serialize(session)
19
+ res.body = serialize(session)
17
20
  rescue Sequel::ValidationFailed, Sequel::ForeignKeyConstraintViolation => e
18
- self.body = { errors: e.message }.to_json
19
- self.status = 422
21
+ halt 422, { errors: e.message }.to_json
20
22
  rescue StandardError => e
21
23
  Application['logger'].error(e.full_message)
22
- self.body = { errors: e.message }.to_json
23
- self.status = 500
24
+ halt 500, { errors: e.message }.to_json
24
25
  end
25
26
 
26
27
  def create_params(params)
@@ -3,12 +3,12 @@ module Inferno
3
3
  module Controllers
4
4
  module TestSessions
5
5
  class LastTestRun < Controller
6
- include Import[test_runs_repo: 'repositories.test_runs']
6
+ include Import[test_runs_repo: 'inferno.repositories.test_runs']
7
7
 
8
- def call(params)
9
- test_run = test_runs_repo.last_test_run(params[:test_session_id])
8
+ def handle(req, res)
9
+ test_run = test_runs_repo.last_test_run(req.params[:id])
10
10
 
11
- self.body =
11
+ res.body =
12
12
  if test_run.nil?
13
13
  nil
14
14
  else
@@ -4,14 +4,14 @@ module Inferno
4
4
  module TestSessions
5
5
  module Results
6
6
  class Index < Controller
7
- include Import[test_sessions_repo: 'repositories.test_sessions']
7
+ include Import[test_sessions_repo: 'inferno.repositories.test_sessions']
8
8
 
9
- def call(params)
10
- self.body =
11
- if params[:all] == 'true'
12
- serialize(test_sessions_repo.results_for_test_session(params[:test_session_id]))
9
+ def handle(req, res)
10
+ res.body =
11
+ if req.params[:all] == 'true'
12
+ serialize(test_sessions_repo.results_for_test_session(req.params[:id]))
13
13
  else
14
- serialize(repo.current_results_for_test_session(params[:test_session_id]))
14
+ serialize(repo.current_results_for_test_session(req.params[:id]))
15
15
  end
16
16
  end
17
17
  end
@@ -1,3 +1,5 @@
1
+ require_relative '../../controller'
2
+
1
3
  module Inferno
2
4
  module Web
3
5
  module Controllers
@@ -5,35 +7,33 @@ module Inferno
5
7
  module SessionData
6
8
  class ApplyPreset < Controller
7
9
  include Import[
8
- test_sessions_repo: 'repositories.test_sessions',
9
- presets_repo: 'repositories.presets'
10
+ test_sessions_repo: 'inferno.repositories.test_sessions',
11
+ presets_repo: 'inferno.repositories.presets'
10
12
  ]
11
13
 
12
14
  def self.resource_class
13
15
  'SessionData'
14
16
  end
15
17
 
16
- def call(params)
17
- test_session_id = params[:test_session_id]
18
+ def handle(req, res)
19
+ test_session_id = req.params[:id]
18
20
  test_session = test_sessions_repo.find(test_session_id)
19
21
 
20
22
  if test_session.nil?
21
23
  Application[:logger].error("Unknown test session #{test_session_id}")
22
- self.status = 404
23
- return
24
+ halt 404
24
25
  end
25
26
 
26
- preset_id = params[:preset_id]
27
+ preset_id = req.params[:preset_id]
27
28
  preset = presets_repo.find(preset_id)
28
29
 
29
30
  if preset.nil?
30
31
  Application[:logger].error("Unknown preset #{preset_id}")
31
- self.status = 404
32
- return
32
+ halt 404
33
33
  end
34
34
 
35
35
  test_sessions_repo.apply_preset(test_session_id, preset_id)
36
- self.status = 200
36
+ res.status = 200
37
37
  end
38
38
  end
39
39
  end
@@ -1,17 +1,19 @@
1
+ require_relative '../../../serializers/session_data'
2
+
1
3
  module Inferno
2
4
  module Web
3
5
  module Controllers
4
6
  module TestSessions
5
7
  module SessionData
6
8
  class Index < Controller
7
- include Import[session_data_repo: 'repositories.session_data']
9
+ include Import[session_data_repo: 'inferno.repositories.session_data']
8
10
 
9
11
  def self.resource_class
10
12
  'SessionData'
11
13
  end
12
14
 
13
- def call(params)
14
- self.body = serialize(session_data_repo.get_all_from_session(params[:test_session_id]))
15
+ def handle(req, res)
16
+ res.body = serialize(session_data_repo.get_all_from_session(req.params[:id]))
15
17
  end
16
18
  end
17
19
  end
@@ -3,11 +3,11 @@ module Inferno
3
3
  module Controllers
4
4
  module TestSessions
5
5
  class Show < Controller
6
- def call(params)
7
- test_session = repo.find(params[:id])
6
+ def handle(req, res)
7
+ test_session = repo.find(req.params[:id])
8
8
  halt 404 if test_session.nil?
9
9
 
10
- self.body = serialize(test_session)
10
+ res.body = serialize(test_session)
11
11
  end
12
12
  end
13
13
  end
@@ -3,11 +3,11 @@ module Inferno
3
3
  module Controllers
4
4
  module TestSuites
5
5
  class CheckConfiguration < Controller
6
- def call(params)
7
- test_suite = repo.find(params[:id])
6
+ def handle(req, res)
7
+ test_suite = repo.find(req.params[:id])
8
8
  halt 404 if test_suite.nil?
9
9
 
10
- self.body =
10
+ res.body =
11
11
  Inferno::Web::Serializers::Message.render(test_suite.configuration_messages(force_recheck: true))
12
12
  end
13
13
  end
@@ -3,8 +3,8 @@ module Inferno
3
3
  module Controllers
4
4
  module TestSuites
5
5
  class Index < Controller
6
- def call(_params)
7
- self.body = serialize(repo.all, view: :summary)
6
+ def handle(_req, res)
7
+ res.body = serialize(repo.all, view: :summary)
8
8
  end
9
9
  end
10
10
  end
@@ -3,11 +3,11 @@ module Inferno
3
3
  module Controllers
4
4
  module TestSuites
5
5
  class Show < Controller
6
- def call(params)
7
- test_suite = repo.find(params[:id])
6
+ def handle(req, res)
7
+ test_suite = repo.find(req.params[:id])
8
8
  halt 404 if test_suite.nil?
9
9
 
10
- self.body = serialize(test_suite, view: :full)
10
+ res.body = serialize(test_suite, view: :full)
11
11
  end
12
12
  end
13
13
  end
@@ -38,14 +38,18 @@
38
38
  height: 100%;
39
39
  display: flex;
40
40
  flex-direction: column;
41
+ overflow: hidden;
41
42
  }
42
43
  .banner {
43
44
  flex-shrink: 1;
45
+ overflow: 'auto';
46
+ white-space: nowrap;
44
47
  }
45
48
  .app {
46
49
  flex-grow: 1;
47
50
  display: flex;
48
51
  flex-direction: column;
52
+ overflow: auto;
49
53
  }
50
54
  </style>
51
55
  <title>Inferno</title>