Skip to content

Commit

Permalink
Merge branch 'stage' into 'master'
Browse files Browse the repository at this point in the history
Stage to Master

See merge request cometa/cometa!606
  • Loading branch information
anandkushwaha064 committed Nov 20, 2024
2 parents 4d0fbb5 + 2f3e177 commit abbda89
Show file tree
Hide file tree
Showing 25 changed files with 442 additions and 62 deletions.
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ stages:
# Build Selenoid browsers
- echo -e "\e[0Ksection_start:`date +%s`:deploy_selenoid\r\e[0KRunning selenoid deployment script"
- bash backend/selenoid/deploy_selenoid.sh
# - docker exec -it cometa_selenoid sh /etc/selenoid/check_for_custom_background.sh
- echo -e "\e[0Ksection_end:`date +%s`:deploy_selenoid\r\e[0K"
# Install new python packages in django and behave container
- docker exec cometa_django poetry install
Expand Down
4 changes: 3 additions & 1 deletion backend/behave/behave_django/schedules/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,10 @@ def updated_step_actions(request):
# Add your new created action files here
actions_files = [
'cometa_itself/steps/actions.py',
'cometa_itself/steps/validation_actions.py',
'ee/cometa_itself/steps/rest_api.py',
'ee/cometa_itself/steps/ai_actions.py'
'ee/cometa_itself/steps/ai_actions.py',
'ee/cometa_itself/steps/conditional_actions.py'
]

# variable to contain action comment
Expand Down
8 changes: 5 additions & 3 deletions backend/behave/cometa_itself/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import os, pickle
from selenium.common.exceptions import InvalidCookieDomainException


sys.path.append("/opt/code/behave_django")
sys.path.append("/code/behave/cometa_itself/steps")

Expand All @@ -25,6 +24,7 @@
from utility.encryption import *
from utility.configurations import ConfigurationManager, load_configurations
from modules.ai import AI
from tools.models import Condition

LOGGER_FORMAT = "\33[96m[%(asctime)s][%(feature_id)s][%(current_step)s/%(total_steps)s][%(levelname)s][%(filename)s:%(lineno)d](%(funcName)s) -\33[0m %(message)s"

Expand Down Expand Up @@ -417,8 +417,8 @@ def before_all(context):
context.tempfiles = [
execution_data_file,
]

context.network_responses = []
context.test_conditions_list: list[Condition] = []

# call update task to create a task with pid.
task = {
Expand Down Expand Up @@ -767,7 +767,8 @@ def after_all(context):

@error_handling()
def before_step(context, step):

context.CURRENT_STEP = step
context.CURRENT_STEP_STATUS = "Failed"
os.environ["current_step"] = str(context.counters["index"] + 1)
# complete step name to let front know about the step that will be executed next
step_name = "%s %s" % (step.keyword, step.name)
Expand Down Expand Up @@ -939,6 +940,7 @@ def after_step(context, step):
"step_result_info": step_result,
"step_time": step.duration,
"error": step_error,
"status": context.CURRENT_STEP_STATUS,
"belongs_to": context.step_data["belongs_to"],
"screenshots": json.dumps(screenshots), # load screenshots object
"vulnerable_headers_count": vulnerable_headers_count,
Expand Down
16 changes: 11 additions & 5 deletions backend/behave/cometa_itself/steps/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def step_impl(context,selector):
def step_impl(context,css_selector):
send_step_details(context, 'Looking for selector')
elem = waitSelector(context, "css", css_selector)
send_step_details(context, 'Clicking')
send_step_details(context, 'Moving Mouse')
ActionChains(context.browser).move_to_element(elem[0]).perform()

# Moves the mouse to the center of css selector
Expand Down Expand Up @@ -467,6 +467,7 @@ def test_folder(context, parameters = {}):

# save to database
save_message="I can test current IBM Cognos folder > Report: %s failed" % report_name
context.CURRENT_STEP_STATUS = "Failed"
saveToDatabase(save_message, (time.time() - report_start_time) * 1000, 0, False, context )

# switch content
Expand Down Expand Up @@ -497,6 +498,7 @@ def test_folder(context, parameters = {}):
#
logger.debug("Saveing report timing as step result to database")
save_message="I can test current IBM Cognos folder > Report: %s tested" % report_name
context.CURRENT_STEP_STATUS = "Success"
saveToDatabase(save_message, (time.time() - report_start_time) * 1000, 0, True, context )

# close the ibm cognos view
Expand Down Expand Up @@ -606,11 +608,13 @@ def test_folder_aso(context, parameters = {}):
# promptPage failed somehow
logger.debug("Prompt Magic returned false - which means, we should fail this report [%s]." % report_name)
logger.info("You might want to look at the screenshot or video and adjust timeouts or fix a broken report.")
logger.debug("Saveing report timing as step result to database.")
logger.debug("Saving report timing as step result to database.")

over_all_results_ok=False

# save to database
save_message="I can test current IBM Cognos folder > Report: %s failed" % report_name
context.CURRENT_STEP_STATUS = "Failed"
saveToDatabase(save_message, (time.time() - report_start_time) * 1000, 0, False, context )

# switch content
Expand Down Expand Up @@ -641,6 +645,7 @@ def test_folder_aso(context, parameters = {}):
#
logger.debug("Saveing report timing as step result to database")
save_message="I can test current IBM Cognos folder > Report: %s tested" % report_name
context.CURRENT_STEP_STATUS = "Success"
saveToDatabase(save_message, (time.time() - report_start_time) * 1000, 0, True, context )

# close the ibm cognos view
Expand Down Expand Up @@ -3353,9 +3358,10 @@ def scrollThroughLazyLoading(context, xpath, MaxScrolls, MaxTimeOfLife):
if __name__ != 'actions':
sys.path.append('/code/behave/')
from ee.cometa_itself.steps import rest_api
from ee.cometa_itself.steps import ai_actions

from ee.cometa_itself.steps import ai_actions
from ee.cometa_itself.steps import conditional_actions

sys.path.append('/code/behave/cometa_itself')
from steps import validation_actions
from steps import unimplemented_steps


19 changes: 16 additions & 3 deletions backend/behave/cometa_itself/steps/tools/common_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

from utility.functions import toWebP
from utility.encryption import *
from tools.models import check_if_step_should_execute

# setup logging
logger = logging.getLogger("FeatureExecution")
Expand Down Expand Up @@ -442,7 +443,17 @@ def execute(*args, **kwargs):
# set page load timeout
args[0].browser.set_page_load_timeout(step_timeout)
# run the requested function
result = func(*args, **kwargs)
# Check if step should execute, It should not lies in the If else conditions
should_execute_the_step = check_if_step_should_execute(args[0])
result = None

if should_execute_the_step:
result = func(*args, **kwargs)
args[0].CURRENT_STEP_STATUS = "Success"
else:
args[0].CURRENT_STEP_STATUS = "Skipped"
logger.debug(f"######################### Skipping the step \" {args[0].CURRENT_STEP.name} \"#########################")

# if step executed without running into timeout cancel the timeout
signal.alarm(0)
# save the result to database
Expand All @@ -452,6 +463,7 @@ def execute(*args, **kwargs):
# return True meaning everything went as expected
return result
except Exception as err:
args[0].CURRENT_STEP_STATUS = "Failed"
# reset timeout incase of exception in function
signal.alarm(0)
# print stack trace
Expand All @@ -465,7 +477,7 @@ def execute(*args, **kwargs):
(time.time() - start_time) * 1000,
0,
False,
args[0],
args[0]
)
except Exception as err:
logger.error(
Expand Down Expand Up @@ -516,6 +528,7 @@ def execute(*args, **kwargs):
def saveToDatabase(
step_name="", execution_time=0, pixel_diff=0, success=False, context=None
):
status = context.CURRENT_STEP_STATUS
screenshots = os.environ["SCREENSHOTS"].split(".")
compares = os.environ["COMPARES"].split(".")
feature_id = context.feature_id
Expand All @@ -526,7 +539,7 @@ def saveToDatabase(
"execution_time": int(execution_time),
"pixel_diff": float(pixel_diff),
"success": success,
"status": "Success" if success else "Failed",
"status": status,
"belongs_to": context.step_data["belongs_to"],
"rest_api_id": context.step_data.get("rest_api", None),
"notes": context.step_data.get("notes", {}),
Expand Down
79 changes: 79 additions & 0 deletions backend/behave/cometa_itself/steps/tools/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import logging


# setup logging
logger = logging.getLogger("FeatureExecution")


def is_step_conditional_statement(step):
step_name :str = step.name
conditional_steps = ("End If", "Else")
return step_name.startswith(conditional_steps)

def check_if_step_should_execute(context):
step = context.CURRENT_STEP
should_execute_step = True
# Check if test flow is with in the condition
if len(context.test_conditions_list) > 0:
current_condition = context.test_conditions_list[-1]
logger.debug(f"Current condition values : {current_condition}")
# Check if current step is not conditional statement
if not is_step_conditional_statement(step):
logger.debug(f"Step {step.name} is with in the if condition")

# When a condition is true and current step lies with in the If section then execute the current step
if current_condition.is_condition_true() and not current_condition.is_else_section_active():
logger.debug(f"Step \"{step.name}\" will be executed with in the if section")
should_execute_step = True
# When a condition is false and current step lies with in the If section then skip the current step execution
elif not current_condition.is_condition_true() and not current_condition.is_else_section_active():
logger.debug(f"Step \"{step.name}\" will be skipped with in the if section")
should_execute_step = False

# When condition is false and current step lies with in the else section then execute the current step
elif not current_condition.is_condition_true() and current_condition.is_else_section_active():
logger.debug(f"Step \"{step.name}\" will be executed with in the else section")
should_execute_step = True
# When condition is true and current step lies with in the else condition then skip the current step execution
elif current_condition.is_condition_true() and current_condition.is_else_section_active():
logger.debug(f"Step \"{step.name}\" will be skipped with in the else section")
should_execute_step = False
else:
logger.debug("Executing step without any condition check")
should_execute_step = True

return should_execute_step

class Condition:
def __init__(self, index):
self.index = index
# if condition is True and not over if mean it is in the if section
# if condition is False and not over it mean it is in the else section
self._is_condition_true = True
self._is_else_section_active = False
self._is_condition_over = False
self._sub_conditions: list[Condition] = []

def set_condition(self, condition_result):
self._is_condition_true = condition_result

def is_condition_true(self):
return self._is_condition_true

def close_condition(self):
self._is_condition_over = True

def is_flow_with_in_condition(self):
return self._is_condition_over

def activate_else_section(self):
self._is_else_section_active = True

def is_else_section_active(self):
return self._is_else_section_active

def __str__(self):
return f"\n _is_condition_true : {self._is_condition_true}, \
\n is_else_section_active: {self._is_else_section_active}, \
\n is_condition_over: {self._is_condition_over}, \
\n count_of_sub_conditions: {len(self._sub_conditions)}"
78 changes: 78 additions & 0 deletions backend/behave/cometa_itself/steps/validation_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from behave import *
import time
import sys
import os
import os.path
import logging
# import PIL
# Import utilities
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from tools.common import *
from tools.exceptions import *
from tools.variables import *

# pycrypto imports
import base64
base64.encodestring = base64.encodebytes
from hashlib import md5
from pathlib import Path
from tools import expected_conditions as CEC
import sys

sys.path.append("/opt/code/behave_django")
sys.path.append('/code/behave/cometa_itself/steps')

from utility.functions import *
from utility.configurations import ConfigurationManager
from utility.common import *
from utility.encryption import *
from tools.common_functions import *

SCREENSHOT_PREFIX = ConfigurationManager.get_configuration('COMETA_SCREENSHOT_PREFIX', '')
ENCRYPTION_START = ConfigurationManager.get_configuration('COMETA_ENCRYPTION_START', '')

# setup logging
logger = logging.getLogger('FeatureExecution')


@step(u'Validate if "{selector}" present in the browser in "{time}" seconds and save result in "{variable}"')
@done(u'Validate if "{selector}" present in the browser in "{time}" seconds and save result in "{variable}"')
def validate_element_presence(context, selector, time, variable):
send_step_details(context, f"Validating if selector '{selector}' is present within {time} seconds")

try:
# Use waitSelector to get the element
element = waitSelector(context, "css", selector, max_timeout=int(time))
if type(element) == list:
element = element[0]

result = element is not None # If element is returned, it's present
send_step_details(context, f"Selector '{selector}' is present: {result}")
except Exception as e:
result = False # If an exception occurs, the element is not present
logger.debug(f"Exception while checking presence of '{selector}': {e}")

# Save the result to the variable
addTestRuntimeVariable(context, variable, str(result))
send_step_details(context, f"Presence validation result for '{selector}' saved to variable '{variable}': {result}")


@step(u'Validate if "{selector}" appeared in the browser in "{time}" seconds and save result in "{variable}"')
@done(u'Validate if "{selector}" appeared in the browser in "{time}" seconds and save result in "{variable}"')
def validate_element_visibility(context, selector, time, variable):
send_step_details(context, f"Validating if selector '{selector}' appeared within {time} seconds")

try:
# Use waitSelector to get the element
element = waitSelector(context, "css", selector, max_timeout=int(time))
if type(element) == list:
element = element[0]
result = element.is_displayed() # Check if the element is visible
send_step_details(context, f"Selector '{selector}' appeared: {result}")
except Exception as e:
result = False # If an exception occurs, the element is not visible
logger.debug(f"Exception while checking visibility of '{selector}': {e}")

# Save the result to the variable
addTestRuntimeVariable(context, variable, str(result))
send_step_details(context, f"Visibility validation result for '{selector}' saved to variable '{variable}': {result}")
Loading

0 comments on commit abbda89

Please sign in to comment.