mirror of
https://github.com/status-im/spiff-arena.git
synced 2025-02-12 01:36:58 +00:00
Merge remote-tracking branch 'origin/main' into bug/improve_reset_to_previous_task
This commit is contained in:
commit
79c3a90e1e
13
Jenkinsfile
vendored
13
Jenkinsfile
vendored
@ -1,3 +1,5 @@
|
|||||||
|
import groovy.json.JsonBuilder
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux' }
|
agent { label 'linux' }
|
||||||
|
|
||||||
@ -45,6 +47,17 @@ pipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
stage('Prep') {
|
||||||
|
steps { script {
|
||||||
|
def jobMetaJson = new JsonBuilder([
|
||||||
|
git_commit: env.GIT_COMMIT.take(7),
|
||||||
|
git_branch: env.GIT_BRANCH,
|
||||||
|
build_id: env.BUILD_ID,
|
||||||
|
]).toPrettyString()
|
||||||
|
sh "echo '${jobMetaJson}' > version_info.json"
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
stage('Build') {
|
stage('Build') {
|
||||||
steps { script {
|
steps { script {
|
||||||
dir("spiffworkflow-${params.COMPONENT}") {
|
dir("spiffworkflow-${params.COMPONENT}") {
|
||||||
|
@ -7,10 +7,15 @@ function error_handler() {
|
|||||||
trap 'error_handler ${LINENO} $?' ERR
|
trap 'error_handler ${LINENO} $?' ERR
|
||||||
set -o errtrace -o errexit -o nounset -o pipefail
|
set -o errtrace -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
port="${SPIFFWORKFLOW_BACKEND_PORT:-7000}"
|
||||||
|
|
||||||
arg="${1:-}"
|
arg="${1:-}"
|
||||||
if [[ "$arg" == "acceptance" ]]; then
|
if [[ "$arg" == "acceptance" ]]; then
|
||||||
export SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA=true
|
export SPIFFWORKFLOW_BACKEND_LOAD_FIXTURE_DATA=true
|
||||||
export SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME=acceptance_tests.yml
|
export SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME=acceptance_tests.yml
|
||||||
|
elif [[ "$arg" == "localopenid" ]]; then
|
||||||
|
export SPIFFWORKFLOW_BACKEND_OPEN_ID_SERVER_URL="http://localhost:$port/openid"
|
||||||
|
export SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME="example.yml"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z "${SPIFFWORKFLOW_BACKEND_ENV:-}" ]]; then
|
if [[ -z "${SPIFFWORKFLOW_BACKEND_ENV:-}" ]]; then
|
||||||
@ -38,5 +43,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# this line blocks
|
# this line blocks
|
||||||
SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER="${SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER}" FLASK_APP=src/spiffworkflow_backend poetry run flask run -p 7000
|
SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER="${SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER}" FLASK_APP=src/spiffworkflow_backend poetry run flask run -p "$port" --host=0.0.0.0
|
||||||
fi
|
fi
|
||||||
|
@ -62,13 +62,16 @@ SPIFFWORKFLOW_BACKEND_OPEN_ID_CLIENT_SECRET_KEY = environ.get(
|
|||||||
default="JXeQExm0JhQPLumgHtIIqf52bDalHz0q",
|
default="JXeQExm0JhQPLumgHtIIqf52bDalHz0q",
|
||||||
) # noqa: S105
|
) # noqa: S105
|
||||||
|
|
||||||
# Tenant specific fields is a comma separated list of field names that we will convert to list of strings
|
# Tenant specific fields is a comma separated list of field names that we will be converted to list of strings
|
||||||
# and store in the user table's tenant_specific_field_n columns. You can have up to three items in this
|
# and store in the user table's tenant_specific_field_n columns. You can have up to three items in this
|
||||||
# comma-separated list.
|
# comma-separated list.
|
||||||
SPIFFWORKFLOW_BACKEND_OPEN_ID_TENANT_SPECIFIC_FIELDS = environ.get(
|
SPIFFWORKFLOW_BACKEND_OPEN_ID_TENANT_SPECIFIC_FIELDS = environ.get(
|
||||||
"SPIFFWORKFLOW_BACKEND_OPEN_ID_TENANT_SPECIFIC_FIELDS"
|
"SPIFFWORKFLOW_BACKEND_OPEN_ID_TENANT_SPECIFIC_FIELDS"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# loggers to use is a comma separated list of logger prefixes that we will be converted to list of strings
|
||||||
|
SPIFFWORKFLOW_BACKEND_LOGGERS_TO_USE = environ.get("SPIFFWORKFLOW_BACKEND_LOGGERS_TO_USE")
|
||||||
|
|
||||||
# cryptography or simple-crypt
|
# cryptography or simple-crypt
|
||||||
SPIFFWORKFLOW_BACKEND_ENCRYPTION_LIB = environ.get(
|
SPIFFWORKFLOW_BACKEND_ENCRYPTION_LIB = environ.get(
|
||||||
# "SPIFFWORKFLOW_BACKEND_ENCRYPTION_LIB", default="cryptography"
|
# "SPIFFWORKFLOW_BACKEND_ENCRYPTION_LIB", default="cryptography"
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
default_group: everybody
|
||||||
|
|
||||||
|
groups:
|
||||||
|
admin:
|
||||||
|
users:
|
||||||
|
- jason@sartography.com
|
||||||
|
- kevin@sartography.com
|
||||||
|
- dan@sartography.com
|
||||||
|
- alex@sartography.com
|
||||||
|
- jon@sartography.com
|
||||||
|
- elizabeth@sartography.com
|
||||||
|
- madhurya@sartography.com
|
||||||
|
|
||||||
|
tech_writers:
|
||||||
|
users:
|
||||||
|
- usama@sartography.com
|
||||||
|
- phillana@sartography.com
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
admin:
|
||||||
|
groups: [admin, tech_writers]
|
||||||
|
users: []
|
||||||
|
allowed_permissions: [create, read, update, delete]
|
||||||
|
uri: /*
|
@ -172,7 +172,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def active_statuses(cls) -> list[str]:
|
def active_statuses(cls) -> list[str]:
|
||||||
return ["user_input_required", "waiting"]
|
return ["not_started", "user_input_required", "waiting"]
|
||||||
|
|
||||||
|
|
||||||
class ProcessInstanceModelSchema(Schema):
|
class ProcessInstanceModelSchema(Schema):
|
||||||
|
@ -87,11 +87,7 @@ def process_group_update(modified_process_group_id: str, body: dict) -> flask.wr
|
|||||||
def process_group_list(
|
def process_group_list(
|
||||||
process_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100
|
process_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
"""Process_group_list."""
|
process_groups = ProcessModelService.get_process_groups_for_api(process_group_identifier)
|
||||||
if process_group_identifier is not None:
|
|
||||||
process_groups = ProcessModelService.get_process_groups(process_group_identifier)
|
|
||||||
else:
|
|
||||||
process_groups = ProcessModelService.get_process_groups()
|
|
||||||
batch = ProcessModelService().get_batch(items=process_groups, page=page, per_page=per_page)
|
batch = ProcessModelService().get_batch(items=process_groups, page=page, per_page=per_page)
|
||||||
pages = len(process_groups) // per_page
|
pages = len(process_groups) // per_page
|
||||||
remainder = len(process_groups) % per_page
|
remainder = len(process_groups) % per_page
|
||||||
|
@ -214,8 +214,7 @@ def process_model_list(
|
|||||||
page: int = 1,
|
page: int = 1,
|
||||||
per_page: int = 100,
|
per_page: int = 100,
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
"""Process model list!"""
|
process_models = ProcessModelService.get_process_models_for_api(
|
||||||
process_models = ProcessModelService.get_process_models(
|
|
||||||
process_group_id=process_group_identifier,
|
process_group_id=process_group_identifier,
|
||||||
recursive=recursive,
|
recursive=recursive,
|
||||||
filter_runnable_by_user=filter_runnable_by_user,
|
filter_runnable_by_user=filter_runnable_by_user,
|
||||||
|
@ -45,7 +45,8 @@ from spiffworkflow_backend.models.process_instance import (
|
|||||||
)
|
)
|
||||||
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
|
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
|
||||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||||
from spiffworkflow_backend.models.task import TaskModel # noqa: F401
|
from spiffworkflow_backend.models.task import Task
|
||||||
|
from spiffworkflow_backend.models.task import TaskModel
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.routes.process_api_blueprint import (
|
from spiffworkflow_backend.routes.process_api_blueprint import (
|
||||||
_find_principal_or_raise,
|
_find_principal_or_raise,
|
||||||
@ -400,6 +401,11 @@ def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[st
|
|||||||
extensions = TaskService.get_extensions_from_task_model(task_model)
|
extensions = TaskService.get_extensions_from_task_model(task_model)
|
||||||
return _render_instructions_for_end_user(task_model, extensions)
|
return _render_instructions_for_end_user(task_model, extensions)
|
||||||
|
|
||||||
|
def render_data(return_type: str, entity: Union[ApiError, Task, ProcessInstanceModel]) -> str:
|
||||||
|
return_hash: dict = {"type": return_type}
|
||||||
|
return_hash[return_type] = entity
|
||||||
|
return f"data: {current_app.json.dumps(return_hash)} \n\n"
|
||||||
|
|
||||||
tasks = get_reportable_tasks()
|
tasks = get_reportable_tasks()
|
||||||
while True:
|
while True:
|
||||||
for spiff_task in tasks:
|
for spiff_task in tasks:
|
||||||
@ -411,23 +417,27 @@ def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[st
|
|||||||
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
yield render_data("error", api_error)
|
||||||
raise e
|
raise e
|
||||||
if instructions and spiff_task.id not in reported_ids:
|
if instructions and spiff_task.id not in reported_ids:
|
||||||
task = ProcessInstanceService.spiff_task_to_api_task(processor, spiff_task)
|
task = ProcessInstanceService.spiff_task_to_api_task(processor, spiff_task)
|
||||||
task.properties = {"instructionsForEndUser": instructions}
|
task.properties = {"instructionsForEndUser": instructions}
|
||||||
yield f"data: {current_app.json.dumps(task)} \n\n"
|
yield render_data("task", task)
|
||||||
reported_ids.append(spiff_task.id)
|
reported_ids.append(spiff_task.id)
|
||||||
if spiff_task.state == TaskState.READY:
|
if spiff_task.state == TaskState.READY:
|
||||||
|
# do not do any processing if the instance is not currently active
|
||||||
|
if process_instance.status not in ProcessInstanceModel.active_statuses():
|
||||||
|
yield render_data("unrunnable_instance", process_instance)
|
||||||
|
break
|
||||||
try:
|
try:
|
||||||
processor.do_engine_steps(execution_strategy_name="one_at_a_time")
|
processor.do_engine_steps(execution_strategy_name="one_at_a_time")
|
||||||
processor.do_engine_steps(execution_strategy_name="run_until_user_message")
|
processor.do_engine_steps(execution_strategy_name="run_until_user_message")
|
||||||
processor.save() # Fixme - maybe find a way not to do this on every loop?
|
processor.save() # Fixme - maybe find a way not to do this on every loop?
|
||||||
except WorkflowTaskException as wfe:
|
except WorkflowTaskException as wfe:
|
||||||
api_error = ApiError.from_workflow_exception(
|
api_error = ApiError.from_workflow_exception(
|
||||||
"engine_steps_error", "Failed complete an automated task.", exp=wfe
|
"engine_steps_error", "Failed to complete an automated task.", exp=wfe
|
||||||
)
|
)
|
||||||
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
yield render_data("error", api_error)
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
api_error = ApiError(
|
api_error = ApiError(
|
||||||
@ -435,7 +445,7 @@ def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[st
|
|||||||
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
yield render_data("error", api_error)
|
||||||
return
|
return
|
||||||
processor.refresh_waiting_tasks()
|
processor.refresh_waiting_tasks()
|
||||||
ready_engine_task_count = get_ready_engine_step_count(processor.bpmn_process_instance)
|
ready_engine_task_count = get_ready_engine_step_count(processor.bpmn_process_instance)
|
||||||
@ -454,10 +464,10 @@ def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[st
|
|||||||
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
message=f"Failed to complete an automated task. Error was: {str(e)}",
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
yield f"data: {current_app.json.dumps(api_error)} \n\n"
|
yield render_data("error", api_error)
|
||||||
raise e
|
raise e
|
||||||
task.properties = {"instructionsForEndUser": instructions}
|
task.properties = {"instructionsForEndUser": instructions}
|
||||||
yield f"data: {current_app.json.dumps(task)} \n\n"
|
yield render_data("task", task)
|
||||||
|
|
||||||
|
|
||||||
def get_ready_engine_step_count(bpmn_process_instance: BpmnWorkflow) -> int:
|
def get_ready_engine_step_count(bpmn_process_instance: BpmnWorkflow) -> int:
|
||||||
@ -472,8 +482,9 @@ def get_ready_engine_step_count(bpmn_process_instance: BpmnWorkflow) -> int:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _dequeued_interstitial_stream(process_instance_id: int) -> Generator[str, Optional[str], None]:
|
def _dequeued_interstitial_stream(process_instance_id: int) -> Generator[Optional[str], Optional[str], None]:
|
||||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||||
|
|
||||||
with ProcessInstanceQueueService.dequeued(process_instance):
|
with ProcessInstanceQueueService.dequeued(process_instance):
|
||||||
yield from _interstitial_stream(process_instance)
|
yield from _interstitial_stream(process_instance)
|
||||||
|
|
||||||
|
@ -577,6 +577,8 @@ class AuthorizationService:
|
|||||||
permissions_to_assign.append(
|
permissions_to_assign.append(
|
||||||
PermissionToAssign(permission="read", target_uri="/process-instances/report-metadata")
|
PermissionToAssign(permission="read", target_uri="/process-instances/report-metadata")
|
||||||
)
|
)
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/process-groups"))
|
||||||
|
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/process-models"))
|
||||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes"))
|
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes"))
|
||||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes/callers"))
|
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes/callers"))
|
||||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/service-tasks"))
|
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/service-tasks"))
|
||||||
|
@ -129,8 +129,27 @@ def setup_logger(app: Flask) -> None:
|
|||||||
spiff_logger_filehandler.setFormatter(log_formatter)
|
spiff_logger_filehandler.setFormatter(log_formatter)
|
||||||
|
|
||||||
# these loggers have been deemed too verbose to be useful
|
# these loggers have been deemed too verbose to be useful
|
||||||
garbage_loggers_to_exclude = ["connexion", "flask_cors.extension"]
|
garbage_loggers_to_exclude = ["connexion", "flask_cors.extension", "flask_cors.core", "sqlalchemy"]
|
||||||
loggers_to_exclude_from_debug = ["sqlalchemy"]
|
|
||||||
|
# if you actually want one of these excluded loggers, there is a config option to turn it on
|
||||||
|
loggers_to_use = app.config.get("SPIFFWORKFLOW_BACKEND_LOGGERS_TO_USE", [])
|
||||||
|
if loggers_to_use is None or loggers_to_use == "":
|
||||||
|
loggers_to_use = []
|
||||||
|
else:
|
||||||
|
loggers_to_use = loggers_to_use.split(",")
|
||||||
|
for logger_to_use in loggers_to_use:
|
||||||
|
if logger_to_use in garbage_loggers_to_exclude:
|
||||||
|
garbage_loggers_to_exclude.remove(logger_to_use)
|
||||||
|
else:
|
||||||
|
app.logger.warning(
|
||||||
|
f"Logger '{logger_to_use}' not found in garbage_loggers_to_exclude. You do not need to add it to"
|
||||||
|
" SPIFFWORKFLOW_BACKEND_LOGGERS_TO_USE."
|
||||||
|
)
|
||||||
|
|
||||||
|
loggers_to_exclude_from_debug = []
|
||||||
|
|
||||||
|
if "sqlalchemy" not in garbage_loggers_to_exclude:
|
||||||
|
loggers_to_exclude_from_debug.append("sqlalchemy")
|
||||||
|
|
||||||
# make all loggers act the same
|
# make all loggers act the same
|
||||||
for name in logging.root.manager.loggerDict:
|
for name in logging.root.manager.loggerDict:
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import uuid
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import List
|
from typing import List
|
||||||
@ -187,9 +188,7 @@ class ProcessModelService(FileSystemService):
|
|||||||
cls,
|
cls,
|
||||||
process_group_id: Optional[str] = None,
|
process_group_id: Optional[str] = None,
|
||||||
recursive: Optional[bool] = False,
|
recursive: Optional[bool] = False,
|
||||||
filter_runnable_by_user: Optional[bool] = False,
|
|
||||||
) -> List[ProcessModelInfo]:
|
) -> List[ProcessModelInfo]:
|
||||||
"""Get process models."""
|
|
||||||
process_models = []
|
process_models = []
|
||||||
root_path = FileSystemService.root_path()
|
root_path = FileSystemService.root_path()
|
||||||
if process_group_id:
|
if process_group_id:
|
||||||
@ -205,22 +204,45 @@ class ProcessModelService(FileSystemService):
|
|||||||
process_model = cls.get_process_model_from_relative_path(os.path.dirname(process_model_relative_path))
|
process_model = cls.get_process_model_from_relative_path(os.path.dirname(process_model_relative_path))
|
||||||
process_models.append(process_model)
|
process_models.append(process_model)
|
||||||
process_models.sort()
|
process_models.sort()
|
||||||
|
|
||||||
if filter_runnable_by_user:
|
|
||||||
user = UserService.current_user()
|
|
||||||
new_process_model_list = []
|
|
||||||
for process_model in process_models:
|
|
||||||
modified_process_model_id = ProcessModelInfo.modify_process_identifier_for_path_param(process_model.id)
|
|
||||||
uri = f"/v1.0/process-instances/{modified_process_model_id}"
|
|
||||||
has_permission = AuthorizationService.user_has_permission(
|
|
||||||
user=user, permission="create", target_uri=uri
|
|
||||||
)
|
|
||||||
if has_permission:
|
|
||||||
new_process_model_list.append(process_model)
|
|
||||||
return new_process_model_list
|
|
||||||
|
|
||||||
return process_models
|
return process_models
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_process_models_for_api(
|
||||||
|
cls,
|
||||||
|
process_group_id: Optional[str] = None,
|
||||||
|
recursive: Optional[bool] = False,
|
||||||
|
filter_runnable_by_user: Optional[bool] = False,
|
||||||
|
) -> List[ProcessModelInfo]:
|
||||||
|
process_models = cls.get_process_models(process_group_id, recursive)
|
||||||
|
|
||||||
|
permission_to_check = "read"
|
||||||
|
permission_base_uri = "/v1.0/process-models"
|
||||||
|
user = UserService.current_user()
|
||||||
|
if filter_runnable_by_user:
|
||||||
|
permission_to_check = "create"
|
||||||
|
permission_base_uri = "/v1.0/process-instances"
|
||||||
|
|
||||||
|
# if user has access to uri/* with that permission then there's no reason to check each one individually
|
||||||
|
guid_of_non_existent_item_to_check_perms_against = str(uuid.uuid4())
|
||||||
|
has_permission = AuthorizationService.user_has_permission(
|
||||||
|
user=user,
|
||||||
|
permission=permission_to_check,
|
||||||
|
target_uri=f"{permission_base_uri}/{guid_of_non_existent_item_to_check_perms_against}",
|
||||||
|
)
|
||||||
|
if has_permission:
|
||||||
|
return process_models
|
||||||
|
|
||||||
|
new_process_model_list = []
|
||||||
|
for process_model in process_models:
|
||||||
|
modified_process_model_id = ProcessModelInfo.modify_process_identifier_for_path_param(process_model.id)
|
||||||
|
uri = f"{permission_base_uri}/{modified_process_model_id}"
|
||||||
|
has_permission = AuthorizationService.user_has_permission(
|
||||||
|
user=user, permission=permission_to_check, target_uri=uri
|
||||||
|
)
|
||||||
|
if has_permission:
|
||||||
|
new_process_model_list.append(process_model)
|
||||||
|
return new_process_model_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_parent_group_array_and_cache_it(
|
def get_parent_group_array_and_cache_it(
|
||||||
cls, process_identifier: str, process_group_cache: dict[str, ProcessGroup]
|
cls, process_identifier: str, process_group_cache: dict[str, ProcessGroup]
|
||||||
@ -256,6 +278,38 @@ class ProcessModelService(FileSystemService):
|
|||||||
process_groups.sort()
|
process_groups.sort()
|
||||||
return process_groups
|
return process_groups
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_process_groups_for_api(
|
||||||
|
cls,
|
||||||
|
process_group_id: Optional[str] = None,
|
||||||
|
) -> List[ProcessGroup]:
|
||||||
|
process_groups = cls.get_process_groups(process_group_id)
|
||||||
|
|
||||||
|
permission_to_check = "read"
|
||||||
|
permission_base_uri = "/v1.0/process-groups"
|
||||||
|
user = UserService.current_user()
|
||||||
|
|
||||||
|
# if user has access to uri/* with that permission then there's no reason to check each one individually
|
||||||
|
guid_of_non_existent_item_to_check_perms_against = str(uuid.uuid4())
|
||||||
|
has_permission = AuthorizationService.user_has_permission(
|
||||||
|
user=user,
|
||||||
|
permission=permission_to_check,
|
||||||
|
target_uri=f"{permission_base_uri}/{guid_of_non_existent_item_to_check_perms_against}",
|
||||||
|
)
|
||||||
|
if has_permission:
|
||||||
|
return process_groups
|
||||||
|
|
||||||
|
new_process_group_list = []
|
||||||
|
for process_group in process_groups:
|
||||||
|
modified_process_group_id = ProcessModelInfo.modify_process_identifier_for_path_param(process_group.id)
|
||||||
|
uri = f"{permission_base_uri}/{modified_process_group_id}"
|
||||||
|
has_permission = AuthorizationService.user_has_permission(
|
||||||
|
user=user, permission=permission_to_check, target_uri=uri
|
||||||
|
)
|
||||||
|
if has_permission:
|
||||||
|
new_process_group_list.append(process_group)
|
||||||
|
return new_process_group_list
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_process_group(cls, process_group_id: str, find_direct_nested_items: bool = True) -> ProcessGroup:
|
def get_process_group(cls, process_group_id: str, find_direct_nested_items: bool = True) -> ProcessGroup:
|
||||||
"""Look for a given process_group, and return it."""
|
"""Look for a given process_group, and return it."""
|
||||||
|
@ -702,7 +702,6 @@ class TestProcessApi(BaseTest):
|
|||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_process_group_list."""
|
|
||||||
# add 5 groups
|
# add 5 groups
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
group_id = f"test_process_group_{i}"
|
group_id = f"test_process_group_{i}"
|
||||||
@ -997,14 +996,13 @@ class TestProcessApi(BaseTest):
|
|||||||
assert response.json is not None
|
assert response.json is not None
|
||||||
assert "test_group/random_fact" == response.json["process_model_identifier"]
|
assert "test_group/random_fact" == response.json["process_model_identifier"]
|
||||||
|
|
||||||
def test_get_process_groups_when_none(
|
def test_process_group_list_when_none(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
client: FlaskClient,
|
client: FlaskClient,
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_get_process_groups_when_none."""
|
|
||||||
response = client.get(
|
response = client.get(
|
||||||
"/v1.0/process-groups",
|
"/v1.0/process-groups",
|
||||||
headers=self.logged_in_headers(with_super_admin_user),
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
@ -1013,14 +1011,13 @@ class TestProcessApi(BaseTest):
|
|||||||
assert response.json is not None
|
assert response.json is not None
|
||||||
assert response.json["results"] == []
|
assert response.json["results"] == []
|
||||||
|
|
||||||
def test_get_process_groups_when_there_are_some(
|
def test_process_group_list_when_there_are_some(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
client: FlaskClient,
|
client: FlaskClient,
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_get_process_groups_when_there_are_some."""
|
|
||||||
self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
self.create_group_and_model_with_bpmn(client, with_super_admin_user)
|
||||||
response = client.get(
|
response = client.get(
|
||||||
"/v1.0/process-groups",
|
"/v1.0/process-groups",
|
||||||
@ -1033,6 +1030,84 @@ class TestProcessApi(BaseTest):
|
|||||||
assert response.json["pagination"]["total"] == 1
|
assert response.json["pagination"]["total"] == 1
|
||||||
assert response.json["pagination"]["pages"] == 1
|
assert response.json["pagination"]["pages"] == 1
|
||||||
|
|
||||||
|
def test_process_group_list_when_user_has_resticted_access(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
self.create_group_and_model_with_bpmn(
|
||||||
|
client, with_super_admin_user, process_group_id="admin_only", process_model_id="random_fact"
|
||||||
|
)
|
||||||
|
self.create_group_and_model_with_bpmn(
|
||||||
|
client, with_super_admin_user, process_group_id="all_users", process_model_id="hello_world"
|
||||||
|
)
|
||||||
|
user_one = self.create_user_with_permission(username="user_one", target_uri="/v1.0/process-groups/all_users:*")
|
||||||
|
self.add_permissions_to_user(user=user_one, target_uri="/v1.0/process-groups", permission_names=["read"])
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
"/v1.0/process-groups",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json is not None
|
||||||
|
assert len(response.json["results"]) == 2
|
||||||
|
assert response.json["pagination"]["count"] == 2
|
||||||
|
assert response.json["pagination"]["total"] == 2
|
||||||
|
assert response.json["pagination"]["pages"] == 1
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
"/v1.0/process-groups",
|
||||||
|
headers=self.logged_in_headers(user_one),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json is not None
|
||||||
|
assert len(response.json["results"]) == 1
|
||||||
|
assert response.json["results"][0]["id"] == "all_users"
|
||||||
|
assert response.json["pagination"]["count"] == 1
|
||||||
|
assert response.json["pagination"]["total"] == 1
|
||||||
|
assert response.json["pagination"]["pages"] == 1
|
||||||
|
|
||||||
|
def test_process_model_list_when_user_has_resticted_access(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
self.create_group_and_model_with_bpmn(
|
||||||
|
client, with_super_admin_user, process_group_id="admin_only", process_model_id="random_fact"
|
||||||
|
)
|
||||||
|
self.create_group_and_model_with_bpmn(
|
||||||
|
client, with_super_admin_user, process_group_id="all_users", process_model_id="hello_world"
|
||||||
|
)
|
||||||
|
user_one = self.create_user_with_permission(username="user_one", target_uri="/v1.0/process-models/all_users:*")
|
||||||
|
self.add_permissions_to_user(user=user_one, target_uri="/v1.0/process-models", permission_names=["read"])
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
"/v1.0/process-models?recursive=true",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json is not None
|
||||||
|
assert len(response.json["results"]) == 2
|
||||||
|
assert response.json["pagination"]["count"] == 2
|
||||||
|
assert response.json["pagination"]["total"] == 2
|
||||||
|
assert response.json["pagination"]["pages"] == 1
|
||||||
|
|
||||||
|
response = client.get(
|
||||||
|
"/v1.0/process-models?recursive=true",
|
||||||
|
headers=self.logged_in_headers(user_one),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json is not None
|
||||||
|
assert len(response.json["results"]) == 1
|
||||||
|
assert response.json["results"][0]["id"] == "all_users/hello_world"
|
||||||
|
assert response.json["pagination"]["count"] == 1
|
||||||
|
assert response.json["pagination"]["total"] == 1
|
||||||
|
assert response.json["pagination"]["pages"] == 1
|
||||||
|
|
||||||
def test_get_process_group_when_found(
|
def test_get_process_group_when_found(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
@ -1688,14 +1763,15 @@ class TestProcessApi(BaseTest):
|
|||||||
# The second script task should produce rendered jinja text
|
# The second script task should produce rendered jinja text
|
||||||
# The Manual Task should then return a message as well.
|
# The Manual Task should then return a message as well.
|
||||||
assert len(results) == 2
|
assert len(results) == 2
|
||||||
assert json_results[0]["state"] == "READY"
|
# import pdb; pdb.set_trace()
|
||||||
assert json_results[0]["title"] == "Script Task #2"
|
assert json_results[0]["task"]["state"] == "READY"
|
||||||
assert json_results[0]["properties"]["instructionsForEndUser"] == "I am Script Task 2"
|
assert json_results[0]["task"]["title"] == "Script Task #2"
|
||||||
assert json_results[1]["state"] == "READY"
|
assert json_results[0]["task"]["properties"]["instructionsForEndUser"] == "I am Script Task 2"
|
||||||
assert json_results[1]["title"] == "Manual Task"
|
assert json_results[1]["task"]["state"] == "READY"
|
||||||
|
assert json_results[1]["task"]["title"] == "Manual Task"
|
||||||
|
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/tasks/{process_instance_id}/{json_results[1]['id']}",
|
f"/v1.0/tasks/{process_instance_id}/{json_results[1]['task']['id']}",
|
||||||
headers=headers,
|
headers=headers,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1705,14 +1781,14 @@ class TestProcessApi(BaseTest):
|
|||||||
results = list(_dequeued_interstitial_stream(process_instance_id))
|
results = list(_dequeued_interstitial_stream(process_instance_id))
|
||||||
json_results = list(map(lambda x: json.loads(x[5:]), results)) # type: ignore
|
json_results = list(map(lambda x: json.loads(x[5:]), results)) # type: ignore
|
||||||
assert len(results) == 1
|
assert len(results) == 1
|
||||||
assert json_results[0]["state"] == "READY"
|
assert json_results[0]["task"]["state"] == "READY"
|
||||||
assert json_results[0]["can_complete"] is False
|
assert json_results[0]["task"]["can_complete"] is False
|
||||||
assert json_results[0]["title"] == "Please Approve"
|
assert json_results[0]["task"]["title"] == "Please Approve"
|
||||||
assert json_results[0]["properties"]["instructionsForEndUser"] == "I am a manual task in another lane"
|
assert json_results[0]["task"]["properties"]["instructionsForEndUser"] == "I am a manual task in another lane"
|
||||||
|
|
||||||
# Complete task as the finance user.
|
# Complete task as the finance user.
|
||||||
response = client.put(
|
response = client.put(
|
||||||
f"/v1.0/tasks/{process_instance_id}/{json_results[0]['id']}",
|
f"/v1.0/tasks/{process_instance_id}/{json_results[0]['task']['id']}",
|
||||||
headers=self.logged_in_headers(finance_user),
|
headers=self.logged_in_headers(finance_user),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1722,8 +1798,8 @@ class TestProcessApi(BaseTest):
|
|||||||
results = list(_dequeued_interstitial_stream(process_instance_id))
|
results = list(_dequeued_interstitial_stream(process_instance_id))
|
||||||
json_results = list(map(lambda x: json.loads(x[5:]), results)) # type: ignore
|
json_results = list(map(lambda x: json.loads(x[5:]), results)) # type: ignore
|
||||||
assert len(json_results) == 1
|
assert len(json_results) == 1
|
||||||
assert json_results[0]["state"] == "COMPLETED"
|
assert json_results[0]["task"]["state"] == "COMPLETED"
|
||||||
assert json_results[0]["properties"]["instructionsForEndUser"] == "I am the end task"
|
assert json_results[0]["task"]["properties"]["instructionsForEndUser"] == "I am the end task"
|
||||||
|
|
||||||
def test_process_instance_list_with_default_list(
|
def test_process_instance_list_with_default_list(
|
||||||
self,
|
self,
|
||||||
|
@ -287,9 +287,9 @@ class TestAuthorizationService(BaseTest):
|
|||||||
client: FlaskClient,
|
client: FlaskClient,
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_explode_permissions_basic."""
|
|
||||||
expected_permissions = [
|
expected_permissions = [
|
||||||
("/active-users/*", "read"),
|
("/active-users/*", "read"),
|
||||||
|
("/process-groups", "read"),
|
||||||
("/process-instances/find-by-id/*", "read"),
|
("/process-instances/find-by-id/*", "read"),
|
||||||
("/process-instances/for-me", "create"),
|
("/process-instances/for-me", "create"),
|
||||||
("/process-instances/report-metadata", "read"),
|
("/process-instances/report-metadata", "read"),
|
||||||
@ -297,6 +297,7 @@ class TestAuthorizationService(BaseTest):
|
|||||||
("/process-instances/reports/*", "delete"),
|
("/process-instances/reports/*", "delete"),
|
||||||
("/process-instances/reports/*", "read"),
|
("/process-instances/reports/*", "read"),
|
||||||
("/process-instances/reports/*", "update"),
|
("/process-instances/reports/*", "update"),
|
||||||
|
("/process-models", "read"),
|
||||||
("/processes", "read"),
|
("/processes", "read"),
|
||||||
("/processes/callers", "read"),
|
("/processes/callers", "read"),
|
||||||
("/service-tasks", "read"),
|
("/service-tasks", "read"),
|
||||||
|
@ -13,6 +13,7 @@ const submitWithUser = (
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.log('=======visit find by id : ');
|
cy.log('=======visit find by id : ');
|
||||||
cy.visit('/admin/process-instances/find-by-id');
|
cy.visit('/admin/process-instances/find-by-id');
|
||||||
|
cy.wait(3000);
|
||||||
cy.get('#process-instance-id-input').type(processInstanceId);
|
cy.get('#process-instance-id-input').type(processInstanceId);
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -53,8 +54,8 @@ const submitWithUser = (
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got people for jobs of any size.');
|
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got people for jobs of any size.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ const submitWithUser = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Consulting Fees Path - Without Files
|
//Consulting Fees Path - Without Files
|
||||||
describe('Consulting Fees Path - Without Files', () => {
|
describe.only('Consulting Fees Path - Without Files', () => {
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//Budget owner approves the request
|
//Budget owner approves the request
|
||||||
it('Budget owner approves', () => {
|
it('Budget owner approves', () => {
|
||||||
@ -120,8 +121,8 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
|
|
||||||
@ -182,9 +183,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, \‘consultant\’ and advisor\’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, \‘consultant\’ and advisor\’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -249,8 +250,8 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -311,9 +312,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -378,8 +379,8 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -441,9 +442,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -532,8 +533,8 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -636,9 +637,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -700,8 +701,8 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -804,9 +805,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -871,8 +872,8 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -974,9 +975,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
|
@ -13,6 +13,7 @@ const submitWithUser = (
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.log('=======visit find by id : ');
|
cy.log('=======visit find by id : ');
|
||||||
cy.visit('/admin/process-instances/find-by-id');
|
cy.visit('/admin/process-instances/find-by-id');
|
||||||
|
cy.wait(3000);
|
||||||
cy.get('#process-instance-id-input').type(processInstanceId);
|
cy.get('#process-instance-id-input').type(processInstanceId);
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -57,8 +58,8 @@ const submitWithUser = (
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Computer hardware includes the physical parts of a computer, such as the case, central processing unit (CPU), random access memory (RAM), monitor, mouse, keyboard, computer data storage, graphics card, sound card');
|
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Computer hardware includes the physical parts of a computer, such as the case, central processing unit (CPU), random access memory (RAM), monitor, mouse, keyboard, computer data storage, graphics card, sound card');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ const submitWithUser = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Equipment Path - Without Files
|
//Equipment Path - Without Files
|
||||||
describe('Equipment Path - Without Files', () => {
|
describe.only('Equipment Path - Without Files', () => {
|
||||||
|
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//Out of Policy. People Ops Partner Group and Budget owner approves the request
|
//Out of Policy. People Ops Partner Group and Budget owner approves the request
|
||||||
@ -124,7 +125,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -196,9 +197,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. This describes a design architecture for a electronic digital computer with subdivisions of a processing unit');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. This describes a design architecture for a electronic digital computer with subdivisions of a processing unit');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -279,7 +280,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -322,9 +323,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('When using computer hardware, an upgrade means adding new or additional hardware to a computer that improves its performance, increases its capacity, or adds new features. For example, \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('When using computer hardware, an upgrade means adding new or additional hardware to a computer that improves its performance, increases its capacity, or adds new features. For example, \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -402,7 +403,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -443,9 +444,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('A supercomputer is superficially similar to a mainframe but is instead intended for extremely demanding computational tasks. As of November 2021, the fastest supercomputer on the TOP500 supercomputer list is Fugaku, in Japan');
|
cy.get('.cds--text-area__wrapper').find('#root').type('A supercomputer is superficially similar to a mainframe but is instead intended for extremely demanding computational tasks. As of November 2021, the fastest supercomputer on the TOP500 supercomputer list is Fugaku, in Japan');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -550,7 +551,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -591,9 +592,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('Computer hardware contain dangerous chemicals such as lead, mercury, nickel, and cadmium. According to the EPA these e-wastes have a harmful effect on the environment unless they are disposed properly. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('Computer hardware contain dangerous chemicals such as lead, mercury, nickel, and cadmium. According to the EPA these e-wastes have a harmful effect on the environment unless they are disposed properly. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -658,7 +659,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -699,9 +700,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, \‘consultant\’ and advisor\’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, \‘consultant\’ and advisor\’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -766,7 +767,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -807,9 +808,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -892,7 +893,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -933,9 +934,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The template for all modern computers is the Von Neumann architecture, detailed in a 1945 paper by Hungarian mathematician John von Neumann. \nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1014,7 +1015,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1055,9 +1056,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The personal computer is one of the most common types of computer due to its versatility and relatively low price. Desktop personal computers have a monitor, a keyboard, a mouse, and a computer case.\nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The personal computer is one of the most common types of computer due to its versatility and relatively low price. Desktop personal computers have a monitor, a keyboard, a mouse, and a computer case.\nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1135,7 +1136,7 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1176,9 +1177,9 @@ describe('Equipment Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The personal computer is one of the most common types of computer due to its versatility and relatively low price. Desktop personal computers have a monitor, a keyboard, a mouse, and a computer case.\nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The personal computer is one of the most common types of computer due to its versatility and relatively low price. Desktop personal computers have a monitor, a keyboard, a mouse, and a computer case.\nhttps://en.wikipedia.org/wiki/Computer_hardware');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1281,7 +1282,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1394,9 +1395,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1475,7 +1476,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1557,9 +1558,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1638,7 +1639,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1719,9 +1720,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1827,7 +1828,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1909,9 +1910,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1977,7 +1978,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -2059,9 +2060,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -2127,7 +2128,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -2208,9 +2209,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -2294,7 +2295,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -2375,9 +2376,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -2457,7 +2458,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -2538,9 +2539,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -2619,7 +2620,7 @@ describe('Equipment Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -2701,9 +2702,9 @@ describe('Equipment Path - With Files', () => {
|
|||||||
.attachFile(['png-5mb-2.png']);
|
.attachFile(['png-5mb-2.png']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
//Software and License - Without Files
|
//Software and License - Without Files
|
||||||
describe('Initiate a Request - Without Files', () => {
|
describe.only('Initiate a Request - Without Files', () => {
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//Submit a Software and License request - Without Files
|
//Submit a Software and License request - Without Files
|
||||||
it('Submit a Software and License request', () => {
|
it('Submit a Software and License request', () => {
|
||||||
@ -87,9 +87,9 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -179,9 +179,9 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
|
|
||||||
//cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
//cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -282,15 +282,15 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S,\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
cy.contains('Edit the Request').click();
|
//cy.contains('Edit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Edit the Request"]').click();
|
//cy.get('input[value="Edit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Edit Request$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
|
|
||||||
@ -312,10 +312,10 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
'Task: Review the Request',
|
'Task: Review the Request',
|
||||||
{ timeout: 60000 });
|
{ timeout: 60000 });
|
||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('EDITING INFO : 2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
cy.get('.cds--text-area__wrapper').find('#root').type('EDITING INFO');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Submit$/)
|
||||||
@ -331,8 +331,8 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//Save as Draft a Software and License request - Without Files
|
//Close a Software and License request 1 - Without Files
|
||||||
it.only('Save as Draft a Software and License request', () => {
|
it('Close a Software and License request 1', () => {
|
||||||
let username = Cypress.env('requestor_username');
|
let username = Cypress.env('requestor_username');
|
||||||
let password = Cypress.env('requestor_password');
|
let password = Cypress.env('requestor_password');
|
||||||
cy.log('=====username : ' + username);
|
cy.log('=====username : ' + username);
|
||||||
@ -405,13 +405,202 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
cy.get('#root_item_1_unit_price').type('4500');
|
cy.get('#root_item_1_unit_price').type('4500');
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Save as draft$/)
|
.contains(/^Close$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
|
//cy.get('button')
|
||||||
|
// .contains(/^Return to Home$/)
|
||||||
|
// .click();
|
||||||
|
|
||||||
|
cy.contains('Started by me', { timeout: 60000 });
|
||||||
|
cy.logout();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//Close a Software and License request 2 - Without Files
|
||||||
|
it('Close a Software and License request 2', () => {
|
||||||
|
let username = Cypress.env('requestor_username');
|
||||||
|
let password = Cypress.env('requestor_password');
|
||||||
|
cy.log('=====username : ' + username);
|
||||||
|
cy.log('=====password : ' + password);
|
||||||
|
|
||||||
|
cy.login(username, password);
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.contains('Start New +').click();
|
||||||
|
cy.contains('Request Goods or Services');
|
||||||
|
|
||||||
|
cy.runPrimaryBpmnFile(true);
|
||||||
|
|
||||||
|
/* cy.contains('Please select the type of request to start the process.');
|
||||||
|
// wait a second to ensure we can click the radio button
|
||||||
|
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('input#root-procurement').click();
|
||||||
|
cy.wait(2000);
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
*/
|
||||||
|
|
||||||
|
cy.contains(
|
||||||
|
'Request Goods or Services',
|
||||||
|
{ timeout: 60000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.url().then((currentUrl) => {
|
||||||
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
|
// extract the digits after /tasks
|
||||||
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
|
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||||
|
let projectId = Cypress.env('project_id');
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('#root_project').select(projectId);
|
||||||
|
cy.get('#root_category').select('soft_and_lic');
|
||||||
|
cy.get('#root_purpose').clear().type('Sware\nA software license is a document that provides legally binding guidelines for the use and distribution of software.\nSoftware licenses typically provide end users with the right to one or more copies of the software without violating copyrights');
|
||||||
|
cy.get('#root_criticality').select('High');
|
||||||
|
cy.get('#root_period').clear().type('25-11-2025');
|
||||||
|
cy.get('body').click();
|
||||||
|
cy.get('#root_vendor').clear().type('Microsoft');
|
||||||
|
cy.get('#root_payment_method').select('Reimbursement');
|
||||||
|
/* cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||||
|
*/
|
||||||
|
//item 0
|
||||||
|
cy.get('#root_item_0_sub_category').select('op_src');
|
||||||
|
cy.get('#root_item_0_item_name').clear().type('Open source software is code that is designed to be publicly accessible anyone can see, modify, END');
|
||||||
|
cy.get('#root_item_0_qty').clear().type('2');
|
||||||
|
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||||
|
cy.get('#root_item_0_currency').select('SNT');
|
||||||
|
cy.get('#root_item_0_unit_price').type('1915');
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||||
|
|
||||||
|
//item 1
|
||||||
|
cy.get('#root_item_1_sub_category').select('lic_and_sub');
|
||||||
|
cy.get('#root_item_1_item_name').clear().type('A software license is a document that provides legally binding guidelines for the use and distri END');
|
||||||
|
//cy.get('#root_item_1_qty').clear().type('1');
|
||||||
|
//cy.get('#root_item_1_currency_type').select('Fiat');
|
||||||
|
//cy.get('#root_item_1_currency').select('AED');
|
||||||
|
//cy.get('#root_item_1_unit_price').type('4500');
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Return to Home$/)
|
.contains(/^Close$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
|
//cy.get('button')
|
||||||
|
// .contains(/^Return to Home$/)
|
||||||
|
// .click();
|
||||||
|
|
||||||
|
cy.contains('Started by me', { timeout: 60000 });
|
||||||
|
cy.logout();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//Close a Software and License request 3 - Without Files
|
||||||
|
it('Close a Software and License request 3', () => {
|
||||||
|
let username = Cypress.env('requestor_username');
|
||||||
|
let password = Cypress.env('requestor_password');
|
||||||
|
cy.log('=====username : ' + username);
|
||||||
|
cy.log('=====password : ' + password);
|
||||||
|
|
||||||
|
cy.login(username, password);
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.contains('Start New +').click();
|
||||||
|
cy.contains('Request Goods or Services');
|
||||||
|
|
||||||
|
cy.runPrimaryBpmnFile(true);
|
||||||
|
|
||||||
|
/* cy.contains('Please select the type of request to start the process.');
|
||||||
|
// wait a second to ensure we can click the radio button
|
||||||
|
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('input#root-procurement').click();
|
||||||
|
cy.wait(2000);
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
*/
|
||||||
|
|
||||||
|
cy.contains(
|
||||||
|
'Request Goods or Services',
|
||||||
|
{ timeout: 60000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.url().then((currentUrl) => {
|
||||||
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
|
// extract the digits after /tasks
|
||||||
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
|
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||||
|
let projectId = Cypress.env('project_id');
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('#root_project').select(projectId);
|
||||||
|
cy.get('#root_category').select('soft_and_lic');
|
||||||
|
cy.get('#root_purpose').clear().type('Sware\nA software license is a document that provides legally binding guidelines for the use and distribution of software.\nSoftware licenses typically provide end users with the right to one or more copies of the software without violating copyrights');
|
||||||
|
cy.get('#root_criticality').select('High');
|
||||||
|
cy.get('#root_period').clear().type('25-11-2025');
|
||||||
|
cy.get('body').click();
|
||||||
|
cy.get('#root_vendor').clear().type('Microsoft');
|
||||||
|
cy.get('#root_payment_method').select('Reimbursement');
|
||||||
|
/* cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||||
|
*/
|
||||||
|
//item 0
|
||||||
|
cy.get('#root_item_0_sub_category').select('op_src');
|
||||||
|
cy.get('#root_item_0_item_name').clear().type('Open source software is code that is designed to be publicly accessible anyone can see, modify, END');
|
||||||
|
cy.get('#root_item_0_qty').clear().type('2');
|
||||||
|
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||||
|
cy.get('#root_item_0_currency').select('SNT');
|
||||||
|
cy.get('#root_item_0_unit_price').type('1915');
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||||
|
|
||||||
|
//item 1
|
||||||
|
cy.get('#root_item_1_sub_category').select('lic_and_sub');
|
||||||
|
cy.get('#root_item_1_item_name').clear().type('A software license is a document that provides legally binding guidelines for the use and distri END');
|
||||||
|
cy.get('#root_item_1_qty').clear().type('1');
|
||||||
|
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||||
|
cy.get('#root_item_1_currency').select('AED');
|
||||||
|
cy.get('#root_item_1_unit_price').type('4500');
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.contains(
|
||||||
|
'Review and provide any supporting information or files for your request.',
|
||||||
|
{ timeout: 60000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Close$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// cy.get('button')
|
||||||
|
// .contains(/^Return to Home$/)
|
||||||
|
// .click();
|
||||||
|
|
||||||
cy.contains('Started by me', { timeout: 60000 });
|
cy.contains('Started by me', { timeout: 60000 });
|
||||||
cy.logout();
|
cy.logout();
|
||||||
|
|
||||||
@ -492,10 +681,10 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
cy.get('#root_item_1_currency').select('AED');
|
cy.get('#root_item_1_currency').select('AED');
|
||||||
cy.get('#root_item_1_unit_price').type('4500');
|
cy.get('#root_item_1_unit_price').type('4500');
|
||||||
|
|
||||||
cy.get('#root-Yes').click();
|
//cy.get('#root-Yes').click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Cancel Request$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -594,16 +783,12 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
cy.contains('Cancel the Request').click();
|
//cy.contains('Cancel the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Cancel the Request"]').click();
|
//cy.get('input[value="Cancel the Request"]').click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Cancel Request$/)
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('button')
|
|
||||||
.contains(/^Return to Home$/)
|
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.contains('Started by me', { timeout: 60000 });
|
cy.contains('Started by me', { timeout: 60000 });
|
||||||
@ -619,7 +804,7 @@ describe('Initiate a Request - Without Files', () => {
|
|||||||
describe('Initiate a Request - With Files', () => {
|
describe('Initiate a Request - With Files', () => {
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//Submit a Software and License request - Without Files
|
//Submit a Software and License request - Without Files
|
||||||
it('Submit a Software and License request', () => {
|
it('Submit a Software and License request - With Files', () => {
|
||||||
let username = Cypress.env('requestor_username');
|
let username = Cypress.env('requestor_username');
|
||||||
let password = Cypress.env('requestor_password');
|
let password = Cypress.env('requestor_password');
|
||||||
cy.log('=====username : ' + username);
|
cy.log('=====username : ' + username);
|
||||||
@ -744,9 +929,9 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -903,9 +1088,9 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -924,7 +1109,7 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Edit a Software and License request - With Files
|
//Edit a Software and License request - With Files
|
||||||
it('Edit a Software and License request', () => {
|
it('Edit a Software and License request - With Files', () => {
|
||||||
let username = Cypress.env('requestor_username');
|
let username = Cypress.env('requestor_username');
|
||||||
let password = Cypress.env('requestor_password');
|
let password = Cypress.env('requestor_password');
|
||||||
cy.log('=====username : ' + username);
|
cy.log('=====username : ' + username);
|
||||||
@ -1051,13 +1236,13 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
|
|
||||||
cy.contains('Edit the Request').click();
|
//cy.contains('Edit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Edit the Request"]').click();
|
//cy.get('input[value="Edit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Edit Request$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
|
|
||||||
@ -1079,8 +1264,8 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('EDITING INFO : 2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
cy.get('.cds--text-area__wrapper').find('#root').type('EDITING INFO : 2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Submit$/)
|
||||||
@ -1096,8 +1281,139 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Close a Software and License request 1 - With Files
|
||||||
|
it('Close a Software and License request 1 - With Files', () => {
|
||||||
|
let username = Cypress.env('requestor_username');
|
||||||
|
let password = Cypress.env('requestor_password');
|
||||||
|
cy.log('=====username : ' + username);
|
||||||
|
cy.log('=====password : ' + password);
|
||||||
|
|
||||||
|
cy.login(username, password);
|
||||||
|
cy.visit('/');
|
||||||
|
|
||||||
|
cy.contains('Start New +').click();
|
||||||
|
cy.contains('Request Goods or Services');
|
||||||
|
|
||||||
|
cy.runPrimaryBpmnFile(true);
|
||||||
|
|
||||||
|
/* cy.contains('Please select the type of request to start the process.');
|
||||||
|
// wait a second to ensure we can click the radio button
|
||||||
|
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('input#root-procurement').click();
|
||||||
|
cy.wait(2000);
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
*/
|
||||||
|
|
||||||
|
cy.contains(
|
||||||
|
'Request Goods or Services',
|
||||||
|
{ timeout: 60000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.url().then((currentUrl) => {
|
||||||
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
|
// extract the digits after /tasks
|
||||||
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
|
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||||
|
let projectId = Cypress.env('project_id');
|
||||||
|
cy.wait(2000);
|
||||||
|
cy.get('#root_project').select(projectId);
|
||||||
|
cy.get('#root_category').select('soft_and_lic');
|
||||||
|
cy.get('#root_purpose').clear().type('Sware\nA software license is a document that provides legally binding guidelines for the use and distribution of software.\nSoftware licenses typically provide end users with the right to one or more copies of the software without violating copyrights');
|
||||||
|
cy.get('#root_criticality').select('High');
|
||||||
|
cy.get('#root_period').clear().type('25-11-2025');
|
||||||
|
cy.get('body').click();
|
||||||
|
cy.get('#root_vendor').clear().type('Microsoft');
|
||||||
|
cy.get('#root_payment_method').select('Reimbursement');
|
||||||
|
/* cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||||
|
*/
|
||||||
|
//item 0
|
||||||
|
cy.get('#root_item_0_sub_category').select('op_src');
|
||||||
|
cy.get('#root_item_0_item_name').clear().type('Open source software is code that is designed to be publicly accessible anyone can see, modify, END');
|
||||||
|
cy.get('#root_item_0_qty').clear().type('2');
|
||||||
|
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||||
|
cy.get('#root_item_0_currency').select('SNT');
|
||||||
|
cy.get('#root_item_0_unit_price').type('1915');
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||||
|
|
||||||
|
//item 1
|
||||||
|
cy.get('#root_item_1_sub_category').select('lic_and_sub');
|
||||||
|
cy.get('#root_item_1_item_name').clear().type('A software license is a document that provides legally binding guidelines for the use and distri END');
|
||||||
|
cy.get('#root_item_1_qty').clear().type('1');
|
||||||
|
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||||
|
cy.get('#root_item_1_currency').select('AED');
|
||||||
|
cy.get('#root_item_1_unit_price').type('4500');
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Submit$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.contains(
|
||||||
|
'Review and provide any supporting information or files for your request.',
|
||||||
|
{ timeout: 60000 }
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('.cds--text-area__wrapper').find('#root').type('2021 Newest HP 17.3 inch FHD Laptop, AMD Ryzen 5 5500U 6core(Beat i7-1160G7, up to 4.0GHz),16GB RAM, 1TB PCIe SSD, Bluetooth 4.2, WiFi, HDMI, USB-A&C, Windows 10 S, w/Ghost Manta Accessories, Silver\nhttps://www.amazon.com/HP-i7-11G7-Bluetooth-Windows');
|
||||||
|
|
||||||
|
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||||
|
|
||||||
|
cy.get("input[type=file]")
|
||||||
|
.attachFile(['lorem-ipsum.pdf']);
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get("input[type=file]")
|
||||||
|
.attachFile(['png-5mb-1.png']);
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get("input[type=file]")
|
||||||
|
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||||
|
|
||||||
|
cy.wait(2000);
|
||||||
|
|
||||||
|
|
||||||
|
cy.get('button')
|
||||||
|
.contains(/^Close$/)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.wait(3000);
|
||||||
|
|
||||||
|
// cy.get('button')
|
||||||
|
// .contains(/^Return to Home$/)
|
||||||
|
// .click();
|
||||||
|
|
||||||
|
cy.contains('Started by me', { timeout: 60000 });
|
||||||
|
cy.logout();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
//Cancel a Software and License request - With Files
|
//Cancel a Software and License request - With Files
|
||||||
it('Cancel a Software and License request', () => {
|
it('Cancel a Software and License request - With Files ', () => {
|
||||||
let username = Cypress.env('requestor_username');
|
let username = Cypress.env('requestor_username');
|
||||||
let password = Cypress.env('requestor_password');
|
let password = Cypress.env('requestor_password');
|
||||||
cy.log('=====username : ' + username);
|
cy.log('=====username : ' + username);
|
||||||
@ -1224,9 +1540,9 @@ describe('Initiate a Request - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Cancel the Request').click();
|
//cy.contains('Cancel the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Cancel the Request"]').click();
|
//cy.get('input[value="Cancel the Request"]').click();
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Submit$/)
|
||||||
|
@ -13,6 +13,7 @@ const submitWithUser = (
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.log('=======visit find by id : ');
|
cy.log('=======visit find by id : ');
|
||||||
cy.visit('/admin/process-instances/find-by-id');
|
cy.visit('/admin/process-instances/find-by-id');
|
||||||
|
cy.wait(3000);
|
||||||
cy.get('#process-instance-id-input').type(processInstanceId);
|
cy.get('#process-instance-id-input').type(processInstanceId);
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -53,8 +54,8 @@ const submitWithUser = (
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Learning and development (L&D) is a function within an organization that is responsible for empowering employees\’ growth and developing their knowledge, skills, and capabilities to drive better business performance.');
|
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Learning and development (L&D) is a function within an organization that is responsible for empowering employees\’ growth and developing their knowledge, skills, and capabilities to drive better business performance.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ const submitWithUser = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Learning and Development Path - Without Files
|
//Learning and Development Path - Without Files
|
||||||
describe('Learning and Development Path - Without Files', () => {
|
describe.only('Learning and Development Path - Without Files', () => {
|
||||||
|
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//People Ops Partner Group approves the request
|
//People Ops Partner Group approves the request
|
||||||
@ -120,7 +121,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -161,9 +162,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('A L&D strategy should be aligned to the organization\’s business strategy and goals with the aim of developing the workforce\’s capability and driving business results.');
|
cy.get('.cds--text-area__wrapper').find('#root').type('A L&D strategy should be aligned to the organization\’s business strategy and goals with the aim of developing the workforce\’s capability and driving business results.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -228,7 +229,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -251,7 +252,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||||
*/
|
*/
|
||||||
cy.get('#root_item_0_sub_category').select('books');
|
cy.get('#root_item_0_sub_category').select('books');
|
||||||
cy.get('#root_item_0_item_name').clear().type('The role of the L&D function has evolved to meet the demands of digital transformation and a modern workforce.');
|
cy.get('#root_item_0_item_name').clear().type('The role of the L&D function has evolved to meet the demands of digital transformation and a modern.');
|
||||||
cy.get('#root_item_0_qty').clear().type('5');
|
cy.get('#root_item_0_qty').clear().type('5');
|
||||||
cy.get('#root_item_0_currency_type').select('Fiat');
|
cy.get('#root_item_0_currency_type').select('Fiat');
|
||||||
cy.get('#root_item_0_currency').select('EUR');
|
cy.get('#root_item_0_currency').select('EUR');
|
||||||
@ -269,9 +270,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('The function may be organized centrally, either independently or sitting under human resources (HR); decentralized throughout different business units; or be a hybrid (sometimes referred to as federated) structure.');
|
cy.get('.cds--text-area__wrapper').find('#root').type('The function may be organized centrally, either independently or sitting under human resources (HR); decentralized throughout different business units; or be a hybrid (sometimes referred to as federated) structure.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -335,7 +336,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -376,9 +377,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('Current and aspiring talent development professionals can enhance their skills with the various professional education courses offered by ATD Education \nhttps://www.aihr.com/blog/learning-and-development/');
|
cy.get('.cds--text-area__wrapper').find('#root').type('Current and aspiring talent development professionals can enhance their skills with the various professional education courses offered by ATD Education \nhttps://www.aihr.com/blog/learning-and-development/');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -461,7 +462,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -524,9 +525,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('Learning and development is a systematic process to enhance an employee\’s skills, knowledge, and competency, resulting in better performance in a work setting. \nhttps://www.aihr.com/blog/learning-and-development/');
|
cy.get('.cds--text-area__wrapper').find('#root').type('Learning and development is a systematic process to enhance an employee\’s skills, knowledge, and competency, resulting in better performance in a work setting. \nhttps://www.aihr.com/blog/learning-and-development/');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -604,7 +605,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -645,9 +646,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('A L&D strategy should be aligned to the organization\’s business strategy and goals with the aim of developing the workforce\’s capability and driving business results.');
|
cy.get('.cds--text-area__wrapper').find('#root').type('A L&D strategy should be aligned to the organization\’s business strategy and goals with the aim of developing the workforce\’s capability and driving business results.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -711,7 +712,7 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -752,9 +753,9 @@ describe('Learning and Development Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('Learning and development is a systematic process to enhance an employee\’s skills, knowledge, and competency, resulting in better performance in a work setting. \nhttps://www.aihr.com/blog/learning-and-development/');
|
cy.get('.cds--text-area__wrapper').find('#root').type('Learning and development is a systematic process to enhance an employee\’s skills, knowledge, and competency, resulting in better performance in a work setting. \nhttps://www.aihr.com/blog/learning-and-development/');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -845,7 +846,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -928,9 +929,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -995,7 +996,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1078,9 +1079,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1145,7 +1146,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1227,9 +1228,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
.attachFile(['sampletext.txt']);
|
.attachFile(['sampletext.txt']);
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1313,7 +1314,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1418,9 +1419,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1498,7 +1499,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1581,9 +1582,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -1648,7 +1649,7 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
@ -1731,9 +1732,9 @@ describe('Learning and Development Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
|
@ -13,6 +13,7 @@ const submitWithUser = (
|
|||||||
cy.wait(1000);
|
cy.wait(1000);
|
||||||
cy.log('=======visit find by id : ');
|
cy.log('=======visit find by id : ');
|
||||||
cy.visit('/admin/process-instances/find-by-id');
|
cy.visit('/admin/process-instances/find-by-id');
|
||||||
|
cy.wait(3000);
|
||||||
cy.get('#process-instance-id-input').type(processInstanceId);
|
cy.get('#process-instance-id-input').type(processInstanceId);
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -53,8 +54,8 @@ const submitWithUser = (
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Coworking tends to fall into two sides: Those that are real-estate-centric (all about selling desks and offices first) while others are community-centric (focused on building community that happens to also have offices)');
|
cy.get('.cds--text-area__wrapper').find('#root').clear().type('Providing additional info. Coworking tends to fall into two sides: Those that are real-estate-centric (all about selling desks and offices first) while others are community-centric (focused on building community that happens to also have offices)');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -84,7 +85,7 @@ const submitWithUser = (
|
|||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('Other Fees Path - Without Files', () => {
|
describe.only('Other Fees Path - Without Files', () => {
|
||||||
|
|
||||||
Cypress._.times(1, () => {
|
Cypress._.times(1, () => {
|
||||||
//Budget owner approves the request
|
//Budget owner approves the request
|
||||||
@ -120,8 +121,8 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -173,9 +174,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -240,8 +241,8 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -281,9 +282,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -347,8 +348,8 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -388,9 +389,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||||||
|
|
||||||
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -478,8 +479,8 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -571,16 +572,16 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Submit$/)
|
.contains(/^Submit$/)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.wait(9000);
|
cy.wait(20000);
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains(/^Return to Home$/)
|
.contains(/^Return to Home$/)
|
||||||
.click();
|
.click();
|
||||||
@ -638,8 +639,8 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -721,9 +722,9 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
@ -788,8 +789,8 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
{ timeout: 60000 }
|
{ timeout: 60000 }
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.wait(5000);
|
//cy.wait(5000);
|
||||||
cy.url().then((currentUrl) => {
|
cy.url().then((currentUrl) => {
|
||||||
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
// if url is "/tasks/8/d37c2f0f-016a-4066-b669-e0925b759560"
|
||||||
// extract the digits after /tasks
|
// extract the digits after /tasks
|
||||||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||||
@ -871,9 +872,9 @@ describe('Other Fees Path - With Files', () => {
|
|||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.contains('Submit the Request').click();
|
//cy.contains('Submit the Request').click();
|
||||||
|
|
||||||
cy.get('input[value="Submit the Request"]').click();
|
//cy.get('input[value="Submit the Request"]').click();
|
||||||
|
|
||||||
|
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -59,11 +59,13 @@ Cypress.Commands.add('login', (username, password) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('logout', (selector, ...args) => {
|
Cypress.Commands.add('logout', (selector, ...args) => {
|
||||||
cy.getBySel('logout-button').click();
|
cy.wait(2000);
|
||||||
|
//cy.getBySel('logout-button').click();
|
||||||
|
cy.get('#root > div > header > div.cds--header__global > span:nth-child(3) > button > svg').click();
|
||||||
if (Cypress.env('SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK') === true) {
|
if (Cypress.env('SPIFFWORKFLOW_FRONTEND_AUTH_WITH_KEYCLOAK') === true) {
|
||||||
// otherwise we can click logout, quickly load the next page, and the javascript
|
// otherwise we can click logout, quickly load the next page, and the javascript
|
||||||
// doesn't have time to actually sign you out
|
// doesn't have time to actually sign you out
|
||||||
|
//cy.wait(4000);
|
||||||
cy.contains('Sign in to your account');
|
cy.contains('Sign in to your account');
|
||||||
} else {
|
} else {
|
||||||
cy.get('#spiff-login-button').should('exist');
|
cy.get('#spiff-login-button').should('exist');
|
||||||
@ -104,7 +106,10 @@ Cypress.Commands.add(
|
|||||||
(expectAutoRedirectToHumanTask = false, returnToProcessModelShow = true) => {
|
(expectAutoRedirectToHumanTask = false, returnToProcessModelShow = true) => {
|
||||||
// cy.getBySel('start-process-instance').click();
|
// cy.getBySel('start-process-instance').click();
|
||||||
// click on button with text Start
|
// click on button with text Start
|
||||||
cy.get('button')
|
//cy.get('button')
|
||||||
|
//cy.get('#process-model-tile-manage-procurement\\/procurement\\/requisition-order-management\\/new-demand-request-procurement > div > button')
|
||||||
|
cy.get('#process-model-tile-manage-procurement\\/procurement\\/requisition-order-management\\/request-goods-services > div > button')
|
||||||
|
//cy.get('#process-model-tile-manage-procurement\\/procurement\\/requisition-order-management\\/raise-new-demand-request > div > button')
|
||||||
.contains(/^Start$/)
|
.contains(/^Start$/)
|
||||||
.click();
|
.click();
|
||||||
if (expectAutoRedirectToHumanTask) {
|
if (expectAutoRedirectToHumanTask) {
|
||||||
|
@ -42,7 +42,7 @@ export default function ActiveUsers() {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
title={`${activeUser.username} is also viewing this page`}
|
title={`${activeUser.username} is also viewing this page`}
|
||||||
className="user-circle"
|
className="user-circle user-circle-for-list"
|
||||||
>
|
>
|
||||||
{activeUser.username.charAt(0).toUpperCase()}
|
{activeUser.username.charAt(0).toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
|
Toggletip,
|
||||||
|
ToggletipButton,
|
||||||
|
ToggletipContent,
|
||||||
|
Button,
|
||||||
Header,
|
Header,
|
||||||
HeaderContainer,
|
HeaderContainer,
|
||||||
HeaderMenuButton,
|
HeaderMenuButton,
|
||||||
@ -77,25 +81,46 @@ export default function NavigationBar() {
|
|||||||
return activeKey === menuItemPath;
|
return activeKey === menuItemPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const profileToggletip = (
|
||||||
|
<div style={{ display: 'flex' }} id="user-profile-toggletip">
|
||||||
|
<Toggletip isTabTip align="bottom-right">
|
||||||
|
<ToggletipButton
|
||||||
|
aria-label="User Actions"
|
||||||
|
className="user-profile-toggletip-button"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div className="user-circle">
|
||||||
|
{UserService.getPreferredUsername()[0].toUpperCase()}
|
||||||
|
</div>
|
||||||
|
</ToggletipButton>
|
||||||
|
<ToggletipContent className="user-profile-toggletip-content">
|
||||||
|
<p>
|
||||||
|
<strong>{UserService.getPreferredUsername()}</strong>
|
||||||
|
</p>
|
||||||
|
<p>{UserService.getUserEmail()}</p>
|
||||||
|
<hr />
|
||||||
|
<Button className="button-link" onClick={handleLogout}>
|
||||||
|
<Logout />
|
||||||
|
Sign out
|
||||||
|
</Button>
|
||||||
|
</ToggletipContent>
|
||||||
|
</Toggletip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const loginAndLogoutAction = () => {
|
const loginAndLogoutAction = () => {
|
||||||
if (UserService.isLoggedIn()) {
|
if (UserService.isLoggedIn()) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{SPIFF_ENVIRONMENT ? (
|
{SPIFF_ENVIRONMENT ? (
|
||||||
<HeaderGlobalAction className="spiff-environment-header-text unclickable-text">
|
<HeaderGlobalAction
|
||||||
|
title={`The current SpiffWorkflow environment is: ${SPIFF_ENVIRONMENT}`}
|
||||||
|
className="spiff-environment-header-text unclickable-text"
|
||||||
|
>
|
||||||
{SPIFF_ENVIRONMENT}
|
{SPIFF_ENVIRONMENT}
|
||||||
</HeaderGlobalAction>
|
</HeaderGlobalAction>
|
||||||
) : null}
|
) : null}
|
||||||
<HeaderGlobalAction className="username-header-text unclickable-text">
|
{profileToggletip}
|
||||||
{UserService.getPreferredUsername()}
|
|
||||||
</HeaderGlobalAction>
|
|
||||||
<HeaderGlobalAction
|
|
||||||
aria-label="Logout"
|
|
||||||
onClick={handleLogout}
|
|
||||||
data-qa="logout-button"
|
|
||||||
>
|
|
||||||
<Logout />
|
|
||||||
</HeaderGlobalAction>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1578,32 +1578,38 @@ export default function ProcessInstanceListTable({
|
|||||||
headers.push('Action');
|
headers.push('Action');
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = processInstances.map((row: ProcessInstance) => {
|
const rows = processInstances.map((processInstance: ProcessInstance) => {
|
||||||
const currentRow = reportColumns().map((column: ReportColumn) => {
|
const currentRow = reportColumns().map((column: ReportColumn) => {
|
||||||
return formattedColumn(row, column);
|
return formattedColumn(processInstance, column);
|
||||||
});
|
});
|
||||||
if (showActionsColumn) {
|
if (showActionsColumn) {
|
||||||
let buttonElement = null;
|
let buttonElement = null;
|
||||||
const interstitialUrl = `/process/${modifyProcessIdentifierForPathParam(
|
const interstitialUrl = `/process/${modifyProcessIdentifierForPathParam(
|
||||||
row.process_model_identifier
|
processInstance.process_model_identifier
|
||||||
)}/${row.id}/interstitial`;
|
)}/${processInstance.id}/interstitial`;
|
||||||
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
const regex = new RegExp(`\\b(${preferredUsername}|${userEmail})\\b`);
|
||||||
let hasAccessToCompleteTask = false;
|
let hasAccessToCompleteTask = false;
|
||||||
if (
|
if (
|
||||||
canCompleteAllTasks ||
|
canCompleteAllTasks ||
|
||||||
(row.potential_owner_usernames || '').match(regex)
|
(processInstance.potential_owner_usernames || '').match(regex)
|
||||||
) {
|
) {
|
||||||
hasAccessToCompleteTask = true;
|
hasAccessToCompleteTask = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buttonText = 'View';
|
||||||
|
let buttonKind = 'ghost';
|
||||||
|
if (
|
||||||
|
processInstance.status !== 'suspended' &&
|
||||||
|
hasAccessToCompleteTask &&
|
||||||
|
processInstance.task_id
|
||||||
|
) {
|
||||||
|
buttonText = 'Go';
|
||||||
|
buttonKind = 'secondary';
|
||||||
|
}
|
||||||
|
|
||||||
buttonElement = (
|
buttonElement = (
|
||||||
<Button
|
<Button kind={buttonKind} href={interstitialUrl}>
|
||||||
kind={
|
{buttonText}
|
||||||
hasAccessToCompleteTask && row.task_id ? 'secondary' : 'ghost'
|
|
||||||
}
|
|
||||||
href={interstitialUrl}
|
|
||||||
>
|
|
||||||
{hasAccessToCompleteTask && row.task_id ? 'Go' : 'View'}
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
currentRow.push(<td>{buttonElement}</td>);
|
currentRow.push(<td>{buttonElement}</td>);
|
||||||
@ -1611,18 +1617,18 @@ export default function ProcessInstanceListTable({
|
|||||||
|
|
||||||
const rowStyle = { cursor: 'pointer' };
|
const rowStyle = { cursor: 'pointer' };
|
||||||
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
||||||
row.process_model_identifier
|
processInstance.process_model_identifier
|
||||||
);
|
);
|
||||||
const navigateToProcessInstance = () => {
|
const navigateToProcessInstance = () => {
|
||||||
navigate(
|
navigate(
|
||||||
`${processInstanceShowPathPrefix}/${modifiedModelId}/${row.id}`
|
`${processInstanceShowPathPrefix}/${modifiedModelId}/${processInstance.id}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||||
<tr
|
<tr
|
||||||
style={rowStyle}
|
style={rowStyle}
|
||||||
key={row.id}
|
key={processInstance.id}
|
||||||
onClick={navigateToProcessInstance}
|
onClick={navigateToProcessInstance}
|
||||||
onKeyDown={navigateToProcessInstance}
|
onKeyDown={navigateToProcessInstance}
|
||||||
>
|
>
|
||||||
|
@ -114,6 +114,12 @@ h2 {
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cds--header__global .cds--btn--primary.button-link {
|
||||||
|
color: #f4f4f4;
|
||||||
|
background-color: #393939;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.cds--header__global .cds--btn--primary {
|
.cds--header__global .cds--btn--primary {
|
||||||
background-color: #161616
|
background-color: #161616
|
||||||
}
|
}
|
||||||
@ -129,8 +135,8 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-logo {
|
.app-logo {
|
||||||
height: 85%;
|
height: 37px;
|
||||||
width: 85%;
|
width: 152px;
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
@ -200,6 +206,44 @@ h1.with-icons {
|
|||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-profile-toggletip-content {
|
||||||
|
background-color: #393939;
|
||||||
|
color: #f4f4f4;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-top: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-profile-toggletip {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
#user-profile-toggletip .cds--popover-content::before {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-profile-toggletip .cds--popover--bottom-right .cds--popover-content {
|
||||||
|
bottom: 11px;
|
||||||
|
right: -2px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 3px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-profile-toggletip .cds--popover-caret {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile-toggletip-button:hover {
|
||||||
|
background-color: #161616;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-profile-toggletip .cds--popover--tab-tip__button::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#user-profile-toggletip .cds--popover--tab-tip.cds--popover--open .cds--popover--tab-tip__button{
|
||||||
|
background-color: #161616;
|
||||||
|
}
|
||||||
|
|
||||||
.with-top-margin {
|
.with-top-margin {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
@ -471,49 +515,12 @@ svg.notification-icon {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-circle-for-list {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-circle.color-1 {
|
|
||||||
background-color: #8e8e8e;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-2 {
|
|
||||||
background-color: #a57c63;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-3 {
|
|
||||||
background-color: #8f7c7c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-4 {
|
|
||||||
background-color: #9a927f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-5 {
|
|
||||||
background-color: #5e5d5d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-6 {
|
|
||||||
background-color: #676767;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-7 {
|
|
||||||
background-color: #6d7d6d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-8 {
|
|
||||||
background-color: #7a7171;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-9 {
|
|
||||||
background-color: #837d63;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-circle.color-10 {
|
|
||||||
background-color: #686a70;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Randomize color assignment */
|
/* Randomize color assignment */
|
||||||
.user-circle:nth-child(1) {
|
.user-circle:nth-child(1) {
|
||||||
background-color: #8e8e8e;
|
background-color: #8e8e8e;
|
||||||
|
@ -351,3 +351,15 @@ export interface ProcessModelCaller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UserGroup {}
|
export interface UserGroup {}
|
||||||
|
|
||||||
|
type InterstitialPageResponseType =
|
||||||
|
| 'task_update'
|
||||||
|
| 'error'
|
||||||
|
| 'unrunnable_instance';
|
||||||
|
|
||||||
|
export interface InterstitialPageResponse {
|
||||||
|
type: InterstitialPageResponseType;
|
||||||
|
error?: any;
|
||||||
|
task?: ProcessInstanceTask;
|
||||||
|
process_instance?: ProcessInstance;
|
||||||
|
}
|
||||||
|
@ -23,10 +23,11 @@ export default function Configuration() {
|
|||||||
[targetUris.authenticationListPath]: ['GET'],
|
[targetUris.authenticationListPath]: ['GET'],
|
||||||
[targetUris.secretListPath]: ['GET'],
|
[targetUris.secretListPath]: ['GET'],
|
||||||
};
|
};
|
||||||
const { ability } = usePermissionFetcher(permissionRequestData);
|
const { ability, permissionsLoaded } = usePermissionFetcher(
|
||||||
|
permissionRequestData
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('Configuration remove error');
|
|
||||||
removeError();
|
removeError();
|
||||||
let newSelectedTabIndex = 0;
|
let newSelectedTabIndex = 0;
|
||||||
if (location.pathname.match(/^\/admin\/configuration\/authentications\b/)) {
|
if (location.pathname.match(/^\/admin\/configuration\/authentications\b/)) {
|
||||||
@ -35,6 +36,13 @@ export default function Configuration() {
|
|||||||
setSelectedTabIndex(newSelectedTabIndex);
|
setSelectedTabIndex(newSelectedTabIndex);
|
||||||
}, [location, removeError]);
|
}, [location, removeError]);
|
||||||
|
|
||||||
|
// wow, if you do not check to see if the permissions are loaded, then in safari,
|
||||||
|
// you will get {null} inside the <TabList> which totally explodes carbon (in safari!).
|
||||||
|
// we *think* that null inside a TabList works fine in all other browsers.
|
||||||
|
if (!permissionsLoaded) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tabs selectedIndex={selectedTabIndex}>
|
<Tabs selectedIndex={selectedTabIndex}>
|
||||||
|
@ -9,12 +9,14 @@ import { getBasicHeaders } from '../services/HttpService';
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
import { ProcessInstanceTask } from '../interfaces';
|
import { ProcessInstance, ProcessInstanceTask } from '../interfaces';
|
||||||
import useAPIError from '../hooks/UseApiError';
|
import useAPIError from '../hooks/UseApiError';
|
||||||
|
|
||||||
export default function ProcessInterstitial() {
|
export default function ProcessInterstitial() {
|
||||||
const [data, setData] = useState<any[]>([]);
|
const [data, setData] = useState<any[]>([]);
|
||||||
const [lastTask, setLastTask] = useState<any>(null);
|
const [lastTask, setLastTask] = useState<any>(null);
|
||||||
|
const [processInstance, setProcessInstance] =
|
||||||
|
useState<ProcessInstance | null>(null);
|
||||||
const [state, setState] = useState<string>('RUNNING');
|
const [state, setState] = useState<string>('RUNNING');
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -32,11 +34,13 @@ export default function ProcessInterstitial() {
|
|||||||
headers: getBasicHeaders(),
|
headers: getBasicHeaders(),
|
||||||
onmessage(ev) {
|
onmessage(ev) {
|
||||||
const retValue = JSON.parse(ev.data);
|
const retValue = JSON.parse(ev.data);
|
||||||
if ('error_code' in retValue) {
|
if (retValue.type === 'error') {
|
||||||
addError(retValue);
|
addError(retValue.error);
|
||||||
} else {
|
} else if (retValue.type === 'task') {
|
||||||
setData((prevData) => [retValue, ...prevData]);
|
setData((prevData) => [retValue.task, ...prevData]);
|
||||||
setLastTask(retValue);
|
setLastTask(retValue.task);
|
||||||
|
} else if (retValue.type === 'unrunnable_instance') {
|
||||||
|
setProcessInstance(retValue.unrunnable_instance);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onclose() {
|
onclose() {
|
||||||
@ -49,9 +53,14 @@ export default function ProcessInterstitial() {
|
|||||||
|
|
||||||
const shouldRedirect = useCallback(
|
const shouldRedirect = useCallback(
|
||||||
(myTask: ProcessInstanceTask): boolean => {
|
(myTask: ProcessInstanceTask): boolean => {
|
||||||
return myTask && myTask.can_complete && userTasks.includes(myTask.type);
|
return (
|
||||||
|
!processInstance &&
|
||||||
|
myTask &&
|
||||||
|
myTask.can_complete &&
|
||||||
|
userTasks.includes(myTask.type)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[userTasks]
|
[userTasks, processInstance]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -68,6 +77,9 @@ export default function ProcessInterstitial() {
|
|||||||
}, [lastTask, navigate, userTasks, shouldRedirect]);
|
}, [lastTask, navigate, userTasks, shouldRedirect]);
|
||||||
|
|
||||||
const getStatus = (): string => {
|
const getStatus = (): string => {
|
||||||
|
if (processInstance) {
|
||||||
|
return 'LOCKED';
|
||||||
|
}
|
||||||
if (!lastTask.can_complete && userTasks.includes(lastTask.type)) {
|
if (!lastTask.can_complete && userTasks.includes(lastTask.type)) {
|
||||||
return 'LOCKED';
|
return 'LOCKED';
|
||||||
}
|
}
|
||||||
@ -135,30 +147,35 @@ export default function ProcessInterstitial() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const userMessage = (myTask: ProcessInstanceTask) => {
|
const userMessage = (myTask: ProcessInstanceTask) => {
|
||||||
if (!myTask.can_complete && userTasks.includes(myTask.type)) {
|
if (!processInstance || processInstance.status === 'completed') {
|
||||||
return (
|
if (!myTask.can_complete && userTasks.includes(myTask.type)) {
|
||||||
<>
|
return (
|
||||||
<h4 className="heading-compact-01">Waiting on Someone Else</h4>
|
<>
|
||||||
<p>
|
<h4 className="heading-compact-01">Waiting on Someone Else</h4>
|
||||||
This next task is assigned to a different person or team. There is
|
<p>
|
||||||
no action for you to take at this time.
|
This next task is assigned to a different person or team. There is
|
||||||
</p>
|
no action for you to take at this time.
|
||||||
</>
|
</p>
|
||||||
);
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (shouldRedirect(myTask)) {
|
||||||
|
return <div>Redirecting you to the next task now ...</div>;
|
||||||
|
}
|
||||||
|
if (myTask.error_message) {
|
||||||
|
return <div>{myTask.error_message}</div>;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (shouldRedirect(myTask)) {
|
|
||||||
return <div>Redirecting you to the next task now ...</div>;
|
let message =
|
||||||
}
|
'There are no additional instructions or information for this task.';
|
||||||
if (myTask.error_message) {
|
if (processInstance && processInstance.status !== 'completed') {
|
||||||
return <div>{myTask.error_message}</div>;
|
message = `The tasks cannot be completed on this instance because its status is "${processInstance.status}".`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<InstructionsForEndUser
|
<InstructionsForEndUser task={myTask} defaultMessage={message} />
|
||||||
task={myTask}
|
|
||||||
defaultMessage="There are no additional instructions or information for this task."
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -176,6 +176,9 @@ export default function TaskShow() {
|
|||||||
if (disabled) {
|
if (disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!formObject) {
|
||||||
|
navigate(`/tasks`);
|
||||||
|
}
|
||||||
let queryParams = '';
|
let queryParams = '';
|
||||||
if (submitType === FormSubmitType.Draft) {
|
if (submitType === FormSubmitType.Draft) {
|
||||||
queryParams = '?save_as_draft=true';
|
queryParams = '?save_as_draft=true';
|
||||||
@ -347,20 +350,21 @@ export default function TaskShow() {
|
|||||||
|
|
||||||
if (task.state === 'READY') {
|
if (task.state === 'READY') {
|
||||||
let submitButtonText = 'Submit';
|
let submitButtonText = 'Submit';
|
||||||
let saveAsDraftButton = null;
|
let closeButton = null;
|
||||||
if (task.typename === 'ManualTask') {
|
if (task.typename === 'ManualTask') {
|
||||||
submitButtonText = 'Continue';
|
submitButtonText = 'Continue';
|
||||||
} else if (task.typename === 'UserTask') {
|
} else if (task.typename === 'UserTask') {
|
||||||
saveAsDraftButton = (
|
closeButton = (
|
||||||
<Button
|
<Button
|
||||||
id="save-as-draft-button"
|
id="close-button"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
kind="secondary"
|
kind="secondary"
|
||||||
|
title="Save changes without submitting."
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleFormSubmit(currentFormObject, null, FormSubmitType.Draft)
|
handleFormSubmit(currentFormObject, null, FormSubmitType.Draft)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Save as draft
|
Close
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -369,7 +373,7 @@ export default function TaskShow() {
|
|||||||
<Button type="submit" id="submit-button" disabled={disabled}>
|
<Button type="submit" id="submit-button" disabled={disabled}>
|
||||||
{submitButtonText}
|
{submitButtonText}
|
||||||
</Button>
|
</Button>
|
||||||
{saveAsDraftButton}
|
{closeButton}
|
||||||
<>
|
<>
|
||||||
{task.signal_buttons.map((signal) => (
|
{task.signal_buttons.map((signal) => (
|
||||||
<Button
|
<Button
|
||||||
|
@ -19,7 +19,8 @@ function SelectWidget({
|
|||||||
placeholder,
|
placeholder,
|
||||||
rawErrors = [],
|
rawErrors = [],
|
||||||
}: WidgetProps) {
|
}: WidgetProps) {
|
||||||
const { enumOptions, enumDisabled } = options;
|
const { enumOptions } = options;
|
||||||
|
let { enumDisabled } = options;
|
||||||
|
|
||||||
const emptyValue = multiple ? [] : '';
|
const emptyValue = multiple ? [] : '';
|
||||||
|
|
||||||
@ -56,6 +57,36 @@ function SelectWidget({
|
|||||||
errorMessageForField = rawErrors[0];
|
errorMessageForField = rawErrors[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ok. so in safari, the select widget showed the first option, whereas in chrome it forced you to select an option.
|
||||||
|
// this change causes causes safari to act a little bit more like chrome, but it's different because we are actually adding
|
||||||
|
// an element to the dropdown.
|
||||||
|
//
|
||||||
|
// https://stackoverflow.com/a/7944490/6090676 safari detection
|
||||||
|
let isSafari = false;
|
||||||
|
const ua = navigator.userAgent.toLowerCase();
|
||||||
|
if (ua.indexOf('safari') != -1) {
|
||||||
|
if (ua.indexOf('chrome') === -1) {
|
||||||
|
isSafari = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSafari) {
|
||||||
|
if (enumOptions && enumOptions[0].value !== '') {
|
||||||
|
enumOptions.unshift({
|
||||||
|
value: '',
|
||||||
|
label: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// enumDisabled is a list of values for which the option should be disabled.
|
||||||
|
// we don't really want users to select the fake empty option we are creating here.
|
||||||
|
// they cannot select it in chrome, after all.
|
||||||
|
// google is always right. https://news.ycombinator.com/item?id=35862041
|
||||||
|
if (enumDisabled === undefined) {
|
||||||
|
enumDisabled = [];
|
||||||
|
}
|
||||||
|
enumDisabled.push('');
|
||||||
|
}
|
||||||
|
|
||||||
// maybe use placeholder somehow. it was previously jammed into the helperText field,
|
// maybe use placeholder somehow. it was previously jammed into the helperText field,
|
||||||
// but allowing ui:help to grab that spot seems much more appropriate.
|
// but allowing ui:help to grab that spot seems much more appropriate.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user