diff --git a/.gitlab/ci/review-apps/qa.gitlab-ci.yml b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
index 77291aac9075a45de86482764b827dca4ecd2302..58ceb744480f5c3433b62445da1d029d04205dc3 100644
--- a/.gitlab/ci/review-apps/qa.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
@@ -13,8 +13,8 @@ include:
 
 .test_variables:
   variables:
-    QA_DEBUG: "true"
     QA_GENERATE_ALLURE_REPORT: "true"
+    COLORIZED_LOGS: "true"
     GITLAB_USERNAME: "root"
     GITLAB_PASSWORD: "${REVIEW_APPS_ROOT_PASSWORD}"
     GITLAB_ADMIN_USERNAME: "root"
diff --git a/qa/.gitignore b/qa/.gitignore
index 3c5db4b565e79f826dc4ab150e3534186f8cc646..31ab17eeeaf47aeb5f950efd549528805fb44ac7 100644
--- a/qa/.gitignore
+++ b/qa/.gitignore
@@ -1,4 +1,3 @@
-tmp/
 reports/
 no_of_examples/
 
diff --git a/qa/Gemfile b/qa/Gemfile
index b504d6d4e9021edf830bfc04a3db90e56b501a98..28fd1c9394dbe1170a1a6e07d8d317abbe507be1 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -2,7 +2,7 @@
 
 source 'https://rubygems.org'
 
-gem 'gitlab-qa', require: 'gitlab/qa'
+gem 'gitlab-qa', '~> 7', require: 'gitlab/qa'
 gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
 gem 'allure-rspec', '~> 2.16.0'
 gem 'capybara', '~> 3.35.0'
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 675d163fe9d3c2330e0fcf74c099d12eb9ad2bad..ca23c4ac39d9c6b8e1f7e1b3f630f678cf432eaf 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -121,7 +121,7 @@ GEM
     gitlab (4.18.0)
       httparty (~> 0.18)
       terminal-table (>= 1.5.1)
-    gitlab-qa (7.24.4)
+    gitlab-qa (7.29.1)
       activesupport (~> 6.1)
       gitlab (~> 4.18.0)
       http (~> 5.0)
@@ -368,7 +368,7 @@ DEPENDENCIES
   deprecation_toolkit (~> 1.5.1)
   faker (~> 2.19, >= 2.19.0)
   fog-google (~> 1.17)
-  gitlab-qa
+  gitlab-qa (~> 7)
   influxdb-client (~> 1.17)
   knapsack (~> 4.0)
   octokit (~> 4.21)
diff --git a/qa/qa/page/base.rb b/qa/qa/page/base.rb
index 248c5f384388cee9690b26e9e31560556366bd35..775a5ead5f783e4b216901c8a0812669e5c7bf59 100644
--- a/qa/qa/page/base.rb
+++ b/qa/qa/page/base.rb
@@ -5,10 +5,12 @@
 module QA
   module Page
     class Base
-      prepend Support::Page::Logging if Runtime::Env.debug?
+      prepend Support::Page::Logging
+
       include Capybara::DSL
       include Scenario::Actable
       include Support::WaitForRequests
+
       extend Validatable
       extend SingleForwardable
 
diff --git a/qa/qa/resource/base.rb b/qa/qa/resource/base.rb
index fc7f8445d4e9591e31c6990c15cd939912458f3e..ba1b581b10070c9dac227e4de808ff70586542ef 100644
--- a/qa/qa/resource/base.rb
+++ b/qa/qa/resource/base.rb
@@ -99,13 +99,13 @@ def log_and_record_fabrication(fabrication_method, resource, parents, args)
               fabrication_time: fabrication_time
             )
 
-            Runtime::Logger.debug do
+            Runtime::Logger.info do
               msg = ["==#{'=' * parents.size}>"]
               msg << "#{fabrication_http_method} a #{Rainbow(name).black.bg(:white)}"
               msg << resource.identifier
               msg << "as a dependency of #{parents.last}" if parents.any?
               msg << "via #{fabrication_method}"
-              msg << "in #{fabrication_time} seconds"
+              msg << "in #{fabrication_time.round(2)} seconds"
 
               msg.compact.join(' ')
             end
@@ -161,7 +161,7 @@ def fabricate!(*_args)
       end
 
       def visit!(skip_resp_code_check: false)
-        Runtime::Logger.debug("Visiting #{Rainbow(self.class.name).black.bg(:white)} at #{web_url}")
+        Runtime::Logger.info("Visiting #{Rainbow(self.class.name).black.bg(:white)} at #{web_url}")
 
         # Just in case an async action is not yet complete
         Support::WaitForRequests.wait_for_requests(skip_resp_code_check: skip_resp_code_check)
@@ -224,7 +224,7 @@ def identifier
       def remove_via_api!
         super
 
-        Runtime::Logger.debug(["Removed a #{self.class.name}", identifier].compact.join(' '))
+        Runtime::Logger.info(["Removed a #{self.class.name}", identifier].compact.join(' '))
       end
 
       protected
diff --git a/qa/qa/resource/members.rb b/qa/qa/resource/members.rb
index 0061f74cec5d95cf9e845410d7b128ffc0d59ba0..d9300f80f5dd618a325eb7b44c0bc12bd50e295d 100644
--- a/qa/qa/resource/members.rb
+++ b/qa/qa/resource/members.rb
@@ -9,7 +9,7 @@ module Resource
     module Members
       def add_member(user, access_level = AccessLevel::DEVELOPER)
         Support::Retrier.retry_until do
-          QA::Runtime::Logger.debug(%Q[Adding user #{user.username} to #{full_path} #{self.class.name}])
+          QA::Runtime::Logger.info(%(Adding user #{user.username} to #{full_path} #{self.class.name}))
 
           response = post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level }
           break true if response.code == QA::Support::API::HTTP_STATUS_CREATED
@@ -18,7 +18,7 @@ def add_member(user, access_level = AccessLevel::DEVELOPER)
       end
 
       def remove_member(user)
-        QA::Runtime::Logger.debug(%Q[Removing user #{user.username} from #{full_path} #{self.class.name}])
+        QA::Runtime::Logger.info(%(Removing user #{user.username} from #{full_path} #{self.class.name}))
 
         delete Runtime::API::Request.new(api_client, "#{api_members_path}/#{user.id}").url
       end
@@ -29,7 +29,7 @@ def list_members
 
       def invite_group(group, access_level = AccessLevel::GUEST)
         Support::Retrier.retry_until do
-          QA::Runtime::Logger.debug(%Q[Sharing #{self.class.name} with #{group.name}])
+          QA::Runtime::Logger.info(%(Sharing #{self.class.name} with #{group.name}))
 
           response = post Runtime::API::Request.new(api_client, api_share_path).url, { group_id: group.id, group_access: access_level }
           response.code == QA::Support::API::HTTP_STATUS_CREATED
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index c014563671dddbce97a66057ec79240d67c812cd..278bdd1cabd35d6e20698dd96e3e1171b73f13b6 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -90,21 +90,19 @@ def api_delete_path
         "/runners/#{id}"
       end
 
-      def api_get_path
-      end
+      def api_get_path; end
 
       def api_post_path
         "/runners"
       end
 
-      def api_post_body
-      end
+      def api_post_body; end
 
       private
 
       def dump_logs
         if @docker_container.running?
-          @docker_container.logs { |line| QA::Runtime::Logger.debug(line) }
+          @docker_container.logs
         else
           QA::Runtime::Logger.debug("No runner container found named #{name}")
         end
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 0db5314de4d0d24113b9fa1e3ff66cffe93a5ca2..7677a18911685f8cb4ba5d671fa13ff755a615b5 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -73,10 +73,6 @@ def default_branch
         ENV['QA_DEFAULT_BRANCH'] || 'main'
       end
 
-      def log_destination
-        ENV['QA_LOG_PATH'] || $stdout
-      end
-
       def colorized_logs?
         enabled?(ENV['COLORIZED_LOGS'], default: false)
       end
diff --git a/qa/qa/runtime/logger.rb b/qa/qa/runtime/logger.rb
index 1f17146303abd728b631ae4b3c78e947e205118d..fa626eb9d16fdebfa1dfea2173ff041d97f3fa18 100644
--- a/qa/qa/runtime/logger.rb
+++ b/qa/qa/runtime/logger.rb
@@ -9,10 +9,14 @@ class Logger
 
       def_delegators :logger, :debug, :info, :warn, :error, :fatal, :unknown
 
+      # Global logger instance
+      #
+      # @return [ActiveSupport::Logger]
       def self.logger
         @logger ||= Gitlab::QA::TestLogger.logger(
-          level: Runtime::Env.debug? ? ::Logger::DEBUG : ::Logger::INFO,
-          source: 'QA Tests'
+          level: Runtime::Env.debug? ? "DEBUG" : Gitlab::QA::Runtime::Env.log_level,
+          source: 'QA Tests',
+          path: File.expand_path('../../tmp', __dir__)
         )
       end
     end
diff --git a/qa/qa/service/docker_run/base.rb b/qa/qa/service/docker_run/base.rb
index 85c06e6c307a7edfe8a13d19d8f1d3c1b2c84dcf..53980b8e0516ec42eea72994b0a4b3cbaeb87de0 100644
--- a/qa/qa/service/docker_run/base.rb
+++ b/qa/qa/service/docker_run/base.rb
@@ -12,9 +12,7 @@ def initialize
         end
 
         def logs
-          shell "docker logs #{@name}" do |line|
-            yield "   #{line.chomp}"
-          end
+          shell "docker logs #{@name}"
         end
 
         def network
diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb
index 0a8ac39dabd82f3f6c579dd5d3ee304b8b8ce91b..1584b577af13ef2f216f495b0c394717b30abcb5 100644
--- a/qa/qa/service/docker_run/gitlab_runner.rb
+++ b/qa/qa/service/docker_run/gitlab_runner.rb
@@ -26,13 +26,13 @@ def initialize(name)
         end
 
         def config
-          @config ||= <<~END
+          @config ||= <<~CONFIG
             concurrent = 1
             check_interval = 0
 
             [session_server]
               session_timeout = 1800
-          END
+          CONFIG
         end
 
         def register!
@@ -40,15 +40,14 @@ def register!
             docker run -d --rm --network #{runner_network} --name #{@name}
             #{'-v /var/run/docker.sock:/var/run/docker.sock' if @executor == :docker}
             --privileged
-            #{@image}  #{add_gitlab_tls_cert if @address.include? "https"} && docker exec --detach #{@name} sh -c "#{register_command}"
+            #{@image}  #{add_gitlab_tls_cert if @address.include? 'https'}
+            && docker exec --detach #{@name} sh -c "#{register_command}"
           CMD
 
           wait_until_running_and_configured
 
           # Prove airgappedness
-          if runner_network == 'airgapped'
-            shell("docker exec #{@name} sh -c '#{prove_airgap}'")
-          end
+          shell("docker exec #{@name} sh -c '#{prove_airgap}'") if runner_network == 'airgapped'
         end
 
         def tags=(tags)
@@ -66,7 +65,7 @@ def register_command
           args << "--registration-token #{@token}"
 
           args << if run_untagged
-                    raise CONFLICTING_VARIABLES_MESSAGE % [:tags=, :run_untagged, run_untagged] if @tags&.any?
+                    raise format(CONFLICTING_VARIABLES_MESSAGE, :tags=, :run_untagged, run_untagged) if @tags&.any?
 
                     '--run-untagged=true'
                   else
@@ -86,7 +85,7 @@ def register_command
           end
 
           <<~CMD.strip
-            printf '#{config.chomp.gsub(/\n/, "\\n").gsub('"', '\"')}' > /etc/gitlab-runner/config.toml &&
+            printf '#{config.chomp.gsub(/\n/, '\\n').gsub('"', '\"')}' > /etc/gitlab-runner/config.toml &&
             gitlab-runner register \
               #{args.join(' ')} &&
             gitlab-runner run
diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb
index 1215268919c94d9292b108cf512e19655cf1407f..8563c3656a8f6ff0ba4d22561b69a32bc12049d1 100644
--- a/qa/qa/service/praefect_manager.rb
+++ b/qa/qa/service/praefect_manager.rb
@@ -115,7 +115,7 @@ def stop_node(name)
 
       def node_state(name)
         state = "stopped"
-        wait_until_shell_command("docker inspect -f {{.State.Status}} #{name}") do |line|
+        wait_until_shell_command("docker inspect -f {{.State.Status}} #{name}", stream_progress: false) do |line|
           QA::Runtime::Logger.debug(line)
           break state = "running" if line.include?("running")
           break state = "paused" if line.include?("paused")
@@ -164,7 +164,8 @@ def reconcile_node_with_node(target, reference)
       end
 
       def query_read_distribution
-        output = shell "docker exec #{@gitlab} bash -c 'curl -s http://localhost:9090/api/v1/query?query=gitaly_praefect_read_distribution'" do |line|
+        cmd = "docker exec #{@gitlab} bash -c 'curl -s http://localhost:9090/api/v1/query?query=gitaly_praefect_read_distribution'"
+        output = shell(cmd, stream_progress: false) do |line|
           QA::Runtime::Logger.debug(line)
           break line
         end
diff --git a/qa/qa/service/shellout.rb b/qa/qa/service/shellout.rb
index 33d1d10b5151f4bad890072fea2b2ee18f7cf352..0507ed6b0b0cf443d618dca31ddbe204c342afcd 100644
--- a/qa/qa/service/shellout.rb
+++ b/qa/qa/service/shellout.rb
@@ -6,34 +6,40 @@ module QA
   module Service
     module Shellout
       using Rainbow
+
       CommandError = Class.new(StandardError)
 
       module_function
 
-      ##
-      # TODO, make it possible to use generic QA framework classes
-      # as a library - gitlab-org/gitlab-qa#94
-      #
-      def shell(command, stdin_data: nil, fail_on_exception: true)
-        QA::Runtime::Logger.info("Executing `#{command}`".cyan)
+      def shell(command, stdin_data: nil, fail_on_exception: true, stream_progress: true) # rubocop:disable Metrics/CyclomaticComplexity
+        cmd_string = Array(command).join(' ')
+
+        QA::Runtime::Logger.info("Executing: `#{cmd_string.cyan}`")
 
         Open3.popen2e(*command) do |stdin, out, wait|
           stdin.puts(stdin_data) if stdin_data
           stdin.close if stdin_data
+
+          print_progress_dots = stream_progress && !Runtime::Env.running_in_ci?
           cmd_output = ''
 
-          if block_given?
-            out.each do |line|
-              cmd_output += line
-              yield line
-            end
+          out.each do |line|
+            cmd_output += line
+            yield line if block_given?
+
+            # indicate progress for local run by printing dots
+            print "." if print_progress_dots
           end
 
-          out.each_char { |char| print char }
+          # add newline after progress dots
+          puts if print_progress_dots && !cmd_output.empty?
 
           if wait.value.exited? && wait.value.exitstatus.nonzero? && fail_on_exception
-            raise CommandError, "Command failed: #{command} \nCommand Output: #{cmd_output}"
+            Runtime::Logger.error("Command output:\n#{cmd_output.strip}") unless cmd_output.empty?
+            raise CommandError, "Command: `#{cmd_string}` failed! ✘"
           end
+
+          Runtime::Logger.debug("Command output:\n#{cmd_output.strip}") unless cmd_output.empty?
         end
       end
 
@@ -46,18 +52,17 @@ def sql_to_docker_exec_cmd(sql, username, password, database, host, container)
 
       def wait_until_shell_command(cmd, **kwargs)
         sleep_interval = kwargs.delete(:sleep_interval) || 1
+        stream_progress = kwargs.delete(:stream_progress).then { |arg| arg.nil? ? true : false }
 
         Support::Waiter.wait_until(sleep_interval: sleep_interval, **kwargs) do
-          shell cmd do |line|
+          shell(cmd, stream_progress: stream_progress) do |line|
             break true if yield line
           end
         end
       end
 
       def wait_until_shell_command_matches(cmd, regex, **kwargs)
-        wait_until_shell_command(cmd, **kwargs) do |line|
-          QA::Runtime::Logger.debug(line.chomp)
-
+        wait_until_shell_command(cmd, stream_progress: false, **kwargs) do |line|
           line =~ regex
         end
       end
diff --git a/qa/qa/support/matchers/eventually_matcher.rb b/qa/qa/support/matchers/eventually_matcher.rb
index 2fb5249d9af3265b5089e3991c2d6abeb06ab903..01d07585f576e4e7d00deafdfc72c1f916b4824b 100644
--- a/qa/qa/support/matchers/eventually_matcher.rb
+++ b/qa/qa/support/matchers/eventually_matcher.rb
@@ -53,7 +53,7 @@ def supports_block_expectations?
             def wait_and_check(actual, expectation_name)
               attempt = 0
 
-              QA::Runtime::Logger.debug(
+              QA::Runtime::Logger.info(
                 "Running eventually matcher with '#{operator_msg}' operator with: '#{retry_args}' arguments"
               )
               QA::Support::Retrier.retry_until(**retry_args, log: false) do
diff --git a/qa/qa/support/page/logging.rb b/qa/qa/support/page/logging.rb
index bc5ee645965eee3bd474771b71cf962798f9cfda..6dfb348a347abdda4b7cbf9c7c1ae004e8278d5e 100644
--- a/qa/qa/support/page/logging.rb
+++ b/qa/qa/support/page/logging.rb
@@ -13,15 +13,15 @@ def assert_no_element(name)
         end
 
         def refresh(skip_finished_loading_check: false)
-          log("refreshing #{current_url}")
+          log("refreshing #{current_url}", :info)
 
           super
         end
 
         def scroll_to(selector, text: nil)
-          msg = "scrolling to :#{Rainbow(selector).underline.bright}"
+          msg = "scrolling to :#{highlight_element(selector)}"
           msg += " with text: #{text}" if text
-          log(msg)
+          log(msg, :info)
 
           super
         end
@@ -39,7 +39,7 @@ def find_element(name, **kwargs)
 
           element = super
 
-          log("found :#{Rainbow(name).underline.bright}")
+          log("found :#{name}")
 
           element
         end
@@ -49,41 +49,41 @@ def all_elements(name, **kwargs)
 
           elements = super
 
-          log("found #{elements.size} :#{Rainbow(name).underline.bright}") if elements
+          log("found #{elements.size} :#{name}") if elements
 
           elements
         end
 
         def check_element(name, click_by_js = nil)
-          log("checking :#{name}")
+          log("checking :#{highlight_element(name)}", :info)
 
           super
         end
 
         def uncheck_element(name, click_by_js = nil)
-          log("unchecking :#{name}")
+          log("unchecking :#{highlight_element(name)}", :info)
 
           super
         end
 
         def click_element_coordinates(name, **kwargs)
-          log(%Q(clicking the coordinates of :#{name}))
+          log(%(clicking the coordinates of :#{highlight_element(name)}), :info)
 
           super
         end
 
         def click_element(name, page = nil, **kwargs)
-          msg = ["clicking :#{Rainbow(name).underline.bright}"]
+          msg = ["clicking :#{highlight_element(name)}"]
           msg << ", expecting to be at #{page.class}" if page
-          msg << "with args #{kwargs}"
 
-          log(msg.compact.join(' '))
+          log(msg.join(' '), :info)
+          log("with args #{kwargs}")
 
           super
         end
 
         def click_via_capybara(method, locator)
-          log("clicking via capybara using '#{method}(#{locator})'")
+          log("clicking via capybara using '#{method}(#{locator})'", :info)
 
           super
         end
@@ -91,13 +91,13 @@ def click_via_capybara(method, locator)
         def fill_element(name, content)
           masked_content = name.to_s.match?(/token|key|password/) ? '*****' : content
 
-          log(%Q(filling :#{name} with "#{masked_content}"))
+          log(%(filling :#{highlight_element(name)} with "#{masked_content}"), :info)
 
           super
         end
 
         def select_element(name, value)
-          log(%Q(selecting "#{value}" in :#{name}))
+          log(%(selecting "#{value}" in :#{highlight_element(name)}), :info)
 
           super
         end
@@ -121,7 +121,7 @@ def has_no_element?(name, **kwargs)
         def has_text?(text, **kwargs)
           found = super
 
-          log(%Q{has_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}})
+          log(%(has_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}))
 
           found
         end
@@ -129,7 +129,7 @@ def has_text?(text, **kwargs)
         def has_no_text?(text, **kwargs)
           found = super
 
-          log(%Q{has_no_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}})
+          log(%(has_no_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}))
 
           found
         end
@@ -173,13 +173,26 @@ def within_element_by_index(name, index)
 
         private
 
-        def log(msg)
-          QA::Runtime::Logger.debug(msg)
+        # Log message
+        #
+        # @param [String] msg
+        # @param [Symbol] level
+        # @return [void]
+        def log(msg, level = :debug)
+          QA::Runtime::Logger.public_send(level, msg)
+        end
+
+        # Highlight element for enhanced logging
+        #
+        # @param [String] element
+        # @return [String]
+        def highlight_element(element)
+          element.to_s.underline.bright
         end
 
         def log_has_element_or_not(method, name, found, **kwargs)
-          msg = ["#{method} :#{Rainbow(name).underline.bright}"]
-          msg << %Q(with text "#{kwargs[:text]}") if kwargs[:text]
+          msg = ["#{method} :#{name}"]
+          msg << %(with text "#{kwargs[:text]}") if kwargs[:text]
           msg << "class: #{kwargs[:class]}" if kwargs[:class]
           msg << "(wait: #{kwargs[:wait] || Capybara.default_max_wait_time})"
           msg << "returned: #{found}"
diff --git a/qa/spec/git/repository_spec.rb b/qa/spec/git/repository_spec.rb
index a6a49f5907af780ad8ea042ed0106a21b72d2354..1b88cba2ba5b62ed44f957c74c31b92fd306e435 100644
--- a/qa/spec/git/repository_spec.rb
+++ b/qa/spec/git/repository_spec.rb
@@ -4,6 +4,7 @@
   include QA::Support::Helpers::StubEnv
 
   shared_context 'unresolvable git directory' do
+    let(:logger) { instance_double(Logger, info: nil, debug: nil) }
     let(:repo_uri) { 'http://foo/bar.git' }
     let(:repo_uri_with_credentials) { 'http://root@foo/bar.git' }
     let(:env_vars) { [%q{HOME="temp"}] }
@@ -22,6 +23,7 @@
     before do
       stub_env('GITLAB_USERNAME', 'root')
       allow(repository).to receive(:tmp_home_dir).and_return(tmp_netrc_dir)
+      allow(QA::Runtime::Logger).to receive(:logger).and_return(logger)
     end
 
     around do |example|
diff --git a/qa/spec/resource/base_spec.rb b/qa/spec/resource/base_spec.rb
index 6dac8e0e3eee0e193dbadbde37cefe4187e553ba..8ac00b0a2944c547986e68fd3dae952717f00bc7 100644
--- a/qa/spec/resource/base_spec.rb
+++ b/qa/spec/resource/base_spec.rb
@@ -112,7 +112,7 @@ def self.name
       let(:method) { 'api' }
 
       before do
-        allow(QA::Runtime::Logger).to receive(:debug)
+        allow(QA::Runtime::Logger).to receive(:info)
         allow(resource).to receive(:api_support?).and_return(true)
         allow(resource).to receive(:fabricate_via_api!)
         allow(resource).to receive(:api_client) { api_client }
@@ -123,7 +123,7 @@ def self.name
 
         subject.fabricate_via_api!('something', resource: resource, parents: [])
 
-        expect(QA::Runtime::Logger).to have_received(:debug) do |&msg|
+        expect(QA::Runtime::Logger).to have_received(:info) do |&msg|
           expect(msg.call).to match_regex(log_regex)
         end
       end
@@ -155,7 +155,7 @@ def self.name
       let(:method) { 'browser_ui' }
 
       before do
-        allow(QA::Runtime::Logger).to receive(:debug)
+        allow(QA::Runtime::Logger).to receive(:info)
       end
 
       it 'logs the resource and build method' do
@@ -163,7 +163,7 @@ def self.name
 
         subject.fabricate_via_browser_ui!('something', resource: resource, parents: [])
 
-        expect(QA::Runtime::Logger).to have_received(:debug) do |&msg|
+        expect(QA::Runtime::Logger).to have_received(:info) do |&msg|
           expect(msg.call).to match_regex(log_regex)
         end
       end
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 22603497019be3beb868b988b1bfc81e3089302c..7efcd9bb8d9b292bef47fdfabbd1637bd838e927 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -264,20 +264,6 @@
     end
   end
 
-  describe '.log_destination' do
-    it 'returns $stdout if QA_LOG_PATH is not defined' do
-      stub_env('QA_LOG_PATH', nil)
-
-      expect(described_class.log_destination).to eq($stdout)
-    end
-
-    it 'returns the path if QA_LOG_PATH is defined' do
-      stub_env('QA_LOG_PATH', 'path/to_file')
-
-      expect(described_class.log_destination).to eq('path/to_file')
-    end
-  end
-
   describe '.can_test?' do
     it_behaves_like 'boolean method with parameter',
       method: :can_test?,
diff --git a/qa/spec/runtime/logger_spec.rb b/qa/spec/runtime/logger_spec.rb
index f0fcfa0564ec1a0201cfdd7473c91ca46420bc6e..652037a7041ccd48f201529625e8dd9665c854dd 100644
--- a/qa/spec/runtime/logger_spec.rb
+++ b/qa/spec/runtime/logger_spec.rb
@@ -2,6 +2,6 @@
 
 RSpec.describe QA::Runtime::Logger do
   it 'returns logger instance' do
-    expect(described_class.logger).to be_an_instance_of(::Logger)
+    expect(described_class.logger).to be_an_instance_of(ActiveSupport::Logger)
   end
 end
diff --git a/qa/tmp/.gitignore b/qa/tmp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..cec9082b6d68f3fdd70f2fef2818bf74ec6ef362
--- /dev/null
+++ b/qa/tmp/.gitignore
@@ -0,0 +1,3 @@
+*
+
+!.gitignore