1173 lines
46 KiB
Python
1173 lines
46 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
The SeleniumBase-Behave Connector configures command-line options.
|
|
******************************************************************
|
|
Examples:
|
|
behave -D browser=edge -D dashboard -D headless
|
|
behave -D rs -D dashboard
|
|
behave -D agent="User Agent String" -D demo
|
|
****************************************************************
|
|
-D browser=BROWSER (The web browser to use. Default: "chrome".)
|
|
-D chrome (Shortcut for "-D browser=chrome". On by default.)
|
|
-D edge (Shortcut for "-D browser=edge".)
|
|
-D firefox (Shortcut for "-D browser=firefox".)
|
|
-D ie (Shortcut for "-D browser=ie".)
|
|
-D opera (Shortcut for "-D browser=opera".)
|
|
-D safari (Shortcut for "-D browser=safari".)
|
|
-D settings-file=FILE (Override default SeleniumBase settings.)
|
|
-D env=ENV (Set the test env. Access with "self.env" in tests.)
|
|
-D account=STR (Set account. Access with "self.account" in tests.)
|
|
-D data=STRING (Extra test data. Access with "self.data" in tests.)
|
|
-D var1=STRING (Extra test data. Access with "self.var1" in tests.)
|
|
-D var2=STRING (Extra test data. Access with "self.var2" in tests.)
|
|
-D var3=STRING (Extra test data. Access with "self.var3" in tests.)
|
|
-D variables=DICT (A test var dict. Access with "self.variables".)
|
|
-D user-data-dir=DIR (Set the Chrome user data directory to use.)
|
|
-D protocol=PROTOCOL (The Selenium Grid protocol: http|https.)
|
|
-D server=SERVER (The Selenium Grid server/IP used for tests.)
|
|
-D port=PORT (The Selenium Grid port used by the test server.)
|
|
-D cap-file=FILE (The web browser's desired capabilities to use.)
|
|
-D cap-string=STRING (The web browser's desired capabilities to use.)
|
|
-D proxy=SERVER:PORT (Connect to a proxy server:port for tests.)
|
|
-D proxy=USERNAME:PASSWORD@SERVER:PORT (Use authenticated proxy server.)
|
|
-D proxy-bypass-list=STRING (";"-separated hosts to bypass, Eg "*.foo.com")
|
|
-D proxy-pac-url=URL (Connect to a proxy server using a PAC_URL.pac file.)
|
|
-D proxy-pac-url=USERNAME:PASSWORD@URL (Authenticated proxy with PAC URL.)
|
|
-D agent=STRING (Modify the web browser's User-Agent string.)
|
|
-D mobile (Use the mobile device emulator while running tests.)
|
|
-D metrics=STRING (Set mobile metrics: "CSSWidth,CSSHeight,PixelRatio".)
|
|
-D chromium-arg=ARG (Add a Chromium arg for Chrome/Edge, comma-separated.)
|
|
-D firefox-arg=ARG (Add a Firefox arg for Firefox, comma-separated.)
|
|
-D firefox-pref=SET (Set a Firefox preference:value set, comma-separated.)
|
|
-D extension-zip=ZIP (Load a Chrome Extension .zip|.crx, comma-separated.)
|
|
-D extension-dir=DIR (Load a Chrome Extension directory, comma-separated.)
|
|
-D headless (Run tests in headless mode. The default arg on Linux OS.)
|
|
-D headed (Run tests in headed/GUI mode on Linux OS.)
|
|
-D xvfb (Run tests using the Xvfb virtual display server on Linux OS.)
|
|
-D locale=LOCALE_CODE (Set the Language Locale Code for the web browser.)
|
|
-D pdb (Activate Post Mortem Debug Mode if a test fails.)
|
|
-D interval=SECONDS (The autoplay interval for presentations & tour steps)
|
|
-D start-page=URL (The starting URL for the web browser when tests begin.)
|
|
-D archive-logs (Archive existing log files instead of deleting them.)
|
|
-D archive-downloads (Archive old downloads instead of deleting them.)
|
|
-D time-limit=SECONDS (Safely fail any test that exceeds the time limit.)
|
|
-D slow (Slow down the automation. Faster than using Demo Mode.)
|
|
-D demo (Slow down and visually see test actions as they occur.)
|
|
-D demo-sleep=SECONDS (Set the wait time after Demo Mode actions.)
|
|
-D highlights=NUM (Number of highlight animations for Demo Mode actions.)
|
|
-D message-duration=SECONDS (The time length for Messenger alerts.)
|
|
-D check-js (Check for JavaScript errors after page loads.)
|
|
-D ad-block (Block some types of display ads after page loads.)
|
|
-D block-images (Block images from loading during tests.)
|
|
-D verify-delay=SECONDS (The delay before MasterQA verification checks.)
|
|
-D recorder (Enables the Recorder for turning browser actions into code.)
|
|
-D rec-behave (Same as Recorder Mode, but also generates behave-gherkin.)
|
|
-D rec-sleep (If the Recorder is enabled, also records self.sleep calls.)
|
|
-D rec-print (If the Recorder is enabled, prints output after tests end.)
|
|
-D disable-csp (Disable the Content Security Policy of websites.)
|
|
-D disable-ws (Disable Web Security on Chromium-based browsers.)
|
|
-D enable-ws (Enable Web Security on Chromium-based browsers.)
|
|
-D enable-sync (Enable "Chrome Sync".)
|
|
-D use-auto-ext (Use Chrome's automation extension.)
|
|
-D remote-debug (Enable Chrome's Remote Debugger on http://localhost:9222)
|
|
-D dashboard (Enable the SeleniumBase Dashboard. Saved at: dashboard.html)
|
|
-D dash-title=STRING (Set the title shown for the generated dashboard.)
|
|
-D swiftshader (Use Chrome's "--use-gl=swiftshader" feature.)
|
|
-D incognito (Enable Chrome's Incognito mode.)
|
|
-D guest (Enable Chrome's Guest mode.)
|
|
-D devtools (Open Chrome's DevTools when the browser opens.)
|
|
-D reuse-session | -D rs (Reuse browser session between tests.)
|
|
-D crumbs (Delete all cookies between tests reusing a session.)
|
|
-D window-size (Set the browser window size: "Width,Height".)
|
|
-D maximize (Start tests with the browser window maximized.)
|
|
-D screenshot (Save a screenshot at the end of each test.)
|
|
-D visual-baseline (Set the visual baseline for Visual/Layout tests.)
|
|
-D external-pdf (Set Chromium "plugins.always_open_pdf_externally": True.)
|
|
-D timeout-multiplier=MULTIPLIER (Multiplies the default timeout values.)
|
|
"""
|
|
|
|
import ast
|
|
import colorama
|
|
import os
|
|
import re
|
|
import sys
|
|
from seleniumbase.config import settings
|
|
from seleniumbase.core import log_helper
|
|
from seleniumbase.core import download_helper
|
|
from seleniumbase.core import proxy_helper
|
|
from seleniumbase.fixtures import constants
|
|
from seleniumbase import config as sb_config
|
|
|
|
sb_config.__base_class = None
|
|
is_windows = False
|
|
if sys.platform in ["win32", "win64", "x64"]:
|
|
is_windows = True
|
|
|
|
|
|
def set_base_class(base_class):
|
|
"""
|
|
# You can override the base class from Behave's environment.py file.
|
|
# If not using SeleniumBase's BaseCase class, then use a subclass.
|
|
from seleniumbase import BaseCase
|
|
from seleniumbase.plugins import behave_plugin
|
|
behave_plugin.set_base_class(BaseCase)
|
|
"""
|
|
sb_config.__base_class = base_class
|
|
|
|
|
|
def get_configured_sb(context):
|
|
if not sb_config.__base_class:
|
|
from seleniumbase import BaseCase
|
|
|
|
sb_config.__base_class = BaseCase
|
|
sb_config.__base_class.test_method = {}
|
|
sb = sb_config.__base_class("test_method")
|
|
|
|
# Set default values
|
|
sb.browser = "chrome"
|
|
sb.is_behave = True
|
|
sb.headless = False
|
|
sb.headed = False
|
|
sb.xvfb = False
|
|
sb.start_page = None
|
|
sb.locale_code = None
|
|
sb.pdb_option = False
|
|
sb.protocol = "http"
|
|
sb.servername = "localhost"
|
|
sb.port = 4444
|
|
sb.data = None
|
|
sb.var1 = None
|
|
sb.var2 = None
|
|
sb.var3 = None
|
|
sb.variables = {}
|
|
sb.account = None
|
|
sb.environment = "test"
|
|
sb.user_agent = None
|
|
sb.incognito = False
|
|
sb.guest_mode = False
|
|
sb.devtools = False
|
|
sb.mobile_emulator = False
|
|
sb.device_metrics = None
|
|
sb.extension_zip = None
|
|
sb.extension_dir = None
|
|
sb.database_env = "test"
|
|
sb.log_path = "latest_logs/"
|
|
sb.archive_logs = False
|
|
sb.disable_csp = False
|
|
sb.disable_ws = False
|
|
sb.enable_ws = False
|
|
sb.enable_sync = False
|
|
sb.use_auto_ext = False
|
|
sb.no_sandbox = False
|
|
sb.disable_gpu = False
|
|
sb._multithreaded = False
|
|
sb._reuse_session = False
|
|
sb._crumbs = False
|
|
sb.visual_baseline = False
|
|
sb.window_size = None
|
|
sb.maximize_option = False
|
|
sb.save_screenshot_after_test = False
|
|
sb.timeout_multiplier = None
|
|
sb.pytest_html_report = None
|
|
sb.with_db_reporting = False
|
|
sb.with_s3_logging = False
|
|
sb.js_checking_on = False
|
|
sb.recorder_mode = False
|
|
sb.recorder_ext = False
|
|
sb.record_sleep = False
|
|
sb.rec_behave = False
|
|
sb.rec_print = False
|
|
sb.report_on = False
|
|
sb.is_pytest = False
|
|
sb.slow_mode = False
|
|
sb.demo_mode = False
|
|
sb.time_limit = None
|
|
sb.demo_sleep = None
|
|
sb.dashboard = False
|
|
sb.dash_title = None
|
|
sb._dash_initialized = False
|
|
sb.message_duration = None
|
|
sb.block_images = False
|
|
sb.external_pdf = False
|
|
sb.remote_debug = False
|
|
sb.settings_file = None
|
|
sb.user_data_dir = None
|
|
sb.chromium_arg = None
|
|
sb.firefox_arg = None
|
|
sb.firefox_pref = None
|
|
sb.proxy_string = None
|
|
sb.proxy_bypass_list = None
|
|
sb.proxy_pac_url = None
|
|
sb.swiftshader = False
|
|
sb.ad_block_on = False
|
|
sb.highlights = None
|
|
sb.interval = None
|
|
sb.cap_file = None
|
|
sb.cap_string = None
|
|
|
|
# Set a few sb_config vars early in case parsing args fails
|
|
sb_config.dashboard = None
|
|
sb_config._has_exception = None
|
|
sb_config.save_screenshot = None
|
|
|
|
browsers = set() # To error if selecting more than one
|
|
valid_browsers = constants.ValidBrowsers.valid_browsers
|
|
valid_envs = constants.ValidEnvs.valid_envs
|
|
# Process command-line options
|
|
userdata = context.config.userdata
|
|
for key in userdata.keys():
|
|
# Convert --ARG to ARG, etc.
|
|
if key.startswith("--"):
|
|
key = key[2:]
|
|
if key.startswith("-"):
|
|
key = key[1:]
|
|
low_key = key.lower()
|
|
# Handle: -D browser=BROWSER
|
|
if low_key == "browser":
|
|
browser = userdata[key].lower()
|
|
if browser in valid_browsers:
|
|
sb.browser = browser
|
|
browsers.add(browser)
|
|
elif browser == "true":
|
|
raise Exception(
|
|
'\nThe "browser" argument requires a value!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D browser="edge"' % valid_browsers
|
|
)
|
|
else:
|
|
raise Exception(
|
|
'\n"%s" is not a valid "browser" selection!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D browser="edge"' % (browser, valid_browsers)
|
|
)
|
|
continue
|
|
# Handle: -D BROWSER
|
|
if low_key in valid_browsers:
|
|
browser = low_key
|
|
sb.browser = browser
|
|
browsers.add(browser)
|
|
continue
|
|
# Handle: -D headless
|
|
if low_key == "headless":
|
|
sb.headless = True
|
|
continue
|
|
# Handle: -D headed / gui
|
|
if low_key in ["headed", "gui"]:
|
|
sb.headed = True
|
|
continue
|
|
# Handle: -D xvfb
|
|
if low_key == "xvfb":
|
|
sb.xvfb = True
|
|
continue
|
|
# Handle: -D start-page=URL / start_page=URL / url=URL
|
|
if low_key in ["start-page", "start_page", "url"]:
|
|
start_page = userdata[key]
|
|
if start_page == "true":
|
|
start_page = sb.start_page # revert to default
|
|
sb.start_page = start_page
|
|
continue
|
|
# Handle: -D locale-code=CODE / locale_code=CODE / locale=CODE
|
|
if low_key in ["locale-code", "locale_code", "locale"]:
|
|
sb.start_page = userdata[key]
|
|
continue
|
|
# Handle: -D pdb / ipdb
|
|
if low_key in ["pdb", "ipdb"]:
|
|
sb.pdb_option = True
|
|
continue
|
|
# Handle: -D protocol=PROTOCOL
|
|
if low_key == "protocol":
|
|
protocol = userdata[key].lower()
|
|
if protocol in ["http", "https"]:
|
|
sb.protocol = protocol
|
|
elif protocol == "true":
|
|
raise Exception(
|
|
'\nThe Selenium Grid "protocol" argument requires a value!'
|
|
'\nChoose from ["http", "https"]'
|
|
'\nEg. -D protocol="https"'
|
|
)
|
|
else:
|
|
raise Exception(
|
|
'\n"%s" is not a valid Selenium Grid "protocol" selection!'
|
|
'\nChoose from ["http", "https"]'
|
|
'\nEg. -D protocol="https"' % protocol
|
|
)
|
|
continue
|
|
# Handle: -D servername=SERVERNAME
|
|
if low_key == "servername":
|
|
servername = userdata[key]
|
|
if servername == "true":
|
|
servername = sb.servername # revert to default
|
|
sb.servername = servername
|
|
continue
|
|
# Handle: -D port=PORT
|
|
if low_key == "port":
|
|
port = int(userdata[key])
|
|
if port == "true":
|
|
port = sb.port # revert to default
|
|
sb.port = port
|
|
continue
|
|
# Handle: -D data=DATA
|
|
if low_key == "data":
|
|
sb.data = userdata[key]
|
|
continue
|
|
# Handle: -D var1=DATA
|
|
if low_key == "var1":
|
|
sb.var1 = userdata[key]
|
|
continue
|
|
# Handle: -D var2=DATA
|
|
if low_key == "var2":
|
|
sb.var2 = userdata[key]
|
|
continue
|
|
# Handle: -D var3=DATA
|
|
if low_key == "var3":
|
|
sb.var3 = userdata[key]
|
|
continue
|
|
# Handle: -D variables="{'KEY':'VALUE','KEY2':'VALUE2'}"
|
|
if low_key == "variables":
|
|
variables = userdata[key]
|
|
if variables and type(variables) is str and len(variables) > 0:
|
|
bad_input = False
|
|
if (
|
|
not variables.startswith("{")
|
|
or not variables.endswith("}")
|
|
):
|
|
bad_input = True
|
|
else:
|
|
try:
|
|
variables = ast.literal_eval(variables)
|
|
if not type(variables) is dict:
|
|
bad_input = True
|
|
except Exception:
|
|
bad_input = True
|
|
if bad_input:
|
|
raise Exception(
|
|
'\nExpecting a Python dictionary for "variables"!'
|
|
"\nEg. -D variables=\"{'KEY':'VALUE', 'KEY2':123}\""
|
|
)
|
|
else:
|
|
variables = {}
|
|
continue
|
|
# Handle: -D account=ACCOUNT
|
|
if low_key == "account":
|
|
sb.account = userdata[key]
|
|
continue
|
|
# Handle: -D env=ENVIRONMENT
|
|
if low_key == "environment":
|
|
environment = userdata[key].lower()
|
|
if environment in valid_envs:
|
|
sb.environment = environment
|
|
elif environment == "true":
|
|
raise Exception(
|
|
'\nThe "env" argument requires a value!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D env="production"' % valid_envs
|
|
)
|
|
else:
|
|
raise Exception(
|
|
'\n"%s" is not a valid "env" selection!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D env="production"' % (environment, valid_envs)
|
|
)
|
|
continue
|
|
# Handle: -D user-agent=STRING / user_agent=STRING / agent=STRING
|
|
if low_key in ["user-agent", "user_agent", "agent"]:
|
|
user_agent = userdata[key]
|
|
if user_agent == "true":
|
|
user_agent = sb.user_agent # revert to default
|
|
sb.user_agent = user_agent
|
|
continue
|
|
# Handle: -D incognito / incognito-mode / incognito_mode
|
|
if low_key in ["incognito", "incognito-mode", "incognito_mode"]:
|
|
sb.incognito = True
|
|
continue
|
|
# Handle: -D guest / guest-mode / guest_mode
|
|
if low_key in ["guest", "guest-mode", "guest_mode"]:
|
|
sb.guest_mode = True
|
|
continue
|
|
# Handle: -D devtools / open-devtools / open_devtools
|
|
if low_key in ["devtools", "open-devtools", "open_devtools"]:
|
|
sb.devtools = True
|
|
continue
|
|
# Handle: -D mobile / mobile-emulator / mobile_emulator
|
|
if low_key in ["mobile", "mobile-emulator", "mobile_emulator"]:
|
|
sb.mobile_emulator = True
|
|
continue
|
|
# Handle: -D metrics=STR / device-metrics=STR / device_metrics=STR
|
|
if low_key in ["metrics", "device-metrics", "device_metrics"]:
|
|
device_metrics = userdata[key]
|
|
if device_metrics == "true":
|
|
device_metrics = sb.device_metrics # revert to default
|
|
sb.device_metrics = device_metrics
|
|
continue
|
|
# Handle: -D crx=ZIP / extension-zip=ZIP / extension_zip=ZIP
|
|
if low_key in ["crx", "extension-zip", "extension_zip"]:
|
|
extension_zip = userdata[key]
|
|
if extension_zip == "true":
|
|
extension_zip = sb.extension_zip # revert to default
|
|
sb.extension_zip = extension_zip
|
|
continue
|
|
# Handle: -D extension-dir=DIR / extension_dir=DIR
|
|
if low_key in ["extension-dir", "extension_dir"]:
|
|
extension_dir = userdata[key]
|
|
if extension_dir == "true":
|
|
extension_dir = sb.extension_dir # revert to default
|
|
sb.extension_dir = extension_dir
|
|
continue
|
|
# Handle: -D database-env=ENVIRONMENT / database_env=ENVIRONMENT
|
|
if low_key in ["database-env", "database_env"]:
|
|
database_env = userdata[key].lower()
|
|
if database_env in valid_envs:
|
|
sb.database_env = database_env
|
|
elif database_env == "true":
|
|
raise Exception(
|
|
'\nThe "database-env" argument requires a value!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D database-env="production"' % valid_envs
|
|
)
|
|
else:
|
|
raise Exception(
|
|
'\n"%s" is not a valid "database-env" selection!'
|
|
"\nChoose from %s."
|
|
'\nEg. -D database-env="production"'
|
|
% (environment, valid_envs)
|
|
)
|
|
continue
|
|
# Handle: -D archive-logs / archive_logs
|
|
if low_key in ["archive-logs", "archive_logs"]:
|
|
sb.archive_logs = True
|
|
continue
|
|
# Handle: -D disable-csp / disable_csp
|
|
if low_key in ["disable-csp", "disable_csp"]:
|
|
sb.disable_csp = True
|
|
continue
|
|
# Handle: -D disable-ws / disable_ws
|
|
if low_key in ["disable-ws", "disable_ws"]:
|
|
sb.disable_ws = True
|
|
continue
|
|
# Handle: -D enable-ws / enable_ws
|
|
if low_key in ["enable-ws", "enable_ws"]:
|
|
sb.enable_ws = True
|
|
continue
|
|
# Handle: -D enable-sync / enable_sync
|
|
if low_key in ["enable-sync", "enable_sync"]:
|
|
sb.enable_sync = True
|
|
continue
|
|
# Handle: -D use-auto-ext / use_auto_ext / auto-ext
|
|
if low_key in ["use-auto-ext", "use_auto_ext", "auto-ext"]:
|
|
sb.use_auto_ext = True
|
|
continue
|
|
# Handle: -D no-sandbox / no_sandbox
|
|
if low_key in ["no-sandbox", "no_sandbox"]:
|
|
sb.no_sandbox = True
|
|
continue
|
|
# Handle: -D disable-gpu / disable_gpu
|
|
if low_key in ["disable-gpu", "disable_gpu"]:
|
|
sb.disable_gpu = True
|
|
continue
|
|
# Handle: -D rs / reuse-session / reuse_session
|
|
if low_key in ["rs", "reuse-session", "reuse_session"]:
|
|
sb._reuse_session = True
|
|
continue
|
|
# Handle: -D crumbs
|
|
if low_key == "crumbs":
|
|
sb._crumbs = True
|
|
continue
|
|
# Handle: -D visual-baseline / visual_baseline
|
|
if low_key in ["visual-baseline", "visual_baseline"]:
|
|
sb.visual_baseline = True
|
|
continue
|
|
# Handle: -D window-size=Width,Height / window_size=Width,Height
|
|
if low_key in ["window-size", "window_size"]:
|
|
window_size = userdata[key]
|
|
if window_size == "true":
|
|
window_size = sb.window_size # revert to default
|
|
sb.window_size = window_size
|
|
continue
|
|
# Handle: -D maximize / fullscreen / maximize-window
|
|
if low_key in [
|
|
"maximize", "fullscreen", "maximize-window", "maximize_window"
|
|
]:
|
|
sb.maximize_option = True
|
|
continue
|
|
# Handle: -D screenshot / save-screenshot / save_screenshot / ss
|
|
if low_key in [
|
|
"screenshot", "save-screenshot", "save_screenshot", "ss"
|
|
]:
|
|
sb.save_screenshot_after_test = True
|
|
continue
|
|
# Handle: -D timeout-multiplier=FLOAT / timeout_multiplier=FLOAT
|
|
if low_key in ["timeout-multiplier", "timeout_multiplier"]:
|
|
timeout_multiplier = userdata[key]
|
|
if timeout_multiplier == "true":
|
|
timeout_multiplier = sb.timeout_multiplier # revert to default
|
|
sb.timeout_multiplier = timeout_multiplier
|
|
continue
|
|
# Handle: -D with-db-reporting / with-db_reporting
|
|
if low_key in ["with-db-reporting", "with-db_reporting"]:
|
|
sb.with_db_reporting = True
|
|
continue
|
|
# Handle: -D with-s3-logging / with-s3_logging
|
|
if low_key in ["with-s3-logging", "with-s3_logging"]:
|
|
sb.with_s3_logging = True
|
|
continue
|
|
# Handle: -D check-js / check_js
|
|
if low_key in ["check-js", "check_js"]:
|
|
sb.js_checking_on = True
|
|
continue
|
|
# Handle: -D recorder / record / rec / codegen
|
|
if low_key in ["recorder", "record", "rec", "codegen"]:
|
|
sb.recorder_mode = True
|
|
sb.recorder_ext = True
|
|
continue
|
|
# Handle: -D rec-behave / rec-gherkin
|
|
if low_key in ["rec-behave", "rec-gherkin"]:
|
|
sb.rec_behave = True
|
|
sb.recorder_mode = True
|
|
sb.recorder_ext = True
|
|
continue
|
|
# Handle: -D record-sleep / record_sleep / rec-sleep / rec_sleep
|
|
if low_key in ["record-sleep", "rec-sleep"]:
|
|
sb.record_sleep = True
|
|
sb.recorder_mode = True
|
|
sb.recorder_ext = True
|
|
continue
|
|
# Handle: -D rec-print
|
|
if low_key in ["rec-print"]:
|
|
sb.rec_print = True
|
|
sb.recorder_mode = True
|
|
sb.recorder_ext = True
|
|
continue
|
|
# Handle: -D slow / slowmo / slow-mode / slow_mode
|
|
if low_key in ["slow", "slowmo", "slow-mode", "slow_mode"]:
|
|
sb.slow_mode = True
|
|
continue
|
|
# Handle: -D demo / demo-mode / demo_mode
|
|
if low_key in ["demo", "demo-mode", "demo_mode"]:
|
|
sb.demo_mode = True
|
|
continue
|
|
# Handle: -D time-limit / time_limit / timelimit
|
|
if low_key in ["time-limit", "time_limit", "timelimit"]:
|
|
time_limit = userdata[key]
|
|
if time_limit == "true":
|
|
time_limit = sb.time_limit # revert to default
|
|
sb.time_limit = time_limit
|
|
continue
|
|
# Handle: -D demo-sleep / demo_sleep
|
|
if low_key in ["demo-sleep", "demo_sleep"]:
|
|
demo_sleep = userdata[key]
|
|
if demo_sleep == "true":
|
|
demo_sleep = sb.demo_sleep # revert to default
|
|
sb.demo_sleep = demo_sleep
|
|
continue
|
|
# Handle: -D dashboard
|
|
if low_key == "dashboard":
|
|
sb.dashboard = True
|
|
continue
|
|
# Handle: -D dash-title=TITLE / dash_title=TITLE
|
|
if low_key in ["dash-title", "dash_title"]:
|
|
sb.dash_title = userdata[key]
|
|
continue
|
|
# Handle: -D message-duration / message_duration
|
|
if low_key in ["message-duration", "message_duration"]:
|
|
message_duration = userdata[key]
|
|
if message_duration == "true":
|
|
message_duration = sb.message_duration # revert to default
|
|
sb.message_duration = message_duration
|
|
continue
|
|
# Handle: -D block-images / block_images
|
|
if low_key in ["block-images", "block_images"]:
|
|
sb.block_images = True
|
|
continue
|
|
# Handle: -D external-pdf / external_pdf
|
|
if low_key in ["external-pdf", "external_pdf"]:
|
|
sb.external_pdf = True
|
|
continue
|
|
# Handle: -D remote-debug / remote_debug
|
|
if low_key in ["remote-debug", "remote_debug"]:
|
|
sb.remote_debug = True
|
|
continue
|
|
# Handle: -D settings=FILE / settings-file=FILE / settings_file=FILE
|
|
if low_key in ["settings", "settings-file", "settings_file"]:
|
|
settings_file = userdata[key]
|
|
if settings_file == "true":
|
|
settings_file = sb.settings_file # revert to default
|
|
sb.settings_file = settings_file
|
|
continue
|
|
# Handle: -D user-data-dir=DIR / user_data_dir=DIR
|
|
if low_key in ["user-data-dir", "user_data_dir"]:
|
|
user_data_dir = userdata[key]
|
|
if user_data_dir == "true":
|
|
user_data_dir = sb.user_data_dir # revert to default
|
|
sb.user_data_dir = user_data_dir
|
|
continue
|
|
# Handle: -D chromium-arg="ARG=N,ARG2" / chromium_arg="ARG=N,ARG2"
|
|
if low_key in ["chromium-arg", "chromium_arg"]:
|
|
chromium_arg = userdata[key]
|
|
if chromium_arg == "true":
|
|
chromium_arg = sb.chromium_arg # revert to default
|
|
sb.chromium_arg = chromium_arg
|
|
continue
|
|
# Handle: -D firefox-arg="ARG=N,ARG2" / firefox_arg="ARG=N,ARG2"
|
|
if low_key in ["firefox-arg", "firefox_arg"]:
|
|
firefox_arg = userdata[key]
|
|
if firefox_arg == "true":
|
|
firefox_arg = sb.firefox_arg # revert to default
|
|
sb.firefox_arg = firefox_arg
|
|
continue
|
|
# Handle: -D firefox-pref="PREF:VAL" / firefox_pref="PREF:VAL"
|
|
if low_key in ["firefox-pref", "firefox_pref"]:
|
|
firefox_pref = userdata[key]
|
|
if firefox_pref == "true":
|
|
firefox_pref = sb.firefox_pref # revert to default
|
|
sb.firefox_pref = firefox_pref
|
|
continue
|
|
# Handle: -D proxy=SERVER:PORT / proxy=USERNAME:PASSWORD@SERVER:PORT
|
|
if low_key in ["proxy", "proxy-server", "proxy-string"]:
|
|
proxy_string = userdata[key]
|
|
if proxy_string == "true":
|
|
proxy_string = sb.proxy_string # revert to default
|
|
sb.proxy_string = proxy_string
|
|
continue
|
|
# Handle: -D proxy-bypass-list="DOMAIN1;D2" / proxy_bypass_list="D1;D2"
|
|
if low_key in ["proxy-bypass-list", "proxy_bypass_list"]:
|
|
proxy_bypass_list = userdata[key]
|
|
if proxy_bypass_list == "true":
|
|
proxy_bypass_list = sb.proxy_bypass_list # revert to default
|
|
sb.proxy_bypass_list = proxy_bypass_list
|
|
continue
|
|
# Handle: -D proxy-pac-url=URL / proxy-pac-url=USERNAME:PASSWORD@URL
|
|
if low_key in ["proxy-pac-url", "proxy_pac_url", "pac-url", "pac_url"]:
|
|
proxy_pac_url = userdata[key]
|
|
if proxy_pac_url == "true":
|
|
proxy_pac_url = sb.proxy_pac_url # revert to default
|
|
sb.proxy_pac_url = proxy_pac_url
|
|
continue
|
|
# Handle: -D swiftshader
|
|
if low_key == "swiftshader":
|
|
sb.swiftshader = True
|
|
continue
|
|
# Handle: -D adblock / ad-block / ad_block / block-ads / block_ads
|
|
if low_key in [
|
|
"adblock", "ad-block", "ad_block", "block-ads", "block_ads"
|
|
]:
|
|
sb.ad_block_on = True
|
|
continue
|
|
# Handle: -D highlights=NUM
|
|
if low_key == "highlights":
|
|
highlights = userdata[key]
|
|
if highlights == "true":
|
|
highlights = sb.highlights # revert to default
|
|
sb.highlights = highlights
|
|
continue
|
|
# Handle: -D interval=SECONDS
|
|
if low_key == "interval":
|
|
interval = userdata[key]
|
|
if interval == "true":
|
|
interval = sb.interval # revert to default
|
|
sb.interval = interval
|
|
continue
|
|
# Handle: -D cap-file=FILE / cap_file=FILE
|
|
if low_key in ["cap-file", "cap_file"]:
|
|
cap_file = userdata[key]
|
|
if cap_file == "true":
|
|
cap_file = sb.cap_file # revert to default
|
|
sb.cap_file = cap_file
|
|
continue
|
|
# Handle: -D cap-string=STRING / cap_string=STRING
|
|
if low_key == "cap_string":
|
|
cap_string = userdata[key]
|
|
if cap_string == "true":
|
|
cap_string = sb.cap_string # revert to default
|
|
sb.cap_string = cap_string
|
|
continue
|
|
|
|
# Fail immediately if trying to set more than one default browser.
|
|
if len(browsers) > 1:
|
|
raise Exception(
|
|
"\nOnly ONE default browser is allowed!\n"
|
|
"%s browsers were selected: %s" % (len(browsers), browsers)
|
|
)
|
|
# Recorder Mode does not support headless browser runs.
|
|
# Chromium does not allow extensions in Headless Mode.
|
|
if sb.recorder_ext and sb.headless:
|
|
raise Exception(
|
|
"\n\n Recorder Mode does NOT support Headless Mode!"
|
|
'\n (DO NOT combine "-D rec" with "-D headless"!)\n'
|
|
)
|
|
# Recorder Mode only supports Chromium browsers.
|
|
if sb.recorder_ext and (sb.browser not in ["chrome", "edge"]):
|
|
raise Exception(
|
|
"\n\n Recorder Mode ONLY supports Chrome and Edge!"
|
|
'\n (Your browser choice was: "%s")\n' % sb.browser
|
|
)
|
|
# The Xvfb virtual display server is for Linux OS Only.
|
|
if sb.xvfb and "linux" not in sys.platform:
|
|
sb.xvfb = False
|
|
if (
|
|
"linux" in sys.platform
|
|
and not sb.headed
|
|
and not sb.headless
|
|
and not sb.xvfb
|
|
):
|
|
print(
|
|
'(Linux uses "-D headless" by default. '
|
|
'To override, use "-D headed" / "-D gui". '
|
|
'For Xvfb mode instead, use "-D xvfb". '
|
|
'Or hide this info with "-D headless".)'
|
|
)
|
|
sb.headless = True
|
|
if not sb.headless:
|
|
sb.headed = True
|
|
if sb.servername != "localhost":
|
|
# Using Selenium Grid
|
|
# (Set -D server="127.0.0.1" for localhost Grid)
|
|
# If the port is "443", the protocol is "https"
|
|
if str(sb.port) == "443":
|
|
sb.protocol = "https"
|
|
if sb.window_size:
|
|
window_size = sb.window_size
|
|
if window_size.count(",") != 1:
|
|
message = (
|
|
'\n\n window_size expects a "width,height" string!'
|
|
'\n (Your input was: "%s")\n' % window_size
|
|
)
|
|
raise Exception(message)
|
|
window_size = window_size.replace(" ", "")
|
|
width = None
|
|
height = None
|
|
try:
|
|
width = int(window_size.split(",")[0])
|
|
height = int(window_size.split(",")[1])
|
|
except Exception:
|
|
message = (
|
|
'\n\n Expecting integer values for "width,height"!'
|
|
'\n (window_size input was: "%s")\n' % window_size
|
|
)
|
|
raise Exception(message)
|
|
settings.CHROME_START_WIDTH = width
|
|
settings.CHROME_START_HEIGHT = height
|
|
settings.HEADLESS_START_WIDTH = width
|
|
settings.HEADLESS_START_HEIGHT = height
|
|
|
|
# Set sb_config
|
|
sb_config.browser = sb.browser
|
|
sb_config.headless = sb.headless
|
|
sb_config.headed = sb.headed
|
|
sb_config.window_size = sb.window_size
|
|
sb_config.maximize_option = sb.maximize_option
|
|
sb_config.xvfb = sb.xvfb
|
|
sb_config.save_screenshot = sb.save_screenshot_after_test
|
|
sb_config._has_logs = False
|
|
sb_config.variables = sb.variables
|
|
sb_config.dashboard = sb.dashboard
|
|
sb_config.dash_title = sb.dash_title
|
|
sb_config.pdb_option = sb.pdb_option
|
|
sb_config.rec_behave = sb.rec_behave
|
|
sb_config.rec_print = sb.rec_print
|
|
sb_config.record_sleep = sb.record_sleep
|
|
sb_config._is_timeout_changed = False
|
|
sb_config._SMALL_TIMEOUT = settings.SMALL_TIMEOUT
|
|
sb_config._LARGE_TIMEOUT = settings.LARGE_TIMEOUT
|
|
sb_config._recorded_actions = {}
|
|
sb_config._behave_recorded_actions = {}
|
|
# Dashboard-specific variables
|
|
sb_config._results = {} # SBase Dashboard test results
|
|
sb_config._duration = {} # SBase Dashboard test duration
|
|
sb_config._display_id = {} # SBase Dashboard display ID
|
|
sb_config._d_t_log_path = {} # SBase Dashboard test log path
|
|
sb_config._dash_html = None # SBase Dashboard HTML copy
|
|
sb_config._test_id = None # SBase Dashboard test id
|
|
sb_config._latest_display_id = None # The latest SBase display id
|
|
sb_config._dashboard_initialized = False # Becomes True after init
|
|
sb_config._has_exception = False # This becomes True if any test fails
|
|
sb_config._multithreaded = False # This becomes True if multithreading
|
|
sb_config._only_unittest = True # If any test uses BaseCase, becomes False
|
|
sb_config._sbase_detected = False # Becomes True during SeleniumBase tests
|
|
sb_config._extra_dash_entries = [] # Dashboard entries for non-SBase tests
|
|
sb_config._using_html_report = False # Becomes True when using html report
|
|
sb_config._dash_is_html_report = False # Dashboard becomes the html report
|
|
sb_config._saved_dashboard_pie = None # Copy of pie chart for html report
|
|
sb_config._dash_final_summary = None # Dash status to add to html report
|
|
sb_config._html_report_name = None # The name of the pytest html report
|
|
|
|
if sb_config.dash_title:
|
|
constants.Dashboard.TITLE = sb_config.dash_title.replace("_", " ")
|
|
|
|
log_helper.log_folder_setup(sb.log_path, sb.archive_logs)
|
|
download_helper.reset_downloads_folder()
|
|
proxy_helper.remove_proxy_zip_if_present()
|
|
|
|
return sb
|
|
|
|
|
|
def calculate_test_id(file_name, scenario_name):
|
|
file_name = file_name.replace("/", ".").replace("\\", ".")
|
|
scenario_name = re.sub(r"[^\w" + r"_ " + r"]", "", scenario_name)
|
|
scenario_name = scenario_name.replace(" ", "_")
|
|
if " -- @" in scenario_name:
|
|
scenario_name = scenario_name.split(" -- @")[0]
|
|
test_id = "%s.%s" % (file_name, scenario_name)
|
|
return test_id
|
|
|
|
|
|
def calculate_display_id(file_name, line_num, scenario_name):
|
|
if " -- @" in scenario_name:
|
|
scenario_name = scenario_name.split(" -- @")[0]
|
|
display_id = "%s:%s => %s" % (file_name, line_num, scenario_name)
|
|
return display_id
|
|
|
|
|
|
def get_test_id():
|
|
file_name = sb_config.behave_scenario.filename
|
|
file_name = file_name.replace("/", ".").replace("\\", ".")
|
|
scenario_name = sb_config.behave_scenario.name
|
|
if " -- @" in scenario_name:
|
|
scenario_name = scenario_name.split(" -- @")[0]
|
|
scenario_name = re.sub(r"[^\w" + r"_ " + r"]", "", scenario_name)
|
|
scenario_name = scenario_name.replace(" ", "_")
|
|
test_id = "%s.%s" % (file_name, scenario_name)
|
|
return test_id
|
|
|
|
|
|
def get_display_id():
|
|
file_name = sb_config.behave_scenario.filename
|
|
line_num = str(sb_config.behave_scenario.line)
|
|
scenario_name = sb_config.behave_scenario.name
|
|
if " -- @" in scenario_name:
|
|
scenario_name = scenario_name.split(" -- @")[0]
|
|
display_id = "%s:%s => %s" % (file_name, line_num, scenario_name)
|
|
return display_id
|
|
|
|
|
|
def _get_test_ids_():
|
|
test_id = get_test_id()
|
|
display_id = get_display_id()
|
|
return test_id, display_id
|
|
|
|
|
|
def dashboard_pre_processing():
|
|
import subprocess
|
|
|
|
command_args = sys.argv[1:]
|
|
command_string = " ".join(command_args)
|
|
command_string = command_string.replace("--quiet", "")
|
|
command_string = command_string.replace("-q", "")
|
|
proc = subprocess.Popen(
|
|
"behave -d %s --show-source" % command_string,
|
|
stdout=subprocess.PIPE,
|
|
shell=True,
|
|
)
|
|
(output, error) = proc.communicate()
|
|
filename_count = 0
|
|
filename_list = []
|
|
feature_count = 0
|
|
feature_list = []
|
|
scenario_count = 0
|
|
scenario_list = []
|
|
sb_config.item_count = 0
|
|
sb_config.item_count_passed = 0
|
|
sb_config.item_count_failed = 0
|
|
sb_config.item_count_skipped = 0
|
|
sb_config.item_count_untested = 0
|
|
filename = None
|
|
feature_name = None
|
|
scenario_name = None
|
|
if is_windows:
|
|
output = output.decode("latin1")
|
|
else:
|
|
output = output.decode("utf-8")
|
|
for row in output.replace("\r", "").split("\n"):
|
|
if row.startswith("Feature: "):
|
|
filename_count += 1
|
|
feature_count += 1
|
|
feature_name = row.split("Feature: ")[1]
|
|
if " # features/" in feature_name:
|
|
filename = feature_name.split(" # features/")[-1]
|
|
filename = "features/" + filename.split(":")[0]
|
|
feature_name = feature_name.split(" # features/")[0]
|
|
elif " # features\\" in feature_name:
|
|
filename = feature_name.split(" # features\\")[-1]
|
|
filename = "features\\" + filename.split(":")[0]
|
|
feature_name = feature_name.split(" # features\\")[0]
|
|
else:
|
|
filename = feature_name.split(" # ")[-1]
|
|
filename = filename.split(":")[0]
|
|
feature_name = feature_name.split(" # ")[-1]
|
|
filename = filename.strip()
|
|
filename_list.append(filename)
|
|
feature_name = feature_name.strip()
|
|
feature_list.append(feature_name) # Maybe filename is good enough
|
|
elif (
|
|
row.startswith(" Scenario: ")
|
|
or row.startswith(" Scenario Outline: ")
|
|
):
|
|
line_num = row.split(":")[-1]
|
|
scenario_count += 1
|
|
scenario_name = None
|
|
if row.startswith(" Scenario: "):
|
|
scenario_name = row.split(" Scenario: ")[-1]
|
|
else:
|
|
scenario_name = row.split(" Scenario Outline: ")[-1]
|
|
if " -- @" in scenario_name:
|
|
scenario_name = scenario_name.split(" -- @")[0]
|
|
elif " # features/" in scenario_name:
|
|
scenario_name = scenario_name.split(" # features/")[0]
|
|
else:
|
|
scenario_name = scenario_name.split(" # ")[0]
|
|
scenario_name = scenario_name.strip()
|
|
scenario_list.append(scenario_name)
|
|
# Dashboard row preparation
|
|
test_id = calculate_test_id(filename, scenario_name)
|
|
display_id = calculate_display_id(
|
|
filename, line_num, scenario_name
|
|
)
|
|
sb_config._results[test_id] = "Untested"
|
|
sb_config._duration[test_id] = "-"
|
|
sb_config._display_id[test_id] = display_id
|
|
sb_config._d_t_log_path[test_id] = None
|
|
# Set the total number of dashboard entries
|
|
sb_config.item_count = scenario_count
|
|
|
|
|
|
def _create_dashboard_assets_():
|
|
import codecs
|
|
from seleniumbase.js_code.live_js import live_js
|
|
from seleniumbase.core.style_sheet import pytest_style
|
|
|
|
abs_path = os.path.abspath(".")
|
|
assets_folder = os.path.join(abs_path, "assets")
|
|
if not os.path.exists(assets_folder):
|
|
os.makedirs(assets_folder)
|
|
pytest_style_css = os.path.join(assets_folder, "pytest_style.css")
|
|
add_pytest_style_css = True
|
|
if os.path.exists(pytest_style_css):
|
|
existing_pytest_style = None
|
|
with open(pytest_style_css, "r") as f:
|
|
existing_pytest_style = f.read()
|
|
if existing_pytest_style == pytest_style:
|
|
add_pytest_style_css = False
|
|
if add_pytest_style_css:
|
|
out_file = codecs.open(pytest_style_css, "w+", encoding="utf-8")
|
|
out_file.writelines(pytest_style)
|
|
out_file.close()
|
|
live_js_file = os.path.join(assets_folder, "live.js")
|
|
add_live_js_file = True
|
|
if os.path.exists(live_js_file):
|
|
existing_live_js = None
|
|
with open(live_js_file, "r") as f:
|
|
existing_live_js = f.read()
|
|
if existing_live_js == live_js:
|
|
add_live_js_file = False
|
|
if add_live_js_file:
|
|
out_file = codecs.open(live_js_file, "w+", encoding="utf-8")
|
|
out_file.writelines(live_js)
|
|
out_file.close()
|
|
|
|
|
|
def behave_dashboard_prepare():
|
|
"""Print the dashboard path if at least one test runs."""
|
|
if sb_config.item_count > 0:
|
|
_create_dashboard_assets_()
|
|
# Output Dashboard info to the console
|
|
sb_config.item_count_untested = sb_config.item_count
|
|
dash_path = os.getcwd() + "/dashboard.html"
|
|
star_len = len("Dashboard: ") + len(dash_path)
|
|
try:
|
|
terminal_size = os.get_terminal_size().columns
|
|
if terminal_size > 30 and star_len > terminal_size:
|
|
star_len = terminal_size
|
|
except Exception:
|
|
pass
|
|
stars = "*" * star_len
|
|
c1 = ""
|
|
cr = ""
|
|
if "linux" not in sys.platform:
|
|
colorama.init(autoreset=True)
|
|
c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
|
|
cr = colorama.Style.RESET_ALL
|
|
print("Dashboard: %s%s%s\n%s" % (c1, dash_path, cr, stars))
|
|
|
|
|
|
def _perform_behave_unconfigure_():
|
|
from seleniumbase.core import log_helper
|
|
from seleniumbase.core import proxy_helper
|
|
|
|
proxy_helper.remove_proxy_zip_if_present()
|
|
if hasattr(sb_config, "reuse_session") and sb_config.reuse_session:
|
|
# Close the shared browser session
|
|
if sb_config.shared_driver:
|
|
try:
|
|
if (
|
|
not is_windows
|
|
or sb_config.browser == "ie"
|
|
or sb_config.shared_driver.service.process
|
|
):
|
|
sb_config.shared_driver.quit()
|
|
except AttributeError:
|
|
pass
|
|
except Exception:
|
|
pass
|
|
sb_config.shared_driver = None
|
|
if hasattr(sb_config, "log_path"):
|
|
log_helper.archive_logs_if_set(
|
|
sb_config.log_path, sb_config.archive_logs
|
|
)
|
|
# Dashboard post-processing: Disable time-based refresh and stamp complete
|
|
if not hasattr(sb_config, "dashboard") or not sb_config.dashboard:
|
|
# Done with "behave_unconfigure" unless using the Dashboard
|
|
return
|
|
stamp = "\n<!--Test Run Complete-->"
|
|
find_it = constants.Dashboard.META_REFRESH_HTML
|
|
swap_with = "" # Stop refreshing the page after the run is done
|
|
find_it_2 = "Awaiting results... (Refresh the page for updates)"
|
|
swap_with_2 = (
|
|
"Test Run ENDED: Some results UNREPORTED due to skipped tearDown()"
|
|
)
|
|
find_it_3 = '<td class="col-result">Untested</td>'
|
|
swap_with_3 = '<td class="col-result">Unreported</td>'
|
|
find_it_4 = 'href="%s"' % constants.Dashboard.DASH_PIE_PNG_1
|
|
swap_with_4 = 'href="%s"' % constants.Dashboard.DASH_PIE_PNG_2
|
|
try:
|
|
abs_path = os.path.abspath(".")
|
|
dashboard_path = os.path.join(abs_path, "dashboard.html")
|
|
# Part 1: Finalizing the dashboard / integrating html report
|
|
if os.path.exists(dashboard_path):
|
|
the_html_d = None
|
|
with open(dashboard_path, "r", encoding="utf-8") as f:
|
|
the_html_d = f.read()
|
|
if sb_config._multithreaded and "-c" in sys.argv:
|
|
# Threads have "-c" in sys.argv, except for the last
|
|
raise Exception('Break out of "try" block.')
|
|
if sb_config._multithreaded:
|
|
dash_pie_loc = constants.Dashboard.DASH_PIE
|
|
pie_path = os.path.join(abs_path, dash_pie_loc)
|
|
if os.path.exists(pie_path):
|
|
import json
|
|
|
|
with open(pie_path, "r") as f:
|
|
dash_pie = f.read().strip()
|
|
sb_config._saved_dashboard_pie = json.loads(dash_pie)
|
|
# If the test run doesn't complete by itself, stop refresh
|
|
the_html_d = the_html_d.replace(find_it, swap_with)
|
|
the_html_d = the_html_d.replace(find_it_2, swap_with_2)
|
|
the_html_d = the_html_d.replace(find_it_3, swap_with_3)
|
|
the_html_d = the_html_d.replace(find_it_4, swap_with_4)
|
|
the_html_d += stamp
|
|
with open(dashboard_path, "w", encoding="utf-8") as f:
|
|
f.write(the_html_d) # Finalize the dashboard
|
|
except KeyboardInterrupt:
|
|
pass
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def do_final_driver_cleanup_as_needed():
|
|
try:
|
|
if hasattr(sb_config, "last_driver") and sb_config.last_driver:
|
|
if (
|
|
not is_windows
|
|
or sb_config.browser == "ie"
|
|
or sb_config.last_driver.service.process
|
|
):
|
|
sb_config.last_driver.quit()
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def _perform_behave_terminal_summary_():
|
|
latest_logs_dir = os.getcwd() + "/latest_logs/"
|
|
dash_path = os.getcwd() + "/dashboard.html"
|
|
equals_len = len("Dashboard: ") + len(dash_path)
|
|
try:
|
|
terminal_size = os.get_terminal_size().columns
|
|
if terminal_size > 30 and equals_len > terminal_size:
|
|
equals_len = terminal_size
|
|
except Exception:
|
|
pass
|
|
equals = "=" * (equals_len + 2)
|
|
c2 = ""
|
|
cr = ""
|
|
if "linux" not in sys.platform:
|
|
colorama.init(autoreset=True)
|
|
c2 = colorama.Fore.MAGENTA + colorama.Back.LIGHTYELLOW_EX
|
|
cr = colorama.Style.RESET_ALL
|
|
if sb_config.dashboard:
|
|
# Print link a second time because the first one may be off-screen
|
|
print("%s- Dashboard:%s %s" % (c2, cr, dash_path))
|
|
if (
|
|
sb_config._has_exception
|
|
or sb_config.save_screenshot
|
|
or sb_config._has_logs
|
|
):
|
|
# Log files are generated during test failures and Screenshot Mode
|
|
print("%s--- LogPath:%s %s" % (c2, cr, latest_logs_dir))
|
|
if (
|
|
sb_config.dashboard
|
|
and not (sb_config._has_exception or sb_config.save_screenshot)
|
|
):
|
|
print("%s" % equals)
|
|
elif (
|
|
not sb_config.dashboard
|
|
and (sb_config._has_exception or sb_config.save_screenshot)
|
|
):
|
|
print("%s" % equals[2:])
|
|
elif (
|
|
sb_config.dashboard
|
|
and (sb_config._has_exception or sb_config.save_screenshot)
|
|
):
|
|
print("%s" % equals[2:])
|
|
|
|
|
|
###########################################
|
|
|
|
|
|
def before_all(context):
|
|
context.sb = get_configured_sb(context)
|
|
if context.sb.dashboard:
|
|
dashboard_pre_processing()
|
|
behave_dashboard_prepare()
|
|
|
|
|
|
def before_feature(context, feature):
|
|
sb_config.behave_feature = feature
|
|
|
|
|
|
def before_scenario(context, scenario):
|
|
sb_config.behave_context = context
|
|
sb_config.behave_scenario = scenario
|
|
sb_config.behave_line_num = scenario.line
|
|
sb_config.behave_step_count = 0
|
|
context.sb.setUp()
|
|
|
|
|
|
def before_step(context, step):
|
|
sb_config.behave_step_count += 1
|
|
sb_config.behave_step = step
|
|
|
|
|
|
def after_step(context, step):
|
|
sb_config.behave_step = step
|
|
if step.status == "failed":
|
|
number = sb_config.behave_step_count
|
|
print(">>> STEP FAILED: (#%s) %s" % (number, step.name))
|
|
print("Class / Feature: ", sb_config.behave_feature.name)
|
|
print("Test / Scenario: ", sb_config.behave_scenario.name)
|
|
|
|
|
|
def after_scenario(context, scenario):
|
|
sb = context.sb
|
|
sb_config.last_driver = sb.driver
|
|
sb_config.behave_context = context
|
|
sb_config.behave_scenario = scenario
|
|
sb.tearDown()
|
|
|
|
|
|
def after_feature(context, feature):
|
|
sb_config.feature = feature
|
|
|
|
|
|
def after_all(context):
|
|
_perform_behave_unconfigure_()
|
|
do_final_driver_cleanup_as_needed()
|
|
_perform_behave_terminal_summary_()
|