inferno_core 0.3.11 → 0.4.0

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