Skip to content

Commit 5c96940

Browse files
committed
Improve the logging system
1 parent d4795d1 commit 5c96940

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

seleniumbase/core/log_helper.py

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,47 @@ def get_html_source_with_base_href(driver, page_source):
105105
return ''
106106

107107

108+
def copytree(src, dst, symlinks=False, ignore=None):
109+
if not os.path.exists(dst):
110+
os.makedirs(dst)
111+
for item in os.listdir(src):
112+
s = os.path.join(src, item)
113+
d = os.path.join(dst, item)
114+
if os.path.isdir(s):
115+
copytree(s, d, symlinks, ignore)
116+
else:
117+
if not os.path.exists(d) or (
118+
os.stat(s).st_mtime - os.stat(d).st_mtime > 1):
119+
shutil.copy2(s, d)
120+
121+
122+
def archive_logs_if_set(log_path, archive_logs=False):
123+
""" Handle Logging """
124+
if "-n" in sys.argv or "".join(sys.argv) == "-c":
125+
return # Skip if multithreaded
126+
if log_path.endswith("/"):
127+
log_path = log_path[:-1]
128+
if not os.path.exists(log_path):
129+
try:
130+
os.makedirs(log_path)
131+
except Exception:
132+
pass # Only reachable during multi-threaded runs
133+
else:
134+
if settings.ARCHIVE_EXISTING_LOGS or archive_logs:
135+
if len(os.listdir(log_path)) > 0:
136+
archived_folder = "%s/../archived_logs/" % log_path
137+
archived_folder = os.path.realpath(archived_folder) + '/'
138+
log_path = os.path.realpath(log_path) + '/'
139+
if not os.path.exists(archived_folder):
140+
try:
141+
os.makedirs(archived_folder)
142+
except Exception:
143+
pass # Only reachable during multi-threaded runs
144+
time_id = str(int(time.time()))
145+
archived_logs = "%slogs_%s" % (archived_folder, time_id)
146+
copytree(log_path, archived_logs)
147+
148+
108149
def log_folder_setup(log_path, archive_logs=False):
109150
""" Handle Logging """
110151
if log_path.endswith("/"):
@@ -116,30 +157,23 @@ def log_folder_setup(log_path, archive_logs=False):
116157
pass # Should only be reachable during multi-threaded runs
117158
else:
118159
archived_folder = "%s/../archived_logs/" % log_path
160+
archived_folder = os.path.realpath(archived_folder) + '/'
119161
if not os.path.exists(archived_folder):
120162
try:
121163
os.makedirs(archived_folder)
122164
except Exception:
123165
pass # Should only be reachable during multi-threaded runs
124-
if not "".join(sys.argv) == "-c":
125-
# Only move log files if the test run is not multi-threaded.
126-
# (Running tests with "-n NUM" will create threads that only
127-
# have "-c" in the sys.argv list. Easy to catch.)
128-
archived_logs = "%slogs_%s" % (
129-
archived_folder, int(time.time()))
130-
if "_logs" not in log_path:
131-
# Don't move files in a custom-named log folder (in case
132-
# the user specifed a folder with important files in it)
133-
# unless the folder name contains "_logs".
134-
# The default name for the log folder is "latest_logs".
135-
return
166+
archived_logs = "%slogs_%s" % (
167+
archived_folder, int(time.time()))
168+
169+
if len(os.listdir(log_path)) > 0:
136170
shutil.move(log_path, archived_logs)
137171
os.makedirs(log_path)
138172
if not settings.ARCHIVE_EXISTING_LOGS and not archive_logs:
139173
shutil.rmtree(archived_logs)
140-
elif len(os.listdir(archived_logs)) == 0:
141-
# Don't archive an empty directory
142-
shutil.rmtree(archived_logs)
143174
else:
144-
# Logs are saved/archived
145-
pass
175+
if ("-n" in sys.argv or "".join(sys.argv) == "-c"):
176+
# Logs are saved/archived now if tests are multithreaded
177+
pass
178+
else:
179+
shutil.rmtree(archived_logs) # (Archive test run later)

seleniumbase/plugins/base_plugin.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# -*- coding: utf-8 -*-
22
""" This is the Nose plugin for setting a test environment and saving logs. """
33

4-
import os
54
import sys
65
import time
76
from nose.plugins import Plugin
@@ -17,7 +16,6 @@ class Base(Plugin):
1716
--env=ENV (Set a test environment. Use "self.env" to use this in tests.)
1817
--data=DATA (Extra data to pass to tests. Use "self.data" in tests.)
1918
--settings-file=FILE (Overrides SeleniumBase settings.py values.)
20-
--log-path=LOG_PATH (The directory where log files get saved to.)
2119
--archive-logs (Archive old log files instead of deleting them.)
2220
--report (The option to create a fancy report after tests complete.)
2321
--show-report If self.report is turned on, then the report will
@@ -59,7 +57,7 @@ def options(self, parser, env):
5957
'--log_path', '--log-path',
6058
dest='log_path',
6159
default='latest_logs/',
62-
help='Where the log files are saved.')
60+
help='Where the log files are saved. (No longer editable!)')
6361
parser.add_option(
6462
'--archive_logs', '--archive-logs',
6563
action="store_true",
@@ -102,16 +100,13 @@ def configure(self, options, conf):
102100
self.page_results_list = []
103101
self.test_count = 0
104102
self.import_error = False
105-
log_path = options.log_path
103+
log_path = 'latest_logs/'
106104
archive_logs = options.archive_logs
107105
log_helper.log_folder_setup(log_path, archive_logs)
108106
if self.report_on:
109107
report_helper.clear_out_old_report_logs(archive_past_runs=False)
110108

111109
def beforeTest(self, test):
112-
test_logpath = self.options.log_path + "/" + test.id()
113-
if not os.path.exists(test_logpath):
114-
os.makedirs(test_logpath)
115110
test.test.environment = self.options.environment
116111
test.test.env = self.options.environment # Add a shortened version
117112
test.test.data = self.options.data
@@ -123,6 +118,8 @@ def beforeTest(self, test):
123118
self.start_time = float(time.time())
124119

125120
def finalize(self, result):
121+
log_helper.archive_logs_if_set(
122+
self.options.log_path, self.options.archive_logs)
126123
if self.report_on:
127124
if not self.import_error:
128125
report_helper.add_bad_page_log_file(self.page_results_list)

seleniumbase/plugins/pytest_plugin.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def pytest_addoption(parser):
2929
--headless (The option to run tests headlessly. The default on Linux OS.)
3030
--headed (The option to run tests with a GUI on Linux OS.)
3131
--start-page=URL (The starting URL for the web browser when tests begin.)
32-
--log-path=LOG_PATH (The directory where log files get saved to.)
3332
--archive-logs (Archive old log files instead of deleting them.)
3433
--slow (The option to slow down the automation.)
3534
--demo (The option to visually see test actions as they occur.)
@@ -113,7 +112,7 @@ def pytest_addoption(parser):
113112
parser.addoption('--log_path', '--log-path',
114113
dest='log_path',
115114
default='latest_logs/',
116-
help='Where the log files are saved.')
115+
help='Where log files are saved. (No longer editable!)')
117116
parser.addoption('--archive_logs', '--archive-logs',
118117
action="store_true",
119118
dest='archive_logs',
@@ -380,7 +379,7 @@ def pytest_configure(config):
380379
sb_config.settings_file = config.getoption('settings_file')
381380
sb_config.user_data_dir = config.getoption('user_data_dir')
382381
sb_config.database_env = config.getoption('database_env')
383-
sb_config.log_path = config.getoption('log_path')
382+
sb_config.log_path = 'latest_logs/' # (No longer editable!)
384383
sb_config.archive_logs = config.getoption('archive_logs')
385384
sb_config.slow_mode = config.getoption('slow_mode')
386385
sb_config.demo_mode = config.getoption('demo_mode')
@@ -433,6 +432,7 @@ def pytest_unconfigure():
433432
except Exception:
434433
pass
435434
sb_config.shared_driver = None
435+
log_helper.archive_logs_if_set(sb_config.log_path, sb_config.archive_logs)
436436

437437

438438
def pytest_runtest_setup():

0 commit comments

Comments
 (0)